light switch. arduino does the opposite of what i need..

Hello all,

I am quite new with arduino programming, but I like to start big. My project is my apartment automation (Lights, heating, etc). But as always the hardest is the start..
I have a simple ON/OFF switch that every one has in they're apartments. I want to take that signal to the arduino. So I'm sending 5v signal through the switch in to the arduino. I wrote it with this simple function to easily expand it to more switches and so that the code would stay clean and not to big..
I want it to read +5v on the pin 23 and turn on the lamp on pin 22. Problem is that it does the opposite.. when it seas ground it switches the output high, when it gets +5v it turns the relay off.. could some on explain me what I'm doing wrong?

If it's needed I have arduino mega 1280 and Relay module of 8 relays.

Thank you!!! The code is below:

int lamp1 = 22;
int switch1 = 23;

void setup() {
pinMode(lamp1, OUTPUT);
pinMode(switch1, INPUT);
}

void loop() {
int x;
int y;
x = switch1;
y = lamp1;
Lempa5VON(x, y);

}

int Lempa5VON(int x, int y){
int temp;

temp = digitalRead(x);
if (temp == HIGH) {
digitalWrite(y, HIGH);
}
else {
digitalWrite(y, LOW);
}
}

a) be better to wrap your code inside [ code] ... [ /code]
b) need to see your hardware configuration to know what's going on
c) you could just change the last few lines to be

int Lempa5VON(int x, int y){
  int temp;

  temp = digitalRead(x);   
  if (temp == HIGH) {               
    digitalWrite(y, LOW);   
  }
  else {             
    digitalWrite(y, HIGH);   
  }
}

We need to know how, exactly the switch is wired. If there is no external pull-up or pull-down resistor, you could have a floating pin condition when the switch is not allowing current to flow to the input pin. You are not, but you could, use the internal pullup resistor, by putting

digitalWrite(switch1, HIGH);

after the pinMode statement sets the switch1 pin to INPUT.

If you do that, HIGH will mean not pressed, and LOW will mean pressed.

  temp = digitalRead(x);   
  if (temp == HIGH) {               
    digitalWrite(y, HIGH);   
  }
  else {             
    digitalWrite(y, LOW);   
  }

Can be simplified to

  temp = digitalRead(x);              
  digitalWrite(y,temp);

or

  digitalWrite(y, digitalRead(x));

The first code set y high if temp was high, and y low if temp was low - it sets y to the state of x, so we can do it without any if statements. In order to make it do the opposit of the first code snippet (high if low, and visa versa), we can use the ! operator:

  digitalWrite(y, !digitalRead(x));

This takes the value read from x. If it is high, it sets y to low. If it is low, it sets y to high.

Onions.

Thank you for the comments.

mmcp42:
a) thanks for the hint. I will use it in future.
b) I have a pull down resistor. But in testing my setup was simplified to:
only Arduino and relay module are connected together. Relay module is powered from arduinos +5v and GND. then pin 22 is connected to the relay module input. For test purpose I just gave +5V or GND from the same arduino board to the pin 23. And it still gives low to the output when I give it a +5V and High when GND is connected.
C) Done that and it functions as I need, but I want to understand how it works because this is the simplest part of the project and it's working not as I understand it..

PaulS:
As I wrote in test setup it's not a problem of floating switch. For the complete setup I soldered a group of pull down resistors.
And do you know is this internal pull up resistor exist for every one of 53 Arduino Mega inputs? And does it have some disadvantages against soldered pull down/up resistors? It is quite tempting to drop out some additional module that could cause some problems in future.

Onions:
Thank you for the explanation and simplification of the code. Only one but.. as you say "The first code set y high if temp was high, and y low if temp was low - it sets y to the state of x" that's exactly what is not happening :smiley: it does the opposite and I don't understand why..

Relay module is powered from arduinos +5v and GND.

Most relays draw more current that the Arduino can provide. Post a link to the relay you are using, please.

Any good reason not to just skip the arduino so that you don't need to program it or use an external transistor to drive the relay?

if your "lamp" is connected between pin 23 and ground then setting pin 23 HIGH will activate it
if your "lamp" is connected between pin 23 and +5 then setting pin 23 LOW will activate it

that's why a circuit diagram matters...

this is my relay module
http://www.ebay.de/itm/8-Kanal-12V-Relais-Relay-Modul-for-PIC-ARM-AVR-Arduino-/280737396005?pt=LH_DefaultDomain_77&hash=item415d40b525#ht_2284wt_981
Its designed for arduno. for one channel there should be enough current..

I attached my test setup. Red and green wires power supply for the relay module. The black wire is the output from arduino to the relay module channel. And with the yellow and orange wires that are connected to +5V and GND I simulated the switch..

Just to be clear. the solution of coding, that when I get high input it sets output to the relay to low, worked. It's just that from my point of thinking it's not correct and I don't understand why in such a simple program I get that kind of results/error..

this is my relay module

OK. You are not actually triggering a relay. You are triggering a transistor that triggers the relay. That's good.

I'd suggest creating a script that reads the switch state, and sends a message to the serial monitor - "Pressed" or "Released". Send the message only as the transition occurs. This will let you determine if HIGH means pressed, or if LOW means pressed. It will also let you determine that you are reading the switch correctly, and determining the transition correctly.

When you are getting consistent Pressed and Released messages, you can write the code to turn the relay on or off to match, whether the values seem logical or not.