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

Ask Electronics

3261 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 15 comments
sorted by: hot top controversial new old
[–] Kalcifer@lemm.ee 2 points 11 months ago* (last edited 11 months ago) (1 children)

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

[–] quiescentcurrent@discuss.tchncs.de 1 points 11 months ago

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

[–] Kalcifer@lemm.ee 1 points 11 months ago* (last edited 11 months ago) (2 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.

[–] mvirts@lemmy.world 1 points 11 months ago (1 children)

I think you got and and or switched, first two lines should be fine for shifting the top 8 bits down.

[–] Kalcifer@lemm.ee 2 points 11 months ago (1 children)

I don't follow what you mean.

[–] FuzzChef@feddit.de 2 points 11 months ago* (last edited 11 months ago) (2 children)

I think what he refers to is that you seem to do a bitwise or for the second line instead of the bitwise and.

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

~~2nd line of what?~~ Oh you are completely right. My bad. Idk why I wrote that. I'll fix my comment.

[–] mvirts@lemmy.world 1 points 11 months ago

Yes that's what I was thinking

[–] quiescentcurrent@discuss.tchncs.de 1 points 11 months ago

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;

[–] FuzzChef@feddit.de 1 points 11 months ago

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

[–] mvirts@lemmy.world 1 points 11 months ago (1 children)

Would it work if you made that delay 1000?

[–] mvirts@lemmy.world 1 points 11 months ago (1 children)

Also try upping the usleep call?

[–] mvirts@lemmy.world 1 points 11 months ago* (last edited 11 months ago) (1 children)

Hmmmm do you want to write to both shift register at the same time? I say this because you're looping 16 times, but seem to be sending the high and low bytes out 16 times over rather than one bit each time, although you are shifting the input.

[–] mvirts@lemmy.world 1 points 11 months ago (1 children)

Maybe I'm getting ahead of myself, but maybe try using digitalWrite for a single bit instead of shiftDataOut?

[–] quiescentcurrent@discuss.tchncs.de 2 points 11 months ago

Good idea, I've tried usleep after all lines, but no change..