Problem with serial read and swiches?

Hi there,

I am working on some code that reads incoming bytes from the serial RX pin on the arduino.
once it receives the correct byte it toggles a led on or off, however the problem i have is that i have a mom switch
hooked up (with a debounce schmitt trigger circuit etc) that i want it to do the same job of toggling the same led, yet they are clashing with each other and not sure how to get around it.

example code

if (Serial.available()){
    Byte1 = Serial.read();

if (Byte1 == 1){
       if (digitalRead (13) == LOW) // led on pin 13
           digitalWrite(13, HIGH);
      else
           digitalWrite(13,LOW); // latches led high or low
}
 //Then i have a switch on pin 3

if (digitalRead (3) == HIGH){ // Read mom switch debounce circuit on pin 3
      if (digitalRead (13) == LOW)      //read led state
          digitalWrite(13, HIGH);}
else 
     digitalWrite(13,LOW); 
}

something along those lines where i want the incoming serial to toggle the led and also the switch to do the same yet they kinda cancel each other out and the led becomes momentary on/off or flashing on/off than latching from either input change.

any ideas?

if (Byte1 == 1){

If you are entering the character 1 in Serial monitor that statement should be if(Byte1 == '1')

..try this one for toggle LED on pin 13:
PINB = bit (5); // portB, bit5

It's not receiving a character, the rx is reading a byte of code from a midi message.

I just don't understand what the reason is as to why a midi message and a seperate switch to toggle the
Same LED. The switch should only be read as high or low to toggle the led but also still allow the midi byte to toggle the led on or off from the serial port at the same time.. Well not both at the same time/both pressed but you get my drift.

My coding isn't that brilliant but I am still managing to get by and get things working the way I want it. I am just stuck
On this little bit as I have tried loads of variations that come to mind...but i only know so much which is why am asking :slight_smile:

kh602:
Hi there,

I am working on some code that reads incoming bytes from the serial RX pin on the arduino.
once it receives the correct byte it toggles a led on or off, however the problem i have is that i have a mom switch
hooked up (with a debounce schmitt trigger circuit etc) that i want it to do the same job of toggling the same led, yet they are clashing with each other and not sure how to get around it.

Keep a record of the state of pin 13 in a boolean variable so that you don't have to read the state of an output.

 boolean ledState = 1;
void loop()...
if (Byte1 == 1){
       if (ledState ==0) // led on pin 13 is on
           digitalWrite(13, HIGH);
      else
           digitalWrite(13,LOW); // latches led high or low
      ledState = !ledState;  //flip the value of ledState
}

 //Then i have a switch on pin 3

if (digitalRead (3) == HIGH){ // Read mom switch debounce circuit on pin 3
      if (ledState == LOW)      //read led state
          digitalWrite(13, HIGH);
      else 
          digitalWrite(13,LOW); 
      ledState = !ledState; //flip the value of ledState
}

But that contracts to:

if (Byte1 == 1){
      digitalWrite(13, !ledState);
      ledState = !ledState;  //flip the value of ledState
}
 //Then i have a switch on pin 3

if (digitalRead (3) == HIGH){ // Read mom switch debounce circuit on pin 3
      digitalWrite(13, !ledstate); 
      ledState = !ledState; //flip the value of ledState
}

and further contracts to:

if (Byte1 == 1 || digitalRead (3) == HIGH){ //Or condition
      digitalWrite(13, !ledState);
      ledState = !ledState;  //flip the value of ledState
}

Henry_Best:

kh602:
Hi there,

I am working on some code that reads incoming bytes from the serial RX pin on the arduino.
once it receives the correct byte it toggles a led on or off, however the problem i have is that i have a mom switch
hooked up (with a debounce schmitt trigger circuit etc) that i want it to do the same job of toggling the same led, yet they are clashing with each other and not sure how to get around it.

Keep a record of the state of pin 13 in a boolean variable so that you don't have to read the state of an output.

 boolean ledState = 1;

void loop()...
if (Byte1 == 1){
       if (ledState ==0) // led on pin 13 is on
           digitalWrite(13, HIGH);
      else
           digitalWrite(13,LOW); // latches led high or low
      ledState = !ledState;  //flip the value of ledState
}

//Then i have a switch on pin 3

if (digitalRead (3) == HIGH){ // Read mom switch debounce circuit on pin 3
      if (ledState == LOW)      //read led state
          digitalWrite(13, HIGH);
      else
          digitalWrite(13,LOW);
      ledState = !ledState; //flip the value of ledState
}



But that contracts to:

if (Byte1 == 1){
      digitalWrite(13, !ledState);
      ledState = !ledState;  //flip the value of ledState
}
//Then i have a switch on pin 3

if (digitalRead (3) == HIGH){ // Read mom switch debounce circuit on pin 3
      digitalWrite(13, !ledstate);
      ledState = !ledState; //flip the value of ledState
}


and further contracts to:

if (Byte1 == 1 || digitalRead (3) == HIGH){ //Or condition
      digitalWrite(13, !ledState);
      ledState = !ledState;  //flip the value of ledState
}

Thanks very much. I will test out the code later today. I guess i could say i was almost there as that last chunk of code as i did try to use OR condition within that line, it was just the boolean/ledstate i didn't have. Hopefully i can push a bit further on now.

You could try setting a flag variable on RX or switch and then change the led depending on that.

If byte1 == 1 then set bit 0 to 1 and if not to 0.
If switch then set bit 1 to 1 and if not to 0.
Neither one affects the other, both affect the result which may be 0, 1, 2, or 3.
If the variable is 0 then led OFF otherwise led ON.

This way you separate each element and code for each separately and you can add more factors without changing the existing code.

kh602:

Henry_Best:

kh602:
Hi there,

I am working on some code that reads incoming bytes from the serial RX pin on the arduino.
once it receives the correct byte it toggles a led on or off, however the problem i have is that i have a mom switch
hooked up (with a debounce schmitt trigger circuit etc) that i want it to do the same job of toggling the same led, yet they are clashing with each other and not sure how to get around it.

Keep a record of the state of pin 13 in a boolean variable so that you don't have to read the state of an output.

 boolean ledState = 1;

void loop()...
if (Byte1 == 1){
       if (ledState ==0) // led on pin 13 is on
           digitalWrite(13, HIGH);
      else
           digitalWrite(13,LOW); // latches led high or low
      ledState = !ledState;  //flip the value of ledState
}

//Then i have a switch on pin 3

if (digitalRead (3) == HIGH){ // Read mom switch debounce circuit on pin 3
      if (ledState == LOW)      //read led state
          digitalWrite(13, HIGH);
      else
          digitalWrite(13,LOW);
      ledState = !ledState; //flip the value of ledState
}



But that contracts to:

if (Byte1 == 1){
      digitalWrite(13, !ledState);
      ledState = !ledState;  //flip the value of ledState
}
//Then i have a switch on pin 3

if (digitalRead (3) == HIGH){ // Read mom switch debounce circuit on pin 3
      digitalWrite(13, !ledstate);
      ledState = !ledState; //flip the value of ledState
}


and further contracts to:

if (Byte1 == 1 || digitalRead (3) == HIGH){ //Or condition
      digitalWrite(13, !ledState);
      ledState = !ledState;  //flip the value of ledState
}

Thanks very much. I will test out the code later today. I guess i could say i was almost there as that last chunk of code as i did try to use OR condition within that line, it was just the boolean/ledstate i didn't have. Hopefully i can push a bit further on now.

It seems to be working ok however the other problem i have with that is if the mom switch is held, the led is flashing on and off am guessing due to that statement being looped if its high send it low, if low send it high etc.
is there a way of stopping that?

i put a delay in just after the digital read of the switch pin to try slow down that bounce on the switch to make it less likely for the led to bounce on and off which helps a little but i also have a hex schmitt trigger in place to sort the bouncing of the switch too.

kh602:

Try:

if (Byte1 == 1 || digitalRead (3) == HIGH){ //Or condition
   digitalWrite(13, !ledState);
   ledState = !ledState;  //flip the value of ledState
   while (digitalRead (3) == HIGH);  
      //sit here and do nothing until button released
}

If you want blocking code, that should do it.

cheers, it does work but now i have another problem haha.

i am using a 1284p so i have more pins and ram etc. i have about 32 if statements and a few for, while and else statements in my code so far. my sketch is 6,292 bytes out of 130,048. the code you gave me above worked fine when i tweaked it slightly however, if i un-comment 1 of the 32 if statements out, it works normally, if i add that back in my lcd display and all the functions totally freeze.

could i have run out of RAM on the chip even tho its more than a normal 328p chip?

If you put your pins into an array, it is alot easier to test them and keep track of them

int drinkPins[] = {41,42,43,44,45,46};  //relays
int buttonPins[] ={31,32,33,34,35,36};  //buttons
int buttonState[] ={0,0,0,0,0,0}; 
int drinkPinCount = 6;  //size of the array



 int thisPin;


  // the array elements are numbered from 0 to (pinCount - 1).
  // use a for loop to initialize each pin as an output:
  for (int thisPin = 0; thisPin < drinkPinCount; thisPin++)  {
    buttonState[thisPin] = digitalRead(buttonPins[thisPin]);
    if (buttonState[thisPin] == HIGH) {

this way you can run one loop and check the status of all the buttons at the same time and have them update the array

jasit:
If you put your pins into an array, it is alot easier to test them and keep track of them

int drinkPins[] = {41,42,43,44,45,46};  //relays

int buttonPins[] ={31,32,33,34,35,36};  //buttons
int buttonState[] ={0,0,0,0,0,0};
int drinkPinCount = 6;  //size of the array

int thisPin;

// the array elements are numbered from 0 to (pinCount - 1).
  // use a for loop to initialize each pin as an output:
  for (int thisPin = 0; thisPin < drinkPinCount; thisPin++)  {
    buttonState[thisPin] = digitalRead(buttonPins[thisPin]);
    if (buttonState[thisPin] == HIGH) {




this way you can run one loop and check the status of all the buttons at the same time and have them update the array

Cheers, i have been meaning to use arrays at some point. I understand arrays to some degree, i think it was tying them to switches and things that was confusing....but am still learning and seem to be doing pretty well. Me and programming arent always the best of pals.

as for my previous comment above, it was a false alarm. one of my debounce switches on the veroboard was tied to ground freezing the whole program due to that while loop to do nothing when a switch is low. soon sorted that out when i resoldered it. works a treat now. must of been a late night building up hardware boards for testing out code.

GoForSmoke:
If you want blocking code, that should do it.

Yep, but it's only blocking whilst someone is leaning on the button. :stuck_out_tongue:

Henry_Best:

GoForSmoke:
If you want blocking code, that should do it.

Yep, but it's only blocking whilst someone is leaning on the button. :stuck_out_tongue:

ahaha yeah true. I definitely need to carry on with programming as i forget quite a bit if i break off for too long. I suppose work doesn't help as it is pretty much non stop every day.

As for the bits of code in this thread, I had the gist of it and kinda knew what i to use yet i probably think to much into how i would do it/pseudo code or its not in the right order etc. Still have quite a bit to do though

is there any way of receiving a serial databyte/message and then running a block of code/a function, then if you receive the same databyte/message again, it switches back to the other block of code/function?

problem i have is running say void function1() /block of code over and over until i receive a specific databyte from the serial rx pin which exits that block of code/function and switches to void function2() and runs that over and over until it receives that databyte again and switches back and vice-versa?

nothing is working for me trying to achieve this. I know its basically a menu but receiving serial data to switch from 1 setting to another. Is it a switch statement i am after?

Not tested.

char ch;
void setup()
{
  Serial.begin(115200);
}

char get_ch()
{
  if (Serial.available())  ch=Serial.read(); else ch='0';
}

void aa()
{
  get_ch(); 
  if(ch=='x') return;
  // procedure 
}
void bb()
{
  get_ch(); 
  if(ch=='x') return;
  // procedure 
}


void loop()
{
  aa();
  bb();
}

kh602:
is there any way of receiving a serial databyte/message and then running a block of code/a function, then if you receive the same databyte/message again, it switches back to the other block of code/function?

That is what finite state machines (a way to code) do. You have a variable that holds a number, the process state, and different parts of the code inside loop() run based on the state.
What is happening and has happened affect the state. For instance if I am parsing text and come across a digit as the first character of the new word, my code may change state to run a part reads the next digits and turns them into a value.

You can find a lot on FSM code here and in blogs. Here are just two links I have bookmarked:

Nick gammon blog, about 1/4 of the way down he explains a State Machine example. Nick is always good with plain, clear, common sense explanations. It's only part of the page but if you get the gist, it may be EXACTLY what you're looking for.

Grumpy Mike is another long timer here. His site has loads of hardware/wiring how-to's. Here is a full State Machine tutorial.
http://www.thebox.myzen.co.uk/Tutorial/State_Machine.html

knut_ny:
Not tested.

char ch;

void setup()
{
  Serial.begin(115200);
}

char get_ch()
{
  if (Serial.available())  ch=Serial.read(); else ch='0';
}

void aa()
{
  get_ch();
  if(ch=='x') return;
  // procedure
}
void bb()
{
  get_ch();
  if(ch=='x') return;
  // procedure
}

void loop()
{
  aa();
  bb();
}

I tried something similar and had no success yet. I am trying to figure out how to receive a midi message from a switch that can act as a menu/option to toggle from 1 function to another.

I tried using if statements amongst a few other things but the program locks up. I can get menuA working on its own and menuB on its own but i can't combine them together to get that midi switch to toggle between the 2 functions and stay within that selected function/block of code. I am guessing i need some sort of variable to detect when it last received that midi message below.

void loop(){  //functions i have

option();      // option to serial.read midi message statusbyte == 192 and databyte1 == 9, so if reads this message run menuA(); 
menuA();     // until it receives the same message again switch to menuB(); and if it doesn't receive anything, stay in the same 
menuB();    // block/function that was originally selected - if that makes sense.

}
void loop(){  //functions i have

option();      // option to serial.read midi message statusbyte == 192 and databyte1 == 9, so if reads this message run menuA(); 
menuA();     // until it receives the same message again switch to menuB(); and if it doesn't receive anything, stay in the same 
menuB();    // block/function that was originally selected - if that makes sense.

}

It looks like you need to break that down into more detail, but at the heart it looks event driven.