this post was submitted on 27 Sep 2023
14 points (100.0% liked)

Ask Electronics

3316 readers
1 users here now

For questions about component-level electronic circuits, tools and equipment.

Rules

1: Be nice.

2: Be on-topic (eg: Electronic, not electrical).

3: No commercial stuff, buying, selling or valuations.

4: Be safe.


founded 1 year ago
MODERATORS
 

Hey friends,

I have a two daisy chained shift registers (74AHC595) which are controlled via an ESP32. I want to set one output to high at a time before switching to the next.

The code seems to work, but the outputs O_9 and O_10 are not staying high (zoom) after setting them, whereas all the other ones are working fine. This is the used code snipped:

pinMode(SHIFT_OUT_DATA, OUTPUT);
pinMode(SHIFT_OUT_CLK, OUTPUT);
pinMode(SHIFT_OUT_N_EN, OUTPUT);
pinMode(SHIFT_OUT_LATCH, OUTPUT);

digitalWrite(SHIFT_OUT_N_EN, LOW);

uint16_t input_bin = 0b1000000000000000;

for(int i=0; i<17; i++){

    byte upper_byte = input_bin >> 8;
    byte lower_byte = input_bin & 0x00FF;

    digitalWrite(SHIFT_OUT_LATCH, LOW);
    shiftDataOut(SHIFT_OUT_DATA, SHIFT_OUT_CLK, MSBFIRST, lower_byte);
    shiftDataOut(SHIFT_OUT_DATA, SHIFT_OUT_CLK, MSBFIRST, upper_byte);
    usleep(10);
    digitalWrite(SHIFT_OUT_LATCH, HIGH);

    delay(10)
    input_bin = input_bin>>1;
} 

Is there anything I'm doing wrong, or any idea on where the problem may lie? I've already tried looking for shorts and other error sources, but the design was manufactured on a PCB and no assembly issues are noticeable.

top 5 comments
sorted by: hot top controversial new old
[–] Kalcifer@lemm.ee 2 points 1 year ago* (last edited 1 year ago) (1 children)

Would you not want to shift out the upper byte first? I could be misinterpreting your setup.

You're probably right, but that should only change the order of the outputs right?

[–] FuzzChef@feddit.de 1 points 1 year ago

What does shiftDataOut do? You loop over it but you give the whole byte to it anyway in each loop.

[–] Kalcifer@lemm.ee 1 points 1 year ago* (last edited 1 year ago) (1 children)

The first two lines of the for loop,

byte upper_byte = input_bin >> 8;
byte lower_byte = input_bin & 0x00FF;

don't really accomplish anything. The first line is bit shifting to the right 8, and then you just bitwise and it resulting in the same thing. For example, starting with input_bin:

1000 0000 0000 0000
>> 8
0000 0000 1000 0000
& 0xFF
0000 0000 1000 0000

So, every time you go through a cycle of the for loop, you'll just start with the same values in upper_byte, and lower_byte. To sequentially output each shifted value, you'll instead want something like:

output_value = 0b1
for i = 1 to 16:
    latch(low)
    shift_out(output_value)
    latch(high)
    output_value = output_value << 1

That is, if I interpereted correctly that you want the shift registers to output the following:

output_count, upper_shift_register, lower_shift_register
1, 00000000, 00000001
2, 00000000, 00000010
3, 00000000, 00000100
.
.
.
16, 10000000, 00000000

Note: Lemmy has a bug where it doesn't format some symbols correctly, so the left angle bracket gets formatted as <. The same issue exists for the right angle bracket, the ampersand, and I would presume others.

You're 100% right, I've lost 'i' somewhere in my debugging process

byte upper_byte = input_bin >> (8+i) ; byte lower_byte = (input_bin >> i) & 0x00FF;