Pages: 1 [2] 3   Go Down
Author Topic: mini RTOS [sic]  (Read 4153 times)
0 Members and 1 Guest are viewing this topic.
Boulder, CO
Offline Offline
Newbie
*
Karma: 0
Posts: 43
I want to be a really useful engine!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Well, I know that you seemed to think that inclusion in the core was not an important question, but a non user-definable method to allocate space for these Alarms/event seems unreasonable if this library is ever going to be a part of the core.  Mem has done a good job of keeping resource usage (RAM) very low for users of his suggested library, but it still uses 60 bytes!  That seems unacceptable to me for core inclusion considering that some people may never even want to use these Alarms.  Choosing a lower default number of Alarms does not seem like a good core solution either, and neither does making things compile time options.  So, if this is ever going to be considered for core inclusion I would suggest a different approach for allocation memory.  However since Mem did do a good job of minimizing RAM usage, any core implementation would probably take up more RAM and therefor as a standalone library his solution may be better.

If libraries are never going to be core solutions, compile time options may well be good solutions, especially if the library does something very specialized that could greatly benefit from compile time options to either save RAM or to increase speed.  For example: I am working on an LED TDM library and have come to the conclusion that speed is paramount.  Although I would like to create a library that could be easily used without recompiling, I have determined that this would potentially mean a significant (3x) speed decrease.  Since this might very well push the library utility out of the problem space that it is trying to address in the first place, this does not seem worth it.  I will probably leave certain things compile time options for this TDM library.

While I certainly agree that the programing interface is important to keep simple, the target user audience is also somewhat dependent on whether a library is meant for core inclusion or not.  Obviously we want to keep interfaces simple, but often times a sacrifice in simplicity is warranted for better performance or flexibility.  Sometimes the only way to make good decisions about which of these tradeoffs to make is by deciding who the likely target audience is.
Logged

London
Offline Offline
Tesla Member
***
Karma: 10
Posts: 6255
Have fun!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Allowing the user to create his own callbacks is easy and probably not much more complicated for a newbie to use (it would look similar to the way attachInterrupt works). Only uses two more bytes per instance so nothing to worry about there.

Creating instances of alarms (or whatever they will be called) at runtime to minimize RAM usage to the minimum needed has also been implemented, I started out with a version of the library that allows the user to create instances of the timers he needs so memory is only consumed when needed, but it seemed a less friendly to newbies then the simpler version posted earlier.

Here is a fragment from one of my test sketches that creates three instances

Code:

AlarmClass Timer1;  
AlarmClass Timer2;
AlarmClass Timer3;

void setup(){
  // you can register time of day Alarms at any time but really shouldn't enable them until the internal clock is set

   if( dtAlarms.registerTimer( &Timer1 ) ) {        
     Timer1.value = DateTime.now() + 11;   // fire at the time of day 11 seconds from now
     Timer1.Mode.isTimeOfDay = true; // the value given above is a time of day
     Timer1.onTickHandler = &OnTimer1Tick;
     Timer1.enable();  
  }
   if( dtAlarms.registerTimer( &Timer2 ) ) {        
     Timer2.value = AlarmHMS(12,30,0)    // this is 30 minutes after 12 noon
     Timer2.onTickHandler = &OnTimer2Tick;
     Timer2.Mode.isTimeOfDay = true;
     Timer2.enable();  
  }
   if( dtAlarms.registerTimer( &Timer3 ) ) {        
     Timer3.Mode.isTimeOfDay = false; // the timer value is treated as a delay in seconds, not absolute time
     Timer3.value =  13;   // delay in seconds from the time this alarm is enabled
     Timer3.onTickHandler = &OnTimer1Tick;
     Timer3.enable();  
  }

}

void OnTimer1Tick(void *Sender){

  if( Sender ==  &Timer1)
      Serial.print("Timer1 event: ");            
   else  if( Sender ==  &Timer3)
      Serial.print("Timer3 event: ");      
  timeDisplay();    
}

void OnTimer2Tick(void *Sender){
    Serial.print("Timer2 event: ");  
}
« Last Edit: August 06, 2008, 11:17:41 am by mem » Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 38
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

mem,
can you tell me what to modify to get your dateTimeAlarm library to run with 0012? I am seeing the
same kind of library compile errors others have seen with moving to 0012
Logged

London
Offline Offline
Tesla Member
***
Karma: 10
Posts: 6255
Have fun!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
can you tell me what to modify to get your dateTimeAlarm library to run with 0012? I am seeing the
same kind of library compile errors others have seen with moving to 0012
In the DateTimeAlarm.h file comment out the following line:

//#include <wiring.h> // this line must be commented out or removed for 0012
« Last Edit: September 24, 2008, 11:08:08 pm by mem » Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 38
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

mem,
Did you mean TimerAlarms.h ? I tried commenting out the include in TimerAlarms.h but it did not work. Same kind of errors at compile time. Any other ideas? I am using the Mac version.
Logged

London
Offline Offline
Tesla Member
***
Karma: 10
Posts: 6255
Have fun!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Yes, DateTimeAlarms.h
Here is my the modified code. note that you need the latest version of DateTime.h for this to compile with 0012
Code:
/*
  DateTimeAlarms.h - Arduino Date and Time alrms library

  This library is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  

*/

#ifndef DateTimeAlarms_h
#define DateTimeAlarms_h

#include <inttypes.h>
//#include <wiring.h> // commenting this out was the only change necessary for 0012

#include "dateTime.h"

typedef enum {
     dtMillisecond, dtSecond, dtMinute, dtHour, dtDay //,clkMonth,clkYear
 } dtUnits_t;

typedef struct  {
      uint8_t isEnabled              :1 ;
      uint8_t isOneShot              :1 ;
      uint8_t isAlarm                :1 ;    
   }
     AlarmMode_t   ;

typedef uint8_t AlarmID_t;
#define dtINVALID_ALARM_ID 255
#define dtNBR_ALARMS 6

class AlarmClass;  // forward reference
typedef void (*OnTick_t)(uint8_t);  // alarm callback function typedef

// class defining an alarm instance, only used by dtAlarmsClass
class AlarmClass
{      
private:
public:
      AlarmClass();
      OnTick_t onTickHandler;      
      void updateNextTrigger();

      time_t value;
      time_t nextTrigger;
      AlarmID_t ID;           // unique instance id (only used for debugging
      AlarmMode_t Mode;
};


// class containing the collection of alarms
class dtAlarmsClass
{
   friend class TimerClass;
private:
   AlarmClass Alarm[dtNBR_ALARMS];
   void serviceAlarms();
   boolean isServicing;
   AlarmID_t nextID;
   AlarmID_t create( time_t value, OnTick_t onTickHandler,boolean isAlarm, boolean isEnabled );
public:
      dtAlarmsClass();
      void delay(unsigned long ms);
      uint8_t getDigitsNow( dtUnits_t Units);  // returns the current digit value for the given time unit
      void waitForDigits( uint8_t Digits, dtUnits_t Units);
      void waitForRollover(dtUnits_t Units);
      
      // functions for specific alarms identifed by alarm ID
      AlarmID_t createAlarm( time_t value, OnTick_t onTickHandler, boolean isEnabled = true );
    AlarmID_t createTimer( time_t value, OnTick_t onTickHandler, boolean isEnabled = true );
      void setValue(AlarmID_t ID, time_t value);
      void enable(AlarmID_t ID);
      void disable(AlarmID_t ID);

};

extern dtAlarmsClass dtAlarms;  // make an instance for the user
/*==============================================================================
 * MACROS
 *============================================================================*/
/* public */
#define waitUntilThisSecond(_val_) waitForDigits( _val_, dtSecond)
#define waitUntilThisMinute(_val_) waitForDigits( _val_, dtMinute)
#define waitUntilThisHour(_val_)   waitForDigits( _val_, dtHour)
#define waitUntilThisDay(_val_)    waitForDigits( _val_, dtDay)
#define waitMinuteRollover() waitForRollover(dtSecond)
#define waitHourRollover()   waitForRollover(dtMinute)
#define waitDayRollover()    waitForRollover(dtHour)

#define AlarmHMS(_hr_, _min_, _sec_) (_hr_ * SECS_PER_HOUR + _min_ * SECS_PER_MIN + _sec_)

#endif /* Clock_h */


« Last Edit: September 26, 2008, 04:10:27 am by mem » Logged

Millicent, South Australia
Offline Offline
Newbie
*
Karma: 0
Posts: 40
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi everyone,

First time poster, long time forum-scourer... smiley

I've been madly searching these forums since receiving my Diecimila a few weeks ago, trying to cobble together some alarm code that I can use to trigger a camera at a given time each day. I was very pleased to find this thread, but I can't seem to work out why I get compile errors when using mem's example code from reply #2 or reply #16. For reply #2, I get:

[EDIT] Never mind, I fixed this first problem..

For reply #16, I get:

 In function 'void setup()':
error: 'class dtAlarmsClass' has no member named 'registerTimer' In function 'void loop()':


  relating to:

Code:
Wire.begin();
    // you can register time of day Alarms at any time but really shouldn't enable them until the internal clock is set
   if( dtAlarms.registerTimer( &TimeForPhoto ) ) {        
     TimeForPhoto.value = AlarmHMS(12,30,0)    // this is 30 minutes after 12 noon
     TimeForPhoto.onTickHandler = &OnTimeForPhotoTick;
     TimeForPhoto.Mode.isTimeOfDay = true;
     TimeForPhoto.enable(); // the above registers an alarm, labelled 'TimeForPhoto', as one that triggers at the given time
 of day.
  }
I'm able to follow the coding to a certain extent, but this is well above anything I've tried before... I've ordered a Mini-DS1307 board to supply the time, so until that comes I thought I'd work on the alarm code.

Any help would be greatly appreciated - and by the way, congrats on such a friendly, supportive forum!

JB
« Last Edit: October 01, 2008, 10:45:07 pm by jbennett » Logged

JB

Millicent, South Australia
Offline Offline
Newbie
*
Karma: 0
Posts: 40
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi again...
Fixing my first problem has left me with another; here's the code:
Code:
#include <DateTime.h>
#include <DateTimeAlarms.h>

AlarmID_t Alarm9,Alarm12,Timer11;  // id to identify what triggered alarm if callbacks are shared

void setup(){
  Serial.begin(19200);
  Alarm9 = dtAlarms.createAlarm( DateTime.now() + 9, OnAlarm); // trigger 9 seconds from now
  Alarm12 = dtAlarms.createAlarm(AlarmHMS(12,0,0), OnAlarm); // trigger at mid day
  Timer11 = dtAlarms.createTimer( 11, OnTimer); // trigger in 11 seconds
}

void OnAlarm(AlarmID_t Sender){
  // callback for time of day alarms
  if( Sender ==  Alarm9) {
    Serial.print("Alarm9: ");        
    dtAlarms.setValue(Alarm9, DateTime.now() + 9 ); // reset alarm to trigger at the time that is 9 seconds from now
  }
  else  if( Sender ==  Alarm12)
  {
    Serial.print("Alarm12: ");
    dtAlarms.setValue(Alarm12, AlarmHMS(12,0,0)); // reset alarm to trigger at noon
  }    
}

void OnTimer(AlarmID_t Sender){
  // callback for time delay alarm
  Serial.print("Timer11: 11 sec timer: ");    
  dtAlarms.setValue(Timer11, 11 ); // delay another 11 seconds
}

void  loop(){  
  
  dtAlarms.waitUntilThisSecond(0); //  this code blocks waiting for start of the next minute, background alarms are still serviced
  digitalWrite(13, HIGH);
  dtAlarms.delay(2000);  // note we call the alarm delay to service the background alarms
  digitalWrite(13,LOW);  
  dtAlarms.delay(2000); // delay is in milliseconds , all other alarm values are seconds
}

...which gives me the following error:

o: In function `loop':
undefined reference to `dtAlarms'o: In function `OnTimer(unsigned char)':
o: In function `OnAlarm(unsigned char)':
o: In function `setup':


Again, thanks for any thoughts!
Logged

JB

London
Offline Offline
Tesla Member
***
Karma: 10
Posts: 6255
Have fun!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi JB, the sketch you posted above compiles ok for me on version 0011 and 0012, which version are you using?

If 0012, are you using the latest version of DateTime.h (if not then download the latest DateTime from the library)
Logged

Millicent, South Australia
Offline Offline
Newbie
*
Karma: 0
Posts: 40
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi mem,

The errors posted are from 0011. I've tried with 0012, but I think I've done something wrong when I instaleld that. On compiling, I get this:
Code:
o: In function `loop':
C:\DOCUME~1\john\LOCALS~1\Temp\build61366.tmp/Temporary_6757_4834.cpp:39: undefined reference to `dtAlarms'


C:\DOCUME~1\john\LOCALS~1\Temp\build61366.tmp/Temporary_6757_4834.cpp:39: undefined reference to `dtAlarms'


C:\DOCUME~1\john\LOCALS~1\Temp\build61366.tmp/Temporary_6757_4834.cpp:39: undefined reference to `dtAlarmsClass::waitForDigits(unsigned char, dtUnits_t)'


C:\DOCUME~1\john\LOCALS~1\Temp\build61366.tmp/Temporary_6757_4834.cpp:41: undefined reference to `dtAlarmsClass::delay(unsigned long)'


C:\DOCUME~1\john\LOCALS~1\Temp\build61366.tmp/Temporary_6757_4834.cpp:43: undefined reference to `dtAlarmsClass::delay(unsigned long)'


o: In function `OnTimer(unsigned char)':
C:\DOCUME~1\john\LOCALS~1\Temp\build61366.tmp/Temporary_6757_4834.cpp:34: undefined reference to `dtAlarms'


C:\DOCUME~1\john\LOCALS~1\Temp\build61366.tmp/Temporary_6757_4834.cpp:34: undefined reference to `dtAlarms'


C:\DOCUME~1\john\LOCALS~1\Temp\build61366.tmp/Temporary_6757_4834.cpp:34: undefined reference to `dtAlarmsClass::setValue(unsigned char, unsigned long)'


o: In function `OnAlarm(unsigned char)':
C:\DOCUME~1\john\LOCALS~1\Temp\build61366.tmp/Temporary_6757_4834.cpp:22: undefined reference to `dtAlarms'


C:\DOCUME~1\john\LOCALS~1\Temp\build61366.tmp/Temporary_6757_4834.cpp:22: undefined reference to `dtAlarms'


C:\DOCUME~1\john\LOCALS~1\Temp\build61366.tmp/Temporary_6757_4834.cpp:22: undefined reference to `dtAlarmsClass::setValue(unsigned char, unsigned long)'


C:\DOCUME~1\john\LOCALS~1\Temp\build61366.tmp/Temporary_6757_4834.cpp:27: undefined reference to `dtAlarms'


C:\DOCUME~1\john\LOCALS~1\Temp\build61366.tmp/Temporary_6757_4834.cpp:27: undefined reference to `dtAlarms'


C:\DOCUME~1\john\LOCALS~1\Temp\build61366.tmp/Temporary_6757_4834.cpp:27: undefined reference to `dtAlarmsClass::setValue(unsigned char, unsigned long)'


o: In function `setup':
C:\DOCUME~1\john\LOCALS~1\Temp\build61366.tmp/Temporary_6757_4834.cpp:13: undefined reference to `dtAlarms'


C:\DOCUME~1\john\LOCALS~1\Temp\build61366.tmp/Temporary_6757_4834.cpp:13: undefined reference to `dtAlarms'


C:\DOCUME~1\john\LOCALS~1\Temp\build61366.tmp/Temporary_6757_4834.cpp:13: undefined reference to `dtAlarmsClass::createAlarm(unsigned long, void (*)(unsigned char), unsigned char)'


C:\DOCUME~1\john\LOCALS~1\Temp\build61366.tmp/Temporary_6757_4834.cpp:14: undefined reference to `dtAlarmsClass::createAlarm(unsigned long, void (*)(unsigned char), unsigned char)'


C:\DOCUME~1\john\LOCALS~1\Temp\build61366.tmp/Temporary_6757_4834.cpp:15: undefined reference to `dtAlarmsClass::createTimer(unsigned long, void (*)(unsigned char), unsigned char)'


Couldn't determine program size: C:\Documents and Settings\john\My Documents\arduino-0012\hardware/tools/avr/bin/avr-size: 'C:\DOCUME~1\john\LOCALS~1\Temp\build61366.tmp\DateTimeAlarmsSketch.hex': No such file
I've got a feeling that this is going to be an embarassingly easy thing to fix but I can't put my finger on it.
Logged

JB

London
Offline Offline
Tesla Member
***
Karma: 10
Posts: 6255
Have fun!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

dtAlarms is an object that is made when DateTimeAlarms.cpp is compiled and is defined in DateTimeAlarms.h

Try deleting DateTimeAlarms.o and recompile your sketch and check to see if the .o file is created.

Did you change the DateTimeAlarms.h file?  If so, try replacing your copy with the  DateTimeAlarms.h code in the thread.
Logged

Millicent, South Australia
Offline Offline
Newbie
*
Karma: 0
Posts: 40
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I was pretty sure that I'd replaced the DateTimeAlarms.h file, but I decided to do a clean install of v0012 in a seperate location anyway. I have a DateTimeAlarms library, but it's only got the DateTimeAlarms.h file; I don't seem to have the DateTimeAlarms.cpp or DateTimeAlarms.o file anywhere, and can't locate it on the forums or main site.

I'm guessing that if someone can point me to that file, my problems may just disappear...

Thanks again!
Logged

JB

London
Offline Offline
Tesla Member
***
Karma: 10
Posts: 6255
Have fun!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

JB the files are posted in the begining of this thread: http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1217881285

try it in 0011 and see if that fixes your problem. the files need a small mod for 0012 and these were posted today in that thread

The mod for 0012 is to move #include <wiring.h> from DateTimeAlarms.h and put it into DateTimeAlarms.cpp
« Last Edit: October 02, 2008, 04:35:18 am by mem » Logged

Millicent, South Australia
Offline Offline
Newbie
*
Karma: 0
Posts: 40
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

OK, so now we get to the bit that's confused me every time I've read this thread: hotcarrier wrote -
Quote
mem,
Did you mean TimerAlarms.h ?
... to which you replied -
Quote
Yes, DateTimeAlarms.h
 
:-? Sorry if I've missed something here, but the thread you directed me to has 'TimerAlarms' files in it, not 'DateTimeAlarms'. I tried renaming them, and replacing any 'TimerAlarm' references with 'DateTimeAlarms' references but that didn't work. Also tried it in 0011 with similar results. I AM getting a different error now though:
Code:
In file included from C:\arduino-0012\hardware\cores\arduino/WProgram.h:4,


c:/arduino-0012/hardware/tools/avr/lib/gcc/../../avr/include/stdlib.h:80: error: expected unqualified-id before 'int'


c:/arduino-0012/hardware/tools/avr/lib/gcc/../../avr/include/stdlib.h:80: error: expected `)' before 'int'


c:/arduino-0012/hardware/tools/avr/lib/gcc/../../avr/include/stdlib.h:80: error: expected `)' before 'int'


c:/arduino-0012/hardware/tools/avr/lib/gcc/../../avr/include/stdlib.h:111: error: expected unqualified-id before 'int'


c:/arduino-0012/hardware/tools/avr/lib/gcc/../../avr/include/stdlib.h:111: error: expected `)' before 'int'


c:/arduino-0012/hardware/tools/avr/lib/gcc/../../avr/include/stdlib.h:111: error: expected `)' before 'int'


c:/arduino-0012/hardware/tools/avr/lib/gcc/../../avr/include/stdlib.h:144: error: expected identifier before '(' token


c:/arduino-0012/hardware/tools/avr/lib/gcc/../../avr/include/stdlib.h:144: error: expected `)' before '(' token


c:/arduino-0012/hardware/tools/avr/lib/gcc/../../avr/include/stdlib.h:144: error: expected ',' or '...' before '(' token


c:/arduino-0012/hardware/tools/avr/lib/gcc/../../avr/include/stdlib.h:144: error: expected initializer before ')' token


c:/arduino-0012/hardware/tools/avr/lib/gcc/../../avr/include/stdlib.h:176: error: '__compar_fn_t' has not been declared


In file included from C:\arduino-0012\hardware\cores\arduino/WProgram.h:6,


 In function 'void setup()':

What am I missing?!? I feel like such a newb... :smiley
Logged

JB

Millicent, South Australia
Offline Offline
Newbie
*
Karma: 0
Posts: 40
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Sorry, just picked up on your comment about MOVING #include <wiring.h> from one file to the other... much better, but still have this last little error:

In function 'void setup()':
error: 'class dtAlarmsClass' has no member named 'createAlarm'


Which is a lot nicer than what I had before...

Again, sorry for not reading your post correctly!!
Logged

JB

Pages: 1 [2] 3   Go Up
Jump to: