I want to control an LED by bluetooth module (hc 05) on galileo gen 2. I need the following procedure: after sending a char, let's say '1', an LED connected to pin 2 turns on for 5 seconds and then it turns off and waits for another command. How could I do this?
I tried code: (This is actually for Galileo Gen 2, but my bluetooth works fine, I checked that on other example with turning led on and off)
include TimerOne.h
TTYUARTClass* gSerialOnePtr = &Serial1;
char input;
int led = 2;
long offAt = 0;
enum States // set values for enum Mode
{
on,
off
};
States currentState, nextState;
void setup()
{
Timer1.initialize(1000000); // seting interrupt time to 1 sec
Timer1.attachInterrupt(checkBluetooth); // Declaring ISR Function name
gSerialOnePtr->begin(9600); //start serial connection
pinMode(led, OUTPUT);
currentState = off;
}
void loop()
{
switch(currentState) // android app sends letters from A to I each letter turn on different Mode.
{
case on://red color
ledOn();
break;
case off://green color
ledOff();
break;
default:
ledOff();
break;
}
currentState = nextState; //saving next mode in current mode.
}
void checkBluetooth() //ISR for timer1
{
if(gSerialOnePtr->available()) // checking if data arrived from bluetooth module.
{
input = gSerialOnePtr->read(); // save character from serial in bt.
if(input == '1')
{
currentState = on;
}
else if(input == '2')
{
currentState = off;
}
}
}
void ledOn()
{
if( (digitalRead(led) == LOW ) )
{
digitalWrite(led, HIGH);
offAt = millis() + 5000; //store var of now + 5 seconds
}
if(digitalRead(led) == HIGH) //if led is on
{
if(millis() >= offAt) //see if it's time to turn off LED
{
digitalWrite(led, LOW); //it's time. this also re-enables the button
}
}
}
void ledOff()
{
digitalWrite(led, LOW);
}
It's not working yet...
I think that your problem is the line
currentState = nextState; //saving next mode in current mode.
Try commenting it. Or, if you want to use it the way I think you want, you have to write
void setup()
{
[...]
currentState = off;
nextState = off;
}
[...]
void checkBluetooth() //ISR for timer1
{
if(gSerialOnePtr->available())
{
input = gSerialOnePtr->read(); // save character from serial in bt.
if(input == '1')
{
nextState = on;
}
else if(input == '2')
{
nextState = off;
}
}
}
By the way, I'd also write
while(gSerialOnePtr->available())
So if you send it a 10 bytes array you don't have to wait for 10 seconds... Personally I'd also reduce the interrupt time to, let's say, 0.1 seconds, but that's not mandatory..
EDIT:
To turn off after 5 seconds, I'd write
NON RETRIGGERABLE METHOD (i.e. if you send a '1' when it's on it will be discarded)
unsigned long startTime;
void setup()
{
[...]
startTime = 0;
}
[...]
void ledOn()
{
digitalWrite(led, HIGH);
if (millis() - startTime > 5000)
nextState = off;
}
void ledOff()
{
digitalWrite(led, LOW);
startTime = millis();
}
RETRIGGERABLE METHOD (i.e. if you send a '1' when it's on the 5 seconds will start again)
unsigned long startTime;
void setup()
{
[...]
startTime = 0;
}
[...]
void checkBluetooth()
{
[...]
if(input == '1')
{
nextState = on;
startTime = millis();
}
else if(input == '2')
{
[...]
}
void ledOn()
{
digitalWrite(led, HIGH);
if (millis() - startTime > 5000)
nextState = off;
}
void ledOff()
{
digitalWrite(led, LOW);
}