Tristate switch

Hello I have a momentary push button and a led I have to make it so when the button is pushed the 1st time the light comes on and it sends a Data packet (see Note) when the button is pushed a 2nd time the light stays on and it sends the same data packet and when it is pushed a 3rd time the light goes out and it sends the data packet again. This is the only try state button the other are already done using the code posted below is there a way to ad or modify the given code to do what I am asking? I have tried afew things but no luck. Any help would be greatly appreciated. Oh and Cock in the code is short for COCKPIT Lights

Data Packet CAN.sendMsgBuf(0x18FF9879, 1, 8, cockon); relates to a CAN Bus module

 //BEGIN COCKPIT LIGHTS SECTION


  CockLed1 = (digitalRead(Cockpitlts));    //BaitLed1 is value of Baitwell button
  delay(50);  //button debounce (not needed if debounce circuit exists)

 if(CockLed1 == 1 && newCockLed1 == 1){  // switch is not and was not pressed
   digitalWrite(CockLed, HIGH);
   newCockLed1 = CockLed1;                  //lastState is still 1
}

 else if(CockLed1 == 0 && newCockLed1 == 1){  // switch was just pressed
   digitalWrite(CockLed, LOW);
   CAN.sendMsgBuf(0x18FF9879, 1, 8, cockon);  // send data:  id = 0x00, standrad flame, data len = 8, stmp: data buf
   newCockLed1 = CockLed1;                   // lastState is now 0
}

 else if(CockLed1 == 1 && newCockLed1 == 0){  // switch was just released
   digitalWrite(CockLed, LOW);      //led is on
   //newCockLed1 = CockLed1;  
}

 else if(CockLed1 == 0 && newCockLed1 == 0){  // switch is pressed and was pressed last time we checked
   digitalWrite(CockLed, HIGH);   //turn led off
   CAN.sendMsgBuf(0x18FF9879, 1, 8, cockon);  // send data:  id = 0x00, standrad flame, data len = 8, stmp: data buf
   newCockLed1 = 1;   //lastState should now be 1 again and loop repeats
}

//END COCKPIT LIGHTS SECTION

KWood: Hello I have a momentary push button and a led I have to make it so when the button is pushed the 1st time the light comes on and it sends a Data packet (see Note) when the button is pushed a 2nd time the light stays on and it sends the same data packet and when it is pushed a 3rd time the light goes out and it sends the data packet again. This is the only try state button the other are already done using the code posted below is there a way to ad or modify the given code to do what I am asking? I have tried afew things but no luck. Any help would be greatly appreciated. Oh and Cock in the code is short for COCKPIT Lights

Data Packet CAN.sendMsgBuf(0x18FF9879, 1, 8, cockon); relates to a CAN Bus module

 //BEGIN COCKPIT LIGHTS SECTION

  CockLed1 = (digitalRead(Cockpitlts));    //BaitLed1 is value of Baitwell button   delay(50);  //button debounce (not needed if debounce circuit exists)

if(CockLed1 == 1 && newCockLed1 == 1){  // switch is not and was not pressed    digitalWrite(CockLed, HIGH);    newCockLed1 = CockLed1;                  //lastState is still 1 }

else if(CockLed1 == 0 && newCockLed1 == 1){  // switch was just pressed    digitalWrite(CockLed, LOW);    CAN.sendMsgBuf(0x18FF9879, 1, 8, cockon);  // send data:  id = 0x00, standrad flame, data len = 8, stmp: data buf    newCockLed1 = CockLed1;                   // lastState is now 0 }

else if(CockLed1 == 1 && newCockLed1 == 0){  // switch was just released    digitalWrite(CockLed, LOW);      //led is on    //newCockLed1 = CockLed1;  }

else if(CockLed1 == 0 && newCockLed1 == 0){  // switch is pressed and was pressed last time we checked    digitalWrite(CockLed, HIGH);   //turn led off    CAN.sendMsgBuf(0x18FF9879, 1, 8, cockon);  // send data:  id = 0x00, standrad flame, data len = 8, stmp: data buf    newCockLed1 = 1;   //lastState should now be 1 again and loop repeats }

//END COCKPIT LIGHTS SECTION

Looks overly complicated. Break the problem down into parts: What needs to happen with the switch. Your pushbutton (and really all momentary buttons) have 4 distinct "states". 1. Not touched 2. Just pressed 3. Being held 4: Just released

States 1 and 3 are static states, and states 2 and 4 are transitional (or in the language of digital signalling, edge states). So for your problem, my interpretation of what you want (please correct me if I'm wrong) the actions for the different states should be: 1. Not touched - Do nothing 2. Just pressed - Do something 3. Being held - Do nothing 4. Just released - Do nothing (well, actually, prepare for the next "Just pressed" state)

So, you can remove 2 of the above if statements (if(CockLed1 == 1 && newCockLed1 == 1){ ... } and if(CockLed1 == 0 && newCockLed1 == 0){ ... }) because we don't need to do anything. (I'm ignoring the else for now. Re-apply as needed after making changes.)

Your section for my #4 state, "Just released" (if(CockLed1 == 1 && newCockLed1 == 0){ ... }) you have turning the LED off (yet you didn't stated that was a desired effect) and you have the part that prepares for the next "Just pressed" state (newCockLed1 = CockLed1;) commented out. I'd remove the digitalWrite and uncomment the assignment.

This leaves state 2, "Just pressed" (if(CockLed1 == 0 && newCockLed1 == 1){ .. }). Because your desired effect for this follows a regular, ordered pattern it can be accomplished with a simple index counter and a switch case based off the index. Here is some pseudocode to go on:

switch CockLedIndex (previously initialized to 0 as either a global variable, or (if this is within a function) a static local variable)
{
  case 0: // first step in rotation
    Turn on CockLed LED
    Send packet
    increment CockLedIndex by one
    break
  case 1: // second step in rotation
    // LED should already be on
    Send packet
    increment CockLedIndex by one
    break
  case 2: // third step in rotation
    Turn off CockLed LED
    Send packet
    set CockLedIndex to 0
    break
  default: // should never reach this
    Send some sort of error message that this point was reached. Might indicate accidental variable name re-use elsewhere in the code.
    set CockLedIndex to 0 // Try to fix things...
}

I'm counting from 0 to (amountOfSteps - 1) here to help you get used to this type of counting to make it similar to using a for loop to scan through an array, because array elements are numbered 0 through (amountOfElements - 1). Before long you will start driving your SO mad when you start creating numbered lists around the house that start with 0... ;)

Because you always want to send the packet (well, except for the "default" case, but that shouldn't happen), so you don't have to write it 3 times (and then if you need to change it having to remember to change it 3 times), remove the 3 instances from the switch case structure, and put it in just once after the switch case structure, before leaving the if statement. That also makes it obvious that the packet (and the same packet) is sent at every "Just pressed" edge state.

I hope this helps more than confuses.

Dear Sembazuru,

Your logic seems sound and I understand what your saying thank you very much for the explanation. I am at home currently and do not have the project code in front of me. With that being said I have never used code like you have posted so im sorry if it is a dumb question but can i use the code you posted directly in my sketch. if not could you please post my code modified to work in the manner you stated. Also I should have stated that when I bring a pin LOW that is actually turning on the LED.

KWood: Dear Sembazuru,

Your logic seems sound and I understand what your saying thank you very much for the explanation. I am at home currently and do not have the project code in front of me. With that being said I have never used code like you have posted so im sorry if it is a dumb question but can i use the code you posted directly in my sketch. if not could you please post my code modified to work in the manner you stated. Also I should have stated that when I bring a pin LOW that is actually turning on the LED.

The code I used is called pseudocode. It will not compile in any compiler that I know of. It is more of a description than actual code. I'm leaving as an exercise to you to figure out how to translate my description to the actual Adruino syntax. I did follow close (but not exactly, check the Arduino reference pages for details) to the syntax for switch case, for example I didn't include appropriate semicolons. I'm hoping it is more informative for you to figure out the correct syntax from a description than me to spoon-feed you the completed code. That way you can practice going from a planned out thought to actual code.

Yes, I did see that you have your CockLed functioning low active (i.e. the active state when something happens (the LED is on in this case) is logic level LOW). You made that clear in your comments. While the Atmel chips on most of the Arduinos are rated for the same source and sink current on the I/O pins, many other chips can actually sink (provide ground) more current than they can source (provide non-ground voltage, usually positive but can be negative in special cases). I'm actually not familiar with the Arm chips used on some of the Arduinos, so I don't know their sinking and sourcing specifications. Getting used to thinking with mixed high active signals and low active signals is a good flexibility to have. (Notice, the reset signal is low active, and momentary switches using the internal pullups are also low active. But the D13 LED and the beginner momentary switch examples using an external pull down resistor are high active.)