3 Relay Shield help, 2/3 of them work

Hi guys:

I’ve been working on a 3 x 3v relay shield. For some reason I cant figure out I cant get one of the relays to work. I have checked the realys, and transistors, diodes and resistances and all of the work, and work fine.

I also checked the PCB for continuity on all tracks… I can figure with the middle relay does not work.

Heres My schematic,

but feel free to ask if more information is needed in order to proper debug.

I would not power the relays off 3.3V, but rather Vin - because of the extra stress on the onboard voltage regulator.

What is the coil current of these relays ?

If you really must use 3.3V for some reason, I would not power the relays from 3V3* (the analog version of the 3.3V rail), but rather from the 3V3 pin.You need to check that with all 3 relays activating, you are not going to exceed the ratings of the regulator.

I would suggest adding a couple of decoupling caps to your board, because relays are notorious for generating nasty transients, and you will want to try and address those as part of your design. Perhaps 4.7 - 10uF electrolytic, and a 100nF in parallel across the power rails.

Also, can you show the code you’re using, there might be a simple typo that is not setting D6 to output properly.


Fully agreeing with @AndyW 's suggestions, I’d just like to ask some clarifying questions.

  • Is it always the same (physical) relay that doesn’t work?
  • If so, which one is it?
  • If not, is it always the the first, second or third (in respect of time) relay you want to switch on?
  • Do you get any feedback of the Core (e.g. RGB LED)?

And as an additional suggestion, if you need 3.3V for the relays but the Cores regulator does not provide enough power, you could feature your own 3V3 regulator on your shield being powered off Vin of the Core or via an external power supply (which could then even power the Core via 3V3 pin).

1 Like

Hey thanks a lot for replying this is the code i am using:

int RELAYS[3] = {D0, D1, D2};

int command = 0;
int pin = 0;
unsigned long data = 0;

#define kCMD_NOP 0
#define kCMD_SET_PIN 1
#define kCMD_TIMED_PIN 2

void setup() {
    Spark.function("setPin", setPin);
    Spark.function("timedPin", timedPin);

void execTimedPin(int pin, unsigned long millis) {
    pinMode(pin, OUTPUT);
    digitalWrite(pin, 1);
    digitalWrite(pin, 0);
    command = kCMD_NOP;

void execSetPin(int pin, int level) {
    pinMode(pin, OUTPUT);
    digitalWrite(pin, level);
    command = kCMD_NOP;

void loop() {
    switch(command) {
        case kCMD_NOP:
        case kCMD_SET_PIN:
            execSetPin(pin, data);
        case kCMD_TIMED_PIN:
            execTimedPin(pin, data);

// transforms <type><number>@<extra> into [analog?, pin number, extra]
int processCommand(String command) {
    if (command.length() < 4) { return -2; } // incomplete command
	int pinNumber = command.charAt(1) - '0';
	if (pinNumber< 0 || pinNumber >7) { return -1; } // wrong pin
	data = command.substring(3).toInt();
	if (command.startsWith("R")) {
	    if (pinNumber < 0 || pinNumber > 2) { return -100; } // wrong relay pin
	    pinNumber = RELAYS[pinNumber];
	} else {
        if (command.startsWith("A")) {
            pinNumber += 10;
    pin = pinNumber;
    return 0; // success

// command format <type><number>@<level>
int setPin(String param) {
    int success = processCommand(param);
    if (success == 0) {
        command = kCMD_SET_PIN;
    return success;

// command format <type><number>@<time millis>
int timedPin(String param) {
    int success = processCommand(param) == 0;
    if (success == 0) {
        command = kCMD_TIMED_PIN;
    return success;

I’ve edited your post to properly format the code. Please check out this post, so you know how to do this yourself in the future. Thanks in advance! ~Jordy

Well, the relays appear to be connected this way:

K1 - D5
K2 - D6
K3 - D7

so I am curious how it’s working at all when you wiggle D0-2.

I don’t have the bandwidth right now to work through the code in detail and understand the logic, but the pin numbering looks wrong, and I’m also curious why you do not simply set the pins to digital output in setup().

Note also that the Vce(sat) for the BC547 is anywhere from 90mV to over 250mV, depending on the current, and 3V3* is almost certainly slightly lower than 3.3V when the relay is trying to actuate, so you may not have enough voltage across the relay to reliably activate it.

Can you point us at the datasheet for the relay you are using ?
You might just be up against manufacturing variation (within spec) in both K2 and T2 that conspire to make it not work, and using 3V3* will only be making things worse.


Hey thanks, turns out It was a broken diode, which was working good enough to beep in the multimeter, after desoldering it was broken.

Changed now working!