状态机无法解释

时间:2017-03-11 11:07:11

标签: loops arduino interrupt sensor state-machine

下面的代码代表一个用arduino制作的血液计,有5种不同的状态:待机,并显示水,糖,咖啡因或酒精含量。

大部分时间它运行良好,但有时它会开始滞后,而改变状态的触摸传感器不会给出任何响应。现在问题不在于硬件,因为在早期版本的软件中,触摸传感器的问题不会出现。

我在所有函数的开头添加了Serial.prints,以查看滞后何时出现,而滞后之前的最后一次打印始终是changeState(),所以问题可能就在那里。或者可能与attachInterrupt有关?

哦,如果你看到了改进,我们随时欢迎他们!

//-------------------------
//--------Libraries--------
//-------------------------
#include <ChainableLED.h>

//-------------------------
//---Sensors & Actuators---
//-------------------------
#define lightSensor     8
#define touchSensor     2
#define vibrationMotor  4

//ChainableLED
#define clkPin          A2
#define dataPin         A3
#define numLEDS         1

//-------------------------
//--------Variables--------
//-------------------------
ChainableLED leds(clkPin,dataPin,numLEDS);

//Blood-levels
byte waterLVL           = 50, sugarLVL = 40, drunkCaffeine, caffeineLVL = 20, drunkAlcohol, alcoholLVL = 30;
boolean waterWarn       = false, sugarWarn = false, caffeineWarn = false, alcoholWarn = false;
byte bloodCounter       = 0;

#define updateTime      50        //Update blood-levels every 5 seconds;
#define maxLVL          40

int touchTime           = 0;
byte vibrateCount       = 0;
#define shortVibration  3
#define longVibration   10

boolean isOn            = false;  //Does lightsensor detect light? If so, device is on
#define minLight        500       //Minimum amount of light detected to turn off Standby

byte stateCounter       = 0;      //Amount of time state is visible
#define delayTime       100       //Amount of ms to wait after loop
#define stateWaitTime   50        //Time state stay in focus until they change back to water

byte curR               = 0;      //Current RGB-values for led
byte curG               = 0;
byte curB               = 0;
#define colorSteps      15

//-------------------------
//------Setup & Loop-------
//-------------------------

void setup() {
  Serial.begin(9600);
  leds.init();

  pinMode(touchSensor, INPUT);
  pinMode(lightSensor, INPUT);
  pinMode(vibrationMotor, OUTPUT);

  //getRandomBloodValues();
  attachInterrupt(touchSensor-2, increaseState, RISING);
  delay(3000);

}

void loop() {
  //updateBloodValues();
  //getWarning();
  //updateStateMachine();
  delay(delayTime);
}


//-------------------------
//------Conditions---------
//-------------------------

boolean isLight() {
  if (digitalRead(lightSensor) == HIGH) {
    return true;
  } else return false;
}


//-------------------------
//-----State machines------
//-------------------------

enum curState {Standby, Water, Sugar, Caffeine, Alcohol};
curState state;

void updateStateMachine() {  
  switch (state) {
    // Wearable staat in standby
    case Standby:
      if (isLight()) {state = Water; changeColour(0,0,255);} 
      break;


    // Wearable toont waterniveau en 3 leds die aangeven
    //of caffeine en/of alcohol aanwezig zijn in het bloed
    case Water:
      if(!isLight()){
        state = Standby;
        break;
        }
      break;


    // Wearable toont suikerniveau in bloed
    case Sugar:
      if(changeState()){break;}
      stateCounter++;
      break;


    // Wearable toont caffeine-niveau in bloed
    case Caffeine :
      if(changeState()){break;}
      stateCounter++;
      break;


    // Wearable toont alcohol-niveau in bloed
    case Alcohol  :
      if(changeState()){break;}
      stateCounter++;
      break;

  } // end switch
}   // end updateStateMachine


//-------------------------
//----AttachInterrupts-----
//-------------------------

void increaseState() {
    switch (state) {
      case Standby:
        state = Water;
        stateCounter = 0;
        changeColour(0,0,map(waterLVL, 0, 100, 0, 255));
        break;

      case Water:
        state = Sugar;
        stateCounter = 0;
        changeColour(map(sugarLVL, 0, 100, 0, 255),map(sugarLVL, 0, 100, 0, 255),0);
        break;

      case Sugar:
        if(caffeineLVL>0){
          state = Caffeine;
          changeColour(0,map(caffeineLVL, 0, 100, 0, 255),0);
        } 
        else if (alcoholLVL>0){
          state = Alcohol;
          changeColour(map(alcoholLVL, 0, 100, 0, 255), 0, map(alcoholLVL, 0, 100, 0, 255));
        }
        else{ 
          state=Water;
          changeColour(0,0,map(waterLVL, 0, 100, 0, 255));
        }
        stateCounter = 0;
        break;

      case Caffeine:
        if(alcoholLVL>0){
          state = Alcohol;
          changeColour(map(alcoholLVL, 0, 100, 0, 255),0,map(alcoholLVL, 0, 100, 0, 255));
        } 
        else{ 
          state = Water;
          changeColour(0,0,map(waterLVL, 0, 100, 0, 255));
        }
        stateCounter = 0;
        break;

      case Alcohol:
        state = Water;
        stateCounter = 0;
        changeColour(0,0,map(waterLVL, 0, 100, 0, 255));
        break;
  }
}


//-------------------------
//--------Actions----------
//-------------------------

boolean changeState(){
  if(!isLight){
    state = Standby;
    return true;
  }
  else if(stateCounter > stateWaitTime){
    state = Water;
    changeColour(0,0,255);
    stateCounter = 0;
    return true;
  }
  return false;
}

void updateBloodValues(){
  if(bloodCounter > updateTime){
    if(!waterLVL    <= 0){waterLVL    -= 10;}
    if(!sugarLVL    <= 0){sugarLVL    -= 10;}
    if(!caffeineLVL <= 0){caffeineLVL -= 10;}
    if(!alcoholLVL  <= 0){alcoholLVL  -= 10;}

    bloodCounter = 0;

    /*Serial.println("");
    Serial.print("Water level     = ");Serial.println(waterLVL);
    Serial.print("Sugar level     = ");Serial.println(sugarLVL);
    Serial.print("Caffeine level  = ");Serial.println(caffeineLVL);
    Serial.print("Alcohol level   = ");Serial.println(alcoholLVL);
    Serial.println("");*/
  }
  else bloodCounter++;
}

void getWarning(){
  if(waterLVL < 20 && waterWarn == false){
    state = Water;
    vibrate(shortVibration);
    waterWarn = true;
  } else if(waterLVL > 20) waterWarn = false;

  if(sugarLVL > maxLVL && sugarWarn == false){
    Serial.println("Watch out for the sugar!");
    state = Sugar;
    vibrate(shortVibration);
    sugarWarn = true;
  } else if(sugarLVL <= maxLVL) sugarWarn = false;

  if(caffeineLVL > maxLVL && caffeineWarn == false){
    Serial.println("Watch out for the caffeine");
    state = Caffeine;
    vibrate(shortVibration);
    caffeineWarn = true;
  } else if(caffeineLVL <= maxLVL) caffeineWarn = false;

  if(alcoholLVL > maxLVL && alcoholWarn == false){
    Serial.println("Watch out for the alcohol!");
    state = Alcohol;
    vibrate(shortVibration);
    alcoholWarn = true;
  } else if(alcoholLVL <= maxLVL) alcoholWarn = false;
}

void vibrate(byte reps){
  do{
      digitalWrite(vibrationMotor, HIGH);
      vibrateCount++;
      delay(100);
    } while(vibrateCount< reps+1);
    digitalWrite(vibrationMotor, LOW);
    vibrateCount = 0;
}

void changeColour(byte newR, byte newG, byte newB){
  for(int i=0; i<colorSteps+1; i++){
    leds.setColorRGB(0, (curR-(i*((curR-newR)/colorSteps))), curG-(i*(curG-newG)/colorSteps), curB-(i*(curB-newB)/colorSteps));
    delay(35);
  }
  curR = newR; curG = newG; curB = newB;
}

0 个答案:

没有答案