Need help with Xbee's connected to Arduino for controlling Relays

Hi Arduino fanatics,

This problem / question should have been asked a million times i guess, but i cannot find any answer to my question. It frustrates me somehow :~
I really need some help here. I'm a complete noob in programming, but wiring and electronic stuff is no problem for me.

My setup is: 2 x Arduino Uno R3 / 2 x Xbee Series 1 / 2 x SF Xbee Explorer Regulated / 6-8 Relays / Bunch of pushbuttons

I have wired everything and connected. The Xbee's are communicating with each other, so this is not my problem.

The case is, that i want to control 6-8 Relays wireless with my Xbee's and arduino's, with just a push of the corresponding button on the transmitter, but i cannot get the code done. I tried a doorbell examples, but they do not work, if i modify them for use with multiple "doorbells (Relays)". They don't need a delay time or such. Just as long as i press the button, the relay needs to be closed. (It's for a claytrap release system)

Knowing that many of you would say, that Xbee could handle this alone, without a microcontroller, or that Xbee is overkill. But this setup will get other extra's over time, like sensors and a LCD display to show data.
These things are not relevant at the moment. I have to start with the buttons and the relays.

Transmitter: 6-8 Buttons --> Arduino --> Xbee explorer regulated --> TX Xbee
Receiver: RX Xbee --> Xbee explorer regulated --> Arduino --> Relays

I sadly just don't get the hang of the programming stuff in Arduino. So if anybody would be so kind, and help me with this getting to work? Working on this for two weeks now, day and night, but i do not understand how it's done :blush: =(

What should i need to modify / add in the code used here Arduino Forum , to use more inputs and outputs?

So please, help this noob on his way with examples or sketches for controlling multiple relays with pushbuttons. Thanks very much :slight_smile:

So please, help this noob on his way with examples or sketches for controlling multiple relays with pushbuttons.

What does this have to with XBees?

Where is YOUR code?

PaulS:

So please, help this noob on his way with examples or sketches for controlling multiple relays with pushbuttons.

What does this have to with XBees?

Where is YOUR code?

As is said before, the Xbee's are not the problem. They communicate with each other. I just need help with the codes / sketches for the Arduino's. The code i used, is in the link i posted. I have tried so many variations in that code, that i totally lost track of it. The one i used last, is this one:

Transmitter:

int BUTTON_A = 2;
int BUTTON_B = 3;
int BUTTON_C = 4;

  void setup() 
  {
    pinMode(BUTTON1, INPUT);
    pinMode(BUTTON2, INPUT);
    pinMode(BUTTON3, INPUT);

    Serial.begin(9600);
  }
  
  void loop() 
  {
  // send a capital A over the serial port if the button is pressed
    if (digitalRead(BUTTON1) == HIGH) 
    {
      Serial.print('A');
      delay(10); // prevents overwhelming the serial port
    }
  // send a capital B over the serial port if the button is pressed
    if (digitalRead(BUTTON2) == HIGH) 
    {
      Serial.print('B');
      delay(10); // prevents overwhelming the serial port
    }
  // send a capital C over the serial port if the button is pressed
    if (digitalRead(BUTTON3) == HIGH) 
    {
      Serial.print('C');
      delay(10); // prevents overwhelming the serial port
    }
  }

Receiver:

int RELAY1 = 2;
int RELAY2 = 3;
int RELAY3 = 4;

  void setup() 
  {
    pinMode(RELAY1, OUTPUT);
    pinMode(RELAY2, OUTPUT);
    pinMode(RELAY3, OUTPUT);

    Serial.begin(9600);
  }
  
  void loop() 
  {
    // look for a capital A over the serial port
    if (Serial.available() > 0) 
    {
      if (Serial.read() == 'A')
      {
        //ring the bell briefly
        digitalWrite(RELAY1, HIGH);
        delay(10);
        digitalWrite(RELAY1, LOW);
      }
    // look for a capital B over the serial port
    if (Serial.available() > 0) 
    {
      if (Serial.read() == 'B')
      {
        //ring the bell briefly
        digitalWrite(RELAY2, HIGH);
        delay(10);
        digitalWrite(RELAY2, LOW);
      }
   // look for a capital C over the serial port
    if (Serial.available() > 0) 
    {
      if (Serial.read() == 'C')
      {
        //ring the bell briefly
        digitalWrite(RELAY3, HIGH);
        delay(10);
        digitalWrite(RELAY3, LOW);
      }
    }
  }

As is said before, the Xbee's are not the problem.

Then, why is your post title "Need help with Xbee's connected to Arduino for controlling Relays". If the XBees are working correctly, then, clearly, you know how to send data to, and read data from, another device where the XBees are the data transport mechanism.

If you don't know how to do that, then, I can't see how you can be sure that the XBees are not the problem.

Without getting defensive, can you clarify what the problem is? Or, change your post title.

What does the code that you posted do/not do? How does that differ from what you want?

PaulS:

As is said before, the Xbee's are not the problem.

Then, why is your post title "Need help with Xbee's connected to Arduino for controlling Relays". If the XBees are working correctly, then, clearly, you know how to send data to, and read data from, another device where the XBees are the data transport mechanism.

If you don't know how to do that, then, I can't see how you can be sure that the XBees are not the problem.

Without getting defensive, can you clarify what the problem is? Or, change your post title.

What does the code that you posted do/not do? How does that differ from what you want?

I choose this topic title because it is just the way it is. I have problems with Xbee's connected to the Arduino (Not the Xbee's themselve) It's in the serial communication between the arduino's via the Xbee's. In other words, the code.

I can exclude the Xbee's, because if i just use the standard code used in the topic i linked, one relay works, with one button. And if i test the Xbee's with the range test in X-CTU, they also work. If i use my code, the relays start "buzzing" like in a very short delay, when i press a button, and hold it. I tried to change the 10ms delays, but that did not work either. Or just one Relay works, but the second does not. It's weird.

But just to clarify, with no hard feelings, i was not being defensive. I just need someone to help me, or look at the code. And tell me what to change or what is wrong in it :slight_smile:

Could this be the problem? Can i have it multiple times in a sketch? Or do i need to change the "> 0" value, if i use it for the other relay in the receiver code?

if (Serial.available() > 0)

Your sender code, unfortunately, leaves a lot to be desired. It appears that you want to send a letter when a switch is pressed. But, you are sending the letter if the switch is pressed.

Yes, there is a difference, and it is not as subtle as it might appear.

The thing that you need to do is send a letter if the switch is pressed this time but was not pressed last time. This means that, for each switch, you need to keep track of the previous state. There is an example, state change detection, that illustrates this.

On the receiver, the problem is that Serial.read() removes the character from the buffer. If you send a 'B', and it arrives just as loop() starts, you will see that there is a character, so you will read it. It isn't an 'A', so you'll look to see if there is another character to read, instead of looking to see it the character just read is a 'B' or a 'C'. There is no way to do that, though, because you do not store the character read. You need something like:

if(Serial.available() > 0)
{
   char ltr = Serial.read();
   if(ltr == 'A')
   {
      // do the a thing
   }
   else if(ltr == 'B')
   {
      // do the b thing
   }
   // more else ifs
}

Try these changes, and let us know if they make any difference. I'm guessing that they will make a big difference.

Ahh, thanks very much PaulS :astonished: That worked. :slight_smile:

The problem with the the letters was in the code already. So if it would be possible code wise, to work without those, i would accept that also.
But as i assume that this is needed for the whole serial communication to work, i would just leave it alone, because it does not tackle my project i guess.

The only problem now that i have, is, when i press two or three buttons at once, as an example lets say "A" and "B", that the corresponding relays start to buzz again. In other words, they switch very fast on and off.
I tried to play with the delay's, but that did not give the result i was looking for. The Relay would stay in "HIGH" for the given time, and this was a no go for my project, as it will be used as a Clayshooting trap release. And i don't want any clay targets flying around, without human interaction. :slight_smile:

So the Relay should only stay "HIGH", as long as i press/hold the button, and go "LOW" as i release the button again. Or even better, that i have to release it, to activate it again, like a safety feature (if this is possible).

The codes i use now are:
Transmitter:

int BUTTON_A = 2;
int BUTTON_B = 3;
int BUTTON_C = 4;

  void setup() 
  {
    pinMode(BUTTON_A, INPUT);
    pinMode(BUTTON_B, INPUT);
    pinMode(BUTTON_C, INPUT);

    Serial.begin(9600);
  }
  
  void loop() 
  {
  // send a capital A over the serial port if the button is pressed
    if (digitalRead(BUTTON_A) == HIGH) 
    {
      Serial.print('A');
      delay(10); // prevents overwhelming the serial port
    }
    
  // send a capital B over the serial port if the button is pressed
    if (digitalRead(BUTTON_B) == HIGH) 
    {
      Serial.print('B');
      delay(10); // prevents overwhelming the serial port
    }
    
  // send a capital C over the serial port if the button is pressed
    if (digitalRead(BUTTON_C) == HIGH) 
    {
      Serial.print('C');
      delay(10); // prevents overwhelming the serial port
    }
   }

Receiver:

int RELAY1 = 2;
int RELAY2 = 3;
int RELAY3 = 4;

  void setup() 
  {
    pinMode(RELAY1, OUTPUT);
    pinMode(RELAY2, OUTPUT);
    pinMode(RELAY3, OUTPUT);

    Serial.begin(9600);
  }
  
  void loop() 
  {
    // look for a capital A over the serial port
    if(Serial.available() > 0)
    {
    char ltr = Serial.read();
    if(ltr == 'A')
    {
      //Activate the Relay
        digitalWrite(RELAY1, HIGH);
        delay(10);
        digitalWrite(RELAY1, LOW);
    }
   else if(ltr == 'B')
   {
      //Activate the Relay
        digitalWrite(RELAY2, HIGH);
        delay(10);
        digitalWrite(RELAY2, LOW);
   }
   if(ltr == 'C')
    {
      //Activate the Relay
        digitalWrite(RELAY3, HIGH);
        delay(10);
        digitalWrite(RELAY3, LOW);
    }
   }
  }

You have only dealt with one of the two issues I pointed out. The other one, where more data is sent than should be still exists.

Learn to use arrays (and switches, instead of buttons).

const int switchPins[] = { 2, 3, 4 };
byte currState[3];
byte prevState[3];

void loop()
{
   for(byte i=0; i<3; i++)
   {
      currState[i] = digitalRead(switchPin[i]);
      if(currState[i] != prevState[i])
      {
         // A transition occurred
         if(currState[i] == HIGH)
         {
            // The transition was to pressed
         }
      }
      prevState[i] = currState[i];
   }
}

If you have your switches wired with external pulldown resistors, then when the switch IS pressed, the value returned by digitalRead() will be HIGH.

If you have your switches wired with external pullup resistors, then when the switch IS pressed, the value returned by digitalRead() will be LOW, and you'll need to change the code above.

If you have your switches wired without external resistors, then you have a hardware problem that no amount of software is going to fix.

As you should be able to see, the code above will be able to trigger an action ONCE each time the switch is pressed. Press and hold the switch, and only one transition occurs. Another occurs when you release the switch.

In the block where the comment says "The transition was to pressed", you would put the code to send a value to the serial port. That value should be 'A'+i, since 'A'+0 is 'A' and 'A'+1 is 'B' and 'A'+2 is 'C'.

See how the use of arrays shortens the code considerably?

The code above does not deal with debouncing the switches, but a single delay(10) at the end of loop() will debounce all three switches.