Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/arduino/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Arduino不执行串行命令,执行速度较慢_Arduino_Rgb_Arduino Uno_Led_Arduino Ide - Fatal编程技术网

Arduino不执行串行命令,执行速度较慢

Arduino不执行串行命令,执行速度较慢,arduino,rgb,arduino-uno,led,arduino-ide,Arduino,Rgb,Arduino Uno,Led,Arduino Ide,我已经有一段时间没有被解雇了,所以我对此表示歉意,社区一直在帮助我,我真的想首先感谢所有人 我有一个arduino项目的问题,我试图让arduino使rgb灯在用户输入时以不同的颜色打开或关闭。这听起来很基本,但不幸的是,arduino在某些情况下不能做到这一点,或者接收用户输入的速度非常慢 我不知道这是代码还是arduino自身的问题 下面是一些代码,我认为这是问题所在,当尝试此菜单时,命令执行一次,但不会放弃循环并将我返回主菜单 请注意,代码确实很长,所以这只是其中的一小部分,下面是完整的代

我已经有一段时间没有被解雇了,所以我对此表示歉意,社区一直在帮助我,我真的想首先感谢所有人

我有一个arduino项目的问题,我试图让arduino使rgb灯在用户输入时以不同的颜色打开或关闭。这听起来很基本,但不幸的是,arduino在某些情况下不能做到这一点,或者接收用户输入的速度非常慢

我不知道这是代码还是arduino自身的问题

下面是一些代码,我认为这是问题所在,当尝试此菜单时,命令执行一次,但不会放弃循环并将我返回主菜单

请注意,代码确实很长,所以这只是其中的一小部分,下面是完整的代码

(FIY ARDUINO UNO R3 ATMEGA 328)

//聚会
如果(模式==“党”| |模式==“党”| |模式==“党模式”| |模式==“党模式”| |模式==“党模式”| |模式==“c”){
Serial.println(“第三方模式”);
Serial.println(“要选择其他模式并返回,请键入back”);
int-y;
int w;
Serial.println(“多少次?注:1次=20秒”);
while(Serial.available()==0){
direct=Serial.readString();
如果(直接==“返回”| |直接==“返回”){
打破
}
y=0;
w=Serial.parseInt();
如果(y=0;fadeValue-=50){
//设置值(范围从0到255):
模拟写入(LEDRR1250);
模拟写入(LEDRL250);
模拟写入(ledBL1,0);
模拟写入(ledBR1,0);
模拟写入(ledRL2,0);
模拟写入(ledGR1,0);
模拟写入(ledBL2,fadeValue);
模拟写入(ledRR2,0);
模拟写入(ledBR2,fadeValue);
延迟(60000);
}
对于(int-fadeValue=250;fadeValue>=0;fadeValue-=50){
//设置值(范围从0到255):
模拟写入(ledRR1,fadeValue);
模拟写入(ledRL1,fadeValue);
模拟写入(ledBL1,0);
模拟写入(ledBR1,0);
模拟写入(ledRL2,0);
模拟写入(ledGR1,0);
模拟写入(ledBL2,0);
模拟写入(ledRR2,0);
模拟写入(ledBR2,0);
//等待30毫秒以查看变暗效果
延迟(60000);
}

对于(int-fadeValue=0;fadeValue我并不奇怪您的代码非常慢(对于usart命令)。有这么多的延迟。对于每个通过循环,您都需要很短的延迟。例如,如果您想要快速响应,状态机

一些陷阱:

  • 糟糕的格式

  • while(Serial.available()==0)
    是一种非常奇怪的情况。如果有数据可用,它总是会跳过整个循环

  • 评论:

        // wait for 30 milliseconds to see the dimming effect
        delay(60000);
    
    它不是30ms而是60000ms(60s)

  • Serial.print有很多常量字符串。您可以使用F(“某些闪存字符串”)助手将这些字符串仅存储在闪存中(否则必须复制到RAM中并从中显示)

如果你每“小时”检查和处理一次输入命令(打个比方),要做到“快”是相当困难的

可以使用类似的方法(只是一个简单的草图):

//原型:
uint32主菜单fsm(字节和状态);
uint32模式菜单fsm(字节和状态);
uint32关闭模式fsm(字节和状态);
uint32轻松模式fsm(字节和状态);
//FSM的全局变量
字节全局状态=0;
uint32\u t next\u check=0;
uint32_t(*状态机)(字节和状态)=主菜单和fsm;
#定义SET_FSM(FSM)Serial.println(“设置:#FSM);全局状态=0;下一次检查=0;状态机器=&FSM
//用于串行处理的全局变量
String inputString=”“;//用于保存传入数据的字符串
//RGBLed类
模板
课堂辩论{
公众:
无效开始(字节r=0,字节g=0,字节b=0){
pinMode(PinR,输出);
pinMode(PinG,输出);
pinMode(PinB,输出);
集合(r,g,b);
}
无效集(字节r=0,字节g=0,字节b=0){
模拟写入(PinR,r);
类比写作(平,g);
模拟写入(PinB,b);
}
};
rg1;
无效设置(){
序列号。开始(57600);
Led1.开始(10,10,10);
inputString.reserve(50);//应该足够所有命令使用
}
void循环(){
uint32_t curr=millis();
如果(当前>下一次检查){
下一步检查=当前+状态机器(全局状态);
/*//调试:
串行打印(curr);
连续打印(“”);
串行打印(下一次检查);
连续打印(“”);
串行打印LN(全局状态);
*/
}
}
void serialEvent(){
while(Serial.available()){
char ch=(char)Serial.read();
如果(ch='\r'| | ch='\n'){
如果(inputString.length()>0){
inputString.toLowerCase();
Serial.println(inputString);
如果(inputString.length()==1){
开关(输入字符串[0]){
案例“a”:设置FSM(放松模式);中断;
案例“o”:设置FSM(关闭模式);中断;
}
}else if(inputString.startsWith(“main”)){
设置\u FSM(主菜单\u FSM);
}else if(inputString.startsWith(“mode”)){
设置FSM(模式菜单);
}
inputString=”“;//重置字符串
break;//进程命令-中断处理
}
}否则{
inputString+=ch;
}
}
}
uint32主菜单fsm(字节和状态){
如果(状态==0){
Serial.println(F(“欢迎来到Andy Mood'O Matic light machine”);
序列号println(F(“”);
Serial.println(F(“请根据您的心情选择模式”);
序列号println(F(“”);
序列号println(F(“”);
Serial.println(F(“命令和可用模式”);
println(F(“命令:主菜单或仅主菜单”);
序列号println(F(“”);
Serial.println(F(“请键入模式以查看可用模式”);
++国家;
}
返回5000UL;
}
uint32模式菜单fsm(字节和状态){
如果(状态==0){
println(F(“可用模式,注意:您可以使用简单的命令!”);
序列号println(F)
//List of pins and corresponding colors

//RIGHT SIDE
//Red1 5
//Green1 3
//Blue1 6

//Red4 A4
//Green4 A3
//Blue4 A5


////////////////////////////////////////////


//Left Side
//Red2 9
//Green2 11
//Blue2 10

//Red3 A1
//Green3 A0
//Blue3 A2


//Right Side
int ledRR1 = 5;
int ledGR1 = 3;
int ledBR1 = 6;

int ledRR2 = A4;
int ledGR2 = A3;
int ledBR2 = A5;

///////////////////

//Left Side
int ledRL1 = 9;
int ledGL1 = 11;
int ledBL1 = 10;

int ledRL2 = A1;
int ledGL2 = A0;
int ledBL2 = A2;

//////////////////


//Strings

String mode;
String node;
String moving;
String direct;
int x;



void setup(){

  Serial.begin(9600);

//PinMode

pinMode(ledRR1, OUTPUT);
pinMode(ledGR1, OUTPUT);
pinMode(ledBR1, OUTPUT);
pinMode(ledRR2, OUTPUT);
pinMode(ledGR2, OUTPUT);
pinMode(ledBR2, OUTPUT);
pinMode(ledRL1, OUTPUT);
pinMode(ledGL1, OUTPUT);
pinMode(ledBL1, OUTPUT);
pinMode(ledRL2, OUTPUT);
pinMode(ledGL2, OUTPUT);
pinMode(ledBL2, OUTPUT);

//START IN THIS STATE:

//Right
analogWrite(ledRR1, 0);
analogWrite(ledGR1, 0);
analogWrite(ledBR1, 0);

analogWrite(ledRR2, 0);
analogWrite(ledGR2, 0);
analogWrite(ledBR2, 0);

//Left
analogWrite(ledRL1, 0);
analogWrite(ledGL1, 0);
analogWrite(ledBL1, 0);

analogWrite(ledRL2, 0);
analogWrite(ledGL2, 0);
analogWrite(ledBL2, 0);

x = 0;


}

void loop(){

Serial.println("Main menu");

 while(Serial.available()==0){

  mode = Serial.readString();
  node = Serial.readString();
  moving = Serial.readString();
  Serial.setTimeout(50);


  while( x <= 0){

  Serial.println("Welcome to Andy Mood'O Matic light machine");
  Serial.println("");
  Serial.println("Please select the mode according to your mood");
  Serial.println("");
  Serial.println("");
  Serial.println("Commands and available modes");
  Serial.println("Commands: Main Menu or just main");
  Serial.println("");
  Serial.println("Please type modes to see the available modes");
  Serial.println("");
  Serial.println("SOMETIMES THE ARDUINO IS SLOW AND YOU HAVE TO INPUT THE COMMAND TWICE!");
  x = x+1;
  }

  if(node == "modes" || node == "Modes"){
    Serial.println("Available modes, NOTE: YOU CAN USE SIMPLE COMMANDS!");
    Serial.println("");
    Serial.println("Relax /SIMPLE COMMAND: a");
      Serial.println("   Automated Relax mode");
    Serial.println("");
    Serial.println("Intimate /SIMPLE COMMAND: b");
      Serial.println("  Automated intimate mode");
    Serial.println("");
    Serial.println("Party mode or Party /SIMPLE COMMAND: c");
      Serial.println("  This is user controlled, set the amount of time you want the lights to go for");
      Serial.println("  Please check description in party mode to see available options");
    Serial.println("");
    Serial.println("Night /SIMPLE COMMAND: d");
      Serial.println("  Automated night mode");
      Serial.println("  User controlled night mode, set how dim the lights should be and time");
    Serial.println("");
    Serial.println("Off /SIMPLE COMMAND o");
      Serial.println("   Turns everything off");


  }

  if(moving == "Main Menu" || moving == "main menu" || moving == "Main menu" || moving == "main Menu" || moving == "main menu" || moving == "main" || moving == "Main"){
    //This is to go back to main main, for each stop loop you have to add this to repeat the println
  x = x-1;
  }




//Relax
  if(mode == "Relax" || mode == "relax" || mode == "a" ){
    Serial.println("This is automatic relax mode");

   for(int fadeValue = 0; fadeValue <= 250; fadeValue +=10){

    analogWrite(ledGR1,fadeValue);
    analogWrite(ledGL1, fadeValue);
    analogWrite(ledBL1, 250);
    analogWrite(ledBR1, 250);
    analogWrite(ledGR2, fadeValue);
    analogWrite(ledGL2,fadeValue);
    analogWrite(ledBR2,fadeValue); 
    analogWrite(ledBL2,fadeValue); 

    delay(60000);
  }


  for (int fadeValue = 250; fadeValue >= 0; fadeValue -= 10){
    // sets the value (range from 0 to 255):
    analogWrite(ledBL1, 250);
    analogWrite(ledBR1, 250);
    analogWrite(ledGR2,fadeValue); 
    analogWrite(ledGL2, fadeValue); 
    analogWrite(ledGR1, fadeValue);
    analogWrite(ledGL1,fadeValue);
    analogWrite(ledBL2,fadeValue); 
    analogWrite(ledBR2,fadeValue); 

    // wait for 30 milliseconds to see the dimming effect
    delay(60000);
  }



   for(int fadeValue = 0; fadeValue <= 250; fadeValue +=10){

    analogWrite(ledGR2,fadeValue);
    analogWrite(ledGL2, 0); 
    analogWrite(ledBL1, 250);
    analogWrite(ledBR1, 250);
    analogWrite(ledGR1, fadeValue);
    analogWrite(ledGL1, 0);
    analogWrite(ledBR2,fadeValue); 
    analogWrite(ledBL2,fadeValue); 

    delay(60000);
  }


  for (int fadeValue = 250; fadeValue >= 0; fadeValue -= 10){
    // sets the value (range from 0 to 255):
    analogWrite(ledBR1, 250);
    analogWrite(ledBL1, 250);
    analogWrite(ledGR2,fadeValue); 
    analogWrite(ledGR1, 0); 
    analogWrite(ledGR2, fadeValue);
    analogWrite(ledGL2, 0);
    analogWrite(ledBL2,fadeValue); 
    analogWrite(ledBR2,fadeValue); 

    // wait for 30 milliseconds to see the dimming effect
    delay(60000);
  }


  analogWrite(ledGL1, 0);
  analogWrite(ledGR1,0);
  analogWrite(ledGR2,0);
  analogWrite(ledGL2,0);
  analogWrite(ledBL1, 250);
  analogWrite(ledBR1, 250);
  analogWrite(ledBL2,0); 
  analogWrite(ledBR2,0); 
}



//Off 
  if(mode == "Off" || mode == "o" || mode == "off"){
    Serial.println("Everything off");

      analogWrite(ledRR1, 0);
      analogWrite(ledGR1, 0);
      analogWrite(ledBR1, 0);

      analogWrite(ledRR2, 0);
      analogWrite(ledGR2, 0);
      analogWrite(ledBR2, 0);


      analogWrite(ledRL1, 0);
      analogWrite(ledGL1, 0);
      analogWrite(ledBL1, 0);

      analogWrite(ledRL2, 0);
      analogWrite(ledGL2, 0);
      analogWrite(ledBL2, 0); 

  }


//Intimate  
  if(mode == "intimate" || mode == "Intimate" || mode == "b"){
    Serial.println("Automatic Intimate mode");
    for(int fadeValue = 0; fadeValue <= 150; fadeValue +=50){

    analogWrite(ledRR1,250);
    analogWrite(ledRL1, 250);
    analogWrite(ledBR1, fadeValue);
    analogWrite(ledBL1, fadeValue);
    analogWrite(ledRL2, fadeValue);
    analogWrite(ledGR1,fadeValue);
    analogWrite(ledBL2,fadeValue);
    analogWrite(ledRR2,fadeValue);
    analogWrite(ledBR2,fadeValue);

    delay(60000);
  }

  for (int fadeValue = 250; fadeValue >= 0; fadeValue -= 50){
    // sets the value (range from 0 to 255):
    analogWrite(ledRR1,250);
    analogWrite(ledRL1, 250);
    analogWrite(ledBL1, fadeValue);
    analogWrite(ledBR1, 250);
    analogWrite(ledRL2, fadeValue);
    analogWrite(ledGR1,fadeValue);
    analogWrite(ledBL2, 250);
    analogWrite(ledRR2,fadeValue);
    analogWrite(ledBR2,150);

    // wait for 30 milliseconds to see the dimming effect
    delay(60000);
  }

      for (int fadeValue = 250; fadeValue >= 150; fadeValue -= 50){
    // sets the value (range from 0 to 255):
    analogWrite(ledRR1, 250);
    analogWrite(ledRL1, 250);
    analogWrite(ledBL1, 0);
    analogWrite(ledBR1, 0);
    analogWrite(ledRL2, 0);
    analogWrite(ledGR1,0);
    analogWrite(ledBL2,fadeValue);
    analogWrite(ledRR2,0);
    analogWrite(ledBR2, 150);
    delay(60000);
      }

    for (int fadeValue = 150; fadeValue >= 0; fadeValue -= 50){
    // sets the value (range from 0 to 255):
    analogWrite(ledRR1,250);
    analogWrite(ledRL1, 250);
    analogWrite(ledBL1, 0);
    analogWrite(ledBR1, 0);
    analogWrite(ledRL2, 0);
    analogWrite(ledGR1,0);
    analogWrite(ledBL2,fadeValue);
    analogWrite(ledRR2,0);
    analogWrite(ledBR2,fadeValue);
    delay(60000);
    }

  for (int fadeValue = 250; fadeValue >= 0; fadeValue -= 50){
    // sets the value (range from 0 to 255):
    analogWrite(ledRR1,fadeValue);
    analogWrite(ledRL1, fadeValue);
    analogWrite(ledBL1, 0);
    analogWrite(ledBR1, 0);
    analogWrite(ledRL2, 0);
    analogWrite(ledGR1,0);
    analogWrite(ledBL2,0);
    analogWrite(ledRR2,0);
    analogWrite(ledBR2,0);

    // wait for 30 milliseconds to see the dimming effect
    delay(60000);
  }

  for(int fadeValue = 0; fadeValue <= 150; fadeValue +=50){

    analogWrite(ledRR1,fadeValue);
    analogWrite(ledRL1, fadeValue);
    analogWrite(ledBL1, fadeValue);
    analogWrite(ledBR1, fadeValue);
    analogWrite(ledRL2, fadeValue);
    analogWrite(ledGR1, 0);
    analogWrite(ledBL2,fadeValue);
    analogWrite(ledRR2,fadeValue);
    analogWrite(ledBR2,fadeValue);

    delay(60000);
  }
    for(int fadeValue = 0; fadeValue <= 250; fadeValue +=50){

    analogWrite(ledRR1, fadeValue);
    analogWrite(ledRL1, fadeValue);
    analogWrite(ledBL1, 150);
    analogWrite(ledBR1, 150);
    analogWrite(ledRL2, fadeValue);
    analogWrite(ledGR1, 0);
    analogWrite(ledBL2, 150);
    analogWrite(ledRR2, fadeValue);
    analogWrite(ledBR2, 150);

    delay(60000);
  }
    analogWrite(ledRR1, 0);
    analogWrite(ledRL1, 0);
    analogWrite(ledBL1, 150);
    analogWrite(ledBR1, 150);
    analogWrite(ledRL2, 0);
    analogWrite(ledGR1, 0);
    analogWrite(ledBL2, 150);
    analogWrite(ledRR2, 0);
    analogWrite(ledBR2, 150);

 }


//Party  
  if(mode == "Party" || mode == "party" || mode == "Party mode" || mode == "party mode" || mode == "Party Mode" || mode == "party Mode" || mode == "c"){
    Serial.println("Party mode");
    Serial.println("For selecting another mode and go back please type back");
  int y;

  int w;
  Serial.println("How many times? note: 1 time = 20 seconds");
while(Serial.available()==0){
  direct = Serial.readString();

  if(direct == "Back" || direct == "back" ){
    break;
  }

  y = 0;
  w = Serial.parseInt();

 if(y <= w){ 

for(int i = 0; i < w; i = i+1){
  Serial.println("Initializing");
  Serial.println(w);

  for(int fadeValue = 0; fadeValue <= 250; fadeValue +=50){
   analogWrite(ledRR1, fadeValue);
   analogWrite(ledBR1, fadeValue);
   delay(500);
   analogWrite(ledGR1, fadeValue);
   analogWrite(ledGL1,fadeValue);
   analogWrite(ledBL1, 0);
   analogWrite(ledRR1,0);
   analogWrite(ledGL2,0);
   analogWrite(ledRL2,0);
   analogWrite(ledBL2,0); 
   analogWrite(ledGR2,0);
   analogWrite(ledRR2,0);
   analogWrite(ledBR2,0);


    delay(500);
  }
  analogWrite(ledRR1, 250);
  analogWrite(ledGR2, 250);
     analogWrite(ledBR1, 0);
     analogWrite(ledGR1, 0);
  analogWrite(ledBL1, 0);
     analogWrite(ledRL1,0);
   analogWrite(ledGL2,0);
   analogWrite(ledRL2,0);
   analogWrite(ledBL2,0); 
   analogWrite(ledGR2,0);
   analogWrite(ledRR2,0);
   analogWrite(ledBR2,0);
  delay(1000);
  analogWrite(ledBR1, 250); 
  analogWrite(ledRL1, 250);
  delay(500);
  analogWrite(ledGR1, 250);
  analogWrite(ledRR1, 250);
  analogWrite(ledBL1, 250);
  analogWrite(ledGL1, 150);
  analogWrite(ledRL1, 50);
  delay(1000);
      analogWrite(ledGR1, 0);
  analogWrite(ledRR1, 0);
  analogWrite(ledBL1, 0);
  analogWrite(ledGL1, 0);
  analogWrite(ledRL1, 0);
  delay(500);
    analogWrite(ledGR1, 250);
  analogWrite(ledRR1, 250);
  analogWrite(ledBL1, 250);
  analogWrite(ledGL1, 150);
  analogWrite(ledRL1, 50);
  delay(500);
      analogWrite(ledGR1, 0);
  analogWrite(ledRR1, 0);
  analogWrite(ledBL1, 0);
  analogWrite(ledGL1, 0);
  analogWrite(ledRL1, 0);
  delay(1000);
    analogWrite(ledGR1, 250);
  analogWrite(ledRR1, 250);
  analogWrite(ledBL1, 250);
  analogWrite(ledGL1, 150);
  analogWrite(ledRL1, 50);
  delay(2000);

  analogWrite(ledGL1,250);
  analogWrite(ledGR1, 250);
  delay(1000);
    analogWrite(ledGL1,0);
  analogWrite(ledGR1, 0);
  delay(500);
    analogWrite(ledRR1,250);
  analogWrite(ledRL1, 250);
  delay(1000);
    analogWrite(ledRR1,0);
  analogWrite(ledRL1, 0);
  delay(500);
    analogWrite(ledGL1,250);
  analogWrite(ledGR1, 250);
  analogWrite(ledBR1,250);
  analogWrite(ledBL1,250);
  delay(2000);
    analogWrite(ledGL1,0);
  analogWrite(ledGR1, 0);
  delay(1000);

    analogWrite(ledRR1, 0);
  analogWrite(ledBR1, 0);
  analogWrite(ledGR1, 0);
  analogWrite(ledGL1,0);
  analogWrite(ledBL1, 0);
  analogWrite(ledRL1,0);
  analogWrite(ledGL2,0);
  analogWrite(ledRL2,0);
  analogWrite(ledBL2,0); 
  analogWrite(ledGR2,0);
  analogWrite(ledRR2,0);
  analogWrite(ledBR2,0);

  y = y +1;
}
 }
 else if(y >= w){
   Serial.println("Please type main to go back to main menu or select another value");
   break;
 }
}

  }


//Night  
  if(mode == "Night" || mode == "night" || mode == "d"){
    Serial.println("Automatic night mode");

      analogWrite(ledRR1, 250);
      analogWrite(ledGR1, 250);
      analogWrite(ledBR1, 250);

      analogWrite(ledRR2, 250);
      analogWrite(ledGR2, 250);
      analogWrite(ledBR2, 250);


      analogWrite(ledRL1, 250);
      analogWrite(ledGL1, 250);
      analogWrite(ledBL1, 250);

      analogWrite(ledRL2, 250);
      analogWrite(ledGL2, 250);
      analogWrite(ledBL2, 250); 
      delay(3600000);


  for(int fadeValue = 250; fadeValue >= 0; fadeValue -=50){

     analogWrite(ledRR1, fadeValue);
      analogWrite(ledGR1, fadeValue);
      analogWrite(ledBR1, fadeValue);

      analogWrite(ledRR2, fadeValue);
      analogWrite(ledGR2, fadeValue);
      analogWrite(ledBR2, fadeValue);


      analogWrite(ledRL1, fadeValue);
      analogWrite(ledGL1, fadeValue);
      analogWrite(ledBL1, fadeValue);

      analogWrite(ledRL2, fadeValue);
      analogWrite(ledGL2, fadeValue);
      analogWrite(ledBL2, fadeValue);

      delay(120000);
     Serial.println("Good Night");


  }
        analogWrite(ledRR1, 0);
      analogWrite(ledGR1, 0);
      analogWrite(ledBR1, 0);

      analogWrite(ledRR2, 0);
      analogWrite(ledGR2, 0);
      analogWrite(ledBR2, 0);


      analogWrite(ledRL1, 0);
      analogWrite(ledGL1, 0);
      analogWrite(ledBL1, 0);

      analogWrite(ledRL2, 0);
      analogWrite(ledGL2, 0);
      analogWrite(ledBL2, 0); 
   break;   
  }

}
}
    // wait for 30 milliseconds to see the dimming effect
    delay(60000);
// prototypes:
uint32_t  main_menu_fsm(byte & state);
uint32_t  mode_menu_fsm(byte & state);
uint32_t   off_mode_fsm(byte & state);
uint32_t relax_mode_fsm(byte & state);

// global variables for FSM
byte                         glob_state = 0;
uint32_t                     next_check = 0;
uint32_t (*state_machine)(byte & state) = &main_menu_fsm;

#define SET_FSM(fsm) Serial.println("Setting: " #fsm); glob_state=0; next_check=0; state_machine = &fsm


// global variables for Serial processing
String inputString = "";         // a string to hold incoming data

// RGBLed class
template <byte PinR, byte PinG, byte PinB>
class RGBLed {
  public:
    void begin(byte r = 0, byte g = 0, byte b = 0) {
      pinMode(PinR, OUTPUT);
      pinMode(PinG, OUTPUT);
      pinMode(PinB, OUTPUT);
      set(r,g,b);
    }

    void set(byte r = 0, byte g = 0, byte b = 0) {
      analogWrite(PinR, r);
      analogWrite(PinG, g);
      analogWrite(PinB, b);
    }
};

RGBLed<9,10,11>  Led1;

void setup() {
  Serial.begin(57600);
  Led1.begin(10,10,10);
  inputString.reserve(50); // should be enough for all commands


}

void loop() {
  uint32_t curr = millis();
  if (curr > next_check) {
    next_check = curr + state_machine(glob_state);
/*  // debug:
    Serial.print(curr);
    Serial.print(" "); 
    Serial.print(next_check);
    Serial.print(" ");
    Serial.println(glob_state);
*/
  }
}

void serialEvent() {
  while (Serial.available()) {
    char ch = (char)Serial.read();
    if (ch == '\r' || ch == '\n') {
      if (inputString.length()>0) {
        inputString.toLowerCase();
        Serial.println(inputString);

        if (inputString.length()==1) {
          switch (inputString[0]) {
            case 'a': SET_FSM(relax_mode_fsm); break;
            case 'o': SET_FSM(off_mode_fsm);   break;
          }
        } else if (inputString.startsWith("main")) {
          SET_FSM(main_menu_fsm);
        } else if (inputString.startsWith("mode")) {
          SET_FSM(mode_menu_fsm);
        }
        inputString = ""; // reset string
        break; // process command - interrupt processing
      }
    } else {
      inputString += ch;
    }
  }
}

uint32_t  main_menu_fsm(byte & state) {
  if (state == 0) {
    Serial.println(F("Welcome to Andy Mood'O Matic light machine"));
    Serial.println(F(""));
    Serial.println(F("Please select the mode according to your mood"));
    Serial.println(F(""));
    Serial.println(F(""));
    Serial.println(F("Commands and available modes"));
    Serial.println(F("Commands: Main Menu or just main"));
    Serial.println(F(""));
    Serial.println(F("Please type modes to see the available modes"));

    ++state;
  }
  return 5000UL;
}

uint32_t  mode_menu_fsm(byte & state) {
  if (state == 0) {
    Serial.println(F("Available modes, NOTE: YOU CAN USE SIMPLE COMMANDS!"));
    Serial.println(F(""));
    Serial.println(F("Relax or a [works only 'a' and just brief implementation]"));
      Serial.println(F("   Automated Relax mode"));
    Serial.println(F(""));
    Serial.println(F("Intimate or b [not implemented]"));
      Serial.println(F("  Automated intimate mode"));
    Serial.println(F(""));
    Serial.println(F("Party mode or Party or c [not implemented]"));
      Serial.println(F("  This is user controlled, set the amount of time you want the lights to go for"));
      Serial.println(F("  Please check description in party mode to see available options"));
    Serial.println(F(""));
    Serial.println(F("Night or d"));
      Serial.println(F("  Automated night mode [not implemented]"));
      Serial.println(F("  User controlled night mode, set how dim the lights should be and time"));
    Serial.println(F(""));
    Serial.println(F("Off or o [works only 'o']"));
      Serial.println(F("   Turns everything off"));

    ++state;
  }
  return 5000UL;
}

uint32_t   off_mode_fsm(byte & state) {
  if (state == 0) {
    Serial.println(F("Entering Off Mode"));
    Led1.set(0,0,0);
    ++state;
  }
  return 5000UL;
}

uint32_t relax_mode_fsm(byte & state) {
  if (state == 0) {
    Serial.println(F("Entering Off Mode"));
  }

  if (++state == 8) state = 1;

  Led1.set((1 & state) * 255, (1 & (state >> 1)) * 128, (1 & (state >> 2)) * 128);

  return 2000UL;
}