Latching logic using serial commands

Hello,

I am trying to create a latching logic that is initiated by a serial command. For example, its supposed to operate so that when i send a 5 over serial, code will run. When i send a 5 again other code will run. I tried modifying the StateChangeDetection example without success. I can get code to run when the latch is on but I cannot get code to when it is turned off.

Im trying to modify the StateChangeDetection example so that I can run code depending on the state of the latch. If I send a 5 and the latch is on: do this. If I send another 5 and the latch turns off: do that. This is the part I cannot figure out.

I've been working at this for so long. I've read every forum post help guide i could find online without success. This is really kicking my butt. its 2:18AM and I'm completely out of ideas. I hope someone can give me guidance on this.

The area of interest is on lines 284 to 313

Note, there are some garbage integers declared that are not used.

I'm going to bed. Thanks in advance.

// constants won't change. They're used here to set pin numbers:

const int buttonPinA = 2;  // the number of the pushbutton pin

const int buttonPinB = 3;  // the number of the pushbutton pin

const int buttonPinC = 4;  // the number of the pushbutton pin

const int buttonPinD = 5;  // the number of the pushbutton pin

const int buttonPinM = 6;  // the number of the pushbutton pin


const int ledPinA = 8;    // the number of the LED pin

const int ledPinB = 9;    // the number of the LED pin

const int ledPinC = 10;    // the number of the LED pin

const int ledPinD = 11;    // the number of the LED pin

const int ledPinM = 12;    // the number of the LED pin



// variables will change:

int buttonStateA = 0;  // variable for reading the pushbutton status

int buttonStateB = 0;  // variable for reading the pushbutton status

int buttonStateC = 0;  // variable for reading the pushbutton status

int buttonStateD = 0;  // variable for reading the pushbutton status

int buttonStateM = 0;  // variable for reading the pushbutton status


int outputVar = 0;


int lastButtonStateA = 0;

int lastButtonStateB = 0;

int lastButtonStateC = 0;

int lastButtonStateD = 0;

int lastButtonStateM = 0;



int lastLedPinA_Mem = 0;

int lastLedPinB_Mem = 0;

int lastLedPinC_Mem = 0;

int lastLedPinD_Mem = 0;

 
bool ledPinA_Mem = 0;

bool ledPinB_Mem = 0;

bool ledPinC_Mem = 0;

bool ledPinD_Mem = 0;

bool ledPinM_Mem = 0;

//serial ints
int incomingByte = 0;
int lastIncomingByte = 0;

int LoadButtonStateM = 0;

int ledPinMstate = 0;
int lastLedPinMstate = 0;

int tempMstate = 0;

int lastTempState = 0;
int buttonPushCounter = 0;


void setup() {


  Serial.begin(9600); // opens serial port, sets data rate to 9600 bps 


  // initialize the LED pin as an output:

  pinMode(ledPinA, OUTPUT);

  pinMode(ledPinB, OUTPUT);

  pinMode(ledPinC, OUTPUT);

  pinMode(ledPinD, OUTPUT);
  
  pinMode(ledPinM, OUTPUT);


  // initialize the pushbutton pin as an input:

  pinMode(buttonPinA, INPUT);

  pinMode(buttonPinB, INPUT);

  pinMode(buttonPinC, INPUT);

  pinMode(buttonPinD, INPUT);
  
  pinMode(buttonPinM, INPUT);


  ledPinA_Mem = 1; //Start with channel 1 activated
}

void loop() {



  //lastIncomingByte = incomingByte;
  lastButtonStateA = buttonStateA;
  lastButtonStateB = buttonStateB;
  lastButtonStateC = buttonStateC;
  lastButtonStateD = buttonStateD;
  //lastButtonStateM = buttonStateM; 
   

  // read the state of the pushbutton value:

  buttonStateA = digitalRead(buttonPinA);

  buttonStateB = digitalRead(buttonPinB);

  buttonStateC = digitalRead(buttonPinC);

  buttonStateD = digitalRead(buttonPinD);
  
  buttonStateM = digitalRead(buttonPinM);
 
 //test logic //ledPinA_Mem = buttonStateA == true && buttonStateB == false && buttonStateC == false && buttonStateD == false;

 //test logic  //ledPinB_Mem = buttonStateA == false && buttonStateB == true && buttonStateC == false && buttonStateD == false;

 //test logic  //ledPinC_Mem = buttonStateA == false && buttonStateB == false && buttonStateC == true && buttonStateD == false;

 //test logic  //ledPinD_Mem = buttonStateA == false && buttonStateB == false && buttonStateC == false && buttonStateD == true;  
 


  
  
  if (tempMstate == false && (buttonStateA == true || incomingByte == '1') && buttonStateB == false && buttonStateC == false && buttonStateD == false)
{
    
    
    if (ledPinA_Mem == 0)
    {
    ledPinA_Mem = 1;
    ledPinB_Mem = 0;
    ledPinC_Mem = 0;
    ledPinD_Mem = 0;
    incomingByte = 0;
      delay(3);

    }
    /*latching logic
    else 
    {
    ledPinA_Mem = 0; 
    }
    */
} 
  
  
  
  
  
 
  
//BUTTON A/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////  

    if (tempMstate == false && buttonStateA == false &&  (buttonStateB == true || incomingByte == '2') && buttonStateC == false && buttonStateD == false)
{
    if (ledPinB_Mem == 0)
    {
    ledPinA_Mem = 0;
    ledPinB_Mem = 1;
    ledPinC_Mem = 0;
    ledPinD_Mem = 0;
        delay(3);
    }
    /*latching logic
    else 
    {
    ledPinB_Mem = 0; 
    }
    */
} 
   
//BUTTON B/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////  

    if (tempMstate == false && buttonStateA == false && buttonStateB == false && (buttonStateC == true || incomingByte == '3') && buttonStateD == false)
{
    if (ledPinC_Mem == 0)
    {
    ledPinA_Mem = 0;
    ledPinB_Mem = 0;
    ledPinC_Mem = 1;
    ledPinD_Mem = 0;
       delay(3);
    }
    /*latching logic
    else 
    {
    ledPinC_Mem = 0; 
    }
    */
} 
   
//BUTTON C/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////  

    if (tempMstate == false && buttonStateA == false && buttonStateB == false && buttonStateC == false && (buttonStateD == true || incomingByte == '4'))
{
    if (ledPinD_Mem == 0)
    {
    ledPinA_Mem = 0;
    ledPinB_Mem = 0;
    ledPinC_Mem = 0;
    ledPinD_Mem = 1;
        delay(3);
    }
    /*latching logic
    else 
    {
    ledPinD_Mem = 0; 
    }
    */
}   

 

//BUTTON M (MUTE)/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////  


  

  
  /*code that i use to copy paste
 
      ledPinM_Mem = HIGH;
      lastLedPinA_Mem = ledPinA_Mem;
      lastLedPinB_Mem = ledPinB_Mem;
      lastLedPinC_Mem = ledPinC_Mem;
      lastLedPinD_Mem = ledPinD_Mem;

    ledPinA_Mem = 0;
    ledPinB_Mem = 0;
    ledPinC_Mem = 0;
    ledPinD_Mem = 0;


   ledPinA_Mem = lastLedPinA_Mem;
   ledPinB_Mem = lastLedPinB_Mem;
   ledPinC_Mem = lastLedPinC_Mem;
           ledPinD_Mem = lastLedPinD_Mem;


    }
    
      
  }  
  */ 

incomingByte = Serial.read();


   if (incomingByte != lastIncomingByte)
  {

    if(incomingByte == '5')
    {
      buttonPushCounter = 1;

      delay(50);
    }
    else
    {
  
//example has code here that i am not using
    }

  }
lastIncomingByte = incomingByte;


if(buttonPushCounter == 1)
{
      digitalWrite(ledPinM, HIGH);
}
else
{
        digitalWrite(ledPinM, LOW);//this does not turn off the LED as its supposed to in the StateChangeDetection example 
}





  
  digitalWrite(ledPinA, ledPinA_Mem);


  digitalWrite(ledPinB, ledPinB_Mem);  

  
  digitalWrite(ledPinC, ledPinC_Mem);  

  
  digitalWrite(ledPinD, ledPinD_Mem);

  
  //digitalWrite(ledPinM, ledPinM_Mem);

  

}
  • At its simplest, you want to turn on a LED when you receive a 5 and turn off the same LED when you send a second 5.

Use a global variable for the LED state. For a single LED it would look like this

const uint8_t ledPin = 3;
uint8_t ledState = 0;

void setup()
{
  Serial.begin(115200);
  pinMode(ledPin, OUTPUT);
  digitalWrite(ledPin, ledState);
}

void loop()
{
  if(Serial.available())
  {
    char ch = Serial.read();
    if(ch == '5')
    {
      // toggle the led state variable
      ledState = !ledState;
      // set the led to the desired state
      digitalWrite(pinLed, ledState);
  }
}

Not compiled or tested; it should give you the idea.

That is correct. I would also like to be able to add some logic in to control other LEDs depending on latch state.

Example,

I send a 5 and the LED turns on and runs some code.

Send another 5 the LED turns off and runs some other code.

  • Did you try @sterretje's code ?

  • Note he uses:
    if(Serial.available())

I have not tried it but I also don't see any way I can add code to be run depending on the state of the latch. If on : do this. If off : do that. Where could I add this with sterretjes code?

it seems you copy this sketch somewhere, without of understanding how it work

I understand how it works but I don't know how to modify it to make it work for my application.

type 1 for change first LED on pin 8, type 5 to change the last one on pin 12
,

const byte ledPin[] = {8, 9, 10, 11, 12}; // the number of the LED pin

void setup() {
  Serial.begin(115200); 
}
void loop() {
  static byte incomingByte = 0;
  if (Serial.available() > 0)incomingByte = Serial.parseInt()-1;
  if (incomingByte > 0)digitalWrite(ledPin[incomingByte], !digitalRead(ledPin[incomingByte]));
}

Try it out.

      ledState = !ledState;
      // set the led to the desired state
      digitalWrite(pinLed, ledState);
  • Do you mean:
if(digitalRead(pinLed) == HIGH)
{
   digitalWrite(pinLed, LOW);
}

else
{
   digitalWrite(pinLed, HIGH);
}

Sorry, I am tired and should have specified better in my original post. I've since updated the post to better articulate my goal. Im not necessarily trying to exclusively control a LED. I'm trying to execute a block of code when the latch is on and then another block of code when the latch is off.

Expanding on the ledState, is there a way examine this state? I've tried the following:

if(ledState == 1)
{
digitalWrite(led, HIGH);
//Do the following 
}

if(ledState == 0)
{
digitalWrite(led, LOW);
//Do more stuff 
}

Obviously this will not work but I don't know how else to show what I'm trying to do.

More like this:

if(incomingByte == '5')//turns latch on
{
digitalWrite(led, HIGH);
//Do the following 
}

if(incomingByte == '5')//turns the latch lff
{
digitalWrite(led, LOW);
//Do more stuff 
}

OK, change the name of the ledState variable to latchState. Toggle that state when you receive the character '5'.

Next add a test for the latchState and do what needs to be done.

const uint8_t ledPin = 3;
bool latchState = false;

void setup()
{
  Serial.begin(115200);
  pinMode(ledPin, OUTPUT);
  digitalWrite(ledPin, LOW);
}

void loop()
{
  // process serial
  if(Serial.available())
  {
    char ch = Serial.read();
    if(ch == '5')
    {
      // toggle the latch state
      latchState = !latchState;
  }

  // process latchState
  if(latchState == true)
  {
    // your block of code
  }
  else
  {
    // your other block of code
  }
}

Note that I have now change the variable type to bool. The original uint8_t was chosen to match the type of the second argument.

Maybe helpful:

You have two states. Make a variable to count '5' receptions. When '5' is received increment the counter, possibly from zero to one. Next '5' increment the counter again ad nauseum. The only possible states of the LSB of the counter are zero and one - false/true. If counter bit zero is zero (false) do A, if one( true) do B.

Bit of a contrived example, but could be simpler. Could be done similar to:

bool five = false;  //or true, depends which you want to run

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

void loop() {
  checkSerial();
  //..later
  if (five) doFive();
  else      doNotFive();
}

void checkSerial() {
  if (Serial.available()) {
    char c = Serial.read();
    switch (c) {
      case '5': five = !five;
        Serial.print("Set five to: ");
        Serial.println(five, BIN);
        break;
      //...other cases...
      default:
        Serial.print("Received unexpected character: ");
        Serial.println(c, HEX);
        break;
    }
  }
}
void doFive() {}
void doNotFive() {}