Arduino C Question

or

There are several possibilities. ALL of are dependant on the scoping and visibility rules of the specific compiler. There is a certain amount that has to be compatible, but i do not profess to know the boundaries. Just the same flags, semaphores, and global variables come to mind. Each method has advantages and liabilities, it is best to learn them thoroughly before using them.

?-)

Reply to
josephkk
Loading thread data ...

The function I was thinking of using this on was a timing function, inside the block would be the functions I wanted to run at that time.

My timer function would become true when it's time to execute and add the time period to the time to run again.

For example, I was some things to run every scan, other things to run maybe every 10ms, other things to run every 100ms, and so on.

if(time_to_exec(20)){ // This comes true every 20 milliseconds update_servos(); // and perhaps RC servos get their position pulse every 20mS ... }

if(time_to_exec(100)) { // execute this block every 100 milliseconds // update display, read buttons... }

This works just fine, I just thought perhaps there was a way to control the execution without using the if().

I've tinkered with C for a long time but not very many projects, I'm a long term newbie that learned from "Teach yourself C" and my most advanced project was to save and load programs to/from an Allen Bradley machine vision system using a Z-World controller with "Dynamic C". I barely touched on using pointers to functions, I don't even remember why I needed them. On that project, you turn a selector switch and it would load that program into the vision system, easier for operators than memory cards. To save a program, you would select a "Save" mode, select with the 6-position selector switch, and it would save the current program in that selected location.

RogerN

Reply to
RogerN

if (time_to_exec()) is how C programmers are going to want to see things.

--

Tim Wescott 
Wescott Design Services 
http://www.wescottdesign.com
Reply to
Tim Wescott

Sure that can be done..

Use modular math on the timer so you can capture the

10ms, 100ms, 1 sec intervals for example and then jump to the appropriate handler.

This means first check for the 10ms handlers and process those first, then 100ms and so on.. Of course you'll need a previous time slice to compare with the current one to make sure you haven't already done the current time slice.

Next, each handler per time group, 10ms, 100ms or 1sec, can check the associated array for function pointers to code blocks to be executed.

This list can be dynamically set instead of having a bunch of boolean checks, that turn out to be false, which waste CPU time.. The idea is to fill an array with pointers per time zone and the end of the list will have a null pointer in it.

I've found with low power processors, you need to help it as much as possible and loading an array of working blocks of code to use via pointers from an array works well because it saves on all the long winded Case, IF, whiles etc..

All you need to do is simply define these arrays via user operation from menus or at start up for some persistent types.

Jamie

Reply to
Maynard A. Philbrook Jr.

really? time_to_exec looks non-trivial how did you do that? is it a macro with a static variable in it?

--
umop apisdn 


--- news://freenews.netfront.net/ - complaints: news@netfront.net ---
Reply to
Jasen Betts

I made a more complicated timer that uses a data structure using status bits and a double int for the starting time. It's the same idea as the Arduino example ~"blink without delay". I created an array of the structure and pass the address of the structure in the function.

Where I want to go with it now is to add a number of milliseconds to a variable, initialized with millis(). So if my time_to_exec is 10, when millis() >= last_exec_time then last_exec_time = last_exec_time +10, return

1, else return 0;

I may, instead, use bits and at the start of the loop, compare millis() with the set value for all the timers and set the corresponding bits true or false. Then in the program I can use something like if(bit10ms){...};. if(bit50ms) {...};...

This isn't as good as interrupts but I want to save the interrupts for tasks with more critical timing. If I program an Arduino similar to a PLC and I get good results performing multiple tasks at what seems like the same time.

Here's my old program with a timer that works similar to a PLC's timer.

typedef struct timerdata { unsigned int accum, starttime; boolean TT,DN,EN; // Timer Timing, DoNe, ENabled } PLCTimer;

PLCTimer BlinkTimer1, BlinkTimer2,BlinkCounter,printtime;

unsigned int prevtime, lastscan, maxscan=0;

void setup() { Serial.begin(9600); pinMode(13,OUTPUT); }

void loop() {

Serial.print(millis()); Serial.print(BlinkTimer1.accum); Serial.print(" "); lastscan=millis()-prevtime; maxscan=max(maxscan, lastscan); prevtime=millis(); T_ON_DLY(&BlinkTimer1,!BlinkTimer2.DN,400,1);// BlinkTimer1 is enabled when BlinkTimer2 is not Done T_ON_DLY(&BlinkTimer2,BlinkTimer1.DN,400,1);//BlinkTimer2 is enabled when BlinkTimer1 is Done T_ON_DLY(&printtime,!printtime.DN,900,1);//Timer used to print scan times every 900 milliseconds if(printtime.DN)// If print timer is done then print data { Serial.print(lastscan); Serial.print(" "); Serial.print(BlinkTimer1.accum); Serial.print(" "); Serial.print(BlinkTimer2.accum); Serial.print(" "); Serial.println(maxscan); } digitalWrite(13, BlinkTimer1.DN);//LED is ON when BlinkTimer1 is Done until BlinkTimer2 is done. COUNT_UP(&BlinkCounter,BlinkTimer1.DN,1000);// counter counts blinks, has a preset of 1000 Serial.println(BlinkCounter.accum); if(BlinkCounter.accum>=20)RES(&BlinkCounter);//BlinkCounter never gets done because it resets at 20 }

int T_ON_DLY(struct timerdata *sp, boolean EN, unsigned int preset, unsigned int base) { if(!base)base=1; // no divide by zero if base unspecified // sp->preset = preset; if(!sp->EN && EN)// Enable has transitioned from falset to true { sp->starttime = millis()/base; sp->EN = EN; sp->accum = 0; } if(EN && !sp->DN) { sp->accum = millis()/base-sp->starttime; sp->DN=sp->accum >= preset; sp->TT = 1; } if(sp->DN)sp->TT=0; if(!EN) { sp->EN=0; sp->DN=0; sp->TT=0; }

}

int COUNT_UP(struct timerdata *sp, int EN, int preset)// Count Up Counter { // sp->preset = preset; if(!sp->EN && EN)// Enable has transitioned from falset to true { sp->accum++; sp->EN = EN; if(sp->accum>=preset)sp->DN=1; } if(!EN)sp->EN=0; if(sp->DN)sp->TT=0; }

void RES(struct timerdata *sp) { sp->accum=0; sp->EN=0; sp->TT=0; sp->DN=0; }

RogerN

Reply to
RogerN

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.