How would I change this code to toggle on off the LEDs?

I have this code here that I found online here and although it works cool it is not quite what I am wanting, I want the button in my interface software to toggle the LED on or off when clicked, I hope that made sense? Now What would I change in this code to do that? So far I can see that he has it so when one LED is active the others are turned off, but there must be a way to toggle on/off with a single buttons press?

int gLed = 10;
int yLed = 11;
int rLed = 12;
int bLed = 13;


char myCol[20];

void setup() {  
   Serial.begin (9600);  
   pinMode(gLed, OUTPUT);    
   pinMode(yLed, OUTPUT);   
   pinMode(rLed, OUTPUT);
   pinMode(bLed, OUTPUT);   
  
   digitalWrite(gLed, LOW);
   digitalWrite(yLed, LOW);
   digitalWrite(rLed, LOW);
   digitalWrite(bLed, LOW); 

}


void loop() {
  int lf = 10;
  Serial.readBytesUntil(lf, myCol, 1);
    if(strcmp(myCol,"r")==0){
       digitalWrite(rLed, HIGH);  //Turn LED On     
       digitalWrite(yLed, LOW);   
       digitalWrite(gLed, LOW);
       digitalWrite(bLed, LOW);
   }
   
  if(strcmp(myCol,"y")==0){
       digitalWrite(rLed, LOW);       
       digitalWrite(yLed, HIGH);   
       digitalWrite(gLed, LOW);
       digitalWrite(bLed, LOW); 
   }
  if(strcmp(myCol,"g")==0){
       digitalWrite(rLed, LOW);       
       digitalWrite(yLed, LOW);   
       digitalWrite(gLed, HIGH);
       digitalWrite(bLed, LOW); 
   }
   if(strcmp(myCol,"b")==0){
       digitalWrite(rLed, LOW);       
       digitalWrite(yLed, LOW);   
       digitalWrite(gLed, LOW);
       digitalWrite(bLed, HIGH); 
   }
}

I want the button in my interface software to toggle the LED on or off when clicked,

It's not really clear if you want to use a "software button" in Unity or a hardware button. I could only help with the hardware version.

I have this code here that I found online here and although it works cool it is not quite what I am wanting, I want the button in my interface software to toggle the LED on or off when clicked, I hope that made sense?

No that doesn't make sense. You need to explain the operation in very plain English. You need to more clearly define your requirements in terms of users, input and output.

That sketch turns on and off LEDs based on serial input. Your description says the LED and the button. It's easy to have one button turn on and off LEDs in a sequence but that sequence needs to be clearly defined at the start.

Jimmy60: No that doesn't make sense. You need to explain the operation in very plain English. You need to more clearly define your requirements in terms of users, input and output.

That sketch turns on and off LEDs based on serial input. Your description says the LED and the button. It's easy to have one button turn on and off LEDs in a sequence but that sequence needs to be clearly defined at the start.

Sorry Jimmy, I'm very new to Arduino best I can do to explain is post a link to my video demo and it might explain better... hopefully lol ;)

Video Demo

florinc: It's not really clear if you want to use a "software button" in Unity or a hardware button. I could only help with the hardware version.

Thanks and sorry, I'm new to Arduino just like my reply to Jimmy the best way is for me to post a link to my Video Demo and hopefully it will explain or you'll bee able to see what is going on.

Video Demo

I watched the video. So you want to use the PC to control the arduino by sending commands through the serial port, rather than just having buttons directly connected to arduino's input pins. That's fine. The PC sends 4 commands to your arduino: "r", "y", "g" and "b", each of which turns the respective LED on and the other 3 off.

A simple change to toggle them all on/off is this:

    if(strcmp(myCol,"r")==0){
       digitalWrite(rLed, HIGH);  //Turn LED On     
       digitalWrite(yLed, HIGH);   
       digitalWrite(gLed, HIGH);
       digitalWrite(bLed, HIGH);
   }
   
  if(strcmp(myCol,"y")==0){
       digitalWrite(rLed, LOW);       
       digitalWrite(yLed, LOW);   
       digitalWrite(gLed, LOW);
       digitalWrite(bLed, LOW); 
   }

Press the button that sends the command "r" to turn all LEDs on, and press the button that sends the command "y" to turn them all off.

I hope this helps.

Ok, do you want them to either be all on or all off as Florinc showed in his code? Or do you want to enter "r" to turn the LED on and enter "r" again to turn it off.

Reason I'm asking is because if you want to toggle the LEDs individually then you would use the second method.

HazardsMind: Ok, do you want them to either be all on or all off as Florinc showed in his code? Or do you want to enter "r" to turn the LED on and enter "r" again to turn it off.

Reason I'm asking is because if you want to toggle the LEDs individually then you would use the second method.

yes, bingo, you've got, Basically I have multiple buttons on my interface as you can see, I want each button to be able to turn on and off a respective LED, either red, yellow, green or blue, depending on what that button is assigned too. Later on the LEDs will be replaced with optocouplers to activate relays. I hope that makes sense?

florinc: I watched the video. So you want to use the PC to control the arduino by sending commands through the serial port, rather than just having buttons directly connected to arduino's input pins. That's fine. The PC sends 4 commands to your arduino: "r", "y", "g" and "b", each of which turns the respective LED on and the other 3 off.

A simple change to toggle them all on/off is this:

    if(strcmp(myCol,"r")==0){
       digitalWrite(rLed, HIGH);  //Turn LED On     
       digitalWrite(yLed, HIGH);   
       digitalWrite(gLed, HIGH);
       digitalWrite(bLed, HIGH);
   }
   
  if(strcmp(myCol,"y")==0){
       digitalWrite(rLed, LOW);       
       digitalWrite(yLed, LOW);   
       digitalWrite(gLed, LOW);
       digitalWrite(bLed, LOW); 
   }

Press the button that sends the command "r" to turn all LEDs on, and press the button that sends the command "y" to turn them all off.

I hope this helps.

Close but not quite, I want each button to be able to turn on and off a specific LED that it is assigned too. Later on the LEDs will be replaced with Optocouplers so they can activate relays. ;)

Ok, easy.

All you need to do is make 4 more byte variables. Call them, idk, Tog_r, Tog_y ...

Then you simply do this, it shouldn't take you more than a minute to see a result.

void loop() 
{
  int lf = 10;
  Serial.readBytesUntil(lf, myCol, 1);

if(strcmp(myCol,"r")==0)
  Tog_r = !Tog_r; // enter r, LED on, enter r again LED off

if(strcmp(myCol,"y")==0)
  Tog_y = !Tog_y;
// add the rest

digitalWrite(rLed, Tog_r);
digitalWrite(yLed, Tog_y);
// add the rest
}

I have one question though, why strings "r*"* (double quotes) instead of single characters 'r*'* (single quotes)? Are you entering the data like this "rgb", "ryb" .. or just single letters?

If you do single characters 'r' it would be faster and take up less memory. So what are you typing in to turn on these LEDs?

HazardsMind: Ok, easy.

All you need to do is make 4 more byte variables. Call them, idk, Tog_r, Tog_y ...

Then you simply do this, it shouldn't take you more than a minute to see a result.

void loop() 
{
  int lf = 10;
  Serial.readBytesUntil(lf, myCol, 1);

if(strcmp(myCol,"r")==0)  Tog_r = !Tog_r; // enter r, LED on, enter r again LED off

if(strcmp(myCol,"y")==0)  Tog_y = !Tog_y; // add the rest

digitalWrite(rLed, Tog_r); digitalWrite(yLed, Tog_y); // add the rest }




I have one question though, why strings **"**r**"** (double quotes) instead of single characters **'**r**'** (single quotes)?
Are you entering the data like this "rgb", "ryb" .. or just single letters?

If you do single characters 'r' it would be faster and take up less memory. So what are you typing in to turn on these LEDs?

Thanks Hazard, not sure I'm fully understanding what you mean I made a few changes but now I get error messages so I must be missing something? Here is what I did to the code:

int gLed = 10;
int yLed = 11;
int rLed = 12;
int bLed = 13;


char myCol[20];

void setup() {  
   Serial.begin (9600);  
   pinMode(gLed, OUTPUT);    
   pinMode(yLed, OUTPUT);   
   pinMode(rLed, OUTPUT);
   pinMode(bLed, OUTPUT);   
  
   digitalWrite(gLed, LOW);
   digitalWrite(yLed, LOW);
   digitalWrite(rLed, LOW);
   digitalWrite(bLed, LOW); 

}


void loop() {
  int lf = 10;
  Serial.readBytesUntil(lf, myCol, 1);
    if(strcmp(myCol,"r")==0){
      Tog_r = !Tog_r; // enter r, LED on, enter r again LED off
       digitalWrite(rLed, Tog_r);
   }
   
  if(strcmp(myCol,"y")==0){
    Tog_y = !Tog_y; // enter y, LED on, enter y again LED off
      digitalWrite(yLed, Tog_y);
   }
  if(strcmp(myCol,"g")==0){
       Tog_g = !Tog_g; // enter g, LED on, enter g again LED off
      digitalWrite(gLed, Tog_g); 
   }
   if(strcmp(myCol,"b")==0){
       Tog_b = !Tog_b; // enter b, LED on, enter b again LED off
      digitalWrite(bLed, Tog_b);
   }
}

You didn't add in the 4 byte variables at the top. You are using them in the code, but you didn't really declare them at the top of the code.

Just add byte Tog_r, Tog_y, Tog_g, Tog_b;

You can also toggle pins by writing a 1 to the appropriate pin in the PINx register for each port. On Arduino pins 8 - 13 are in port B, reading register PINB will show the state of each pin. If you want to toggle gLed you could write:

bitSet(PINB,gLed - 8);

Or to toggle all at once write:

PINB = PINB | bit(gLed - 8) | bit(yLed - 8) | bit(rLed - 8) | bit(bLed - 8);

Have fun.

EDIT! Added " - 8s" in second example.

Or more readable. To toggle the state of a pin

digitalWrite(aPin, !digitalRead(aPin));

HazardsMind: You didn't add in the 4 byte variables at the top. You are using them in the code, but you didn't really declare them at the top of the code.

Just add byte Tog_r, Tog_y, Tog_g, Tog_b;

Hi HazardsMind, OK now at startup it turns all of my LEDs on and when I press my button it makes the LED selected flash on and off? Something is not right there. Here is the code:

int gLed = 10;
int yLed = 11;
int rLed = 12;
int bLed = 13;

byte Tog_r, Tog_y, Tog_g, Tog_b;
char myCol[20];

void setup() {  
   Serial.begin (9600);  
   pinMode(gLed, OUTPUT);    
   pinMode(yLed, OUTPUT);   
   pinMode(rLed, OUTPUT);
   pinMode(bLed, OUTPUT);   
  
   digitalWrite(gLed, !Tog_g);
   digitalWrite(yLed, !Tog_y);
   digitalWrite(rLed, !Tog_r);
   digitalWrite(bLed, !Tog_b); 

}


void loop() {
  int lf = 10;
  Serial.readBytesUntil(lf, myCol, 1);
    if(strcmp(myCol,"r")==0){
      Tog_r = !Tog_r; // enter r, LED on, enter r again LED off
       digitalWrite(rLed, Tog_r);
   }
   
  if(strcmp(myCol,"y")==0){
    Tog_y = !Tog_y; // enter y, LED on, enter y again LED off
      digitalWrite(yLed, Tog_y);
   }
  if(strcmp(myCol,"g")==0){
       Tog_g = !Tog_g; // enter g, LED on, enter g again LED off
      digitalWrite(gLed, Tog_g); 
   }
   if(strcmp(myCol,"b")==0){
       Tog_b = !Tog_b; // enter b, LED on, enter b again LED off
      digitalWrite(bLed, Tog_b);
   }
}

when I press my button it makes the LED selected flash on and off

Do you mean that it makes the LED flash on/off whilst you hold the button down or just on and off once ?

What do you actually send when a button is held down ? If it is a stream of the same character, such as 'r', then the Arduino will continually change the state of the associated LED. You either need to change the PC program to send a character when the button [u]becomes[/u] pressed rather than [u]is[/u] pressed or have it send a different character for a press and a release, perhaps 'R' and 'r' so that the Arduino code can be written to differentiate between the press and the release.

jcallen: You can also toggle pins by writing a 1 to the appropriate pin in the PINx register for each port. On Arduino pins 8 - 13 are in port B, reading register PINB will show the state of each pin. If you want to toggle gLed you could write:

bitSet(PINB,gLed - 8);

Or to toggle all at once write:

PINB = PINB | bit(gLed - 8) | bit(yLed - 8) | bit(rLed - 8) | bit(bLed - 8);

Have fun.

EDIT! Added " - 8s" in second example.

Thanks, I'm not sure I'm explaining what I want right. ;) I have a button on my software interface, many buttons but lets just focus on one the get the format working to follow on with the rest. now this button I want to turn on and off a device when clicked, in this case for experimentation a simple LED Right now I have been able to get them to do all sorts of funky stuff following the answers here but not the what I thought would be very simple task of just turning and LED on when clicked and it staying on until I click the button again to turn it off. What could be simpler? lol or so I thought ;)

You should ditch the PC application while you are debugging this. Only send characters from the serial monitor, see what happens.

aarg: You should ditch the PC application while you are debugging this. Only send characters from the serial monitor, see what happens.

Thanks aargh, I'll try that, in the mean time maybe if I post the sending code from Unity might help, maybe part of the problem is in there although I don't see how, as near as I can tell each button press is simply sending a single character to the serial port on my Mac. ;)

using UnityEngine;
using System.Collections;
using System.IO.Ports;
using System.Threading;

public class Sending : MonoBehaviour {
    
    //public static SerialPort sp = new SerialPort("COM4", 9600, Parity.None, 8, StopBits.One);
    public static SerialPort sp = new SerialPort("/dev/cu.wchusbserial1420", 9600);
    public string message2;
    float timePassed = 0.0f;
    // Use this for initialization
    void Start () {
        OpenConnection();
    }

    // Update is called once per frame
    void Update () {
        //timePassed+=Time.deltaTime;
        //if(timePassed>=0.2f){

            //print("BytesToRead" +sp.BytesToRead);
            message2 = sp.ReadLine();
            print(message2);
        //  timePassed = 0.0f;
        //}
    }

    public void OpenConnection() 
    {
       if (sp != null) 
       {
         if (sp.IsOpen) 
         {
          sp.Close();
          print("Closing port, because it was already open!");
         }
         else 
         {
          sp.Open();  // opens the connection
          sp.ReadTimeout = 16;  // sets the timeout value before reporting error
          print("Port Opened!");
        //      message = "Port Opened!";
         }
       }
       else 
       {
         if (sp.IsOpen)
         {
          print("Port is already open");
         }
         else 
         {
          print("Port == null");
         }
       }
    }

    void OnApplicationQuit() 
    {
       sp.Close();
    }

    public static void sendYellow(){
      sp.Write("y");
    }

    public static void sendGreen(){
      sp.Write("g");
      //sp.Write("\n");
    }


    public static void sendRed(){
      sp.Write("r");
    }


    public static void sendBlue(){
        sp.Write("b");
    }
}

What is it in the Unity code that triggers the send* functions ? Does Unity open the serial connection each time it sends data or does it remain open ? Opening the serial connection to most Arduinos will cause it to reset.