I am trying to shift 10 bit data out to 2 x 74HC595 ICs configured as in the page below:
The code I am using is posted below. I am trying to light the LEDs one by one, by sending only powers of 2, and it seems to work most of the time. However, at times, I see an LED being skipped, or 2 adjacent LEDs being lit. I am not sure about the delays() I have put in - how much time should SH_CP and ST_CP be kept high?. I'd appreciate any feedback on the code below:
/*
* ShiftOutTest
*
*/
// 74HC595 pins
int pin_SH_CP = 6;
int pin_ST_CP = 7;
int pin_DS = 5;
// values
int vals[] = {
1, 2, 4, 8, 16, 32, 64, 128, 256, 512};
void setup()
{
pinMode(pin_SH_CP, OUTPUT);
pinMode(pin_ST_CP, OUTPUT);
pinMode(pin_DS, OUTPUT);
}
void loop()
{
for(int i = 0; i < 10; i++) {
// ST_CP low
PORTD &= ~(1<<7);
// shift 10 LSB bits of data to shift register
shiftOut10(vals[i]);
// ST_CP high
PORTD |= (1<<7);
// delay needed?
delayMicroseconds(100);
// ST_CP low
PORTD &= ~(1<<7);
delay(500);
}
}
// shift out 10 bits of data
void shiftOut10(int data)
{
for(int i = 0; i < 10; i++) {
// delay needed?
delayMicroseconds(100);
// SH_CP low
PORTD &= ~(1<<6);
// DS
// is i-th bit of data high?
if(data & (1<<i)) {
PORTD |= (1<<5);
}
else {
PORTD &= ~(1<<5);
}
// SH_CP high
PORTD |= (1<<6);
// delay needed?
delayMicroseconds(100);
}
// SH_CP low
PORTD &= ~(1<<6);
}
Is there a reason you are writing to the low level registers instead of using digitalWrite. It makes that code difficult to follow.
This is going to be an input to a DAC, and I will need to do the shifting from a high frequency timer callback. The opinion in the forums seems to be that digitalWrite() will be too slow for that purpose.
If you put this macro in your sketch: #define fastWrite(pin, state) ( pin < 8 ? (state ? PORTD |= 1 << pin : PORTD &= ~(1 << pin )) : (state ? PORTB |= 1 << (pin -8) : PORTB &= ~(1 << (pin -8) )))
// the macro sets or clears the appropriate bit in port D if the pin is less than 8 or port B if between 8 and 13
And replace:
int pin_SH_CP = 6;
int pin_ST_CP = 7;
with #define pin_SH_CP 6 #define pin_ST_CP 7
Then you can replace:
PORTD |= (1<<7);
PORTD &= ~(1<<7);
With
fastWrite(pin_ST_CP,HIGH);
fastWrite(pin_ST_CP,LOW);
But if you have 100us delays then you would be no worse of using digitalWrite
The 74hc595 is capable of operating much faster then Arduino (even if you use the fastWrite macros) so you should not need delays.
I suggest you start with a sketch that uses the standard digitalWrite to drive the pins and when you have that working in your test sketch without glitches you can replace them with the fastWrite macros. If you do get glitches with digitalWrite (without delays) perhaps you can post the revised sketch.
I switched to digitalWrite(), removed all the delays and now it works fine. I can send 0-1023 without problems. I am using the same shiftOut10 method, so that part is fine. I wonder if it was a loose contact that was the problem.
Thanks for your suggestions - the fastWrite code will come in handy later.