ShiftingOut data from Serial.Read to Control Multiple 74hc595s

Hi,

I'm Working On A DIY Project to Control Numerous LEDs by UNO and ShiftRegistrers.

And Here I Need to Control The LEDs with SerialInput Continuously,

like TurningOn Some 40 of Those 300+ LEDs At Once On giving Some Serial Command.

I Trying Few Approaches like SPI, ShiftOut etc. And Failing Since A week.

Please Suggest Me Some Code For This To Control Few LEDs At Once By Serial Input, Probably In Binary Form.

Note : Selection Of LEDs to Glow Changes Everytime.

Hi,
Welcome to the forum.

Please read the first post in any forum entitled how to use this forum.
http://forum.arduino.cc/index.php/topic,148850.0.html . Then look down to item #7 about how to post your code.
It will be formatted in a scrolling window that makes it easier to read.

Can you please post a copy of your circuit, in CAD or a picture of a hand drawn circuit in jpg, png so we can see how you have the 595 connected together and the UNO?

Thanks.. Tom... :slight_smile:

And Here I Need to Control The LEDs with SerialInput Continuously,

Have you any ideas as to the format of the user input ?

Thank You Mr. TomGeorge,

Actually I'm Expecting Some Code to Control LEDs Of Custom Selection By Serial.read,

I'd Tried Several Code pieces To use serial input in Shiftout before Formatting FullCode.

here the simplified code of one of those using SPI.

#include <SPI.h>
      const byte LATCH = 10; 
      byte c; char data;  
      byte byte0;byte byte1;
      
void setup () { SPI.begin ();  Serial.begin(9600); }  

void loop() {
        if (Serial.available() > 0){
        delay(10);  
        char c = Serial.read();}
      

        Serial.print(bytea);Serial.print("\n");
        

        digitalWrite (LATCH, LOW);
        SPI.transfer (B10101010); // here i want my input to act aka 'bytea'
        digitalWrite (LATCH, HIGH);
        delay (200);

        }}

And getting This error : no matching function for call to 'SPIClass::transfer(String&)'

Please help Me to use Serial Input As ShiftOut output.

Not Necessarily Using SPI, But Any method to Control Custom Selection Of LEDs Every time.

UKHeliBob:
Have you any ideas as to the format of the user input ?

Yah,

It Will Be In Binary Format,

A line Of 100+ 0s and 1s.

So, If It is '1' then the corresponding LED will Glow.

starkp4:
Yah,

It Will Be In Binary Format,

A line Of 100+ 0s and 1s.

So, If It is '1' then the corresponding LED will Glow.

So, to control 300 LEDs the user will be required to enter 300 characters. Is that right ?

UKHeliBob:
So, to control 300 LEDs the user will be required to enter 300 characters. Is that right ?

Yes,

And, Its Okay to Convert Them To Any Other Format As ASCII, Hex, Dec etc. Before Sending to UNO.

I Mean "Using Another Format In Serial Transmission"

The most compact form that they could be sent as is 1 bit per LED so you will need to send 300/8 bytes, ie 37 bytes and you would need 37 cascaded shift registers. Are you sure that you have thought this through ?

Do you have to use shift registers or could you use a simple strip of WS2812 LEDs ?

UKHeliBob:
Do you have to use shift registers or could you use a simple strip of WS2812 LEDs ?

The problem with WS2812 strips is that you sometimes lose UART data, because it relies heavily on interrupts to get the timing right.

Pieter

UKHeliBob:
The most compact form that they could be sent as is 1 bit per LED so you will need to send 300/8 bytes, ie 37 bytes and you would need 37 cascaded shift registers. Are you sure that you have thought this through ?

Do you have to use shift registers or could you use a simple strip of WS2812 LEDs ?

We Can,

But, Right Now I'm Experimenting With Shift Registers,

And Please Suggest Any WS2812 IC Arrays (Not LED Strips) If Any . .

You could receive the serial data and store it in an array.
Send it in a couple different ways: 40 bytes all in one shot, update the whole array; send a byte # to update and its data; a variation of that, send in a start address to begin storing data, the number of bytes, and the data.

One the data is updated, send it to the shift register chain:

digitalWrite (ssPin, LOW);
for (x=0, x:40; x=x+1){
SPI.transfer(dataArray[x]);
}
digitalWrite (ssPin, HIGH); // all outputs update on this rising edge

I made up a box with 45 shift registers like this, and coded it to update at a 20 KHz rate by unwrapping the for:loop, using port manipulation, writing to the SPI register directly and adding NOPs to wait out the transfer; and turning off interrupts during the data transfer.
The data came from a preloaded 45 byte x hundreds of rows long array in the 16K SRAM of a '1284P.

CrossRoads:
You could receive the serial data and store it in an array.
Send it in a couple different ways: 40 bytes all in one shot, update the whole array; send a byte # to update and its data; a variation of that, send in a start address to begin storing data, the number of bytes, and the data.

One the data is updated, send it to the shift register chain:

digitalWrite (ssPin, LOW);

for (x=0, x:40; x=x+1){
SPI.transfer(dataArray[x]);
}
digitalWrite (ssPin, HIGH); // all outputs update on this rising edge



I made up a box with 45 shift registers like this, and coded it to update at a 20 KHz rate by unwrapping the for:loop, using port manipulation, writing to the SPI register directly and adding NOPs to wait out the transfer; and turning off interrupts during the data transfer.
The data came from a preloaded 45 byte x hundreds of rows long array in the 16K SRAM of a '1284P.

SPI :wink:

Sir, Could You Please Share The Code,

Adafruit and others.

Adafruit has several 8x8 and a 8x32 matrix

It also wouldn't be hard to layout out strips in whatever length x whatever depth matrix you wanted for something custom.

"Sir, Could You Please Share The Code,"

I did share the SPI code to send the data to the shift registers. The code to receive serial data and put it into an array is not written, I was loading the array by updating the sketch and re-downloading into the 1284P.

CrossRoads:
Adafruit has several 8x8 and a 8x32 matrix

Search Results for 'neomatrix' on Adafruit Industries

It also wouldn't be hard to layout out strips in whatever length x whatever depth matrix you wanted for something custom.

Actually, Showcasing Some Product was Not My Concept,

I Wanna Learn And Build Something, So I Started . .

And Came here for Help In Code,

CrossRoads:
"Sir, Could You Please Share The Code,"

I did share the SPI code to send the data to the shift registers. The code to receive serial data and put it into an array is not written, I was loading the array by updating the sketch and re-downloading into the 1284P.

I'd Tried Several Options Get Serial input And Sending Data To Shift Registers ,

But I'm Continuously Failing to Put That Serial Input in ShiftOut,

Because of Strings Usage, ASCII Conversions etc . . .

Or Simply Because, I'm Not So Good In Coding . .

Please post the code that you tried

Have you actually built the circuit with 37 shift registers ?

"Actually, Showcasing Some Product was Not My Concept,"
and yet you asked:
"And Please Suggest Any WS2812 IC Arrays (Not LED Strips) If Any . ."

Do want to use RGD LEDs? Then WS2812B in whatever form factor is good: individual SMD, SMD on strips, SMD in arrays or circles, or thruhole arranged however you want
LED - RGB Addressable, PTH, 5mm Diffused (5 Pack) - COM-12986 - SparkFun Electronics or LED - RGB Addressable, PTH, 5mm Clear (5 Pack) - COM-12999 - SparkFun Electronics

WS2812B means learning how to use one of the libraries that makes up the timing needed, Neopixel library from Adafruit, or the FastLed.h library.

With 'dumb' RGB LEDs (no controller built in) or single color LEDs, than you can use shift registers, TPIC6C595 works better than 74HC595 as you have more current to drive the LEDs without overstressing the HC595, and both work the same way - shift in a 1, the output turns in. With TPIC6C595, On means the output goes low, so the LEDs are wired in series like this:
5V anode, cathode to resistor, resistor to output pin.
Then shift in whatever pattern you want.

Say you had 40 LEDs on 5 shift registers, and it was always 5 that came in:

while (Serial.available() <5){
// hang out and wait
}
// 5 bytes came in, proceed
for (x=0; x<5; x=x+1){
dataArray[x] = Serial.read();
}
// and send it to the shift register as above

If you wanted to have it come in from the serial monitor in the IDE, would you sit there and type 40 0s and 1s?
Then the 0s and 1s come in as ASCII,

0 = 0x30, or 48 decimal
1 = 0x31, or 49 decimal
Do the same serial receiving trick, but convert the data from ASCII to binary and also convert bits into bytes

while (Serial.available() <40){
// hang out and wait
}
// 40 bytes came in, proceed
for (x=0; x<40; x=x+1){
dataArrayBits[x] = Serial.read() - 0x30; // convert from 0x30, 0x31 to 0, 1
}
// convert to 5 bytes, assumes the highest bits (39,38, etc.) go into bits 7:0 of the highest byte
byte4 = (dataArrayBits[39] <<7) + (dataArrayBits[38] <<6) + (dataArrayBits[37] <<5) + (dataArrayBits[36] <<4) + (dataArrayBits[35] <<3) + (dataArrayBits[34] <<3) + (dataArrayBits[33] <<1) + (dataArrayBits[32]; 
byte4 = (dataArrayBits[31] <<7) + (dataArrayBits[30] <<6) + (dataArrayBits[29] <<5) + (dataArrayBits[28] <<4) + (dataArrayBits[27] <<3) + (dataArrayBits[26] <<3) + (dataArrayBits[25] <<1) + (dataArrayBits[24]; 
byte4 = (dataArrayBits[23] <<7) + (dataArrayBits[22] <<6) + (dataArrayBits[21] <<5) + (dataArrayBits[20] <<4) + (dataArrayBits[19] <<3) + (dataArrayBits[18] <<3) + (dataArrayBits[17] <<1) + (dataArrayBits[16];
byte4 = (dataArrayBits[15] <<7) + (dataArrayBits[14] <<6) + (dataArrayBits[13] <<5) + (dataArrayBits[12] <<4) + (dataArrayBits[11] <<3) + (dataArrayBits[10] <<3) + (dataArrayBits[9] <<1) + (dataArrayBits[9];
byte4 = (dataArrayBits[7] <<7) + (dataArrayBits[6] <<6) + (dataArrayBits[6] <<5) + (dataArrayBits[4] <<4) + (dataArrayBits[3] <<3) + (dataArrayBits[2] <<3) + (dataArrayBits[1] <<1) + (dataArrayBits[0];   
// and send it to the shift register as above

Then after you tired of typing in 001101011101010010101 ...everytime, you might decide to enter data in hex format, so instead of typing 40 0s and 1s you could just enter 5 pairs of characters 0,1,2,3,4,5,6,7,8,9,a,b,c,d,e,f, and put those into array directly. 00000000 becomes 00. 01010101 becomes 55. 10101010 becomes aa. etc. The conversion is a little more than Serial.read() - 0x30, that works for 0 to 9, but a to f need Serial.read() - 0x51, so that 61 becomes 0x0a, 62 becomes 0x0b, etc up to 66 becoming 0x0f, and then you shift 4 bits over instead of 8 to make the bytes.

Is this what you're looking for?

It's a Python script that controls LEDs connected to an Arduino, driven by shift registers. You don't have to use Python, you just need to send the binary data over the serial port using the SLIP protocol, so you can use any language that can open serial ports.

Pieter