3v3 SIPO problem

I am not sure which of the components is actually causing the problem but is seems to be SIPO related. I am already using a very similar design (that works flawlessly) in an earlier version of my device so the problem must be due to something that I changed in the new version.

The devices use 2 of those 5V 4-Relay modules (with built-in opto-couplers, etc) and I am using a SIPO (74HC595) to feed the 8 inputs that control the relays (0V activates the relay, 5V deactivates it).

My original device used a 5V ATMega128 or ATMega328P, i.e. everything was using the same 5V and it worked without a glitch (based on the experience with this device I’d guess that the 74HC595 outputs are strong enough to control the relay modules and I therefore guess that this should not be the problem here).

My current device is based on an ESP8266EX (3v3), i.e. I am using an additional level-shifter (one of those 12 pin PCBs that allow to bi-directionally shift 4 lines) for the CLK/LATCH/DATA lines to the SIPO. I already replaced the level-shifter and the SIPO and that did not resolve the problem. The pins I am using
are GPIO12-GPIO14 so I think that there should not be any limitations attached to them.

The device is powered via a 2A buck-converter that creates the 5V used in the device (starting from a 3A 12V DC power supply). I’d guess that should be enough to power everything (and it worked fine in the old device).

As a test I am using a simple sketch that activates one relay at a time and round-robin cycles through the 8 relais using 500ms pauses (see code below) … I’d say half of the time this works as expected but some of the time instead of activating one particular relais, ALL 8 are simultaneously activated. This erroneous state may then be repeated for 1 or several steps before the relays are suddenly correctly activated again…
The time between correct/wrong activations seems to be totally random (i.e. there can be a streak on 80 correct activations and then it fails 20 times before it again works correctly - for a while).

I am currently not using any capacitors on either of the lines and I don’t know if the ESP8266 pins (the ones that I am using) react differently to what I was used to from the ATMega* stuff…

Any ideas?

const int ValveDriver::sLatchPin = D7;		// blue
const int ValveDriver::sClockPin = D6;		// brown
const int ValveDriver::sDataPin = D5;		// yellow
const int ValveDriver::sSelectVoltagePin = D0;

const int ValveDriver::sBurnOutDetectionPin = A0;


void ValveDriver::setupValveCtrlPins(void) {
	//set 74HC595 shift register pins to output because they are addressed in the main loop
	pinMode(ValveDriver::sLatchPin, OUTPUT);
	pinMode(ValveDriver::sDataPin, OUTPUT);
	pinMode(ValveDriver::sClockPin, OUTPUT);

	pinMode(ValveDriver::sSelectVoltagePin, OUTPUT);
}

ValveDriver::ValveDriver(void) {
	fNumValves = 8;

	setupValveCtrlPins();

	closeAllValves();
}

int ValveDriver::getNumberOfValves() {
	return fNumValves;
}

void ValveDriver::closeAllValves(void) {
	digitalWrite(ValveDriver::sLatchPin, LOW);
	shiftOut(ValveDriver::sDataPin, ValveDriver::sClockPin, MSBFIRST, 0xff);
	digitalWrite(ValveDriver::sLatchPin, HIGH);
}

void ValveDriver::powerUpValve(int whichPin) {
	digitalWrite(ValveDriver::sSelectVoltagePin, LOW);  // initially use 12V

	// This method sends bits to the shift register 74HC595
	byte bitsToSend = ~(1 << whichPin); // invert bits because LOW actually switches relay ON

	digitalWrite(ValveDriver::sLatchPin, LOW); // turn off the output while you're shifting bits
	shiftOut(sDataPin, ValveDriver::sClockPin, MSBFIRST, bitsToSend); // shift the bits out
	digitalWrite(ValveDriver::sLatchPin, HIGH);
}

void ValveDriver::sustainVoltage() {
	digitalWrite(ValveDriver::sSelectVoltagePin, HIGH); // fall back to 9V once the valve is active
}

void ValveDriver::resetVoltage() {
	digitalWrite(ValveDriver::sSelectVoltagePin, LOW); // 12V default.. so that additional converter can be switched off
}


ValveDriver *driver;
int i= 0;

void setup()
{
	Serial.begin(9600);	// Debugging only
	driver= new ValveDriver();
}

// The loop function is called in an endless loop
void ICACHE_FLASH_ATTR loop()
{
	delay(500);

	driver->powerUpValve(i);

	i= (i+1);
	if (i == driver->getNumberOfValves()) i= 0;
}

"SIPO" ? Never heard that before. Perhaps you should say "parallel output shift register" and people might understand you.

You never place capacitors on a logic line, that's a misprint in the guide that the originator
never cares to correct as far as I know.

This sounds like an issue that needs a good 'scope to diagnose. Just make sure all the devices
are getting the right supply voltage, and crucially every chip has decoupling. This is mandatory
for all logic circuits and lack of decoupling can have completely strange and confusing effects...

MarkT:
This sounds like an issue that needs a good 'scope to diagnose. Just make sure all the devices
are getting the right supply voltage, and crucially every chip has decoupling. This is mandatory
for all logic circuits and lack of decoupling can have completely strange and confusing effects...

My two multi-meters cannot even agree on the same voltage ... :wink: I first tried your "decoupling" hint - eventhough I probably don't know how to do that properly: I just added a 0.1uF ceramic cap on both supply sides of my level-shifter (I had read about the additional 10uF but I currently don't have any of those in my parts box..) - but that did not make any difference.

I then verified if the effect might be esp8266 specific - it isn't and I got the exact same problem when using a 3v3 ATMega328P instead.

Finally I did find a workaround by playing with the 74HC595N's MR pin ("Master Reclear, active low"): According to my old schematics I had left this pin unconnected in my older designs (I did not verify it, so
that might just be an inconsistency in the schematics).. though what I found in my new 3v3 device is that the problem accurs when this pin is unconnected or connected to GND. As soon as I connected it to 5V the problem disappeared.