system
July 11, 2014, 2:42pm
1
Hi first time posting here so hello everyone.
I have been trying to code my 8 channel sainsmart relay board so that if i send a 1 or 2 over the serial it turns that relay on and off.
basically if i send a 1 it turns on then if i send 1 again it turns off.
I realize my coding probably sucks and is wrong . I just would like someone to tell me how it should look or a simple way of doing what I've done.
Currently it works but I have to send a 1 or 2 around 3 or 4 times before the relay actually turns off.
Here my current code
int incomingByte = 0; // for incoming serial data
int relay1 = 2;
int relay2 = 3;
boolean relayState1 = false;
boolean relayState2 = false;
void setup() {
Serial.begin(9600); // opens serial port, sets data rate to 9600 bps
pinMode(relay1, OUTPUT);
pinMode(relay2, OUTPUT);
}
void loop() {
// send data only when you receive data:
if (Serial.available() > 0) {
// read the incoming byte:
incomingByte = Serial.read();
if (incomingByte == '1') {
digitalWrite(relay1, HIGH);
relayState1 = !relayState1;
Serial.println(incomingByte, DEC);
}
}
if (relayState1 == true) {
digitalWrite(relay1, LOW);
}
// send data only when you receive data:
if (Serial.available() > 0) {
// read the incoming byte:
incomingByte = Serial.read();
if (incomingByte == '2') {
digitalWrite(relay2, HIGH);
relayState2 = !relayState2;
Serial.println(incomingByte, DEC);
}
}
if (relayState2 == true) {
digitalWrite(relay2, LOW);
}
}
system
July 11, 2014, 2:51pm
2
Imagine you send a '2' and the first "Serial.available" sees it.
You read the character, and compare it to '1'.
It isn't a '1', so you do nothing.
Oops.
(uncompiled, untested)
const byte relay1 = 2;
const byte relay2 = 3;
boolean relayState1;
boolean relayState2;
void setup()
{
Serial.begin(9600);
pinMode(relay1, OUTPUT);
pinMode(relay2, OUTPUT);
}
void loop()
{
if (Serial.available() > 0) {
int incomingByte = Serial.read();
Serial.println((char) incomingByte); // echo for debug
if (incomingByte == '1') {
relayState1 = !relayState1;
}
if (incomingByte == '2') {
relayState2 = !relayState2;
}
digitalWrite(relay2, relaystate2);
digitalWrite(relay1, relaystate1);
}
}
Arrch
July 11, 2014, 3:32pm
3
// send data only when you receive data:
if (Serial.available() > 0) {
// read the incoming byte:
incomingByte = Serial.read();
...
}
...
if (Serial.available() > 0) {
// read the incoming byte:
incomingByte = Serial.read();
...
}
Two separate reads in the loop, means you're leaving it up to chance as to which one is going to read the byte. Imagine a fighting couple share a mailbox and check it at different times of the day. If the husband gets a letter addressed to the wife, he throws it out. If a wife gets a letter for the husband, she throws it out. In this scenario you have to time when you drop the letter in, to make sure it goes to the write person. You need to mend the relationship so that only the wife gets the mail. She checks to see if it is addressed to her, if not, she gives it to her husband who checks to see if it's addressed to him. If not, he throws it out.
system
July 11, 2014, 4:42pm
4
Thanks guys makes a lot of sense and that code worked perfect!
system
July 11, 2014, 5:09pm
5
More flexible, for up to 8 relays
const byte relayPin [] = {2, 3};
const byte N_RELAYS = sizeof (relayPin) / sizeof (relayPin [0]);
byte relayState; // good for a MAXIMUM OF 8 RELAYS
void setup()
{
Serial.begin(9600);
for (byte i = 0; i < N_RELAYS; i++) {
pinMode(relayPin [i], OUTPUT);
}
}
void loop()
{
for (byte i = 0; i < N_RELAYS; i++) {
digitalWrite (relayPin [i], relayState & (1 << i));
}
if (Serial.available() > 0) {
int incomingByte = Serial.read() - '0' - 1;
if (incomingByte >= 0 && incomingByte < N_RELAYS)
{
Serial.println( incomingByte); // echo for debug
relayState ^= 1 << incomingByte;
}
}
}