Driving auto relays

General project help for Adafruit customers

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
Locked
sbrooke
 
Posts: 27
Joined: Wed Nov 23, 2011 12:01 pm

Driving auto relays

Post by sbrooke »

I'm having some trouble driving some automotive relays properly. I have an Arduino with a shift register connected to a ULN2803. I've followed all the directions for hooking up a common auto relay, the 87 or 87a. When I power on the setup and the ULN2803 flashes all outputs to on (I know I need to fix that) the auto relays trigger. It would not seem to be a power or wiring issue.

I have two buttons hooked into the Arduino that I've assigned to trigger pins 0 and 1 on the ULN2803. When I press the buttons (HIGH) I can hear a high pitched buzzing but the relays don't trigger. I've tested the code using LEDs in place of the relays and the LEDs light correctly when the buttons are pressed.

How come the initial boot up of the ULN2803 is sufficient to activate the relays but my code isn't? I'm just sending the pins to HIGH using registerWrite(0, HIGH). Fiddling with it some more it almost sounds like sometimes the initial boot up isn't quite enough to trigger the relays either. It must be just on the edge of how much amps it needs.

Anyone have any insight into this? It looks like the ULN2803 can output up to 500ma per pin which should be plenty for the 87a relay.

User avatar
Franklin97355
 
Posts: 23912
Joined: Mon Apr 21, 2008 2:33 pm

Re: Driving auto relays

Post by Franklin97355 »

Do you have a link to the relay you are using?

User avatar
zener
 
Posts: 4567
Joined: Sat Feb 21, 2009 2:38 am

Re: Driving auto relays

Post by zener »

Do you have a scope? Otherwise, use a DMM and see what the coil voltages are doing. BTW you should have flyback diodes on the relay coils, although that likely won't address this problem but is good practice. If you post your schematic that might help.

User avatar
easternstargeek
 
Posts: 347
Joined: Mon Dec 13, 2010 1:39 pm

Re: Driving auto relays

Post by easternstargeek »

Your power supply may be collapsing. Have you checked to make sure you have enough juice? Some automotive relays are mighty hungry.

Good luck!

User avatar
richms
 
Posts: 558
Joined: Tue Jan 20, 2009 3:05 am

Re: Driving auto relays

Post by richms »

high pitched could mean you have somewhere else turning it back off again so its just oscilating the pin making the relay into a speaker.

sbrooke
 
Posts: 27
Joined: Wed Nov 23, 2011 12:01 pm

Re: Driving auto relays

Post by sbrooke »

I'm basically using this diagram:

http://cm.bezalel.ac.il/courses/files/2 ... scheme.jpg (Too big to post!)

Which I found in the forums here.

I am trying to use this in a car with a regular 12v battery. I don't have a scope. :cry:

I'm feeding the arduino from the same 12v source using a power regulator to step it down to 5v. I'm wondering now if that's flaky in some way. I'll throw my voltmeter on it to check.

User avatar
Franklin97355
 
Posts: 23912
Joined: Mon Apr 21, 2008 2:33 pm

Re: Driving auto relays

Post by Franklin97355 »

It depends somewhat on the relays and how much power it takes in the coils. This is why I asked for a link to the relay but if you could give the specs that would help.

sbrooke
 
Posts: 27
Joined: Wed Nov 23, 2011 12:01 pm

Re: Driving auto relays

Post by sbrooke »

It's a generic 87/87a automative relay. I have a couple of different brands I'm using but they're all pretty nondescript.

uoip
 
Posts: 127
Joined: Wed Sep 23, 2009 5:48 pm

Re: Driving auto relays

Post by uoip »

The diagram to the schematic shows an approach that ought to work, so you seem to be on the right track. I would probably add snubber diodes across the relay coils to prevent inductive kickback, but the ULN2803A is supposed to take care of this for you, so my addition may be a case of belt and suspenders overengineering.

A scope would certainly be helpful to track down the high pitched buzzing, but you can still do a fair bit of troubleshooting with a meter.

When you say you're using it "in a car with a regular 12V battery" I assume you mean the car's 12V lead-acid battery? That's got well more than enough current capability to drive the relays.

I'd start by disconnecting the wire connecting your arduino out to the input of the ULN2803A. Take the arduino out of the picture for a minute and connect the input of the ULN2803A directly to the +5V supply to turn the relay on, and wire it to ground to turn them off. Do the relays work now? Measure the current consumed by the ULN2803A input when the relay is turned on. The data sheet says it's got a 2.7k resistor on the input, so input current should be somewhere around 5V/2.7k, or less than 2 mA, well within the ability of the Arduino to deliver (there will be some diode drops in there, so the 2.7k input resistor shouldn't see the full 5V, so the current ought to be even less than I calculated).

If things are good so far, then connect the darlington back to the Arduino, and set the Arduino output high. Measure the voltage and current on the Arduino output pin. It should be very nearly 5V, and the current ought to be very close to the same as you measured earlier. Both voltage and current should be steady and reliable, unchanging. If you don't get good readings here, then I'd suspect a software problem is causing your Arduino outputs to not be high like they're supposed to be.

My wild unsubstantiated guess is that you've got a software issue where your Arduino pin isn't being held high, but is oscillating between high and low, and isn't staying high for long enough to switch the relay. But that could easily be wrong. You might have a bad darlington array, or the relays may be beyond the ability of the darlington array to handle. If so, that'll show up when you connect the input of the darlington array to +5V.

sbrooke
 
Posts: 27
Joined: Wed Nov 23, 2011 12:01 pm

Re: Driving auto relays

Post by sbrooke »

Sorry it took so long to respond. I finally wired a button directly from the 5v rail on the breadboard to the 1st pin on the ULN2803. It works without issue.

So, could be a code issue but could it also be something with the shift register? I'll try that next perhaps. Take a spare pin on the arduino directly to the ULN2803A instead of going through the shift register.

Here's the code going through the shift register:

Code: Select all

/*
  Shift Register Example
 for 74HC595 shift register

 This sketch turns reads serial input and uses it to set the pins
 of a 74HC595 shift register.

 Hardware:
 * 74HC595 shift register attached to pins 2, 3, and 4 of the Arduino,
 as detailed below.
 * LEDs attached to each of the outputs of the shift register

 Created 22 May 2009
 Created 23 Mar 2010
 by Tom Igoe

 */

//Pin connected to latch pin (ST_CP) of 74HC595
const int latchPin = 8;
//Pin connected to clock pin (SH_CP) of 74HC595
const int clockPin = 12;
////Pin connected to Data in (DS) of 74HC595
const int dataPin = 11;
///Pushbutton Red
const int redButton = 5;
///Pushbutton Black
const int blackButton = 6;

int redbuttonState = 0;
int blackbuttonState = 0;

void setup() {
  //set pins to output because they are addressed in the main loop
  pinMode(latchPin, OUTPUT);
  pinMode(dataPin, OUTPUT);  
  pinMode(clockPin, OUTPUT);
  pinMode(redButton, INPUT);
  pinMode(blackButton, INPUT);
  Serial.begin(9600);
  Serial.println("reset");
}

void loop() {
  //if (Serial.available() > 0) {
    // ASCII '0' through '9' characters are
    // represented by the values 48 through 57.
    // so if the user types a number from 0 through 9 in ASCII, 
    // you can subtract 48 to get the actual value:
    //int bitToSet = Serial.read() - 48;

  // write to the shift register with the correct bit set high:
  //  registerWrite(bitToSet, HIGH);
    
    //Check Red Button
    redbuttonState = digitalRead(redButton);
    if (redbuttonState == HIGH) {
      // Turn on LED 0
      registerWrite(0, HIGH);
    }
    else {
      //turn off LED 0
      registerWrite(0, LOW);
    }
   //Check Black Button
    blackbuttonState = digitalRead(blackButton);
    if (blackbuttonState == HIGH) {
      // Turn on LED 1
      registerWrite(1, HIGH);
    }
    else {
      //turn off LED 0
      registerWrite(1, LOW);
    }
    //}
}

// This method sends bits to the shift register:

void registerWrite(int whichPin, int whichState) {
// the bits you want to send
  byte bitsToSend = 0;

  // turn off the output so the pins don't light up
  // while you're shifting bits:
  digitalWrite(latchPin, LOW);

  // turn on the next highest bit in bitsToSend:
  bitWrite(bitsToSend, whichPin, whichState);

  // shift the bits out:
  shiftOut(dataPin, clockPin, MSBFIRST, bitsToSend);

    // turn on the output so the LEDs can light up:
  digitalWrite(latchPin, HIGH);

}
When I had LED's on the ULN2803 instead of the relays it worked fine.

uoip
 
Posts: 127
Joined: Wed Sep 23, 2009 5:48 pm

Re: Driving auto relays

Post by uoip »

The software is your problem.

Note that the registerwrite disables the outputs (puts them into high impedance state), then writes to them, then re-enables them.

The loop looks at each button, reads its state, and then always calls registerWrite to write the state to the output.

Net result, you're constantly disabling and re-enabling the outputs, even while the button state is constantly HIGH or LOW.

The easiest fix is to do something like declare an int previousRedButtonState, then alter the loop is as follows:

//Check Red Button
redbuttonState = digitalRead(redButton);
if (redbuttonState != previousRedButtonState {
registerWrite (0, redButtonState);
previousRedButtonState = redButtonState;
}


Do something similar for the other button.

This way, we only call registerWrite when we need to, that is, when the button's state changes. If the button stays high, we just leave the output high continuously, instead of disabling/re-enabling it rapidly in the loop.

Note also that I got rid of the if block which would write HIGH or LOW depending on whether the redButtonState is HIGH or LOW, since it's simpler to just write the state directly without using an if block. That's purely a stylistic change, though, and should have no effect on your problem. If you want to, you can keep that particular if the way it was.

The LEDs were working because you can't see them flickering so quickly.

sbrooke
 
Posts: 27
Joined: Wed Nov 23, 2011 12:01 pm

Re: Driving auto relays

Post by sbrooke »

Uoip, you rock! That worked perfectly! Thanks for helping me through some programming education.

sbrooke
 
Posts: 27
Joined: Wed Nov 23, 2011 12:01 pm

Re: Driving auto relays

Post by sbrooke »

Follow up question. A couple of you mention the flyback diode, which the ULN2803 has built in. If I want to drive 4 auto relays with a 12v coil level and 4 PCB relays with a 5v coil level do I need to connect the common to 12v or 5v or is this not an option?

Thanks again!

User avatar
adafruit_support_bill
 
Posts: 88093
Joined: Sat Feb 07, 2009 10:11 am

Re: Driving auto relays

Post by adafruit_support_bill »

Best to use separate ULN2803s for 5v and 12v.

Locked
Please be positive and constructive with your questions and comments.

Return to “General Project help”