2024-11-20 04:38 AM - last edited on 2024-11-21 01:55 AM by Andrew Neil
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.
2024-11-20 03:00 PM
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.
2024-11-20 06:33 PM
Hi,
Have you measured the CLK speed, minimum Data setup and hold times?
Kind regards
Pedro
2024-11-21 01:18 AM
@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);
2024-11-21 01:26 AM
@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?
2024-11-21 09:46 AM
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.
2024-11-22 05:57 AM
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.
2024-11-22 06:48 AM
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.
2024-11-22 07:01 AM - edited 2024-11-22 07:05 AM
@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);
}
}
}
2024-11-22 07:08 AM
@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:
2024-11-22 07:21 AM
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