Relay buzzing under load, Don't know why

Status
Not open for further replies.

tikawawa

Member
Hi,

I looked everywhere and could not fiind an answer.

My teensy is connected to a standard 8 relay module with SRD-05VDC-SL-C relays. The teensy is recieving ppm signals from an rc receiver X8R by frsky and checking if there around 2ms it turns on the corresponding relay. It works great without load but as soon as I add a load, the relays start buzzing for a bit and then they fully engage turning on the load.

The teensy power is from the laptop. I tried both, powering the relay module from with the laptop with jumper in place, and also removing the jumper and giving it it's own 4v power supply (single cell lithium ion battery) and removing the ground wire from the teensy to the board, no luck.

The rc receiver need 7.4v and that is powered by a switching power QM12v5A UBEC from hobbyking.

The load is a 12v fuel pump on one relay and a starter solenoid for an gas engine on another relay. All grounds are connected together.

I trying connecting a short led strip to the relay and the buzzing is not noticable, I really don't think the load is too high, it's a small pump, my guess is the emf is going back to the board somehow.

I also saw that the serial monitor on the teensy also displays garbage values of the ppm pins when the really is buzzing.

I am attaching the code below, there are 2 tabs, I got some help with the code but I understand most of it.

Please help, thanks

Code:
/************************************************************
Integrating RC and Relay position and sending them wirelessly
to another arduino to dispaly on screnn**
************************************************************/

#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
#define RF24_SCLK 27
                                            
int RelaySigOut [] = {A9,A8,A7,A6,A5,A4,A3};   // Pins from arduino to relay board
int Pulse [] = {2,3,4,5,6,7,8 };               // Pins from rc receiver to arduino
unsigned long long Pduration [8];           // Total number of pins,* Has to match pinCount
int pinCount = 7;                           // Total number of pins
int relaysValues [7];                       // To save the boolean values of the relays

const int valuesArraySize = 2;              // The size on the array values[] that will be sent 
int values[2];                              // To save the values that will be sent

RF24 radio(30,29);                          // CE (Chip Enable), CSN (Chip Select)
byte addresses[][6] = {"1Node","2Node"};

void setup() {
  Serial.begin(9600);
  
  // For loop to cycle through all pins 
  for (int thisPin = 0; thisPin < pinCount; thisPin++) 
  {
    //digitalWrite(RelaySigOut[thisPin], HIGH);      // set all pins to high so not switching states when resetting
    pinMode(Pulse[thisPin], INPUT);         //set all pulse pins to inputs
    pinMode(RelaySigOut[thisPin], OUTPUT);  //set all relay pins to output
    pinMode(RelaySigOut[thisPin], HIGH);    //set all relay pins to high
  }
  
  //Start Radio communication
  SPI.setSCK(RF24_SCLK);                    // Set system clock oin in SPI Library
  radio.begin();
  radio.setPALevel(RF24_PA_MIN);
  radio.openWritingPipe(addresses[1]);
  radio.openReadingPipe(1,addresses[0]);
  radio.startListening();


  // Attaching interrupts
  Attach_interrupts();
  
}

void loop() {
  for (int thisPin = 0; thisPin < pinCount; thisPin++) 
  {
    // Detect pulses and choose them to be triggered when HIGH
    if (Pduration[thisPin] > 1850 && Pduration[thisPin] <2100){
      digitalWrite(RelaySigOut[thisPin], LOW);
      relaysValues[thisPin] = LOW;
    }
    else //if (Pduration[thisPin] > 900 && Pduration[thisPin] <1050)
    {
      digitalWrite(RelaySigOut[thisPin], HIGH);
      relaysValues[thisPin] = HIGH;
    };
    
    // Print each pin value serial monitor (inside for loop)
    Serial.print (String((long)thisPin+1) + " - " + String((long)Pduration[thisPin]) + "    ");
  }
  Serial.println();  // Newline when all value are written

  
  values[0] = relayFormatter(relaysValues, pinCount);                   // The relays message
  values[1] = encoderSpeed(Pduration[8], 10);                           // Dummy value for testing
  
  sendValues();
}



// Send the values after getting the stating message
void sendValues(){
  if (radio.available()) {
    int startMessage = 0;                             // A variable to check the starting message
    radio.read(&startMessage, sizeof(startMessage));
    
    if (startMessage == 1){                           // If the starting value is correct
      radio.stopListening();
      // Sending the values array
      for (int i = 0; i < valuesArraySize; i++){
        radio.write( &values[i], sizeof(int));
      }
      radio.startListening();
    }
  }
}



/*
 * Takes a binary array named values[] and the size of the array as a function
 * and returns an int that hase the bit bumber i set to the value of values[i]
 */
int relayFormatter(int values[], int arraySize){
  int ret = 0;
  for (int i = 0; i < arraySize; i++){
    //Setting the bit number i in ret to 0/1 according to values[i] by adding pow(2, i) * values[i]
    ret = ret + ( values[i] * pow(2, i) );
  }
  return ret;
}

// Takes the duration between two pulses of the encoder and returns the speed of the motor
long long encoderSpeed(unsigned long long duration, int pulsePerRev){
  return (60ll * 1000000ll) / (duration * pulsePerRev);
}


Code:
/* 
 * prevReading[6] is an array to store when the interrupts was called last time
 * currReading in to store the current time in the called interrupt
 */
volatile unsigned long long prevReading[8], currReading;

// Attaches the interrupts
void Attach_interrupts(){
  attachInterrupt(digitalPinToInterrupt(Pulse[0]), ISR_rellay_0, CHANGE);
  attachInterrupt(digitalPinToInterrupt(Pulse[1]), ISR_rellay_1, CHANGE);
  attachInterrupt(digitalPinToInterrupt(Pulse[2]), ISR_rellay_2, CHANGE);
  attachInterrupt(digitalPinToInterrupt(Pulse[3]), ISR_rellay_3, CHANGE);
  attachInterrupt(digitalPinToInterrupt(Pulse[4]), ISR_rellay_4, CHANGE);
  attachInterrupt(digitalPinToInterrupt(Pulse[5]), ISR_rellay_5, CHANGE);
  attachInterrupt(digitalPinToInterrupt(Pulse[6]), ISR_rellay_6, CHANGE);
  attachInterrupt(digitalPinToInterrupt(Pulse[7]), ISR_encoder_0, CHANGE);
}


// Sets the Pduration to the current time - last time the interrupt was called
void ISR_rellay_0(){
  currReading = micros();
  if (!digitalRead(Pulse[0]))
    Pduration[0] = currReading - prevReading[0];
  prevReading[0] = currReading;
}

void ISR_rellay_1(){
  currReading = micros();
  if (!digitalRead(Pulse[1]))
    Pduration[1] = currReading - prevReading[1];
  prevReading[1] = currReading;
}

void ISR_rellay_2(){
  currReading = micros();
  if (!digitalRead(Pulse[2]))
    Pduration[2] = currReading - prevReading[2];
  prevReading[2] = currReading;
}

void ISR_rellay_3(){
  currReading = micros();
  if (!digitalRead(Pulse[3]))
    Pduration[3] = currReading - prevReading[3];
  prevReading[3] = currReading;
}

void ISR_rellay_4(){
  currReading = micros();
  if (!digitalRead(Pulse[4]))
    Pduration[4] = currReading - prevReading[4];
  prevReading[4] = currReading;
}

void ISR_rellay_5(){
  currReading = micros();
  if (!digitalRead(Pulse[5]))
    Pduration[5] = currReading - prevReading[5];
  prevReading[5] = currReading;
}

void ISR_rellay_6(){
  currReading = micros();
  if (!digitalRead(Pulse[6]))
    Pduration[6] = currReading - prevReading[6];
  prevReading[6] = currReading;
}

void ISR_encoder_0(){
  currReading = micros();
  Pduration[7] = currReading - prevReading[7];
  prevReading[7] = currReading;
}
 
Isn't 2mS on the upper end of a RC PPM signal? Have you tried 1.75mS or 1.5mS to check if the signal is on the edge? Can you adjust the PPM signal trim to more than 2mS? This would ensure it is fully on.
 
The range of the ppm is between 1ms (fully off) and 2ms (fully on). I am using on and off switches on my transmitter, so I only need fully on and fully off. On the serial monitor, I am displaying it in micros. The If stament is below and that works with no problems.

What do you mean by adjusting the trim to more than 2ms?

Code:
if (Pduration[thisPin] > 1850 && Pduration[thisPin] <2100){
      digitalWrite(RelaySigOut[thisPin], LOW);
      relaysValues[thisPin] = LOW;
    }
    else //if (Pduration[thisPin] > 900 && Pduration[thisPin] <1050)
    {
      digitalWrite(RelaySigOut[thisPin], HIGH);
      relaysValues[thisPin] = HIGH;
    };
 
Might help to see hookup.

Example are the teensy pins directly driving the relays? Or throw something like a transistor. I.e. wonder if enough current available to do relays. Do more than one go at same time. If so can you stagger them?

Maybe someone who is less electronically challenged can give more complete answer.

EDIT: Again just an FYI - If you look at the schematic for the official Arduino Relay shield:
https://www.arduino.cc/en/uploads/Main/Arduino-4-Relays-Shield-V1.pdf

You will notice that the IO pins go through a transistor to then power the relay. They also have several capacitors on the board, so I am assuming they maybe have ones again near the relay in order to be able to supply sufficient current to power the coils on those relays.
 
Last edited:
Is the Rc receiver and the fuel pump both powered from the hobbyking Bec?
I’m thinking your rc receiver is getting a really dodgy supply when the pump is running.
 
Okay, I see you are checking for a range. I was curious if the fully on PPM signal was moving around enough to cause it to move into and out of detection. That doesn't sound like the case.
Do you have a scope to see if any of the control signals are dropping out? Does it do the same thing when you just send a digital out to the relay with no other logic?
 
In many cases like this, the first thing I often suspect is power issues.

Again I don't know what the specs are for your relay board. I see some that look similar on Amazon.com, although looks like standard pins instead screw terminals...

I am guessing that it has built in transistors to convert the IO pins output to high enough current to throw the relay. The one I saw showed that it has +5v supply... Not sure what voltage you are connecting.

I am wondering if your pump startup current is causing voltage to drop to RC and Teensy?

But again only guessing
 
Is the Rc receiver and the fuel pump both powered from the hobbyking Bec?
I’m thinking your rc receiver is getting a really dodgy supply when the pump is running.

No the fuel pump is connected to the 12V battery directly, no power supply in between

Demolishun
Okay, I see you are checking for a range. I was curious if the fully on PPM signal was moving around enough to cause it to move into and out of detection. That doesn't sound like the case.
Do you have a scope to see if any of the control signals are dropping out? Does it do the same thing when you just send a digital out to the relay with no other logic?

I wiil try that good idea

KurtE I am wondering if your pump startup current is causing voltage to drop to RC and Teensy?

I will check that also

I am also going to move the relay board away from the teensy and see if that makes a difference

I'll keep you guys posted
 
Demolishun
Okay, I see you are checking for a range. I was curious if the fully on PPM signal was moving around enough to cause it to move into and out of detection. That doesn't sound like the case.
Do you have a scope to see if any of the control signals are dropping out? Does it do the same thing when you just send a digital out to the relay with no other logic?

I tried that and there is no buzzing at all. The relay connects perfect and disconnects. That illiminates the issue of output signal and voltage drop on the output only. That leaves the input signal to teensy board from the rc receiver.

I moved the receiver physically away and covered the wires from the receiver to the teensy with aluminium foil and grounded them and there is a big improvement. This might be the solution. I'll keep you guys updated.
 
It turns out that it was a voltage drop. Even though, I did not see it in the scope or maybe I don't know how to setup the scope for that. I put capacitors across the output of the relays. I am not sure if that is the right place to put them but it worked. It is odd because I am using a car battery, is the power from the car battery dirty or something and not consistent? What exactly is happening?

I will also check the power supply to the RC receiver and find a way to see in the scope.

Thanks for the input.
 
What awg of wire is feeding the relay board? It could be if the wire is small enough and long enough it cannot handle the surge. Using a cap at the device will help. Not sure what size of wire you might need.
Car battery should be consistent unless it is drained, low on power. Is the battery charged?
 
The wire feeding the relay board is pretty short, I am not sue of the awg, but it is not too thin. I added a 470umf cap at the teensy Vin and Gnd and one 100umf on each device end.

Yeah the battery is charged, I am suspecting it is the power to the teensy via USB, in all cases this is solved or easily solvable with more caps. Thank you. :)

I have another question that I will create a new post for.
 
Status
Not open for further replies.
Back
Top