Relay circuit kills Arduino? Need help for how to protect the Arduino

Hi everybody. I am working on making an automated testing tool for something at work. But I think I have killed my mega. It is still "functional" but I got odd behavior on one of the pins activating one of the relays. It behaves like it is inverted. When I boot up the code, I have a for loop to write all of them low, and it turns on. When I go farther down the code to turn it on, it turns off. And then I noticed the chip on the mega get hot to the touch. And even gets hot when nothing than the USB is connected. I have already killed a nano, but that one ended with no serial connection, and a hot chip. Code is still work in progress. Lots up debugging serial prints. And some unused integers. The function "serialReturnChar I could not get working, so it is not used. Not my main focus now, but I dont mind some tips on how to return chars from serial. What I had in mind was mostly using it as y/n (yes/no) scenarios when I need user input on something I cant do electrical. :slight_smile:
Automatic_liftboks_test.ino

#include "myDeclarations.h"
int testPwrOn[1];
int results[15];
const unsigned int MAX_MESSAGE_LENGTH = 12;
static char message[MAX_MESSAGE_LENGTH];
int pwrOnPin[2]{ 32, 33 };
int pwrOn[2];

int testSelect = 0;
void setup() {
  Serial.begin(9600);
  while (!Serial)
    ;
  for (int i = 22; i <= 27; i++) {
    pinMode(i, OUTPUT);
    delay(100);
    digitalWrite(i, LOW);
    delay(100);
    Serial.print(i);
    Serial.println("pinMode OUTPUT");
  }
  for (int i = 32; i <= 45; i++) {
    pinMode(i, INPUT);
    Serial.print(i);
    Serial.println("pinMode INPUT");
  }
  delay(1000);
  Serial.println("Setup done");
}

void loop() {
  int runOnce = 0;
  Serial.println("\n \n \n \n What test to run? Type the number to your desired test and press enter to start");
  Serial.println("1 Full test");
  Serial.println("2 Idle test");
  Serial.println("3 Relay test");
  //Serial.println("Geting input from user");
  testSelect = serialReturn();
  Serial.print("Number from user retrived");
  Serial.println(testSelect);
  if (testSelect == 1) {
    Serial.println("Full test");
    idleTest();

  } else if (testSelect == 2) {
    Serial.println("Idle test");
    idleTest();
  } else if (testSelect == 3) {
    Serial.println("Relay test");
    relayTest();
  }
}
int serialReturn() {
  int number = 0;
  while (number < 1) {
    if (Serial.available()) {
      static char message[MAX_MESSAGE_LENGTH];
      static unsigned int message_pos = 0;
      char inByte = Serial.read();
      if (inByte != '\n' && (message_pos < MAX_MESSAGE_LENGTH - 1)) {
        message[message_pos] = inByte;
        message_pos++;
      } else {
        message[message_pos] = '\0';
        number = atoi(message);
        message_pos = 0;
      }
    }
  }
  //Serial.println("Number recived: ");
  //Serial.println(number);
  return (number);
}
/*
void serialReturnChar() {
  char returnChar = 0;
  
  static unsigned int message_pos;
  //Check to see if anything is available in the serial receive buffer
  while (returnChar < 1) {
    if (Serial.available()) {
      //Create a place to hold the incoming message
      
      static unsigned int message_pos = 0;
      //Read the next available byte in the serial receive buffer
      char inByte = Serial.read();
      //Message coming in (check not terminating character) and guard for over message size
      if (inByte != '\n' && (message_pos < MAX_MESSAGE_LENGTH - 1)) {
        //Add the incoming byte to our message
        message[message_pos] = inByte;
        message_pos++;
      }
      //Full message received...
      else {
        //Add null character to string
        message[message_pos] = '\0';
        //Print the message (or do other things)
        Serial.println(message);
        returnChar = 'message';
        //Reset for the next message
        
      }
    }
  }
}
*/
void idleTest() {
  int input = 0;
  Serial.println("Idle test starting");
  Serial.println("Sett switch in OFF position. When ready type 1 and press enter");
  while (input != 1) {
    input = serialReturn();
    Serial.print("Input:  ");
    Serial.println(input);
  }
  for (int i = 0; i <= 1; i++) {
    pwrOn[i] = digitalRead(pwrOnPin[i]);
    Serial.print("digitalRead pwrOnPin");
    Serial.println(i);
    Serial.print("pwrOn ");
    Serial.println(pwrOn[i]);
    if (pwrOn[i] == 1) {
      Serial.print("pwrOn");
      Serial.print(i);
      Serial.println("  Pass");
    } else {
      Serial.print("pwrOn");
      Serial.print(i);
      Serial.println("  Fail");
    }
  }
}

void relayTest() {
  Serial.println("To exit test type 9 and press enter");
  int input = 0;
  while (input != 7) {
    input = serialReturn();
    Serial.println(input);
    int relay = input + 21;
    digitalWrite(relay, !digitalRead(relay));
  }
  for (int i = 22; i <= 27; i++) {
    Serial.println(i);
    digitalWrite(i, LOW);
    delay(100);
  }
}

myDecleration.h

void idleTest();
int serialReturn();
void serialReturnChar();
void relayTest();

Welcome to the forum

It is normal for relay modules to turn on when their input goes LOW and off when it goes HIGH

It is also normal for relay modules to require more current than an Arduino pin can safely supply in order to turn on. Consider using an external power supply for the relay module

I have posted a schematic where you see I use NPN transistor to drive the relays. Relays are normally open and I measure 5 volt over R2.

Add a free wheel diode to the coil of the K7-23.

Will that be necessary? There are only relays, resistors diodes and a big switch in the unit I am testing. Will it induct voltage over on the Arduino side of the relay?

D1-D6 are diodes? You didn't use the diode symbol.

Not sure what R2, R4... R12 are for.

For the "signals to read", best to connect the relay contacts between the Arduino pin and ground. Use INPUT_PULLUP. No need for R13.

For all your output relays, is anything connected to the contacts? If so, and those components are more relays, motors, electromagnets, solenoids etc, then you need diodes across their coils also.

I don't know what went over my head. Yes D1-D6 are diodes. Not the wrong symbol. But the wrong symbol for this type of drawing. Yes there is a whole circuit in the control box. The relay contacts are indeed in use. I am simulating buttons and switches with Arduino and k1-6. I see I have mixed my native language and written "boks" instead of "box" in the drawing. What advantages is there to pull up resistors than pull down? Except form not needing the R13. If I can save space on I will sure make that change.

And R2, R4 and so on. I think I found a drawing for how to wire up a NPN transistor. But if I remember correctly, I don't know. Was going to say leakage current, but that seams not so import in this circuit.

You bettor check the diodes and the transistors to make sure they are not burned out or shorted.

Definitely not shorted. Did some quick ohm readings. If there are any function problem later I will do a diode test on the transistors. Your input is appreciated :slight_smile:

For debugging purposes, rather than connecting it to the arduino GPIOs, does it work correctly if you connect the transistors to a +5V supply

Hello balleklorin04

Use optocoupler to control the relays simply.

You know what. What a brilliant idea. Got to do some redoing in my circuit.

This I will keep in mind.

Firstly, Welcome to the forum, and congrats, you're among the select few who's original post meets all the major criteria for a great start - legible schematic, coherent post that compiles (other than a missing .h file), and comprehensible textual statement of problem and desired help!

Others have given useful advice about your hardware. I concur on,

  • buy a commercial relay board; if this is a prototype, use amazon cheapies, but if this is for a real application, buy something from a reputable source likely to have better quality relays. Ensure it has opto-iso protection for your CPU, with transistor/mosfet drive for the relay and good reverse-diode protection from the relay field collapse.
  • if a prototype, yeah, change your contact sensing to using internal pullups and low-active logic; it'll do for short term. Again, if it's commercial, think about better input isolation, especially if it's not "all in a box" - if your inputs are exposed to other mechanical/electrical equipment's foibles, it's not dificult to arrange those contact inputs as drivers for optical isolation inbound, especially since you seem to have 24V available. Again, multi-input iso boards are available very cheaply, and without electromechanical relays, durability is less of a concern.

As for Serial input, read

As Serial input details are some of the most commonly rehashed and misunderstood problems we see here. If that doesn't get you on the straight-and-narrow, come back and ask your questions - on this thread please, don't start a new one, as the context will be lost.
Again, Welcome!

1 Like

Thank you so much for your detailed response and your compliments (the .h file is there also :wink: ). I have been reading a lot in this forum and seen tons of complaints about code and missing drawings. But would you be so kind to send me a link as an example of the opto-iso board you are describing? Struggling to find any good results.

If you buy one from Amazon, Ebay or Aliexpress, buy at least two.

1 Like

So that's your .h file? Hmm. Okay. What am I missing?

Search Amazon for "Optocoupler Isolation Board"
Good luck.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.