cancel
Showing results for 
Search instead for 
Did you mean: 

control algorithm for LED shift register

XooM
Senior

Friends, which algorithm do you use to control the LEDs in this structure? I need your ideas. I have prepared a table of the LEDs' turn on order.

ttaa

 

54 REPLIES 54

 

First of all, thank you very much for your kind and detailed explanation.

I have some problems.

1. I do not know English. I am writing to you via Translate. That is why I cannot understand some of your technical statements. It is not understood when translated.

2. As important as I said before, I am not as good a programmer as you. I know at a basic level.

3. I understand a little of what you say, but I understand better when you write code.

4. I have some missing topics, I learn as I practice.

If you have enough time to write a code that can run this system, I would love to see it.

Thank you. I control 24 LEDs by scanning with 250us using the codes I gave.

But as I said at the beginning, I opened this topic because I did not like the code I wrote.

 

 

 

 

Hi,

Have you measured the CLK speed, minimum Data setup and hold times?

Kind regards
Pedro

AI = Artificial Intelligence, NI = No Intelligence, RI = Real Intelligence.

@unsigned_char_array wrote:

Why are you bit banging and why aren't you using SPI?

One advantage of bit-banging - at this point, at least - is that you can step the process bit-by-bit to watch what's happening.

 


@unsigned_char_array wrote:
  • I would avoid using any inputs for the moment and just use fixed values, makes it much easier to test. This way you can test inputs and outputs separately.

Absolutely!

 


@unsigned_char_array wrote:
I wouldn't use magic numbers. Use bitshifting instead. So if you want bit 9 set for instance use currentval = 1UL<<9

Definitely!

@XooM - and if you want to set a bit without affecting others, use:

currentval |= 1UL<<9;

 Or, to clear a bit:

currentval &= ~(1UL<<9);

 

A complex system that works is invariably found to have evolved from a simple system that worked.
A complex system designed from scratch never works and cannot be patched up to make it work.

@XooM wrote:

1. I do not know English. I am writing to you via Translate. That is why I cannot understand some of your technical statements. It is not understood when translated.


Do you not have any colleagues or teachers, etc, locally who could help you?

 


@XooM wrote:

Thank you. I control 24 LEDs by scanning with 250us


Still not sure what you mean by, "scanning with 250us" ?

Is it: every 250ms you send a new 16-bit pattern to select a new LED ?

If so, that means that each LED is only ON for 250ms ?

 


@XooM wrote:

But as I said at the beginning, I opened this topic because I did not like the code I wrote.


No, you didn't say that; you just said, "which algorithm do you use to control the LEDs in this structure? I need your ideas. I have prepared a table of the LEDs' turn on order" - nothing there about having written anything!"

So what is it, exactly, that you "do not like" about your code?

A complex system that works is invariably found to have evolved from a simple system that worked.
A complex system designed from scratch never works and cannot be patched up to make it work.

Never mind, focus on the other topics. I don't like you questioning me. You don't have to answer every topic. Those who want to help me and guide me are already showing themselves. You are constantly being rude. I don't really get along with you. The question is very clear and simple. "How do you control these LEDs?" Sometimes I may want to light up just 1 LED, sometimes 10 LEDs. That's the question and it's simple. But never mind. You can ask 100 questions now.

I thought about what you wrote.
currentval = 1UL<<9 ( I don't know this usage)
I didn't understand how to control the LEDs with SPI.

if(input1==0) { currentVal=0b1000000010000000; //led1 HC4094write(); } if(input2==0) { currentVal=0b1000000001000000; // led2 HC4094write(); } if(input3==0) { currentVal=0b1000000000100000; //led3 HC4094write(); } if(input4==0) { currentVal=0b0100000010000000; //led4 HC4094write(); }

These are the sensor inputs coming to my input port.
I turn on the LED that belongs to the sensor from which data is coming.
Data is coming from 10 different sensors at the same time and I need to turn on 10 LEDs at the same time.
When I send it one after the other (250us), the LEDs I want turn on.
But as I said, I opened the title to learn how to control it differently.

Again,  "Magic Numbers" are best avoided - it would make your code clearer to give names to your LED patterns; eg,

#define LED01_PATTERN 0b1000000010000000 #define LED02_PATTERN 0b1000000001000000 #define LED03_PATTERN 0b1000000000100000 #define LED04_PATTERN 0b0100000010000000 : : #define LED24_PATTERN 0b0000000100100000

Combine that with earlier advice to pass the pattern as parameter - rather than via a global variable - to get:

if(input1==0) { HC4094write( LED01_PATTERN ); } if(input2==0) { HC4094write( LED02_PATTERN ); } if(input3==0) { HC4094write( LED03_PATTERN ); } if(input4==0) { HC4094write( LED04_PATTERN ); }

Which is a lot clearer and more concise.

But this still means that, as soon as you have written the pattern for LED1, you immediately over-write it with the pattern for LED2.

 

I think a better approach would be something like:

#define LED01 (1UL<<0) // Set bit 0 for the 1st LED #define LED02 (1UL<<1) // Set bit 1 for the 2nd LED #define LED03 (1UL<<2) // Set bit 2 for the 3rd LED #define LED04 (1UL<<3) // Set bit 3 for the 4th LED : #define LED24 (1UL<<23) // Set bit 4 for the 24th LED uint32_t required_leds = 0; // This will be a bitmap of the LEDs required to be ON // Now set the bits for each LED that is required to be ON if(input1==0) { required_leds |= LED01; } if(input2==0) { required_leds |= LED02; } if(input3==0) { required_leds |= LED03; } if(input4==0) { required_leds |= LED04; } // required_leds now has one bit set for each LED required to be ON // The HC4094 function turns this into the required pattern(s) to send // to the shift registers HC4094( required_leds );
View more

As @unsigned_char_array pointed out earlier, your display consists of 8 groups of 3 LEDs.

So have the HC4094() function inspect the bitmap of which LEDs are required to be on, and then write to each group in turn.

That way you can write to 8 LEDs at once - instead of just one at a time.

Then you don't need to scan so fast - so your LEDs can be brighter.

A complex system that works is invariably found to have evolved from a simple system that worked.
A complex system designed from scratch never works and cannot be patched up to make it work.

@XooM wrote:

I thought about what you wrote.
currentval = 1UL<<9 ( I don't know this usage)


It's easy:

 

 

uint32_t led_states = 0; // all LEDs off led_states = 1UL << 0 | 1UL << 1 | 1UL << 2 | 1UL << 9; // turn on first three LEDs and 10th LED

 

 

 


@XooM wrote:

Data is coming from 10 different sensors at the same time and I need to turn on 10 LEDs at the same time.


You can't. You need to strobe.

 

Untested pseudo code for strobing LEDs (example turns them on 1 by one and then starts over):

 

 

volatile uint32_t led_states; // called at 300Hz or higher to get strobing of at least 100Hz, higher is better, but using SPI takes time too, so don't make it too high void timer_callback() { static uint8_t strobe_state = 0; uint8_t groups = 0; for(int i=0; i<8; ++i) { if (led_states & (1<<(i*3+strobe_state))) // this group has this LED on { groups |= 1UL << i; // select group } } // write groups to first shift register to select groups that have current LED on // write strobe_state to second shift register to select current LED (0,1,2) uint16 shift_register_data = strobe_state << 8 | groups; HC4094wrote(shift_register_data); strobe_state = (strobe_state + 1) %3; // next state } void main() { while(1) { for(i=0;i<24;++i) { led_states = 1UL<<i; delay(100); } } }
View more

 

 

 

Kudo posts if you have the same problem and kudo replies if the solution works.
Click "Accept as Solution" if a reply solved your problem. If no solution was posted please answer with your own.

@Andrew Neil wrote:

As @unsigned_char_array pointed out earlier, your display consists of 8 groups of 3 LEDs.


I mean 3 groups of 8 LEDs:

AndrewNeil_0-1732288007617.png

 

A complex system that works is invariably found to have evolved from a simple system that worked.
A complex system designed from scratch never works and cannot be patched up to make it work.

So each bit in required_leds represents one LED:

               |<---- unused bits ---->|24 23 22 21 20 19 18 17 16 15 14 13 12 11 10  9  8  7  6  5  4  3  2  1
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
required_leds | |  |  | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
Group 0 LEDs: 22 19 16 13 10 7 4 1
Group 1 LEDs: 23 20 17 14 11 8 5 2
Group 2 LEDs: 24 21 16 15 12 9 6 3

 

 

A complex system that works is invariably found to have evolved from a simple system that worked.
A complex system designed from scratch never works and cannot be patched up to make it work.