cancel
Showing results for 
Search instead for 
Did you mean: 

control algorithm for LED shift register

XooM
Associate III

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);

 


@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?

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 );

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.


@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);
        }
    }
}

 

 

 

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

 

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