0

I'm still very new to arduino and coding and having some difficulties trying to figure out what I am doing wrong here.

This program is to have control over 2 relays, using a combination of an IR receiver and a ir_remotecontrol with pre-programmed buttons (ir_remote buttons 1 = relay 1 toggle, button 2 = relay 2 toggle). A master momentary hard wired switch to override changes to the relays and toggle their states i.e if both relays are on via ir remote - toggle them off, or if only 1 relay is on toggle it off with first click of button then toggle both back on after second click of button. The Bluetooth module and android app is to also control relays the same as the ir_remote via integers sent through the serial port.

It all sort of works at the moment...

If I just work the relays using the ir remote and the momentary switch it all works perfectly.

if I make sure the relays are in the off position using the remote switch and then use the Bluetooth it also works perfectly.

The problem only is when I use a combination of the ir remote or switch and the Bluetooth - things get weird - the Bluetooth commands seem to reverse and the relays start making a buzzing noise and the momentary switch muddles things up so basically it's all bad news! I've stared at this code for hours and tried a few different things but I just can't see what's wrong.

Let me know if I need to give a more detailed example of the errors I am having. Just thinking it is probably obvious for you pro's out there when you see my noob code!.

Any help would be greatly appreciated!

/*This program is to have control over 2 relays, using a cobination of   an IR reciever and remote control with pre programmed buttons    (ir_remote buttons 1 = relay 1 toggle, 2 = relay 2 toggle). 
A master momentery hard wired switch to overide changes to the relays and toggle their states i.e if both relays are on via ir remote - toggle them off, or if 1 only relay is on toggle it off with first click of button then toggle both back on after sencond click of button. 
Bluetooth module and andoid app to also control relays the same as the ir_remote.
 */    
//include libaries, and initialise variables
#include <SoftwareSerial.h>
#include <IRremote.h>
#define irPin 8
#define RxD 7
#define TxD 6
#define relay1 13
#define relay2 12
#define buttonPin 2 
SoftwareSerial blueTooth(RxD, TxD);
IRrecv irrecv(irPin);
decode_results results;
int comdata; 
const int wait = 30;
int sensorValue = 0;
int sensorOut = 0;
int relay1State = 0; 
int relay2State = 0;
int masterState = 0;
int buttonState = 0;        
int lastButtonState = 0;   
long lastDebounceTime = 0;  
long debounceDelay = 50;    



void setup()
{
  blueTooth.begin(38400);                     //set bluetooth baud rate
  delay(500);
  irrecv.enableIRIn();                        //enable infrared recieve
  pinMode(relay1, OUTPUT);                    //setting relays 1 & 2 to output
  pinMode(relay2, OUTPUT);
  pinMode(buttonPin, INPUT);                  //setting momentery swith (overide) to inpt          
  digitalWrite(relay1, relay1State);          //putting current status of relays into a variable
  digitalWrite(relay2, relay2State);

}


void loop()
{
  if (blueTooth.available())                  //setting a variable for bluetooth recieved serial commands
  comdata = blueTooth.read();

  if(comdata == '1'){

  digitalWrite(relay1, relay1State);          //if bluetooth receivs "1" toggle relay1state -- essentially relay 1 ON
  }
  if(comdata == '0'){
  digitalWrite(relay1, !relay1State);         //if bluetooth receivs "0" toggle relay1state -- essentially relay 1 OFF

  }
  if(comdata == '2'){
  digitalWrite(relay2, relay2State);          //if bluetooth receivs "2" toggle relay2state -- essentially relay 2 ON

  }
  if(comdata == '3'){
  digitalWrite(relay2, !relay2State);         //if bluetooth receivs "3" toggle relay2state -- essentially relay 2 OFF
  }


  if (irrecv.decode(&results)){                     //Start listing for ir commands, if set remote button code is recvived toggle the variable relay1State or relay2state
  switch (results.value){
      case 0xFF30CF:
        relay1State = !relay1State;
        digitalWrite(relay1, relay1State);
        delay(250);
        break;
      case 0xFF18E7:
        relay2State = !relay2State;
        digitalWrite(relay2, relay2State);
        delay(250);
        break;
    }
    irrecv.resume();
    }

  int reading = digitalRead(buttonPin);          //debounce used to help with faulse readings from momentery switch
  if (reading != lastButtonState) {
   lastDebounceTime = millis();
  }
  if ((millis() - lastDebounceTime) > debounceDelay) {

  if (reading != buttonState) {
      buttonState = reading;

  if (buttonState == HIGH) {                      //if the momentery switch is pressed toggle masterstate which is both relay 1 and relay 2 state
     masterState = !masterState;
     relay1State = masterState;
     relay2State = masterState;
      }
      }
    }

  digitalWrite(relay1, relay1State);
  digitalWrite(relay2, relay2State);
  lastButtonState = reading;

}
11
  • Do you want the relay pins to always match the relayStates? If you get a "1" on the bluetooth, what do you intend to have happen? Maybe write a "toggleRelayState(relayNumber){} and setRelayState(relayNumber,state) functions to handle all the state changes, and then invoke these identical functions from each input method. Also, maybe add some debugging info with a Serial.print and delay(1000) until you can diagnose what is going on.
    – Dave X
    Commented Dec 3, 2015 at 14:40
  • You might also check the debouncing code. It looks like the bracket after "lastDebounceTime = millis();" should be moved way down below "lastButtonState = reading;"
    – Dave X
    Commented Dec 3, 2015 at 14:48
  • Hi Dave, thanks for taking a look at this for me. I'm sorry to be a pain, but I can't get my head around what you're asking me to do exactly. I am maybe trying to run before I can walk with all this. But I have to say I am learning quicker by just doing, rather than reading and forgetting! To answer your question - If I press 1 on the bluetooth I want it to turn on relay 1 if it is off or do nothing if it is already on. Commented Dec 3, 2015 at 18:03
  • Looking at this now I guess the blue tooth receive '2' & '3' are not necessary as I'm just setting an opposite value for their respective 'relayState's'? I've removed them for now and added: if(comdata == '1'){ relay1State = !relay1State; digitalWrite(relay1, relay1State); but still not working as I'd hoped Commented Dec 3, 2015 at 18:22
  • " If I press 1 on the bluetooth I want it to turn on relay 1 if it is off or do nothing if it is already on." -- for this I'd say "if(comdata == '1') {relay1State = 1;digitalWrite(relay1, relay1State);}" to remember the desired state in relay1State and set the output to match. Otherwise, the 3rd to last statement in the currently posted code will reset the output to zero, since the relayState1 was unchanged by the bluetooth command.
    – Dave X
    Commented Dec 3, 2015 at 20:04

2 Answers 2

1

Looks like it could be reusing the old comdata values in the first part of loop(). Maybe make the first chunk:

   if (blueTooth.available()) {
      comdata = blueTooth.read();
      switch (comdata) {  // set state variables based on bluetooth
      case  '0':  // if bluetooth receivs "0" clear 1
          relay1State = 0;
          break; 
      case  '1':  // if bluetooth receivs "1" set 1
          relay1State = 1; 
          break; 
      case  '2':  // if bluetooth receivs "2" set 2
          relay2State = 1;
          break; 
      case  '3':  // if bluetooth receivs "1" clear2
          relay2State = 0; 
          break; 

      case  '4':  // if bluetooth receivs "4" toggle 1
          relay1State = !relay1State; 
          break; 
      case  '5':  // if bluetooth receivs "5" toggle 2
          relay2State = !relay2State; 
          break; 
      case  '6':  // if bluetooth receivs "6" toggle master/both
          masterState = relay1State = relay2State = !masterState;
          break; 
      }  // end of switch
      // apply state variables to outputs
      // (could be left to the end of the loop() code)
      digitalWrite(relay1, relay1State);  
      digitalWrite(relay2, relay2State);
   } // end of bluetooth processing

   ... /// IR processing code

   // debounce button and toggle masterstate & set state vars accordingly
   // see http://arduino.stackexchange.com/questions/17443/how-to-simulate-delay-to-debounce-mechanical-button-using-millis
   // 

// re-ensure output state matches the state variables.
digitalWrite(relay1, relay1State);
digitalWrite(relay2, relay2State);
}

As it is, the if() statements trigger on the state of the last read comdata, not on the whether a new command was read.

Also, maybe check whether the toggling comments match the code or the code matches the intention properly.

3
  • 1
    Stmt relay1State = relay1State; has no effect Commented Dec 2, 2015 at 19:18
  • True. I'm not sure if the Poster wants the comdata==?? inputs to toggle or actually change the state variables or not.
    – Dave X
    Commented Dec 2, 2015 at 20:30
  • Thanks for your reply. I tried the changes you suggested but to no avail.. As for my comments - they're probably very wrong as I'm really just getting to grips with arduino and coding, how I think the code works and how it probably works are usually 2 different things, but every day I think I grasp a little more. And having you guys to guide me when I am stuck really helps too! Thanks, Michael Commented Dec 3, 2015 at 0:41
2

Only the button changes relay1State and relay2State. The IR and BT only change the pin using digitalWrite. But then in the last 3 lines, the pin is changed back to the value of relay1State and relay2State.

I think for the IR and BT you need to change e.g. digitalWrite(relay2, !relay2State); to relay2State=false; etc.

PS It there a pull-up/pull-down resistor on the button pin?

3
  • Thanks for the reply! I have tried making the changes you suggested but it didn't help - unless of course I am not doing it correctly (very possible!) I tried changing the both IR statements to relay2State=false and then also the BT. I also tried changing the BT to True for the on state and false for the off state but that didn't help either? I have a pull-down resistor on the button pin. Thanks again. Commented Dec 3, 2015 at 0:36
  • You need to change all digitalWrites except for the last two, right?
    – Gerben
    Commented Dec 3, 2015 at 11:12
  • Yeah, tried all except the last 2. I can only turn the relays on but not off. Commented Dec 3, 2015 at 13:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.