Show Posts
Pages: 1 ... 46 47 [48] 49 50 ... 62
706  Community / Bar Sport / Re: Your latest purchase on: June 30, 2011, 01:56:36 pm
As an owner of a mega2560, I'm wondering what makes you call it a 'bitch'.  I have my own personal gripes about the 2560 and would like to know yours as well.  That is, unless 'bitch' has a different meaning in your area.

So, tell me, what has that bitch done that made you mad?
707  Using Arduino / Programming Questions / Re: Why is there a delay at the end of void Loop? on: June 30, 2011, 01:35:33 pm
Oh, good grief.  Almost everyone involved in this discussion is right, and you're arguing about something that will never, ever be decided.

Just a touch of history.  The original languages used didn't have subroutine calls, the machines didn't have a stack, goto was all there was.  People HAD to code using goto.  As time went by, ideas happened and code and machines evolved.  I cut my teeth on an IBM360 and a DEC PDP11/45; one had a stack, the other didn't.  One had something spelled 'call' the other didn't.  Goto was common.

Code written with goto in it was often a problem because there was NOTHING else to help the programmer get done what needed to be done.  So, lousy programmers made a mess of things, just like today with obscure library code and indirect referrences.  Hence the rebellion against goto which software managers took up as an anathema and created 'coding standards' that made people avoid the use of what was once the ONLY flow control method available.  Tons of articles on 'structured programming' touted the 'new' paradigm and it almost became a religion.  Actually from the nature of the various responses, it may actually BE a religion.

Yes, I'm ignoring things like JNZ, jump not zero and JO, jump on overflow because these are just conditional goto statements.

Net, goto is just something that is not worth arguing about in the 21st century with all the other capabilities out there.  If a person wants to use goto, who cares, you don't have to use his code and convincing him what he's doing is somehow wrong isn't going to accomplish much.  Plus, you may be wrong, his method may be better somehow.

The first page of this thread was really useful.  I, for one, didn't know what the actual code was that called setup and loop; that was a valuable part of the discussion.  The timing of the return and call illustrated that hanging inside loop might be useful in time critical situations.  The argument over goto is something that many of us have heard a thousand times and just isn't interesting anymore.

Code it anyway you want to, just use reasonable names and comment the heck out of it.
708  Development / Other Software Development / Re: bug in the timealarm library on: June 29, 2011, 11:15:39 pm
Mem, you didn't look closely enough at my response.  To try and create an alarm to see if you can create an alarm just uses up alarms if you're going to check to see if you're getting close to the limit; especially if you're going to have to let it expire to get rid of it.  Since it's a compile time limit, and there is no way to extend it, monitoring in advance makes it more robust.

But, it doesn't really matter.  Leave the count function out if it in some way conflicts with some philosophical point I don't understand.  I am perfectly capable of putting it back in the library I use having already done so once.  That's one of the good things about open source.
709  Using Arduino / Project Guidance / Re: Flowmeter Node: RFM12b + Ethernet Shield on: June 29, 2011, 07:40:55 pm
I looked through the code you attached and you're totally correct, the return response from pachube is not the problem.  I didn't go into depth looking at your state machine, but the cursory look I did didn't turn up anything that would cause me suspicions.   I haven't worked on the RF stuff you're using so I don't know about that.  Net, nothing.

Since you're catching it after a timeout, is there something on the RF that can tell you anything?  A receive light or something?  The idea about printing where you last were is not a bad idea, it may help to see what the last thing that happened is.   Although the state machine could complicate the output too much.  One other thing, you have a nice state machine for handling the internet connection, could something like this help you with the RFM12 interaction.  It seems this is the device that is failing to respond and it could be an interrupt interaction where the ethernet board snatches the data away from the RF; this might require you to have a failure case for the RF parts.

Recovery is possible using the watchdog timer, but that solution sucks since you're hanging up so quickly.

Maybe someone familiar with the pieces I haven't worked with will speak up.
710  Development / Other Software Development / Re: bug in the timealarm library on: June 29, 2011, 05:28:45 pm

heh, It's not much, just something on the order of,

If (Alarm.count == dtNBR_ALARMS){
   don't set the alarm.

I then do something else.  In one case, where I really need the particular alarm, I set a flag to try again later (without using an alarm).  I also use the count to tell me if I need to up the max number of alarms the next time I compile.  An example of this is a controller I have for various functions around the house.  Things like turn off the A/C recirculators, guarantee a pump is shut off before going to bed, that kind of thing.  I get the count of alarms active, save the max over time and display it.  This way when I get close to the compiled max, I bump the max, recompile and put the device back in service.  It's not an elegant, sophisticated solution, but it keeps me from running out of timers.  On this device I have dtNBR_ALARMS  set to 20 and at run time I max out around 14 over a couple of days operation. 

See, when you dynamically create alarms to handle something like retrying a failed communication (such as Pachube) or time a response from a remote device that may be slow responding (my neighbors chicken feeder that may fail because a chicken is asleep on it), it's easy to loose track of how many are possible at a given instant.   Additionally, it may not be possible to actually know the max used because seemingly random hardware events happen.  Yes, I could possibly count up all the instances of creation and set the max for that number, but that is wasteful of the limited memory on the Arduino.  The twenty I already have eat up 240 bytes and I'm not close to being done with the eventual capabilities of the device and I must have 25 or thirty timerOnce calls scattered around in the code doing various things.

Obviously, it would be nice to be able to allocate a new timer whenever the number hit the max, but that would likely require malloc and I'm reasonably convinced that would introduce unexpected problems over the long term on a little device.  If you want to see the controller where I display the timer count it's at this page.  Scroll down a little and there is a short video that illustrates what happens.

And, reviewing the thread you pointed out, I disagree with Dave Mellis, returning the alarm id is such a tiny complication that it wouldn't be worth mentioning.  At least IMHO.


Yes, I could use the ID like you illustrate, but suppose the ID isn't just an index into the array?  In some libraries the token is a pointer, offset into a buffer, structure or something even more exotic.  Relying on what it appears to be (index) seems a little scary.

711  Development / Other Software Development / Re: bug in the timealarm library on: June 29, 2011, 03:04:19 pm
Actually, that is a really good question; I hadn't thought about that.

The count function is probably the only function that I actually need.  That is, unless there is a way I can do it in some other fashion; in which case, I certainly don't mind having code in the sketch to handle it.  The others I stuck in were to handle some silly thing I was working on at that particular time and I'm not really sure they make much sense looking back. 

On that note, a weekly alarm based on day of week can be handled in the fashion I accidentally found:  Set an alarmonce for Tuesday at 10AM and when it fires, set one for Tuesday at 10AM.  I know, it's not as elegant, but it seems to work.

Frankly though, this is such a cool library.  I use it a lot, even for things like turning off an LED.  When an event happens, I turn on an LED and set a timer for a second or so from now to turn it off.  That way my code can blissfully wander off doing other things and the timer takes care of the details for me.  So, you can see why I need the count function !  Heck, updating displays, sounding a bell when the soups ready, testing fire alarms, there's just no end to it.
712  Development / Other Software Development / Re: bug in the timealarm library on: June 29, 2011, 02:29:21 pm
Sorry, I was posting stuff at the same time you were.

However, you'll notice that I included stuff from other people that have commented.  The count function is especially useful if you're putting stuff in on the fly for dynamic timers.  It helps keep from running out of them!  Ok, so I get a little carried away from time to time.
713  Development / Other Software Development / Re: bug in the timealarm library on: June 29, 2011, 02:25:48 pm
and  pieces of TimeAlarms.cpp, It wouldn't all fit in the allowed size:
// return the value for alarms only
time_t TimeAlarmsClass::readAlarm(AlarmID_t ID)
  if(ID < dtNBR_ALARMS && Alarm[ID].Mode.isAllocated && Alarm[ID].Mode.isAlarm)
    return Alarm[ID].value ;
    return 0l; 

// return the value for timers only
time_t TimeAlarmsClass::readTimer(AlarmID_t ID)
  if(ID < dtNBR_ALARMS && Alarm[ID].Mode.isAllocated && Alarm[ID].Mode.isAlarm == false && Alarm[ID].Mode.isOneShot)
    return Alarm[ID].value ;
    return 0l; 

void TimeAlarmsClass::clear()  // clear and disable all alarms and make them avialable for allocation 
  for(uint8_t id = 0; id < dtNBR_ALARMS; id++){
     Alarm[id].Mode.isEnabled = false; 
     Alarm[id].Mode.isAllocated = false;

uint8_t TimeAlarmsClass::count()  // return the number of alarms active
  uint8_t count = 0;
  for(uint8_t id = 0; id < dtNBR_ALARMS; id++){
    if (Alarm[id].Mode.isAllocated)

AlarmID_t TimeAlarmsClass::getTriggeredAlarmId() //returns the currently triggered  alarm id
// returns  dtINVALID_ALARM_ID if not invoked from within an alarm handler
       return  servicedAlarmId;  // new private data member used instead of local loop variable i in serviceAlarms();
     return dtINVALID_ALARM_ID; // valid ids only available when servicing a callback

// and under the private stuff

 void TimeAlarmsClass::serviceAlarms()
  if(! isServicing)
    isServicing = true;
    for( servicedAlarmId = 0; servicedAlarmId < dtNBR_ALARMS; servicedAlarmId++)
      if( Alarm[servicedAlarmId].Mode.isEnabled && (now() >= Alarm[servicedAlarmId].nextTrigger)  )
        OnTick_t TickHandler = Alarm[servicedAlarmId].onTickHandler;
          Alarm[servicedAlarmId].Mode.isEnabled = Alarm[servicedAlarmId].Mode.isAllocated = false;  // free the ID if mode is OnShot
        if( TickHandler != NULL) {       
          (*TickHandler)();     // call the handler 
    isServicing = false;

714  Development / Other Software Development / Re: bug in the timealarm library on: June 29, 2011, 02:12:44 pm
#ifndef TimeAlarms_h
#define TimeAlarms_h

#include <inttypes.h>

#include "Time.h"

#define dtNBR_ALARMS 20

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

typedef struct  {
    uint8_t isAllocated            :1 ;  // the alarm is avialable for allocation if false
    uint8_t isEnabled              :1 ;  // the timer is only actioned if isEnabled is true
    uint8_t isOneShot              :1 ;  // the timer will be de-allocated after trigger is processed
    uint8_t isAlarm                :1 ;  // time of day alarm if true, period timer if false  
    AlarmMode_t   ;

typedef uint8_t AlarmID_t;
typedef AlarmID_t AlarmId;  // Arduino friendly name
#define dtINVALID_ALARM_ID 255

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

// class defining an alarm instance, only used by dtAlarmsClass
class AlarmClass
  OnTick_t onTickHandler;  
  void updateNextTrigger();
  time_t value;
  time_t nextTrigger;
  AlarmMode_t Mode;

// class containing the collection of alarms
class TimeAlarmsClass
   AlarmClass Alarm[dtNBR_ALARMS];
   void serviceAlarms();
   uint8_t isServicing;
   uint8_t servicedAlarmId; // the alarm currently being serviced
   AlarmID_t create( time_t value, OnTick_t onTickHandler, uint8_t isAlarm, uint8_t isOneShot, uint8_t isEnabled=true);
  // functions to create alarms and timers
  AlarmID_t alarmRepeat(time_t value, OnTick_t onTickHandler);                    // trigger daily at given time of day
  AlarmID_t alarmRepeat(const int H,  const int M,  const int S, OnTick_t onTickHandler); // as above, with hms arguments
  AlarmID_t alarmRepeat(const timeDayOfWeek_t DOW, const int H,  const int M,  const int S, OnTick_t onTickHandler); // as above, with day of week
  AlarmID_t alarmOnce(time_t value, OnTick_t onTickHandler);                     // trigger once at given time of day
  AlarmID_t alarmOnce( const int H,  const int M,  const int S, OnTick_t onTickHandler);  // as above, with hms arguments
  AlarmID_t alarmOnce(const timeDayOfWeek_t DOW, const int H,  const int M,  const int S, OnTick_t onTickHandler); // as above, with day of week
  AlarmID_t timerOnce(time_t value, OnTick_t onTickHandler);   // trigger once after the given number of seconds
  AlarmID_t timerOnce(const int H,  const int M,  const int S, OnTick_t onTickHandler);   // As above with HMS arguments
  AlarmID_t timerRepeat(time_t value, OnTick_t onTickHandler); // trigger after the given number of seconds continuously
  AlarmID_t timerRepeat(const int H,  const int M,  const int S, OnTick_t onTickHandler);   // As above with HMS arguments
  void delay(unsigned long ms);
  // utility methods
  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);
  void clear(); // disable and clear all alarms from memory
  time_t readAlarm(AlarmID_t ID); // return the value for given alarm
  time_t readTimer(AlarmID_t ID); // return the value for given timer
  uint8_t count();
  AlarmID_t getTriggeredAlarmId();
  // low level methods
  void enable(AlarmID_t ID);
  void disable(AlarmID_t ID);
  void write(AlarmID_t ID, time_t value);    // write the value (and enable) the alarm with the given ID
  time_t read(AlarmID_t ID);                 // return the value for the given timer

extern TimeAlarmsClass Alarm;  // make an instance for the user


/* 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 /* TimeAlarms_h */

715  Development / Other Software Development / Re: bug in the timealarm library on: June 29, 2011, 02:11:25 pm
I just tested the changes for getting the alarm id.  There were a few items I had to change to compile it and then I ran it with Vicknet's trick of updating the seconds in every loop for a couple of (virtual) years.  It worked fine.  Of course since I was setting the seconds (or in a few high speed tests, minutes) it didn't hit right on the second, but it ran fine.

The code I used to test it with:
#include <Time.h>
#include <TimeAlarms.h>

AlarmID_t morningAlarmID, afternoonAlarmID, eveningAlarmID;
char buf[100];

void setup()
  morningAlarmID   = Alarm.alarmRepeat(8,30,0, onAlarm);
  afternoonAlarmID = Alarm.alarmRepeat(13,25,0,onAlarm);
  eveningAlarmID   = Alarm.alarmRepeat(17,45,0,onAlarm);  

void onAlarm()
  // alarm callback function
  AlarmId id = Alarm. getTriggeredAlarmId();

  if(id == morningAlarmID) {
    Serial.println("Morning Alarm");
  else if (id == afternoonAlarmID) {  
    Serial.println("Afternoon Alarm");
  else if (id == eveningAlarmID) {  
    Serial.println("Evening Alarm");
  else {  
    Serial.println("Invalid Alarm ID");
  sprintf(buf,"Time %d:%d:%d %d/%d/%d", hour(),minute(),second(),day(),month(),year());

void loop()
//  sprintf(buf,"Time %d:%d:%d %d/%d/%d", hour(),minute(),second(),day(),month(),year());
//  Serial.println(buf);

716  Using Arduino / Project Guidance / Re: wireless sprinker system control on: June 29, 2011, 12:48:03 pm
Heh, heh, I'm so proud.  Take a look here for a no handling charge purchase.  They carry the entire line too, backpack, sheild, led populated ones, etc.
717  Using Arduino / Project Guidance / Re: wireless sprinker system control on: June 28, 2011, 06:41:33 pm
Truly, I'm not trying to hijack this thread, but there are so many interesting items coming out of it.  Regarding the Ardweeny, that little thing is just fascinating, however they want a $5.00 handling charge to top off the 9.95 shipping charge and the darn device only costs 9.95.

What the heck is up with that?  $15 to ship a $10 thingie?  I was all ready to order the ardweeny, a shield for it, a backpack and a couple of sockets (just in case) until I saw the 'handling' charge.  It annoyed me so much I just cancelled out.  Handling charge?  I wonder if digi sells them.  A stupid envelope only costs a couple of bucks including postage.


[edit after storming around the house throwing things]  I found it somewhere else, same price, 5.95 shipping and no handling charge.  Fine, showed them didn't I?
718  Development / Other Software Development / Re: bug in the timealarm library on: June 28, 2011, 05:47:05 pm
Wow, it looks like you're right.  The reason I haven't seen it is that I use the firing of an alarm to set another one for next time.  That way I only use alarmOnce and just keep repeating that.  I did that for debugging purposes when I was bringing the initial code up and never changed it.  The author didn't notice that he needed to calculate for same time next week, not same time span from now.

Regarding which timer, can't you grab the timer id and the use it in the callback routine to tell which one you are responding to?  Maybe I'm not understanding this problem.
719  Using Arduino / Project Guidance / Re: wireless sprinker system control on: June 28, 2011, 05:13:22 pm
I have been working (with, for, around) the developer that wrote the bootloader and he has fixes for everything.  However, there is a process for putting them in place that is taking a lot of time.  I have a thread about it here, subscribe to it and I'll post there when it is available.
720  Using Arduino / Installation & Troubleshooting / Re: Mega 2560 upload problem Windows on: June 28, 2011, 05:07:54 pm
Hopefully there will be soon.  I have been posting about this in the thread here  follow it for my latest findings.
Pages: 1 ... 46 47 [48] 49 50 ... 62