Page 2 of 9

Re: Lee's Feature Complete PDE

Posted: Fri Mar 29, 2013 1:18 pm
by lnevo
Ok, the code compiles. Only a few syntax errors :) Anyway, it's posted in the 2nd post. Enjoy

Re: Lee's Feature Complete PDE

Posted: Fri Mar 29, 2013 3:27 pm
by Piper
Nice work, Lee! I need to dial in my wave patterns and wave maker code this weekend. I'll be digging through your code for ideas while I'm at it :)

Lee's Feature Complete PDE

Posted: Fri Mar 29, 2013 5:11 pm
by lnevo
rimai wrote:Hey Lee,
This actually triggered a very nice idea :)
I'm going to create a handful of function calls that can be triggered using the wifi commands.
Just like /mf that starts feeding mode.
This way, you can call custom functions through the web browser and we harass Curt to implement in the app too :)
By having those function calls, you can start CalibrateDosingPumps() or runSwabbie() for example without having to trigger it through memory bit set.
Instead of creating stub functions or hard coded function names that need to be defined and then needing to be added by curt and whoever on the iPhone app...why not have it take the name of a function and we can have it call a pointer to the function by name?

Re: Lee's Feature Complete PDE

Posted: Fri Mar 29, 2013 7:04 pm
by rimai
Can you elaborate more?

Lee's Feature Complete PDE

Posted: Fri Mar 29, 2013 7:13 pm
by lnevo
I'll see if I can write up some demo code...

Lee's Feature Complete PDE

Posted: Fri Mar 29, 2013 7:51 pm
by lnevo
Maybe not exactly call by name...you'd need either a struct or object to hold properties of the function, like a name / index...

Code: Select all

Store your callback functions in an array like this.
// 2 can be from a #define num_functions 2
typedef void (*FunctionPointer) ();
FunctionPointer functions[2];

// user defines their functions, whatever name they want
void DoFunction1(void) {
   // do whatever here
};

void DoFunction2(void) {
   // do whatever here
};

// user assigns their functions to global variable, ie. ReefAngel.CustomFunctions[]
functions[0]=DoFunction1;
functions[1]=DoFunction2;

// add to web code (pseudo)
If http command == run_function {
    functions[x]();
}
If you made "functions" a linked list or even just an array of object that you could push and pop new functions. It old have a variable property name. A case would go through the list of objects until name="passed" name and then you would execute object.function();

Code: Select all

struct _Object {
    void (* functionPointer)();
    int value;
    char [] name;
};

    /* create struct */
    struct _Object Object;
    Object.value = 1;
    Object.name = "DoFunction1";
    Object.function = DoFunction1;
Anyway this could be used for a lot of things...adding screens, menus, callbacks for timers..(assign a function to a TimerClass to run when timer is triggered...

Lee's Feature Complete PDE

Posted: Fri Mar 29, 2013 7:52 pm
by lnevo

Lee's Feature Complete PDE

Posted: Fri Mar 29, 2013 8:12 pm
by lnevo
Here's a good demo for a timer made for Arduino that calls a function when complete.

http://playground.arduino.cc/Code/SimpleTimer

Lee's Feature Complete PDE

Posted: Fri Mar 29, 2013 8:17 pm
by jsclownfish
Calling functions through the wifi would be nice for things like triggering the remote feeding. It would be easier than changing a memory location like I am doing now. On your feeder, I eventually changed mine to feed small amounts every hour through the day. I don't know if it really helps the fish, but it sure did train them quickly to swim to a certain spot whenever the wavemakers stop. :)

-Jon

Re: Lee's Feature Complete PDE

Posted: Fri Mar 29, 2013 8:28 pm
by rimai
I'm still not convinced that keeping all the pointer and function arrays and names will be much benefit.
It seems to me that it uses a lot of RAM for little benefit.
I can see how power users may get some benefit, but I don't see anybody else even understanding it, let alone using it.
It's much simpler to just add fixed function calls. just like Curt did with the menu entries.
Like define DoFunction1() on h file and code it inside the INO code, so when the wifi command comes in, it goes and process what's inside DoFunction1() in your INO code.

Lee's Feature Complete PDE

Posted: Fri Mar 29, 2013 8:34 pm
by lnevo
Yah it's definitely a power user function...we'd need to wrap it in a simple API for users. But the benefit would be whatever number of callbacks with whatever name and other apps wouldn't have to be modified or anything to support more or less, or even the portal too :)

Lee's Feature Complete PDE

Posted: Fri Mar 29, 2013 8:37 pm
by lnevo
Anyway just an idea I've been wondering how we could do things like add more than 9 menu items or make screen management easier...etc.

Lee's Feature Complete PDE

Posted: Fri Mar 29, 2013 8:54 pm
by lnevo
Maybe I'm explaining wrong also, because in the long run it could be easier for users... Instead of

Code: Select all

#include <avr/pgmspace.h>
prog_char menu1_label[] PROGMEM = "Feeding";
prog_char menu2_label[] PROGMEM = "Water Change";
prog_char menu3_label[] PROGMEM = "Vortech Mode";
prog_char menu4_label[] PROGMEM = "Refugium Light";
prog_char menu5_label[] PROGMEM = "ATO Clear";
prog_char menu6_label[] PROGMEM = "Overheat Clear";
prog_char menu7_label[] PROGMEM = "PH Calibration";
prog_char menu8_label[] PROGMEM = "WLS Calibration";
prog_char menu9_label[] PROGMEM = "Date / Time";

// Group the menu entries together
PROGMEM const char *menu_items[] = {
menu1_label, menu2_label, menu3_label,
menu4_label, menu5_label, menu6_label,
menu7_label, menu8_label, menu9_label
};
They would have

Code: Select all

AddMenuItem("Feeding",myFeedingFunction);
AddMenuItem("WaterChange",ReefAngel.WaterChangeModeStart);
AddMenuItem("Vortech Mode",cycleVortechMode);
...
Anyway, definitely a lot of work but as I said the concept can apply in a lot of places, and we would definitely need some API work...if you don't think it's worth it, never mind...it would need everyone on board to make it worthwhile.

Re: Lee's Feature Complete PDE

Posted: Fri Mar 29, 2013 9:16 pm
by rimai
I see now where you are trying to get.
I could have gone the route of storing char arrays too when I was coding the menu logic, but you will find out that you will run out of RAM memory quick if you keep storing char arrays in memory.
That's the reason those arrays are stored in PROGMEM. They do not consume RAM memory.
On the RA+, it may work because we got much more memory.

Lee's Feature Complete PDE

Posted: Sat Mar 30, 2013 5:20 am
by lnevo
Hehe wasn't it bill gates said 64k of ram was plenty :) I forget sometimes that we are working on these little arduino boards.

Re: Lee's Feature Complete PDE

Posted: Sun Mar 31, 2013 12:52 pm
by binder
I originally was going to use function pointers for the menu's but it failed for me...big time. I kept having the controller run out of memory and lose the reference to the pointer and you would get out of memory exceptions and the controller would do random things....lock up, display strange text, etc. Of course, I was also calling new and delete to create the menu and trying to allow for dynamically created menus. This system, unfortunately, isn't designed to handle all that extra overhead. It's the low level logic stuff that works the best on it especially when we have so much involved. It could need to be revisited and retested because that was from 2010 when I was originally updating the menus.

Lee's Feature Complete PDE

Posted: Sat Apr 06, 2013 9:10 pm
by lnevo
Inspired by the Android apps ability to lock ports, I wrote up this code to reset the masks for my dosing pumps and auto feeder to make sure they don't get tripped by mistake. Gave myself a back door in case I do need to override for some reason, it's important that this runs before ReefAngel.ShowInterface() when Relay.Write() is issued.

Code: Select all

// Override masks for things that should not be turned on by mistake
void lockPorts() {
  if(InternalMemory.reas(Mem_B_LockPorts) {
    // Reset RelayMaskOn
    bitClear(ReefAngel.Relay.RelayMaskOnE[0],FeederBit);
    bitClear(ReefAngel.Relay.RelayMaskOnE[0],DPump1Bit);
    bitClear(ReefAngel.Relay.RelayMaskOnE[0],DPump2Bit);

    // Reset RelayMaskOff
    bitSet(ReefAngel.Relay.RelayMaskOffE[0],FeederBit);
    bitSet(ReefAngel.Relay.RelayMaskOffE[0],DPump1Bit);
    bitSet(ReefAngel.Relay.RelayMaskOffE[0],DPump1Bit);
  }  
}

Re: Lee's Feature Complete PDE

Posted: Mon Apr 29, 2013 4:05 pm
by lnevo
My new version is finally in production and posted :) Lots of new goodies!

Re: Lee's Feature Complete PDE

Posted: Thu May 02, 2013 12:01 pm
by lnevo
So, talk about narrow misses and being saved by RA... I have a bug since implementing my new float switch configuration. I was using the same portal variable to alert if either switch was activated. The problem I had was that the skimmate collector switch check came after my other float switches and was resetting the value to true... thus no alert.

Luckily my wife txt'd me on the train that the water level in the display was low... luckily it had only been a few minutes. I was thrown off because I usually get those nice txt alerts that something is wrong before that... I turned my return back on and then my skimmer, and boom they went back off. After some peeking around I figured out what had happened. When the return chamber goes too low, the return and skimmer turn off to prevent cavitation of my pump. I re-enabled the pump but left the skimmer off so that I'd have some time before I got home to let things run.

What I saw when poking around was that my water level in my ATO reservoir had not changed in about 20 hours. It was at 92% for that duration... so I knew something was up. My ATO is a gravity feed.... or I thought. I guess it's more of a siphon feed which is controlled by a float valve. It's worked great for 9 months, but I had taken everything apart to get to my electronics this past weekend. Anyway, after resetting the siphon and hooking it back up, everything was back to normal. Skimmer put back on and all crisis averted.

I would have found out eventually thanks to my wife, but with her help and my RA, I was able to get everything going again and no issues. Without the portal charts, remote control relays, and failsafes programmed into my controller, I could have ended up with a burned up pump and a dead sump.

Anyway, I fixed the bug in my variable usage and a few other fixes that I'm not sure I updated. I'll be updating my code post later tonight after I upload it to my RA.

Lee's Feature Complete PDE

Posted: Thu May 09, 2013 8:28 pm
by lnevo

Re: Lee's Feature Complete PDE

Posted: Thu May 09, 2013 8:38 pm
by enigma32
Nice. I wish I had space for fun toys like that :-)

Re: Lee's Feature Complete PDE

Posted: Thu May 30, 2013 7:36 am
by lnevo
Latest version published. Lots of new stuff.

WiFiAlerts
Dosing by Volume
Log Dosing volume to portal
Virtual Outlets

Re: Lee's Feature Complete PDE

Posted: Thu May 30, 2013 3:44 pm
by mudcat1
Lee,
I love your INO code. I have stole and learned so much from it. I really appreciate all of the assistance you have giving me working through getting WifiAlert working.

I am courious why you added the delays
skimmerAlert.SetDelay(3600);
atoAlert.SetDelay(3600);

Did you receive frequent alerts because these are float switches and the delays minimized the number of alerts you received? I am having that problem with the float switch that is submerged in my RO container that is used to alert me when the container is empty. It texts me every few minutes. If I add the SetDelay(3600) will it reduce the text frequency to 1 text message per hour?

Re: Lee's Feature Complete PDE

Posted: Thu May 30, 2013 4:54 pm
by lnevo
mudcat1 wrote:Lee,
I love your INO code. I have stole and learned so much from it. I really appreciate all of the assistance you have giving me working through getting WifiAlert working.

I am courious why you added the delays
skimmerAlert.SetDelay(3600);
atoAlert.SetDelay(3600);

Did you receive frequent alerts because these are float switches and the delays minimized the number of alerts you received? I am having that problem with the float switch that is submerged in my RO container that is used to alert me when the container is empty. It texts me every few minutes. If I add the SetDelay(3600) will it reduce the text frequency to 1 text message per hour?
Exactly, that alert type will only send once an hour.

If skimmer is full, I don't need an alert either every 15 minutes and if the sump is low on water, I can turn off skimmer and run return till I get home or can have my wife open the shutoff valve I probably left closed. It's gravity based... I want to add a check to make sure it's draining at an expected level measured by the water expansion.

Re: Lee's Feature Complete PDE

Posted: Sat Jun 01, 2013 9:56 am
by lnevo
Some more features. Some memory location flags (ie Vacation / AutoFeeder) flags are now represented by virtual outlets. They still need to be in memory but now I can change it in either the memory directly or through the outlet. Dosing routines have been fixed a bit and I can now update dosage volume or time and the result is calculated.

Re: Lee's Feature Complete PDE

Posted: Sun Jun 02, 2013 10:03 pm
by lnevo
Ok. new feature some might be interested. I use the Water Level sensor to monitor my ATO reservoir. I use a gravity feed ATO so it's not something I can easily monitor if something isn't working right. Usually by the time I know of a problem, it's because the return pump has shutdown because the water level dropped too low. So I'm now calculating the ATO reservoir level every 6 hours. If the rate of loss per day is not greater than 15% then send me an alert. I *should* have a rate between 20-25% since my container goes 4-5 days. If a 6 hour period goes by and the rate has not moved by that much then there is a problem.

I also added a counter for the number of times my feeder is activated. Trying to tune an automated feeding schedule and I had an issue previously where it probably ran a few dozen times on me before I caught it. Now I'm paranoid.

Re: Lee's Feature Complete PDE

Posted: Mon Jun 03, 2013 8:43 am
by cjrudy
lnevo wrote:Latest version published. Lots of new stuff.

WiFiAlerts
Dosing by Volume
Log Dosing volume to portal
Virtual Outlets

I'm sure I am missing something simple here but where exactly is your code published ? Cant seem to find it.

Re: Lee's Feature Complete PDE

Posted: Mon Jun 03, 2013 9:02 am
by lnevo
At the beginning of the thread. 2nd post

Re: Lee's Feature Complete PDE

Posted: Mon Jun 03, 2013 9:23 am
by cjrudy
lnevo wrote:At the beginning of the thread. 2nd post
Your just updating that everytime, got it, Thanks

Re: Lee's Feature Complete PDE

Posted: Tue Jun 04, 2013 5:20 am
by lnevo
Just added daily mode change inside my custom rf mode. So now my speed will follow my tide wave form, but each day i should get a different wave form applied on top.