bits to byte for a shift register

Hi All,

I've had a look around for help on this one and its stumped me I can't find the correct terms!

Essesially I need to send 4 x 14 bits out using the shiftOut program but obviously need to write it as 7 bytes first. of

The bits are currently (probably incorrectly) stored as int values in an array[36] please see the snippet of code below.

I presume I'm coming at this from the wrong angle given my inablility to find any reference examples?

int datArray[36] = {00000000000000, 00000000000000, 00000000000000, 00000000000000

No I think you’re coming at this from the angle of not explaining your problem

Thank you for your quick response TheMemberFormerlyKnownAsAWOL. Unfortunately, I don't know the correct terms to use in order to describe my problem properly.

Essentially I have four 15 segment displays, and in order to reduce the number of shift registers I need to drive them I have reduced them to 14 segment in the wiring so I only need to drive them with 14 bits. However the shiftOut function only accepts bytes.

Big on numbers, short on details.
Back to you.

Ben assuming I have understood you correctly then first off, you have to shift out 8 bits at a time, that’s the way the hardware works. Second, I have never seen a 7 bit shift register, so I assume you have four 8 bit shift registers. That being the case, use 7 bits out of each, leaving 1 spare bit on each and shift out 32 bits in 8 bit chunks, with 1 bit unused in each of the 4 bytes.

If that’s not what you meant the please draw what you mean.
How to post an image

Thank you for your quick response TheMemberFormerlyKnownAsAWOL. What I was intially thinking was to in some way take the four int from the array.

00000000000000 00000000000000 00000000000000 00000000000000

and convert them to 7 bytes in a similar array

B00000000 B00000000 B00000000 B00000000 B00000000 B00000000 B00000000

What other details may you need?

OK, so I got the number of bits wrong, principal is the same.
Storing bits as integers is an awful waste of memory!

Hi Ben,

Your codeline

int datArray[36] = {00000000000000, 00000000000000, 00000000000000, 00000000000000

stores four zeros in the array elemens [0], [1], [2], [3]
The commata are the delimiters for the value.

So I need some more information what you are trying to do

Do the bits change over runtime?
How do you obtain the bits?
Do you have some kind of reading in the bits and then have to "shift-out" the bits again?

shiftregisters use to have 8 or 16 bits,
What kind of shift-registers are you using?
Do the 4x14 = 56 bits have to be in sequence on the shift-registers outputs?

best regards Stefan

Sorry PerryBebbington, I meant an 8 bit shift register.

The bits in the array are set, the groups of 14 represent the LEDs to be turned on. However, the selection may be different.

I didn’t think storing the bits as intergers would be the correct way, but they cannot be stored as bytes as they may be called in different orders. Similarly, I cannot just store two bytes and disregard the last (or first) two bits as the shift registers are in series.

I’m sorry for the poor explaination but I really can’t even think of the terms to use.

int = 32bit (signed, 31bit)
0000000000000000 = 32x '0' != 32 bit !!
B0000000000000000 == 32 bit!!

MfG

ben_stacey:
Sorry PerryBebbington, I meant an 8 bit shift register.

The bits in the array are set, the groups of 14 represent the LEDs to be turned on. However, the selection may be different.

I didn't think storing the bits as intergers would be the correct way, but they cannot be stored as bytes as they may be called in different orders. Similarly, I cannot just store two bytes and disregard the last (or first) two bits as the shift registers are in series.

I'm sorry for the poor explaination but I really can't even think of the terms to use.

So, is it the case that you have 2 * 8 bit shift registers for 14 LEDs? So 2 bits spare out of 16?

They cannot be stored as bytes as they may be called in different orders. Similarly, I cannot just store two bytes and disregard the last (or first) two bits as the shift registers are in series.

That makes no sense at all. You store them as 2 bytes per 14 bits with 2 spare bits. You wire 2 * 8 bit shift registers per 14 bits with 2 outputs spare. You can daisy chain as many as you like that way and the missing bits won't matter, they just end up on spare shift register outputs.

postmaster-ino:
int = 32bit (signed, 31bit)

…on some architectures.
Not AVRs

This is what I use for controlling shift registers, it supports easy to use digitalWrite functions to address the individual outputs:

Basic example that toggles a single shift register output to blink an LED
Example with many LEDs

The number between angled brackets is the number of bits in the shift registers, it doesn't have to be a multiple of 8, and it doesn't matter how many bits there are in a single shift register.

Pieter

Yes thnak you PerryBebbington, this would be the case.

However, I have already wired the 7 shift registers for the four 14 segment displays. I need to shiftout 56 bits from the groups of 14 bits.

The wiring can't be changed, this was done to reduce the amount of shift registers needed.

The wiring can't be changed, this was done to reduce the amount of shift registers needed.

That's why we needed a schematic from the start!

I think PieterP has given you the best answer yet.

If you post a schematic, it will greatly help to overcome the confusion. We know how to read those.

Hi Ben,

so please describe in normal words what the display is doing?
Is it a 14-segment display that can create alphanumeric characters?

Are these 4x14 LEDs physically grouped in a special way?

the C++programming language has a command for bitshifting inside of byte (8 bit) , integers (16 bit) , longs (32 bit)

BitNumber:      87654321
Values of Bits: 10110001

command << 2 (left-shift) results in 
BitNumber:      87654321
Values of Bits: 11000100

compairing the values
10110001
11000100

the two most left bits are "thrown out" the two rightest bits are added as zero

If you use a integer

BitNumber:      87654321 87654321
Values of Bits: 00000000 10110001

command << 2 (left-shift) results in 
BitNumber:      87654321 87654321
Values of Bits: 00000011 11000100

command << 3 would shift all bits three positions to the left

command << 11 would shift all bits eleven positions to the left

With this bitshifting command you can move any bitpattern inside a variable
As you are using 56 bits they don't fit into a long (32 bits) this means there has to be some additional code that manages the "throw out" on the left end

Anyway how would you describe your knowledge-level about programming?
Just a raw estimation

a.) almost nothing

b.) somehoe advanced

c.) expert

This will help to give you answers that you really understand
best regards Stefan

With the solution of PieterP the problem is reduced to
you just need some memory to store the value of each single bit.
If your code does not much more than shift-out these 56 bits there is enough RAM to store each single bit even in a long.
Though each long needs four bytes. Wich is - somehow - a waste of memory though you don't ran out of memory it would be a working solution.

to give you some lines of code we (the other forum-members) still need a schematic and a description in normal words what your display is doing.
best regards Stefan

StefanL38:
With the solution of PieterP the problem is reduced to
you just need some memory to store the value of each single bit.

The code I linked to uses one bit of memory for each bit of the shift register, so 7 bytes for 56 bits (plus some constant overhead for pin numbers etc.).

You can use the shift register object in your code as “storage” for the data. You can use digitalWriteBuffered to set or clear the bits in the buffer, and then use updateBufferedOutputs to actually send the buffer to the shift registers.

For example:

SPIShiftRegisterOut<56> sreg = {SS, MSBFIRST};

void setup() {
  sreg.begin(); // Initialize the shift registers
}

void loop() {
  sreg.digitalWriteBuffered(0, HIGH); // this sets the state of the first output to 1 (in the buffer only)
  sreg.digitalWriteBuffered(1, LOW);
  sreg.digitalWriteBuffered(2, HIGH);
  // ...
  sreg.updateBufferedOutputs(); // this sends the states in the buffer to the shift registers
}