Gloucestershire, UK
Offline
Jr. Member
Karma: 0
Posts: 53
Outta Steam
|
 |
« on: December 11, 2011, 05:21:39 pm » |
Ok I admit it, I am stupid. I'm trying to get an Arduino to strobe an LED, ie around 1 second off with a brief tenth second flash.
Using delay - not a problem. Thing is I want the led flashing to occur whilst the arduino is doing other things, I've just spent a whole weekend trying to modify various variations of the blink without delay sketch, ie using millis, but I just can't get my head around how to control two processes (ie interval off and interval on), nothing I try seems to work.
I haven't got any code to submit, as its just the blink without delay sketch. I cannot work out how to make the on and off intervals different from each other, and really don't know where to start. Does anyone know of any pointers or tutorials that I could read?
Thanks in advance.
|
|
|
|
|
Logged
|
|
|
|
|
Seattle, WA USA
Online
Brattain Member
Karma: 313
Posts: 35502
Seattle, WA USA
|
 |
« Reply #1 on: December 11, 2011, 05:26:49 pm » |
The blink without delay sketch compares the current time minus the last time that an event occurred to an interval.
To have uneven intervals, you must have two different intervals. When the light is on, and you are waiting to turn if off, use one interval. When the light is off, and you are waiting to turn it on, use the other interval.
|
|
|
|
|
Logged
|
|
|
|
|
0
Offline
Sr. Member
Karma: 0
Posts: 360
Arduino rocks
|
 |
« Reply #2 on: December 11, 2011, 05:28:35 pm » |
Something like this should work: #define PIN 13 #define ON_INTERVAL 100 #define OFF_INTERVAL 1000 uint32_t nextTime;
void setup() { pinMode(PIN, OUTPUT); }
void loop() { uint32_t currentTime = millis(); if (currentTime > nextTime) { if (digitalRead(PIN)) { digitalWrite(PIN, LOW); nextTime = currentTime + OFF_INTERVAL; } else { digitalWrite(PIN, HIGH); nextTime = currentTime + ON_INTERVAL; } } }
|
|
|
|
|
Logged
|
|
|
|
|
Gloucestershire, UK
Offline
Jr. Member
Karma: 0
Posts: 53
Outta Steam
|
 |
« Reply #3 on: December 11, 2011, 05:40:47 pm » |
Wooh - that was fast!
Thanks to you both guys. That works well I've never come across "uint32_t" before Aeturnalus - what is it?
Sorry for my lack of knowledge, I'm at the bottom of a very steep looking learning curve with a headache at the moment!!
|
|
|
|
|
Logged
|
|
|
|
|
Seattle, WA USA
Online
Brattain Member
Karma: 313
Posts: 35502
Seattle, WA USA
|
 |
« Reply #4 on: December 11, 2011, 07:02:58 pm » |
I've never come across "uint32_t" before u = unsigned int = integer 32 = number of bits So, it's an unsigned long.
|
|
|
|
|
Logged
|
|
|
|
|
SF Bay Area (USA)
Offline
Faraday Member
Karma: 78
Posts: 5453
Strongly opinionated, but not official!
|
 |
« Reply #5 on: December 11, 2011, 09:41:27 pm » |
So, it's an unsigned long. On Arduino it's an unsigned long. uint32_t will always be an unsigned 32bit integer, even on cpus/systems where a "long" is a different size. (likewise uint16_t, uint8_t) When writing code that is supposed to behave the same even if it's ported elsewhere, it is a good idea to use these "standardized" types. It's too bad that they're so ... obscure-looking.
|
|
|
|
|
Logged
|
|
|
|
|
Pittsburgh, PA, USA
Offline
Faraday Member
Karma: 30
Posts: 2918
I only know some basic electricity....
|
 |
« Reply #6 on: December 12, 2011, 01:34:50 am » |
One way to handle multiple processes would be to code loop() as a state-engine. One variable holds the state number and each time through loop that number is used in a switch-case to choose which process to run as either in-line code or a function. Some time in the run, state is changed or not depending on what makes the most sense.
That doesn't mean that data capture or critical tasks can't occur before the state switch-case. It's just a way to say, this time through the woods I will take this path. You get flexibility to separate processes and add or cut processes as you will. State engines are great little tools for reducing indent levels and complexity.
|
|
|
|
|
Logged
|
Examples can be found at Learning in the Main Site and at the Playground
|
|
|
|
Gloucestershire, UK
Offline
Jr. Member
Karma: 0
Posts: 53
Outta Steam
|
 |
« Reply #7 on: December 12, 2011, 08:02:56 am » |
Many thanks PaulS and westfw  I do understand the significance of uint32-t now, but as you say westfw, why is it so hidden away  Thanks too GoForSmoke - I'll have to try that approach sometime - when I'm a bit more familiar with Arduino coding (could be some time  ) Cheers Guys
|
|
|
|
|
Logged
|
|
|
|
|
Seattle, WA USA
Online
Brattain Member
Karma: 313
Posts: 35502
Seattle, WA USA
|
 |
« Reply #8 on: December 12, 2011, 08:09:31 am » |
I do understand the significance of uint32-t now, but as you say westfw, why is it so hidden away Because it is not a necessary data type on the Arduino. The likelihood of running the same code on the Arduino, and on some other hardware, and needing the variables to be the same size on both platforms, is pretty slim. If you do have that need, it is likely that you have the experience to know that the _t types are what you need to use.
|
|
|
|
|
Logged
|
|
|
|
|
Gloucestershire, UK
Offline
Jr. Member
Karma: 0
Posts: 53
Outta Steam
|
 |
« Reply #9 on: December 12, 2011, 10:53:02 am » |
Ah right.... I can't see the need for me to use any cross platform code, so in future I'll just use std unsigned long variables and not confuse my tiny brain 
|
|
|
|
|
Logged
|
|
|
|
|
0
Offline
Sr. Member
Karma: 0
Posts: 360
Arduino rocks
|
 |
« Reply #10 on: December 12, 2011, 11:11:24 am » |
Arduino is beginning to expand to other microcontrollers--it therefore seems to make sense to use more cross-platform-compatible types.
(My own preference for them is a result of hours of debugging computer-to-Arduino communications, where reconstructing things fails miserably unless the width of the various types is easy to figure out)
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 6
Swim
|
 |
« Reply #11 on: December 18, 2011, 01:36:01 pm » |
Ok, I am like the first guy who asked the question, spending at least 20 hours trying to get one led to blink every second for (about250) 59 seconds and getting another led to blink on the 60th second to get my counter to reset. I can not even get the first led to blink one tine for that off 750 and on 250. Let alone for 59 times. I have been playing with the blink without delay the same as he has. I tried copying your demonstration into my UNO but the code just came up with a lot of error messages. What I am trying to do is use the led on function to power 10 ma relays in a deli counter board for a 60 minute clock. To use a swim practice. All I have really ben able to do is get 13 to flash at intervals but it occures so fast I can barely see the red led on 13 flash. I have changed the HIGH duration many many different times but no real change. Thanks
|
|
|
|
|
Logged
|
|
|
|
|
Seattle, WA USA
Online
Brattain Member
Karma: 313
Posts: 35502
Seattle, WA USA
|
 |
« Reply #12 on: December 18, 2011, 02:18:56 pm » |
I am like the first guy who asked the question Right no code. Just some confusing set of requirements. Perhaps if we saw some code, we could understand the requirements. All I have really ben able to do is get 13 to flash at intervals but it occures so fast I can barely see the red led on 13 flash. Using what code?
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Edison Member
Karma: 23
Posts: 1376
Now, More Than Ever
|
 |
« Reply #13 on: December 18, 2011, 02:23:16 pm » |
|
|
|
|
|
Logged
|
Don't Be Upset By The Results You Didn't Get With The Work You Didn't Do
|
|
|
|
Pittsburgh, PA, USA
Offline
Faraday Member
Karma: 30
Posts: 2918
I only know some basic electricity....
|
 |
« Reply #14 on: December 19, 2011, 12:13:58 am » |
This version takes number input from serial to change the blink rate. It uses my UNO's on-board led on pin 13 and works. Don't feed it garbage and it will behave as expected, bigger numbers make longer ON time. unsigned long waitUntil = 0UL; // because millis() returns UL enum whatFlag { led13state, endOfLine, dataBegun }; byte Flags = 0;
void setup() { pinMode( 13, OUTPUT ); digitalWrite( 13, bitRead( Flags, led13state )); Serial.begin( 9600 ); Serial.println( "Blink w/user input. Enter up to 1000 for led-on interval" ); Serial.println(); }
void loop() { static byte c; // c for character buffer // static byte endOfLineState = 0; static unsigned long timeSinceLastSerialRead = 0UL; static int enter = 0; // to get serial-entered number value. static int ledMillisOn = 100; // must be 0-999 // flash led and state changer if ( waitUntil - millis() >= 10000UL ) // when millis() passes waitUntil the _unsigned_ subtract { // leaves very large positive result Flags ^= ( 1 << led13state ); // led13state T/F bit toggle
if (bitRead( Flags, led13state )) waitUntil = millis() + (unsigned long)(ledMillisOn); else waitUntil = millis() + (unsigned long)(999 - ledMillisOn); digitalWrite(13, bitRead( Flags, led13state )); } // serial input if (Serial.available()) { c = Serial.read(); // Serial.print("."); // Serial.print( c ); timeSinceLastSerialRead = millis(); if ( c >= '0' && c <= '9' ) { enter *= 10; // decimal shifting whatever is in enter 1 place up enter += ( c - '0' ); // ascii 48 is '0' bitSet(Flags, dataBegun ); // entry is treated as finished if ( enter >= 100 ) // next digit being able to take the total > 999 { bitSet(Flags, endOfLine ); // entry is treated as finished } } else if (( c == 13 || c == 10 ) && bitRead( Flags, dataBegun )) { bitSet( Flags, endOfLine ); // entry is treated as finished } else if (( millis() - timeSinceLastSerialRead >= 500 ) && ! bitRead( Flags, endOfLine )) { bitSet( Flags, endOfLine ); // entry is treated as finished } } // serial output if ( bitRead( Flags, endOfLine ) && bitRead( Flags, dataBegun )) // should be done and have data { Serial.print( ">> " ); Serial.print( enter ); Serial.println( " <<" );
ledMillisOn = enter; enter = 0; bitClear( Flags, endOfLine ); bitClear( Flags, dataBegun ); // clears bits, endOfLine and dataBegun } }
|
|
|
|
|
Logged
|
Examples can be found at Learning in the Main Site and at the Playground
|
|
|
|
|