variable pulsing LED Status

Go To Last Post
8 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I have a a series a flags in my code that signify either stages of Serial reception or errors.
For Example:
Rx_Data meaning the new Byte of data has been received
CRC_Error meaning CRC error
FEC_Error Forward Error Correction not possible

The flags are arranges so that only the most significant error is prioritised.
What I would like to do is show the error on a single LED and use either the number of pulses the led is On or the duty cycle to indicate the error.

For example
when the RX_Data flag is set the led will toggle on off at the same time period (say 500ms)
When the CRC_Error Flag is set the Led will pulse for twice and then stay off for for one period.
I have represented the LED Status in the attached graphic.

When the flag is cleared the Status will then report the next lower priority. If no data received, the LED will be fully ON.
What I am trying to get my head around is to how to implement such function. I figured I would use timer0 on the Mega16 to set the pulse period, and I can toggle the LED when the RX_Data flag is set. But, it is the others I am having difficult working out.
Can you suggest an approach I can investigate?

Attachment(s): 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

i think I worked it out( no Timer ISR - but it should work)

If FEC_error
  On 
  Delay 1
  Off 
  Delay 1
  On 
  Delay 1
  Off 
  Delay 1
  On 
  Delay 1
  Off 
  Delay 2
Else if CRC_error
  On 
  Delay 1
  Off 
  Delay 1
  On 
  Delay 1
  Off 
  Delay 2
Else if RX_Data
  On 
  Delay 1
  Off 
  Delay 1
Else
  On
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Take your own problem description. Replace every usage of "when" in your text with "if(" -> you are then on your way to a first version of pseudo code.

Example, after changing the when to if(, and some more massaging the sentence

Quote:
when the RX_Data flag is set the led will toggle on off at the same time period (say 500ms)
becomes
if(RC_Data == true) {
   on_time = 500;
   off_time = 500;
} else { ...

Stealing Proteus doesn't make you an engineer.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

ArnoldB wrote:

Example, after changing the when to if(, and some more massaging the sentence
Quote:
when the RX_Data flag is set the led will toggle on off at the same time period (say 500ms)
becomes
if(RC_Data == true) {
   on_time = 500;
   off_time = 500;
} else { ...

That is similar to my own poor Pseudo code. What I have been trying to do use a timer ISR instead of using Delay statement.
Anyway I will keep trying.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I understand that you want different intensities for each error. So you drive the LED with PWM. The PWM value alters with the error status.

A more human friendly approach may be to flash 3 times every 5 seconds or whatever. e.g. on-off 250ms pulse 3 times then off for 3.5 seconds.

So with a 250ms Timer IRQ, you have:

uint8_t flashes;         // 2, 4, 6 .. i.e. # 2*blinks

ISR(TIM1_OVF)               // every 250ms
{
    static uint8_t count;
    if (++count >= 20)
        count = 0;          // reset every 5 secs
    if (count <= flashes)
        LEDPORT ^= (1<<3);  // toggle LED
}

You need a good gap between blinks. You also need the blinks to 'look' obvious. Young people probably like to distinguish microseconds.

You possibly already have a regular timer ISR() but a lot more frequent than 250ms. So you just increment another counter, and only execute the above sequence when this counter 'overflows'.

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

david.prentice wrote:
I understand that you want different intensities for each error. So you drive the LED with PWM. The PWM value alters with the error status.

No I don't want PWM.
david.prentice wrote:

A more human friendly approach may be to flash 3 times every 5 seconds or whatever. e.g. on-off 250ms pulse 3 times then off for 3.5 seconds.

That is exactly what I want to do
david.prentice wrote:

So with a 250ms Timer IRQ, you have:

uint8_t flashes;         // 2, 4, 6 .. i.e. # 2*blinks

ISR(TIM1_OVF)               // every 250ms
{
    static uint8_t count;
    if (++count >= 20)
        count = 0;          // reset every 5 secs
    if (count <= flashes)
        LEDPORT ^= (1<<3);  // toggle LED
}

You need a good gap between blinks. You also need the blinks to 'look' obvious. Young people probably like to distinguish microseconds.

You possibly already have a regular timer ISR() but a lot more frequent than 250ms. So you just increment another counter, and only execute the above sequence when this counter 'overflows'.

David.

I don't immediately understand what

LEDPORT ^= (1<<3);  // toggle LED

does. but let me discover. If I get stuck I will come back.

if I understand correctly
My cast I would reset the timer 4 seconds.
RX_Data: Flashes = 4
RCR_Error: Flashes = 2
FEC_Error: Flashes = 3
And I can also add another Error flag to Flashes = 1.

I also see your piont of making sure there is a long Off period.
Thanx a ton. I am going to try this out.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The ^= just toggles the bits in the mask. e.g. bit 3 of LEDPORT in my example.

You set flashes to 8 for RX_Data etc.

You will need to do some experimenting. I suspect you want a very inconspicuous (but reassuring) blink for RX_Data. And it only fires once per character.

The error conditions need to be noticeable and probably continuous until cleared.

Note that most USB->RS232 cables will give you the reassuring RX_Data blink. So you possibly only want the error blinking.

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Happy to report this works a treat! David thanks for the idea.
If anyone tries using some thing similar, the only change I had to make is the number of flashes need to be old numbers. (count above is the number of toggles not flashes) Also make sure you initialise the LED port to OFF. This will ensure the pulsed LED defaults to OFF. :)

I am using 3 alarms states, 1, 2, and 3 flashes. 3 flashes really is continuous flashes. No flashes means no alarms.

I am using a 20M Crystal and timer1 clocks are 256ms seems pretty good. the pulse period may need to be adjusted to suit your needs