Hey Everyone,
I hope this is the right forum to post this in.
I am currently using a shift register to power 8 separate relays depending on a parsed serial input from my computer (which will eventually be replaced with an rpi). Everything works just great until I add a load to the business end of the relay, and the load im adding is a just a small DC motor from an elegoo starter kit for testing purposes, and its on its own 6v circuit that has nothing at all to do with the rest of the setup. The shift register I am using is a 74HC595, which also comes with the elegoo starter kit. I bought an inland 8-channel 5V Relay Module from a local store.
I dont have a wiring diagram so youll have to bear with me as I explain all the connections
Arduino 5v => Shift Register pin 16 (Vcc) and 10 (SRCLR)
Arduino 6 => Shift Register pin 14 (SER)
Arduino 7 => Shift Register pin 11 (SRCLK)
Arduino 8 => Shift Register pin (RCLK)
Arduino GND => Shift Register pin 8 (GND) and pin 13 (OE) and Relay Board GND
Shift Register QA-QD => Relay Board IN1-4 (im only using half the relays right now)
Separate 5v Power Supply (+) => Relay Board Vcc
Separate 5v Power Supply (-) => Relay Board GND and Arduino GND
Another Separate 6v Power Supply (+) => DC Motor (+)
DC Motor (-) => Relay Normally Open Terminal 1 (far left relay screw terminal)
Relay Common (middle relay screw terminal) => Separate 6v Power Supply (-)
There is also a small removable jumper that is attached between two small relay input pins labeled COM and a second GND, I do not know what this is for so I left it attached.
When I run my program, It works every time without the DC motor attached, and then when I attach the motor, it will work once but freeze the serial monitor and the Arduino IDE software. I force close the software and try to reload the program to the Arduino again and get this error
"An error occurred while uploading the sketch, avrdude: ser_open(): can't set com-state for "\.\COM3"
The fix for this seems to be unplugging and plugging in the USB connection from my computer to the Arduino.
Again, the motor is on its own separate circuit, the relay board has its own separate Vcc and GND but the Relay Board GND is also tied back into the Arduino GND for signaling.
const byte numChars = 32; //number of characters set to 32, constant which means read only basically
char receivedChars[numChars];
char tempChars[numChars]; // temporary array for use when parsing
char messageFromPC[numChars] = {0}; // variables to hold the parsed data
int bottleNum = 0; //defining first input variable for location
int msOpen = 0; //defining second input variable for duration
bool newData = false;
char receivedCommand;
int binaryValue = 0;
int clearPin = 5;
int serialData = 6;
int shiftClock = 7;
int latchClock = 8;
void setup()
{
pinMode(clearPin, OUTPUT);
pinMode(shiftClock, OUTPUT);
pinMode(latchClock, OUTPUT);
pinMode(serialData, OUTPUT);
Serial.begin(9600); //baud rate for serial monitor
Serial.println("Shift Register and Relay Testing"); //print this message on open
Serial.println("Positions available: 1-4"); // ^
Serial.println("Enter data in this Format <01,1000> ");
binaryValue = 0;
activateRelay();
}
void loop()
{
//check for recieved commands on the serial monitor
recieveData(); //void command defined later
if (newData == true) {
strcpy(tempChars, receivedChars); // this temporary copy is necessary to protect the original data because strtok() used in parseData() replaces the commas with \0
parseData(); //void command defined later
printData(); //void command defined later
checkSerial();
newData = false; //setting new data bool back to false at end of loop
}
}
void recieveData() { //command for recieving data and identifying start and end markers
static boolean recvInProgress = false; //static is visible to only one function, defining this static bool as false by default
static byte owo = 0; //static as above, but for number of characters
char startMarker = '<'; //defining start marker
char endMarker = '>'; //defining end marker
char uwu; //defining variable uwu as a character value
while (Serial.available() > 0 && newData == false) { //while serial monitor is unavailable, i.e getting inputs between markers
uwu = Serial.read(); //set input to variable uwu
if (recvInProgress == true) { //if we are currently recieving data
if (uwu != endMarker) { //if the character is not an end marker
receivedChars[owo] = uwu; //Set number of characters to static byte
owo++; //add one character to static byte
if (owo >= numChars) { //if static byte is the same or greater than contant byte
owo = numChars - 1; //static byte becomes constant byte
}
}
else {
receivedChars[owo] = '\0'; // terminate the string
recvInProgress = false; //set recieve in progress to false
owo = 0; //set static byte back to 0
newData = true; //set new data to true
}
}
else if (uwu == startMarker) { //set character value to start marker
recvInProgress = true; //set recieve in progress to true
}
}
}
void parseData()
{
char * strtokIndx; // this is used by strtok() as an index
strtokIndx = strtok(tempChars, ","); // get the first part
bottleNum = atoi(strtokIndx); // convert it to an integer
strtokIndx = strtok(NULL, ","); //get the second part
msOpen = atoi(strtokIndx); // convert it to an integer
}
void checkSerial() //check for recieved commands on the serial
{
switch (bottleNum) //we check what is the command
{
case 1: //Power Relay 1
Serial.println("Powering Relay 1"); //print text before moving
binaryValue = 1;
commandRelay(); //run the command for powering a relay
break;
case 2: //Power Relay 2
Serial.println("Powering Relay 2"); //print text before moving
binaryValue = 2;
commandRelay(); //run the command for powering a relay
break;
case 3: //Power Relay 3
Serial.println("Powering Relay 3"); //print text before moving
binaryValue = 4;
commandRelay(); //run the command for powering a relay
break;
case 4: //Power Relay 4
Serial.println("Powering Relay 4"); //print text before moving
binaryValue = 8;
commandRelay(); //run the command for powering a relay
break;
case 5: //Power Relay 4
Serial.println("Powering Relay 4"); //print text before moving
binaryValue = 16;
commandRelay(); //run the command for powering a relay
break;
case 6: //Power Relay 4
Serial.println("Powering Relay 4"); //print text before moving
binaryValue = 32;
commandRelay(); //run the command for powering a relay
break;
case 7: //Power Relay 4
Serial.println("Powering Relay 4"); //print text before moving
binaryValue = 64;
commandRelay(); //run the command for powering a relay
break;
case 8: //Power Relay 4
Serial.println("Powering Relay 4"); //print text before moving
binaryValue = 128;
commandRelay(); //run the command for powering a relay
break;
default:
break;
}
}
void commandRelay()
{
activateRelay();
delay(msOpen);
deactivateRelay();
}
void activateRelay()
{
digitalWrite(latchClock, LOW);
shiftOut(serialData, shiftClock, MSBFIRST, binaryValue);
Serial.println(binaryValue);
digitalWrite(latchClock, HIGH);
}
void deactivateRelay()
{
digitalWrite(latchClock, LOW);
shiftOut(serialData, shiftClock, MSBFIRST, 0);
Serial.println("Relay Off");
Serial.println();
digitalWrite(latchClock, HIGH);
}
void printData()
{
Serial.print("Recieved Bottle Number: ");
Serial.println(bottleNum);
Serial.print("Recieved Duration ");
Serial.println(msOpen);
}
Thank you very very much to anyone who can tell me where I screwed up!