Increment LEDs

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

Hi guys, 

 

I would like to write a function that increment LED

*       - 500ms

**     - 500ms

***    -500ms

****  -500ms

*****

The function will be triggered by a switch statement, so when the particular case is entered the increment should start. 

 

I have difficulties setting the time. I don't care if need to be done by simple delay function.  

So any idea how this should be done, I am using ATmega329PA

 

P.S I don't know if I'm writing in the right forum so if not feel free to move,. 

 

Thanks in advance!

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

Sounds something like:

uint8_t pattern;

int main(void) {
    DDRB = 0xFF;
    pattern = 0x80;
    while (1) {
        DDRB = pattern;
        _delay_ms(500);
        pattern >>= 1;
        pattern |= 0x80;
        if (pattern == (uint8_t)0xFF) {
            pattern = 0x80;
        }
    }
}

 

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

Thanks for the reply, 

 

But I cannot find the _delay_ms dunction only __delay_cycles. 

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

Which C compiler are you using? (my example was avr-gcc as found in AS7)

 

It's true that most compilers have some kind of _delay_ms()/delay_ms() style function. But if there is only _delay_cycles() or even __builtin_avr_delay_cycles() then I guess to delay for 500ms you need to know how fast the CPU is being clocked at. Say it was 7.4648MHz then there is 7,464,800 cycles in one second (1000ms) so in 500ms there would be 3,732,400 so I guess that would make the call to delay 500ms delay_cycles(3732400) perhaps?

 

Life is easier if there is some kind of delay_ms() function provided but even if there is the compiler will presumably need to be told that the CPU speed is 7464800 or whatever so it can work out how long to delay to reach 500ms.

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

Or, now would be a good time to learn how to use a H/W timer to measure your delay times.

Example, setup a timer to overflow every 10ms, then count the number of overflows using an ISR!

You will find that useful for many things in embedded projects.

 

Jim

 

 

 

FF = PI > S.E.T

 

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

ki0bk wrote:
You will find that useful for many things in embedded projects.
+1yes

David

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

So this is what I have come up with:

 

because I have 5 LED a

 

UINT8 count = 0;
UINT8 pattern = 0x01;
UINT8 DDRBd = 0xFF;

	while (count < 6)
		{
			DDRBd = pattern;
			SetLedContinuous(DDRBd, 1);
			__delay_cycles(PROCESSOR_SPEED_Hz / 16); // If I do it /2 nothing happensanything after 8 is fine.
			pattern = pattern << 1;

			count = count + 1;

		}

SetLedContinious is a function that set the LEDs to be on or off.

 

Unfortunately I don't see any infringement of the LEDs . 

clowson I don't get why you put an if statement so i din't included it bu I don't think that is the problem.

Last Edited: Mon. Apr 24, 2017 - 03:34 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You aren't showing us the complete program. 

Metio wrote:
SetLedContinuous(DDRBd, 1);

A lot of mystery there, especially as "DDRB" is implied.  (I'd expect a PORTB in there somewhere.)

 

-- Give a complete test program.

-- Tell language, toolchain, version, optimization settings.

-- Tell AVR model and clock speed.  (is it really ATmega329PA, or the much more common '328?)

 

The pattern in your original post implies you want 1-n LEDs lit; the code implies to me one at a time.  What >>are<< you trying to do?

 

 

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

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

theusch wrote:
The pattern in your original post implies you want 1-n LEDs lit; the code implies to me one at a time. What >>are<< you trying to do?
And that is why I wrote:

    pattern = 0x80;
    while (1) {
        DDRB = pattern;
        _delay_ms(500);
        pattern >>= 1;
        pattern |= 0x80;
        if (pattern == (uint8_t)0xFF) {
            pattern = 0x80;
        }

The pattern starts as 0x80 which is:

 

10000000

 

After the

        pattern >>= 1;

this becomes:

 

01000000

 

and then after:

        pattern |= 0x80;

it becomes:

 

11000000

 

and so on...

 

11100000

11110000

11111000

11111100

 

I did it like that for the very reason that #1 said:

 

*       - 500ms

**     - 500ms

***    -500ms

****  -500ms

*****

 

Which seems to be incrementally lighting more and more LEDs from left to right (and hence accumulating 0x80, 0x40, 0x20 and so on....)

 

It is for the same reason I wrote:

        if (pattern == (uint8_t)0xFF) {
            pattern = 0x80;
        }

on the assumption that once you get to:

 

11111111

 

then to see anything further happen you presumably what to restart back to the:

 

10000000

 

case?

 

The way engineering works is that someone write a high level specification saying what they want to achieve and then an engineer implements code to try and as closely as possible match the given specification. I thought I had!

 

But as Lee points you then went and switched the original specification when you wrote:

		pattern = pattern << 1;

That just moves a single LED (not an increasing accumulation of LEDs) from right to left, not the left to right that the original specification appeared to require.

 

Before you learn to program you should learn to accurately specify as this is usually the key stage of the entire engineering (just implementing is trivial once the specification is fixed!)

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

theusch wrote:
... especially as "DDRB" is implied. (I'd expect a PORTB in there somewhere.)
Cliff is to blame for that. wink

Stefan Ernst

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

clawson wrote:
Before you learn to program you should learn to accurately specify as this is usually the key stage of the entire engineering

Indeed!

 

Programming (and, in fact, any form of engineering) is, at it's heart, about problem solving.

 

And you can't solve a problem before you have an adequate understanding of what that problem actually is!

 

 

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Isn't this just the case of a missing delay.h file (same file that is missing in clawsons GIF avatar)

if you add that, then you get your access to the delay_ms function and example code given here should work.