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

@XooM wrote:

I need to turn on 10 LEDs at the same time.


As already noted, you can't.

Your shift register structure means that the maximum you can independently control at one time is 8 - one "group".

But you can strobe the groups so that it appears (to the human eye) that any number of LEDs is on "at the same time".

 

Hi,

Strobing LEDs at a rate of 24 - 30Hz is usually a good starting point. Faster makes them look dim. Slower makes look "strobing"...

Kind regards
Pedro

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

@XooM wrote:

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.


There is nothing rude about what @Andrew Neil has posted. He is asking legitimate questions. It wasn't clear on what you were trying to do until after questions were asked. So now it's clear that you want to turn On more than 1 LED at a time and that you have 24 sensors.

 

 

@XooM wrote:

In LED display, segments are sent at once. Scanning is done as many times as the number of digits. In my design circuit, you have to scan 24 LEDs one by one. 24x5ms= 120ms causes very large flicker.


@Andrew Neil  is also correct that you only need to update 8 groups at a time, instead of scanning for each of the 24 LED's. 

 

Lean to use a data structure. I've shown you how to do it with inputs from a previous post of yours. You can do the same with LED status. You just need 8 groups of 3 LED's

// PollingRoutine.h

typedef struct
{
	unsigned :5; // these bits are zero
	unsigned U2_q2:1;
	unsigned U2_q1:1;
	unsigned U2_q0:1;
	uint8_t U1; // when declaring variable, we can set U1 bits.
}LED_Status_t;

typedef union
{
	struct
	{
		uint16_t data[8];
	}_u16;
	struct
	{
		LED_Status_t grp_1;
		LED_Status_t grp_2;
		LED_Status_t grp_3;
		LED_Status_t grp_4;
		LED_Status_t grp_5;
		LED_Status_t grp_6;
		LED_Status_t grp_7;
		LED_Status_t grp_8;
	}Status;
}LED_Group_t;

void PollingInit(void);
void PollingRoutine(void);
void LED_Update(void);

void GPIO_ReadSensor(LED_Group_t *led);
void HC4094write(uint16_t data);

 

 

  • Initialize the led_group variable and set U1 (bits 15-8) 
  • Just poll the sensor inputs, 3 inputs at a time and update the bits for U2 (bits 7-5). 
  • bits 4-0 is zero.
  • Then you can index through each of the 8 group and pass them to your HC4094write

.

// PollingRoutine.c

#include "main.h"

extern TIM_HandleTypeDef htim1;

LED_Group_t led_group =
{
  .Status.grp_1.U1 = 0x80,
  .Status.grp_2.U1 = 0x40,
  .Status.grp_3.U1 = 0x20,
  .Status.grp_4.U1 = 0x10,
  .Status.grp_5.U1 = 0x08,
  .Status.grp_6.U1 = 0x04,
  .Status.grp_7.U1 = 0x02,
  .Status.grp_8.U1 = 0x01
};

// called before main while loop
void PollingInit(void)
{
	TimerCallbackRegisterOnly(&timerCallback, LED_Update);
	TimerCallbackTimerStart(&timerCallback, LED_Update, 1, TIMER_REPEAT); // 100us * 1 = 200us, 100us * 2 = 200us, etc...
}
// called from main while loop
void PollingRoutine(void)
{
	TimerCallbackCheck(&timerCallback);

	GPIO_ReadSensor(&led_group);
}
// Update 8 groups one at a time using Timercallback
void LED_Update(void)
{
	static int i = 0;

	HC4094write(led_group._u16.data[i]);

	if(++i == 8)
	{
		i = 0;
	}
}

/*
 * Set timer for 100us interrupt. You may need to adjust in case of flickering or dimness
 */
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
	if(htim == &htim1)
	{
		TimerCallbackTick(&timerCallback);
	}
}

/*
 * Read 3 sensors in a group for each call to minimize blocking
 */
void GPIO_ReadSensor(LED_Group_t *led)
{
	static int group = 1;

	switch(group)
	{
	case 1:
		led->Status.grp_1.U2_q2 = HAL_GPIO_ReadPin(Sensor_x_GPIO_Port, Sensor_x_Pin); // adjust each pin for your sensor pin
		led->Status.grp_1.U2_q1 = HAL_GPIO_ReadPin(Sensor_x_GPIO_Port, Sensor_x_Pin);
		led->Status.grp_1.U2_q0 = HAL_GPIO_ReadPin(Sensor_x_GPIO_Port, Sensor_x_Pin);
		group++;
		break;
	case 2:
		led->Status.grp_2.U2_q2 = HAL_GPIO_ReadPin(Sensor_x_GPIO_Port, Sensor_x_Pin);
		led->Status.grp_2.U2_q1 = HAL_GPIO_ReadPin(Sensor_x_GPIO_Port, Sensor_x_Pin);
		led->Status.grp_2.U2_q0 = HAL_GPIO_ReadPin(Sensor_x_GPIO_Port, Sensor_x_Pin);
		group++;
		break;
	case 3:
		led->Status.grp_3.U2_q2 = HAL_GPIO_ReadPin(Sensor_x_GPIO_Port, Sensor_x_Pin);
		led->Status.grp_3.U2_q1 = HAL_GPIO_ReadPin(Sensor_x_GPIO_Port, Sensor_x_Pin);
		led->Status.grp_3.U2_q0 = HAL_GPIO_ReadPin(Sensor_x_GPIO_Port, Sensor_x_Pin);
		group++;
		break;
	case 4:
		led->Status.grp_4.U2_q2 = HAL_GPIO_ReadPin(Sensor_x_GPIO_Port, Sensor_x_Pin);
		led->Status.grp_4.U2_q1 = HAL_GPIO_ReadPin(Sensor_x_GPIO_Port, Sensor_x_Pin);
		led->Status.grp_4.U2_q0 = HAL_GPIO_ReadPin(Sensor_x_GPIO_Port, Sensor_x_Pin);
		group++;
		break;
	case 5:
		led->Status.grp_5.U2_q2 = HAL_GPIO_ReadPin(Sensor_x_GPIO_Port, Sensor_x_Pin);
		led->Status.grp_5.U2_q1 = HAL_GPIO_ReadPin(Sensor_x_GPIO_Port, Sensor_x_Pin);
		led->Status.grp_5.U2_q0 = HAL_GPIO_ReadPin(Sensor_x_GPIO_Port, Sensor_x_Pin);
		group++;
		break;
	case 6:
		led->Status.grp_6.U2_q2 = HAL_GPIO_ReadPin(Sensor_x_GPIO_Port, Sensor_x_Pin);
		led->Status.grp_6.U2_q1 = HAL_GPIO_ReadPin(Sensor_x_GPIO_Port, Sensor_x_Pin);
		led->Status.grp_6.U2_q0 = HAL_GPIO_ReadPin(Sensor_x_GPIO_Port, Sensor_x_Pin);
		group++;
		break;
	case 7:
		led->Status.grp_7.U2_q2 = HAL_GPIO_ReadPin(Sensor_x_GPIO_Port, Sensor_x_Pin);
		led->Status.grp_7.U2_q1 = HAL_GPIO_ReadPin(Sensor_x_GPIO_Port, Sensor_x_Pin);
		led->Status.grp_7.U2_q0 = HAL_GPIO_ReadPin(Sensor_x_GPIO_Port, Sensor_x_Pin);
		group++;
		break;
	case 8:
		led->Status.grp_8.U2_q2 = HAL_GPIO_ReadPin(Sensor_x_GPIO_Port, Sensor_x_Pin);
		led->Status.grp_8.U2_q1 = HAL_GPIO_ReadPin(Sensor_x_GPIO_Port, Sensor_x_Pin);
		led->Status.grp_8.U2_q0 = HAL_GPIO_ReadPin(Sensor_x_GPIO_Port, Sensor_x_Pin);
		group = 1;
		break;
	}
}

void HC4094write(uint16_t data)
{

}

 

 

 

 

Tips and Tricks with TimerCallback https://www.youtube.com/@eebykarl
If you find my solution useful, please click the Accept as Solution so others see the solution.
XooM
Senior

Thank you.
I can't understand your codes.
I think I need to work a little.
I can't understand some topics and what some commands do, I guess I can't think as complicated as you think.

I have to work hard.
I guess I have no choice but to use the commands I control.
I have to work very, very hard. You are all good programmers.
I am not at your level yet.

Or maybe something like this - considering the groups of LEDs

// An array where each element is the bits for one group of 8 LEDs
# define NUM_GROUPS 3
uint8_t led_groups[NUM_GROUPS];

// LEDs 1, 2, and 3 are all the first bit in their respective group
#define SET_LED01 led_groups[0] |= (1UL<<0)
#define SET_LED02 led_groups[1] |= (1UL<<0) 
#define SET LED03 led_groups[2] |= (1UL<<0)

// LEDs 4, 5, and 6 are all the 2ND bit in their respective group
#define SET_LED04 led_groups[0] |= (1UL<<1)
#define SET_LED05 led_groups[1] |= (1UL<<1) 
#define SET LED06 led_groups[2] |= (1UL<<1)

// LEDs 7, 8, and 9 are all the 3rd bit in their respective group
#define SET_LED07 led_groups[0] |= (1UL<<2)
#define SET_LED08 led_groups[1] |= (1UL<<2) 
#define SET LED09 led_groups[2] |= (1UL<<2)
:
:
// LEDs 22, 23, and 24 are all the last bit in their respective group
#define SET_LED22 led_groups[0] |= (1UL<<7)
#define SET_LED23 led_groups[1] |= (1UL<<7) 
#define SET LED24 led_groups[2] |= (1UL<<7)

  

Used as:

if(input1==0)
{
   SET_LED01;
}
if(input2==0)
{
   SET_LED02;
}
if(input3==0)
{
   SET_LED03;
}
if(input4==0)
{
   SET_LED04;
}

drive_leds( led_groups );

 

The drive_leds() function handles sending the patterns for the 3 groups.

But those all have just one LED connected to each shift-register bit - none of this multiplexed group stuff.

Have you got it to work? What's the current state of your project? Did you get some LEDs to turn on?
If it is really hard to figure out you can control the shift register using switches instead of using software (debounce the switches to prevent too many pulses). When you've figured out how it works you can put it in software.

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.

@unsigned_char_array wrote:

If it is really hard to figure out you can control the shift register using switches instead of using software. When you've figured out how it works you can put it in software.


Excellent advice!

In general, you need to understand how something works before trying to code it!

@XooM just be sure that your switches (especially the clock) are debounced - glitches on the clock line could make things very confusing!