Using Android with bluetooth to control relays

I have developed an Android app that controls some relays via bluetooth to a nano. It has been working quite happily for four years but, it uses delay built into the app. I'm redesigning the app and having the delay in the app is now giving some problems. Here is the code that works using the app delay. Not shown are 6 more relays that are simply on/off.

char data = 0;
void setup()
{
  Serial.begin(9600);
  pinMode(2, OUTPUT);
  pinMode(3, OUTPUT);


  digitalWrite(2, HIGH);
  digitalWrite(3, HIGH);

}
void loop()
{
  if (Serial.available() > 0)
  {
    data = Serial.read();
    Serial.print(data);
    Serial.print("\n");

    //----------------------------------3
    //door lock-------------
    if (data == 'E')
      digitalWrite(2, LOW);
                          //delay 3.5 seconds 3500 built into the app

    else if (data == 'F')//App uses this command to set 2 high
      digitalWrite(2, HIGH);
    //----------------------------------4
    //door unlock-------------
    if (data == 'G')
      digitalWrite(3, LOW);
                          //delay 3.5 seconds 3500 built into the app

    else if (data == 'H')//App uses this command to set 3 high
      digitalWrite(3, HIGH);



  }

}

As usual I've looked at all I can find on the subject of using millis and don't seem to find quite what I am looking for. I need the pin to stay LOW for a period of time after the arduino gets the bluetooth signal to go low then go HIGH until requested again.
I thought this would do it. Not only does it not work, none of the other 6 relays work and I get a broken pipe error.




unsigned long startMillis;  
unsigned long currentMillis;
unsigned long currentTime = millis();


unsigned long prevTime_T1 = millis();
unsigned long prevTime_T4 = millis();

long interval_T1 = 3000; // reset door lock relay
long interval_T4 = 3000; //reset door unlock relay

char data = 0;
void setup()
{
  Serial.begin(9600);
  pinMode(2, OUTPUT);
  pinMode(3, OUTPUT);
 
  digitalWrite(2, HIGH);
  digitalWrite(3, HIGH);
 

  startMillis = millis();  //initial start time

}
void loop()
{
  if (Serial.available() > 0)
    unsigned long currentTime = millis();
  {
    data = Serial.read();
    Serial.print(data);
    Serial.print("\n");

    //----------------------------------3
    //door lock-------------
    if (data == 'E') 
      digitalWrite(2, LOW);
  
     if (currentTime - prevTime_T1 > interval_T1)
      
 
  digitalWrite(2, HIGH);
    prevTime_T1 = currentTime;

    //----------------------------------4
    //door unlock-------------
    if (data == 'G') 
      digitalWrite(3, LOW);
      if (currentTime - prevTime_T4 > interval_T4)
  
   digitalWrite(3, HIGH);
   prevTime_T4 = currentTime; 
  }
}



Thanks for looking

When serial becomes available, do you want to do everything else in your loop to happen? If so then you need to move the opening curly brace to be right after your if

if (Serial.available() > 0)   {
    unsigned long currentTime = millis();
    data = Serial.read();

To run with a timed cycle after input, you will need to separate the cycle timing from the .available() input block.

Record a start time when you turn on with input and use a boolean control to enable a timed cycle.

See this example for turning on an led for a period of time after input.

https://forum.arduino.cc/t/buetooth-controller-timing-problem/984515/4

try this simple test

// whn E entered switch on LED for three seconds

#define ONTIME 3000

void setup() {
  Serial.begin(115200);
  pinMode(LED_BUILTIN, OUTPUT);
}

void loop() {
  static unsigned long startTime=0;  // this holds time when LED is switched on
  // if E entered switch on LED
  if(Serial.available()) {   
    if(Serial.read()=='E') {
      digitalWrite(LED_BUILTIN, HIGH);   
      startTime=millis();
    }
  }
  /// if three seconds elpased switch off LED
  if((startTime>0) && (millis()-startTime)> ONTIME) {
    startTime=0;
    digitalWrite(LED_BUILTIN, LOW);  
  }
}

the variable startTime is static so it maintains updated values across sucessive calls to loop() - otherwise it would be reset to 0 on each call

1 Like

Yes, that works after changing Serial.begin to (9600)
Thank you.

simple to add more commands and relays or even more complex senarios, e.g.
on recipt of 'X' switch on relay 2 for 10 seconds but only if relay 1 is NOT on

1 Like

Got everything working in the complete sketch. Had a few "well that didn't work" moments. All is good now. Thanks again.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.