下面的代码代表一个用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;
}