Hi all,
I'm trying to get my Arduino talking to a 16 relay board I picked up using a shift register - at this point in time I'm only working with 8 but once it's all working will move to use all 16.
I am using MQTT to receive a number relating to which relay to turn on or off. My code checks this number against a current status array and turns it on or off accordingly. I decided to have (to start with) an integer with zero value. I also have an array with my relay values as follows:
const int relayValues[]={1,2,4,8,16,32,64,128};
This way I can get the number of the relay that is being flipped, subtract 1 from it and get it's index value from this array. I then check if it's currently on or off - if it's on I XOR it with the current status, if it's off I OR it.
For example, if I received a value of 3, it would return 4 from this array. If no other relays are on, it would OR with the current value (which is an int that begins as 0) and output the new number (in this case 4).
I then send this number to my shift register after NOT-ing it, as my relay board uses a 1 to turn the relay off and 0 to turn it on. This then makes the value (in the example) -5.
My problem is this: my shiftOut command then looks like this:
shiftOut(datapin,clockpin,MSBFIRST,-5)
but nothing gets received at the other side of the shift register.
I'm confused why I'm getting -5 instead of 251 and if this would be causing my shift register to sit there with a dumb look on its face.
(the number in binary after NOTing is 11111011)
Full code below, criticism welcomed as I'm flying by the seat of my pants here.
Thanks
#include <SPI.h>
#include <Ethernet.h>
#include <PubSubClient.h>
#define datapin 2
#define clockpin 3
#define latchpin 4
int current = 0; // 00000000
const int relayValues[]={1,2,4,8,16,32,64,128};
int relayCheck[] = {0,0,0,0,0,0,0,0};
int changeVal = 0;
int chkOnOff[]={0,1};
String OnOrOff;
byte mac[] = {
0x00, 0xAA, 0xBB, 0xCC, 0xDE, 0x02 };
byte mqttserver[] = { 192, 168, 2, 7 };
EthernetClient ethClient;
PubSubClient clientr(mqttserver, 1883, callback);
int calculateRelayVal(int newVal) {
Serial.print("Starting calculateRelayVal with val of ");
Serial.println(newVal);
Serial.print("Current value is ");
Serial.println(current);
// newVal has relay we need to toggle
// referenced in relayCheck as newVal-1
int intRelayToWorkWith = relayValues[(newVal-1)];
if(relayCheck[(newVal-1)]==0) {
// relay is currently off, turn on
changeVal = current | intRelayToWorkWith;
relayCheck[(newVal-1)]=1;
} else {
// relay is currently on, turn off
changeVal = current ^ intRelayToWorkWith;
relayCheck[(newVal-1)]=0;
}
Serial.print("Finished checking values, changeVal currently ");
Serial.println(changeVal);
current = changeVal;
return current;
Serial.println("completing calculateRelayVal");
Serial.println("");
}
void doWork(int val) {
Serial.println("");
Serial.print("doWork starting with val of ");
Serial.println(val);
// as relays need a '0' to turn on and a '1' to turn off, need to NOT this value
int realVal = ~val;
Serial.print("Doing NOT conversion gives result of ");
Serial.println(realVal);
digitalWrite(latchpin,LOW);
shiftOut(datapin,clockpin,MSBFIRST,realVal);
digitalWrite(latchpin,HIGH);
Serial.println("sent value, closing doWork");
Serial.println("");
}
static void callback(char* topic, byte* payload, unsigned int length) {
Serial.print("callback with payload ");
length=length/2;
Serial.write(payload,length);
int readVar = (unsigned int)atoi((char *) payload);
Serial.println(readVar);
String debugcalReV = "Calling calculateRelayVal with the payload of ";
String debugcalReVGO = debugcalReV + readVar;
Serial.print(debugcalReVGO);
Serial.println(" ... ");
int registerValue = calculateRelayVal(readVar);
String debugregVal = "registerValue is set to ";
String debugregValGO = debugregVal + registerValue;
Serial.println(debugregValGO);
Serial.println("doing work now for above value ... ");
doWork(registerValue);
String debugdoWork = "doWork complete for ";
String debugdoWorkGO = debugdoWork + registerValue;
Serial.println(debugdoWorkGO);
if(relayCheck[(readVar-1)]==1) {
OnOrOff = " turned on.";
} else {
OnOrOff = " turned off.";
}
String DataMash = "Publishing data - relay ";
String DataResult = DataMash + readVar + OnOrOff;
Serial.println(DataResult);
char PublishData[100];
DataResult.toCharArray(PublishData,100);
clientr.publish("RelayControlReport", PublishData);
}
void setup()
{
Serial.begin(9600);
if (Ethernet.begin(mac) == 0) {
Serial.println("Failed to configure Ethernet using DHCP");
// no point in carrying on, so do nothing forevermore:
for(;;)
;
}
if(clientr.connect("arduinoClient")) {
clientr.publish("checkInTopic","Relay Controller Online");
clientr.publish("RelayControlReport","Relay Controller Online");
clientr.subscribe("RelayControl");
}
delay(500);
Serial.println("Scouris - MQTT Control, booting up.");
Serial.println("Resetting relays to OFF ...");
doWork(0);
Serial.println("Continuing.");
delay(1000);
}
void loop()
{
clientr.loop();
}