two switches one led

Hi
I am experiencing trouble in solving the following problem and I need help.
I have to switch on a led using two ways: via serial monitor sending an “A” to switch on the led, sending an “S” to switch off the led or using a button: one shoot on, one shoot off.
My problem is that I need, for example, to switch-on the led via serial port and switch-off the led with the button or to switch-on the led with the button and switch-off via serial.

I have tried to use an XOR port but the truth table is not suitable for the problem. See attachment.

Thank you

arduino012.pdf (90 KB)

First of all you need to get the circuit right. That is not the way to connect a button. Connect the button from input to ground with the resistor from input to +5, or enable the internal pull up resistor and do not use the resistor.

Next draw out the truth table of what you actually need.

Thank you for suggestion.

Here the truth table

S B L 0 0 0 0 1 1 1 0 1 1 1 1

Where S=serial, B=button, L=led

Maybe i have to explain more:

Starting with 0 0 i push the button and I go to 0 1. Now I wish, for example, to swich off via serial sending an "S" that set the status of the pin to 0, but the status is already to 0.........

I hope have explained better what is my concern.

What you have drawn is the truth table for an inclusive OR gate.
So if any one input is a logic 1 then the output (LED) is a logic one. It is only when both inputs are zero is the output zero.

So having got that it is easy enough to code it:-
your loop() function consists of

  1. Test the button and turn the LED on if it is pushed.
  2. Look at the last byte sent to the serial and turn the LED on if it is set to be on.
  3. If the last serial is off and the push button is off then only then turn the LED off.
  4. If new data has arrived at the serial port read it to update the last serial request.

Thank you for time spent, I'll set up the code and I let you know.

Regards

Reading your first post it seemed to me that what you are wanting is something which does the same as the switches used at the top and bottom of a staircase to turn the light on and off. In this case you might find that something like this would work:

/*
This needs a button from + 5 volts and digital pin 8 and a 10kohm resistor from pin 8 to ground.
Pin 9 controls the circuit you wish to turn on and off.

*/

int highlow = LOW;
byte mychar;    // for incoming serial data
int button = LOW;
int newbutton = LOW;
long waittime= 1000; 
void setup() 
{
  Serial.begin(9600);  
  pinMode(8, INPUT);
  pinMode(9, OUTPUT);
}

void loop() 
{
  if ((Serial.available() > 0) && ((mychar = Serial.read()) == 'A'))
  {
   highlow = !highlow;
   }
  button = digitalRead(8);
  delay(50);
  newbutton = digitalRead(8);
  if (( button == HIGH) && (newbutton == HIGH))
  {
    highlow = !highlow;
  }
  digitalWrite(9,highlow);  
  delay( waittime);
}

it seemed to me that what you are wanting is something which does the same as the switches used at the top and bottom of a staircase to turn the light on and off.

No when you draw the truth table of that you get an exclusive OR logic function not an inclusive OR.

http://whatis.techtarget.com/definition/0,,sid9_gci213512,00.html

@Grumpy_Mike I agree of course but if what I stated is actually correct then I think that sketch would do the job.

@Giulio So, can I ask you is what you wanted to do what I described or not?

Giulio:
S B L
0 0 0
0 1 1
1 0 1
1 1 1

You have three inputs:
Serial
Button
What the current state is

You have one output:
What the next state is

Your table does not reflect this.

What you probably want is a simple set of if statements and a global variable.

bool on = false;
void loop() {
  if (hasButton()) on = !on;
  if (hasSerial()) {
    char ch = readSerial();
    if (ch == 'A') on = true;
    if (ch == 'S') on = false;
  }
  setOutputPin(on);
}

Note: you have to translate to digitalRead(), Serial.available(), and other such functions, depending on your specific needs.

From what you wrote, OP, I support jwatte’s pseudo code. It’s not really a static true table from a combination logic so your truth table may not work. Your problem seems to be more of a state machine with defined input state and actions to those states for an output state.

Here’s my actual code:

#include <phi_interfaces.h>

#define btn 2
#define led 3
#define total_buttons 1

byte status=LOW;
char mapping[]={'B'};
byte pins[]={btn};
phi_button_groups my_btns(mapping, pins, total_buttons);
phi_serial_keypads my_serial(&Serial, 9600);

void setup(){
  Serial.begin(9600);
  digitalWrite(led,status);
}

void loop(){
  char temp;
  temp=my_serial.getKey();
  if (temp==NO_KEY) temp=my_btns.getKey();
  switch(temp)
  {
    case 'A':
    status=HIGH;
    break;
    
    case 'B':
    status=!status;
    break;
    
    case 'S':
    status=LOW;
    break;
  }
  digitalWrite(led,status);
}

The phi_interfaces library for sensing virtually all types of buttons is here:

http://code.google.com/p/phi-prompt-user-interface-library/downloads/detail?name=phi_interfaces_V100.zip&can=2&q=#makechanges

This code can be easily expandable now that it’s a poorman’s state machine.

According to what Guilio said, rather than his table, once he sends 'A' then the button should be ignored until he sends 'S' but I do not think that is what he actually wants. So until he replies with a clarification I guess we cannot resolve his problem. :D

First of all thank to the all the people that reply to me. I have to think to all the tips that you all have sent to me and I need some time....I am not very expert with the C++ language. After having read all your reply maybe I need to more precisely on what I wish that Arduino does.

I have built a regulated dual power supply and to add more functionality I have added Arduino as logic unit to control it. Actually Arduino has the following functions all tested and running: - It reads and display on a LCD display the voltage on both the channels - It reads the temperature on both the heath sinks of the LM317 and LM337 - It controls the speed of a fan - It send to a small loud speaker a sound when temperature has reached a threshold The last tip that I wish to add is to switch on/off the power supply with a button on the PSU and also with the serial cable sending an "A" to switch on and an "S" to switch off the PSU. Both these have to act separately. So for example I switch on with the button I must have the possibility to switch off sending an "S" trough the serial port and to switch on, for example, with the same serial port. At the end of story it would be similar to the command that we have on the television set. We can switch on with the button on the set and for example switch off trough the remote control (just to be more clear...).

I hope this will clarify my problem to all.

Again, thank you for time spent for me.

Giulio:
The last tip that I wish to add is to switch on/off the power supply with a button on the PSU and also with the serial cable sending an “A” to switch on and an “S” to switch off the PSU. Both these have to act separately. So for example I switch on with the button I must have the possibility to switch off sending an “S” trough the serial port and to switch on, for example, with the same serial port. At the end of story it would be similar to the command that we have on the television set. We can switch on with the button on the set and for example switch off trough the remote control (just to be more clear…).

Hi Giulio

Just to clarify for me what you intend to do I have three questions and the reason for them.
First the reason: pressing the button tells arduino to switch the power supply
ON if it is OFF
OR
OFF if it is ON.

You say sending ‘A’ turns it on and ‘S’ turns it off which implies that each can only do the one thing, This also means they are NOT doing the same thing as the button. It also seems to imply that the commands over-ride the requests from the button.

1/ Do you want what I have described above?

2/ Do you want the commands to do the same as the button? ( If you want the sending of commands to do the same as the button then you only need the one command. )

3/ Do you want some other combination?

Thanks.

The combinations should be also:

ON if the previous command sent via serial port was"S" (led switched off via serial port and switched on via button) OFF if the previous command sent via serial port was "A" (led switched on via serial port and switched off via button)

So the second question is : YES

Thanks

Then I think my code in reply #5 will be what you need.

In other words just send one character say for arguments sake 'T' ( T for toggle perhaps ) and test for it in the code.

Unless you want to be able to see what you last sent in which case I think you will need to change

  if ((Serial.available() > 0) && ((mychar = Serial.read()) == 'A'))
     {
    
         highlow = !highlow;
     }

to

if (Serial.available() > 0)
  {
    mychar = Serial.read();
    if (mychar == 'A')
      { 
         highlow = HIGH;
      }
    else if (mychar == 'S')
      {
         highlow = LOW;
      }
  }

hope that helps.

buteman, not to undermine your reply here but if-statement is fine only for few conditions and only gets overly complicated to add more conditions when you need more. OP definitely benefits from using switch-case statement in this situation.

Just read up on my code. Besides, it's the only reply with a complete code. :P

Thanks Liudr,

Your code is interesting and I will certainly look into the phi_interfaces library which is new to me.

Just one small point though is that as Giulio only wants to to use the serial data sent to do the same as a button then, as far as I can see, my code is also complete in that it seems to do what he wants.

If I am not right then please explain why as I always want to improve my coding.

Yes, both codes should work. It starts to show the drawbacks of if-statement if the OP wants more, say control the fan with serial port as well, then the nested if-statement gets more and more difficult to read and change. I use if-statement when I have multiple input logic variables and combine them to see if a few conditions are met. They work best if the program doesn't have to give a unique respond for every possible input value and value combination. Say if you accept 'A', 'X', and all numeric value as turn on system, then if does its best. If you make unique response with every possible input value, switch-case works better. Just my 2 cents.

You are welcome to take a look at my library. It essentially unites all input devices under one roof so a program can call that_device.getKey() regardless what the actual device is, buttons, keypads, rotary encoders, or serial input or serial keypads.

Here is a blog page: http://liudr.wordpress.com/phi_interfaces/

Just been thinking about this again and wondered what you think to this for a solution: Edit - Tested this and it seems to work okay. Just need to send A over serial line to get LED to turn on or off or press the button.

/*
This needs a button from + 5 volts to digital pin 9 and a 10kohm resistor from pin 9 to ground.
 Pin 13 controls the circuit you wish to turn on and off.
 It turns the onboard LED on and off at the moment.
Just need to send  A over serial line to get LED to turn on or off or press the button.
 */
boolean highlow;
int waittime= 2000; // wait 2 seconds
char mychar;

void setup() 
{
  Serial.begin(9600);  
  pinMode(9, INPUT);
  pinMode(13, OUTPUT);
}

void loop() 
{
  if ((Serial.available()  && (mychar=Serial.read()=='A'))|| (digitalRead(9) == HIGH))
  {
     highlow=!highlow;
  digitalWrite(13,highlow);
    delay( waittime);
  }


}

Thank you, I’ll try