How to make timing sequence?

Hi,

i have newbie question about millis():
I want to make loop sequence that last 240ms and on the first 4ms I want to set one pin HIGH. This sequence should repeat nonstop.
Its maybe very simple but as I realize not for me...
My code desnot work and I dont know why... :-/

Please can you help me with this?
Here is the code:

int looptime = 240; // time of whole sequence
long timer;

void loop()
{

timer = millis ();

if (( timer - 4) <= 0) // when first 4ms of sequence is now
{
digitalWrite (sync, HIGH);
}
else
{
digitalWrite (sync, LOW);
}

if ((timer - looptime) == 0) // when the time is 240ms
{
timer = 0; // reset the timer
}

}

Thanks a lot!

Hi,

You didn't understand millis() :slight_smile:

millis() gives you the milliseconds since the start of the controller, so the value of millis() will always increase.

You have to compare some vars, like this (untested)

int looptime = 240; // time of whole sequence
int timer = 4; // first sequence delay

long lastTimer;

void setup()
{
   lastTimer = millis();
}

void loop()
{
    if ((lastTimer + timer) < millis() )
        digitalWrite (sync, HIGH);
    else
        digitalWrite (sync, LOW);

    if ((lastTimer + looptime) <= millis() )
        lastTimer = millis();  // reset the timer

    // other stuff here

}

Cheers
KiWiX

This is a simpler way of continuously pulsing a pin for 4ms followed by a delay of 236ms.

void loop(){
   digitalWrite (sync, HIGH);
   delay(4);
   digitalWrite (sync, LOW);
   delay(236) ;
}

@mem: This is the simplest way, but you can't do any other thing, during this sequence

Cheers
KiWiX

You actually can do other things, using ISRs :slight_smile:

Thanks,
I will try it. Yes it was mistake that I though that I can start counting millis when I want....
Delay is probably not good idea, becasue I want to do lot of things inside a loop. I dont know what is ISRs....

KiWiX: so in this case you store in one moment the millis value into the lastTimer and then compare to real millis. And the key is to store the value in the right moment - at the end of the loop. Is it right?

if ((lastTimer + timer) < millis() ) // isnt > the right solution?
digitalWrite (sync, HIGH);
else
digitalWrite (sync, LOW);

if ((lastTimer + looptime) <= millis() ) // isnt better to use == ?
lastTimer = millis(); // reset the timer

Thanks!

P.S.: please how do you put here on the forum the code inside the frame ::slight_smile:

To put code inside a code block, use the # (pound symbol) in the message reply toolbar

? I want to do lot of things inside a loop

This would have been useful say in your first post :wink:

And the key is to store the value in the right moment - at the end of the loop. Is it right?

This is a little bit complicated because you need to know which time period you are in, the period timing the high pulse or the period timing the following 236ms low pulse. There are quite a few ways to do this, which one is easiest depends on the rest of your application. Perhaps you could describe the other things you want the sketch to do.

OK.Its quite difficult task before me...I will describe whole thing:

I want to make controlled 6x8 LED matrix.
I use ATMEGA168 for 6PWM outs and stepper that is driven from ATMEGA168 by 1sync pulse for begining of every loop and 1 sync pulse for moving on next step.
Stepper has 8 outputs. So completly 48LEDs.

What I want is to make very fast loop that I can make static ornaments driven and modified just by 6 PWM.
So inside the loop must be some parametres that will drive the PWM outputs synced with sync pulse for stepper. This is the way how to control bright of each led independently. I know it is very time critical... But anyway now I have still another problem:

I begin with the sync pulse. Now it basicly works.
But what I realize is very confusing: even when I have the fastest loop as posible with int ( so it is 1ms for one step - completely 48ms) **the matrix is still blinking - its not too fast to have feeling of static led ON... **:stuck_out_tongue:

I have not experience with float, but I think it is the only way.
Is it possible to make pulse 0.1ms and all computing with millis() do also with float?

Thanks a lot for any suggestion!

Floats will slow things down, not speed them up so that won't help. But I think you should be able to get the 48 leds controlled fast enough so they don't blink.

Could you clarify what the stepper is for – are you using it somehow to switch the LEDs?

Yes I think so. But what I realize as possible is to use micros instead millis :wink:

Stepper has 8 outputs that drives 8 columms in matrix. PWM drives 6 rows in matrix. So I set value on PWM and set speed of the step.
Stepper is moving in this speed (as I wrote 48ms for one loop - 1ms for one step). It moves sequencely and reads the row PWM value and for the moment blink the led conected in the current collum with the PWM value. than make another step - another collum and read the the PWM value and blink the led. etc...
When stepper is not driving the collum the led is off.
Each step must be driven by short pulse ON and longer OFF.

This should make 48 steps and than begin once again. In the beginnig of the sequence I must put sync pulse

This is my firts issue with timing and stepper... The stepper builds for me my friend.

Do you think micros should be ok?

I am not fully understanding what your stepper is and why you need 48 steps. I think you have 48 leds connected as a matrix of 6 rows and 8 columns. Why not drive all 6 rows at once, stepping sequentially through the 8 columns. This would make the cycle speed 6 times faster and drive each led 6 times longer.

There is information in the playground on driving an LED matrix that you may find relevant: Arduino Playground - LEDMatrix

Please do clarify what your stepper is if I have misunderstood what you are doing.

Hi,

if ((lastTimer + timer) < millis() ) // isnt > the right solution?

No, you said you want to have it high in the first 4ms.

if ((lastTimer + looptime) <= millis() ) // isnt better to use == ?

No, I don't think so, 'cause you have to be on that part of your code at the right millisecond, but if your switching of LEDs need a little bit more time, you hit this statement anymore.

Cheers
KiWiX

mem: you are right. The stepper works like you described. I can drive all 6wpm at once and have just 8 steps. The 48 steps was my little misunderstood. After 48 steps I need to send just short sync pulse - its for syncing the begining of the sequence (or it could be after 8, 16, 24 steps - its just important to be number multiplied by 8...).

And the "stepper" is decade counter CMOS 4017
http://www.tep.org.uk/Members/PDF/Control%20Technology/DECADE%20COUNTER%20(CMOS%204017).pdf

I try program also with micros() and its quite good now. The led shine continuosly.

But now I have quite big head how to program the visuals for matrix...
Its really problematic for exact syncing the PWM values with the steps.

kiwix: but really it works only with ((lastTimer + timer) > millis() )
becasue the lastTimer is setup exactly at the end of the previous loop so in the new loop lastTimer + timer is bigger - but only for first 4ms than millis overgrow the condition.

So what is it you are doing between each step? From what I understand, you would do the following:
For each of the columns
send a pulse to select the column
analogWrite PWM values for each of the rows for this column
delay

yes on each step I have to

  1. send step pulse for the CMOS 4017 (on and off)
  2. set PWM value for each row.

after 48 steps I must send other sync pulse (on other pin) for syncing the 4017. (this pulse must be little bit longer than other step pulses ).

Is it clear now?

I want to have the steptime controled - I want to be able slow down whole steping to see each steps and than speed up it to see matrix as one continious image without seeing the steps.

I dont use delay - maybe it could be ok, but I am not sure.
I am still beginner ::slight_smile:

Perhaps I am still not clear on what you want to do, but it sounds like it is simpler than you may think.

Not sure why you say 48 steps as there are only 8 columns??

If you are using a CD4017 then the 8 steps would be as follows:

For each of the columns
analogWrite PWM values for each of the rows for this column
delay 10 milliseconds (you may need to experiment with the refresh rate)
pulse the 4017 clock pin

after 8 pulses (all 8 columns have been displayed) pulse the 4017 reset pin to start again from the first column

The 4017 is capable of being driven as fast as the Arduino can digitalWrite, so the only time you need a delay is for the period of time you are driving each columns LEDs. You haven't indicated anything else that needs to happen in this time.

Is there more circuitry in the 'stepper' than just the 4017?

mem: yes thats it. I know this, but how to program it is something else... Specially how to organize PWM values on each steps to get some interesting ornaments from the matrix.

I see that 48 steps is something what disturbs you :smiley:
As I wrote this is pulse for reset pin - for syncing the begining of sequence. It could be aslo after each 8 steps, but could be aslo afte 800 steps. If there is no reseting the stepper always continue with the loop of 8steps.The reset is used to be sure that 4017 starts from the first step.

Does delay affect the SimplemessageSystem? Because I read some data from max/msp and these data drives some variables like the global brightnes of the leds, the steptime, the minimal brightnes of leds and the type of ornament.

OK. I will try it aslo with delay, but I have done the code with micros() on the base described by kiwix. And it works. I have separate steppulse, separate reset pulse - but now is difficult for me to organize the timing of PWM for - I must describe PWM value for each step.

The best way for me would be to be able setup value for each led in matrix - like this>
1A - maxi
1B - mini
1C - midi
1D - maxi
1E - maxi
1F -mini
1G - maxi
1H - mini
2A - mini
...

the int maxi,midi,mini is variables for brightness - driven from MAX/MSP.

I will work on it on Sunday.
Thanks for any suggestion!
all the best. :slight_smile:

Using millis is more flexible and efficient but it makes the sketch more difficult to understand. Understanding what you sketch is doing is more important to getting something working then efficiency that's not really required. My advice is to keep things as simple as possible and only add complexity when its essential. If you are keen to master millis then I do not want to stop you, but you will be working harder than you need to.

You can get serial input using delay if yo serial inputs just before or after the delay periods, you would reduce the delay time to take into account the time to read the serial data.

But if you have the code working and you understand it well enough to finish of the functionality you need then well done :slight_smile:

have fun!

mem: I am still beginner and with millis total beginer so I dont know if I will pass this issue... I hope so. But probably I will be asking here for some other more concrete questions. Now it is too much generall.
But you already know whats going on...

Anyway please have anybody experience with programing led matrix with the stepper like me /or similar/ ?

What I find out is that in step speed 1ms some PWM values makes some phasing effect on led matrix - probably the speed of steps are quite similar with pwm and it makes something strange with the real voltage going to leds. Does anyone experienced this also??

I would expect the duration in each step to affect the perceived display. I had posted earlier I would guess that a 10ms time in each step would be a good place to start and increase from there until just before the LEDs are visibly flashing. This assumes that every LED will get pulsed every 6 steps. I have not built such a display so this is just a guess.