1

The code below represents a blood-level meter made with arduino with 5 different states: Standby, and showing water, sugar, caffeine or alcohol-level.

Most of the time it works well, but sometimes it starts lagging a lot, and the touch sensor that changes states does not give any response. Now the problem is not in the hardware, because with earlier versions of the software, the problem with the touch sensor does not appear.

I added Serial.prints to the start of all functions to see when the lag appeared, and the last print before lagging was always changeState(), so maybe the problem is somewhere in there. Or maybe has something to do with the attachInterrupt?

Oh and if you see improvements, they are always welcome!

//-------------------------
//--------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 Answers0