Offline
God Member
Karma: 10
Posts: 871
|
 |
« on: September 27, 2012, 03:06:40 am » |
I was thinking... what's the easiest and i mean EASIEST way to create a "delay" without actually implementing a delay, for example, you have a sensor sending the results between 0-1024. but, when you do Serial.println(data); so, what are your options? Create a Delay time, measure how many seconds pass and if > 3 seconds, display(whatever); the other way is to simply Serial.println(data) delay(400); but that might effect time critical routines... so a few weeks back it occurred to me ... int n = random(500); if (n==65) Serial.println(data);
every couple of seconds or so, you see the data coming in, is using Random? taxing on the CPU? any benefits to using this method?
|
|
|
|
« Last Edit: September 28, 2012, 11:54:25 am by Coding Badly »
|
Logged
|
|
|
|
|
Global Moderator
Dallas
Online
Shannon Member
Karma: 118
Posts: 10153
|
 |
« Reply #1 on: September 27, 2012, 03:21:56 am » |
is using Random? taxing on the CPU? Relative to the println, no.
|
|
|
|
|
Logged
|
|
|
|
|
SF Bay Area (USA)
Offline
Faraday Member
Karma: 78
Posts: 5453
Strongly opinionated, but not official!
|
 |
« Reply #2 on: September 27, 2012, 03:40:45 am » |
You might also think about something like if ((millis() & 0x1ff) == 0) { Serial.println(data); } That should print something about every half a second...
|
|
|
|
|
Logged
|
|
|
|
|
UK
Offline
Tesla Member
Karma: 89
Posts: 6377
-
|
 |
« Reply #3 on: September 27, 2012, 07:09:21 am » |
any benefits to using this method?
The only benefit I can see is that you output arrives at random intervals. If that's what you wanted, this achieves it. If what you really want is to have the output arrive at defined regular intervals while also doing other things in the meantime, then the technique demonstrated in the 'blink without delay' example sketch shows you how to achieve that.
|
|
|
|
|
Logged
|
|
|
|
|
Offline
God Member
Karma: 10
Posts: 871
|
 |
« Reply #4 on: September 27, 2012, 07:35:11 am » |
i was offering this as a "tip" for other users and if it's worthy enough to be used as a tip.
obviously not.
|
|
|
|
|
Logged
|
|
|
|
|
0
Offline
God Member
Karma: 2
Posts: 849
Arduino rocks!
|
 |
« Reply #5 on: September 27, 2012, 12:57:52 pm » |
if ((millis() & 0x1ff) == 0) { Serial.println(data); } If your loop takes more than half a millisecond or so, won't you miss some of the times the last 9 bits of millis() are 0? It seems you'll have your println at some pseudo-random multiple of half a second.
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Edison Member
Karma: 15
Posts: 1006
Arduino rocks
|
 |
« Reply #6 on: September 27, 2012, 06:07:58 pm » |
Well the correct way to do it is only three lines: static unsigned long lasttime; if (millis() - lasttime > 1000) { Serial.println(); lasttime = milis(); }
I suppose you could make a macro #define RUNEVERY(n) for (static unsigned long lasttime; millis() - lasttime > (n); lasttime = millis())
and then use it like this: void loop() { int sens = analogRead(0); RUNEVERY(500) { Serial.print(F("Sens: ")); Serial.println(sens); } }
That's untested, since I don't have arduino on this computer. But if that works, I'd support it being defiend in Arduino.h --- it is extremely useful and would preempt a lot of questions on this forum. (Although there is something to be said for learning to do it the "right" way, the same can be said of "hibyte," "lowbyte," "shiftout," "bitRead," etc.)
|
|
|
|
|
Logged
|
|
|
|
|
UK
Offline
Tesla Member
Karma: 89
Posts: 6377
-
|
 |
« Reply #7 on: September 27, 2012, 07:20:23 pm » |
I've never tried declaring a static variable in the initialisation expression of a for loop. It that legal?
|
|
|
|
|
Logged
|
|
|
|
|
North Queensland, Australia
Offline
Edison Member
Karma: 31
Posts: 1181
|
 |
« Reply #8 on: September 27, 2012, 08:36:40 pm » |
Yes, its legal. If GCC is standard conforming, it should only be in scope for the loop that's all.
|
|
|
|
|
Logged
|
|
|
|
|
Global Moderator
Dallas
Online
Shannon Member
Karma: 118
Posts: 10153
|
 |
« Reply #9 on: September 27, 2012, 09:23:00 pm » |
"Run every" implies that it should run N times in T time...
#define RUNEVERY(n) for (static unsigned long lasttime, unsigned long t = (n); millis() - lasttime > t; lasttime += t)
"Run after" implies that it should run after T milliseconds have elapsed...
#define RUNAFTER(n) for (static unsigned long lasttime; millis() - lasttime > (n); lasttime = millis())
The variable should be named to reduce the chances of a conflict...
#define RUNAFTER(n) for (static unsigned long _lasttime; millis() - _lasttime > (n); _lasttime = millis())
To be more Arduinoish the macro should be named in modified camel...
#define runAfter(n) for (static unsigned long _lasttime; millis() - _lasttime > (n); _lasttime = millis())
To eliminate drift, time should be sampled once...
#define runAfter(n) for (static unsigned long _lasttime, unsigned long _thistime = millis(); _thistime - _lasttime > (n); _lasttime = _thistime)
The error needs to be eliminated...
#define runAfter(n) for (static unsigned long _lasttime, unsigned long _thistime = millis(); _thistime - _lasttime >= (n); _lasttime = _thistime)
16 bit may be a better choice...
#define runAfter(n) for (static uint16_t _lasttime, uint16_t _thistime = millis(); (uint16_t)(_thistime - _lasttime) >= (uint16_t)(n); _lasttime = _thistime)
What did I forget?
|
|
|
|
« Last Edit: September 27, 2012, 09:25:26 pm by Coding Badly »
|
Logged
|
|
|
|
|
Offline
Edison Member
Karma: 15
Posts: 1006
Arduino rocks
|
 |
« Reply #10 on: September 27, 2012, 11:51:00 pm » |
static uint16_t _lasttime, uint16_t _thistime is illegal. You might be able to do some strange things with a struct though: #define runAfter(n) for (struct { static uint16_t last; uint16_t now; } _rA = {0, millis()}; _rA.now - _rA.last >= (n); _rA.last += (n))
That doesn't work either, though: static means something different there. I also think that runEvery is a better name because it reads "Run every 500" (ms) which is exactly what it does. runAfter imples it only runs once, and has a built in delay. _thistime is unnecessary if you do the += (n) trick, since then millis() wil only be called once. so this is what I'm thinking of: #define runEvery(t) for (static uint16_t _lasttime; millis() - _lasttime > (t); _lasttime += (t))
which is tested and works on my uno. Thanks for checking it out though --- hopefully a macro like this one will be useful to others.
|
|
|
|
|
Logged
|
|
|
|
|
North Queensland, Australia
Offline
Edison Member
Karma: 31
Posts: 1181
|
 |
« Reply #11 on: September 28, 2012, 12:56:59 am » |
static uint16_t _lasttime, uint16_t _thistime is illegal. You might be able to do some strange things with a struct though: According to the standard. 6.5.3 - 3 If the for-init-statement is a declaration, the scope of the name(s) declared extends to the end of the for-statement. But I see the static now,  . hmmm
|
|
|
|
« Last Edit: September 28, 2012, 01:02:46 am by pYro_65 »
|
Logged
|
|
|
|
|
SF Bay Area (USA)
Offline
Faraday Member
Karma: 78
Posts: 5453
Strongly opinionated, but not official!
|
 |
« Reply #12 on: September 28, 2012, 03:27:22 am » |
Both the original (random) and my hack (bitwise and) don't use extra ram... Whether they're suitable or not depends on unspecified requirements and behaviors.
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Edison Member
Karma: 4
Posts: 1131
If you're not living on the Edge, you're taking up too much space!
|
 |
« Reply #13 on: September 28, 2012, 10:03:22 am » |
Nice Macro! Very useful. I wish there was a way for beginners to find it easily while Googling.
|
|
|
|
|
Logged
|
If you fall... I'll be there for you! -Floor
Skype Brighteyes3333 (262) 696-9619
|
|
|
|
Global Moderator
Dallas
Online
Shannon Member
Karma: 118
Posts: 10153
|
 |
« Reply #14 on: September 28, 2012, 12:00:49 pm » |
I wish there was a way for beginners to find it easily while Googling. You can give Google a helping hand. If you or anyone you know has a blog, add a paragraph or two about the macro and include a link to this topic.
|
|
|
|
|
Logged
|
|
|
|
|
|