controlling LED with virtual wire

i have been trying to use virtual wire library to control a LED by using a push button mounted on a different arduino , the problem is that the LED keep blinking after i press the push button for the first time instead of turning on then it stop responding .

P.S:(i want the LED to turn off or on every time i press the push button)

sender code

#include <VirtualWire.h>
char *controller;
int a;
int b;
int c;
void setup() {
pinMode(7,INPUT);
pinMode(8,INPUT);
pinMode(9,INPUT);
vw_set_ptt_inverted(true); //
vw_set_tx_pin(12);
vw_setup(4000);
}

void loop(){
         
  b = digitalRead(8);
  a = digitalRead(7);
  c = digitalRead(9);
  if (a == HIGH){
controller="0";
vw_send((uint8_t *)controller, strlen(controller));
vw_wait_tx(); // Wait until the whole message is gone
}
if (b == HIGH){
controller="1";
vw_send((uint8_t *)controller, strlen(controller));
vw_wait_tx(); // Wait until the whole message is gone
}
if (c == HIGH){
controller="2";
vw_send((uint8_t *)controller, strlen(controller));
vw_wait_tx(); // Wait until the whole message is gone
}
}

receiver code

#include <VirtualWire.h>
int a=0;
void setup()
{
    vw_set_ptt_inverted(true); // Required for DR3100
    vw_set_rx_pin(12);
    vw_setup(4000);  // Bits per sec
    pinMode(13, OUTPUT);
    pinMode(11, OUTPUT);
    pinMode(9, OUTPUT);
    vw_rx_start();       // Start the receiver PLL running
     }
      void loop()
      {
       uint8_t buf[VW_MAX_MESSAGE_LEN];
       uint8_t buflen = VW_MAX_MESSAGE_LEN;
       if (vw_get_message(buf, &buflen)) // Non-blocking
       {
        if(buf[0]=='0'){
        digitalWrite(13, !digitalRead(13));
        }
        if (buf[0] =='1'){
        digitalWrite(11, !digitalRead(11));
        }
        if (buf[0] =='2'){
        digitalWrite(9, !digitalRead(9));
        }
       }
      }

thanks for you help and i apologies for my stupidity.

How are pins 7, 8 and 9 wired?

P.S:(i want the LED to turn off or on every time i press the push button)

So why are you sending toggle messages all the time the button is pushed?

AWOL:
How are pins 7, 8 and 9 wired?

they are wired straight from a 5v Dc source to a push button then to the pin.

isn't toggling mean it gives the opposite from the previous statues (like if it was on it will turn off or if it was off it will turn on) only when i press the push button.

isn't toggling mean it gives the opposite from the previous statues (like if it was on it will turn off or if it was off it will turn on) only when i press the push button.

Yes, that is what toggling means. But, the Arduino does not see that the button has become pressed. It sees that the switch is pressed or is not pressed.

If you want to change the state (toggle it) only once, when the switch becomes pressed, you need different code than you need if you want to toggle the state every time the Arduino reads that the switch is pressed.

The Arduino can read that the switch IS pressed about 150,000 times per second.

The Arduino can read that the switch IS pressed about 150,000 times per second.

Or it could, if it wasn't busy sending messages at 4000 bits per second (which is, IMO, a little optimistic)

Frist a tip, watch your code indentation. It should indent after every {. Makes it way more readable.

Then a question, why use the virtual version and not the hardware version?

samm1e:
they are wired straight from a 5v Dc source to a push button then to the pin.

That will also not work... Now when the button is not pressed the input ios just floating, it's undefined, it can be high or low. So you need a pull down resistor between GND and the Arduino input as well. Or, make life easie and connect the button between GND and the input and enable the internal pull ups. Only now you read LOW when the button is pushed and high when it's not pushed.

And then part two, only sent when the button became pushed, not when it is pushed. Then you will notice something called bounce in the button (Google it :wink: ). So you need to debounce it. Easiest solution? Use a library like Bounce2. It even does all the work for you regarding the becoming pressed part.

Also, I would not send strings, I would just send a single byte over to toggle.

#include <VirtualWire.h>
#include <Bounce2.h>

const byte ButtonPins[] = {7, 8, 9};
Bounce buttons[sizeof(ButtonPins)];

void setup() {
  for(byte i = 0; i < sizeof(ButtonPins); i++){
    buttons[i].attach(ButtonPins[i], INPUT_PULLUP);
  }
  vw_set_ptt_inverted(true); //
  vw_set_tx_pin(12);
  vw_setup(4000);
}

void loop(){
  for(byte i = 0; i < sizeof(ButtonPins); i++){
    if(buttons[i].fell()){
      vw_send((uint8_t *)i, 1);
      vw_wait_tx();
    }
  }
}
#include <VirtualWire.h>

cont byte LedPins[] = {13, 11, 9};

void setup(){
  vw_set_ptt_inverted(true); // Required for DR3100
  vw_set_rx_pin(12);
  vw_setup(4000);  // Bits per sec

  for(byte i = 0; i < sizeof(LedPins); i++){
    pinMode(LedPins[i], OUTPUT);
  }
  
  vw_rx_start();       // Start the receiver PLL running
}

void loop(){
  uint8_t buf[VW_MAX_MESSAGE_LEN];
  uint8_t buflen = VW_MAX_MESSAGE_LEN;

  if(vw_get_message(buf, &buflen)){ // Non-blocking
    if(buf[0] < sizeof(LedPins)){
      digitalWrite(LedPins[buf[0]], !digitalRead(LedPins[buf[0]]));
    }
  }
}

thank you all of helping me do this and sorry for my silliness but its my 3rd time working with arduino and it wasn't optional , i only use simple java codes that's why you can tell my code is not good.

i will take your advises seriously and thanks for the code MR septillion i'll try to understand it as much as possible, i kinda feel like achieved what i want so thank you all again .
:slight_smile:

Java or C, your code would still send toggle messages whilst the switch was closed.