Lee's Feature Complete PDE

Share you PDE file with our community
User avatar
lnevo
Posts: 5430
Joined: Fri Jul 20, 2012 9:42 am

Re: Lee's Feature Complete PDE

Post by lnevo »

And what will trigger the refresh if I don't switch screens?
User avatar
lnevo
Posts: 5430
Joined: Fri Jul 20, 2012 9:42 am

Re: Lee's Feature Complete PDE

Post by lnevo »

Nevermind..
Piper
Posts: 296
Joined: Fri Jul 20, 2012 7:13 am
Location: Oakley, CA

Re: Lee's Feature Complete PDE

Post by Piper »

lnevo wrote:Nevermind..
You can't leave me hanging like that! What was the problem and fix?
User avatar
lnevo
Posts: 5430
Joined: Fri Jul 20, 2012 9:42 am

Lee's Feature Complete PDE

Post by lnevo »

I still am drawing the graph on DrawCustomGraph()
User avatar
lnevo
Posts: 5430
Joined: Fri Jul 20, 2012 9:42 am

Lee's Feature Complete PDE

Post by lnevo »

I currently have screen 0 as my graph, screen 1 is ato and rf status, screen 3 is sun/moon info :)
Piper
Posts: 296
Joined: Fri Jul 20, 2012 7:13 am
Location: Oakley, CA

Re: Lee's Feature Complete PDE

Post by Piper »

Very cool. I'll let you get it all sorted and out check back later today. Then I'll copy your code :)
User avatar
lnevo
Posts: 5430
Joined: Fri Jul 20, 2012 9:42 am

Lee's Feature Complete PDE

Post by lnevo »

Its posted and working :)
User avatar
lnevo
Posts: 5430
Joined: Fri Jul 20, 2012 9:42 am

Re: Lee's Feature Complete PDE

Post by lnevo »

So I did a lot of cleaning up :) I haven't yet compiled or uploaded anything so for now this post is just a preview of what's to come.

First off, I cleaned up a lot of the functions. The only global variables I have are basically the vortech varialbes and my Tide and SunLocation classes. The big benefit is that most of my functions are 100% self-contained and can be copied pretty easily. My setup() custom code is now like 3 lines and my loop() is also extremely clean as everything has been moved to subroutines.

I have also moved a lot of stuff into memory locations. I really need to make this standard practice so that nothing needs to be hard-coded. To support that, I wrote my own init_memory function so that I could re-arrange the variables, make sure new ones are initialized properly, etc. I'm using memory location 199 as the flag bit to trigger the memory reset. I only run this in setup() so you'll have to flip the flag and reboot the controller. Or flip the flag and upload new code. I also changed a lot of the memory locations and variables to use true/false instead of 1=on 0=off, since it cleans up a lot of code. One of the reasons I needed the init_memory function :)

So, what else is new in the coming version? I've added a few things

1) CalibrateDosingPumps() - I wrote this function as I'm about to finally enable my dosers. You flip the memory bit to true and it will turn on both pumps for 10 minutes. Then you can measure how much fluid was pumped and set your pumps accordingly. It will get used once in a blue moon, but hopefully someone will find it useful.

2) runSwabbie() - This function will run my swabbie (using the DosingPumpRepeat() function but I also added a "manual" mode. If you override the default status of the swabbie port, it will clear the override and run the swabbie for 1 minute. Will be fun to demo for people :)

3) runFeeder() - This uses a memory location as a trigger, but basically will StartFeedingMode() and then wait for a specified delay (stored in memory) and then "press" the auto-feeder button for 5 seconds. I have integrated it into my vacation() mode by flipping on the memory location at 7pm when vacation is enabled. I may change the behavior later on after I get my auto-feeder and mod it and I decide I want it running daily :)

That's it for now. I'll probably have some time this weekend to debug the code (written with Textastic on my iPad) and get it uploaded to the controller. My swabbie is going to be a while and I'm waiting for a bracket for the dosing pumps so still some hardware pending :)
rimai
Posts: 12881
Joined: Fri Mar 18, 2011 6:47 pm

Re: Lee's Feature Complete PDE

Post by rimai »

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.
Roberto.
User avatar
lnevo
Posts: 5430
Joined: Fri Jul 20, 2012 9:42 am

Lee's Feature Complete PDE

Post by lnevo »

Sounds good :) I'm all about saving writes to memory locations :) i should consolidate some though...its kind of a waste of a byte when you only need a bit...anyway off-track :)

What i wanted to share was however we call the function or memory. It's still a http call. I've made myself a bit of a "control panel" html page with all the links I use as shortcuts. Basically a glorified bookmark page. This way I never need to remember what bit to flip :)
User avatar
lnevo
Posts: 5430
Joined: Fri Jul 20, 2012 9:42 am

Re: Lee's Feature Complete PDE

Post by lnevo »

Ok, the code compiles. Only a few syntax errors :) Anyway, it's posted in the 2nd post. Enjoy
Piper
Posts: 296
Joined: Fri Jul 20, 2012 7:13 am
Location: Oakley, CA

Re: Lee's Feature Complete PDE

Post 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 :)
User avatar
lnevo
Posts: 5430
Joined: Fri Jul 20, 2012 9:42 am

Lee's Feature Complete PDE

Post 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?
rimai
Posts: 12881
Joined: Fri Mar 18, 2011 6:47 pm

Re: Lee's Feature Complete PDE

Post by rimai »

Can you elaborate more?
Roberto.
User avatar
lnevo
Posts: 5430
Joined: Fri Jul 20, 2012 9:42 am

Lee's Feature Complete PDE

Post by lnevo »

I'll see if I can write up some demo code...
User avatar
lnevo
Posts: 5430
Joined: Fri Jul 20, 2012 9:42 am

Lee's Feature Complete PDE

Post 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...
User avatar
lnevo
Posts: 5430
Joined: Fri Jul 20, 2012 9:42 am

Lee's Feature Complete PDE

Post 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
User avatar
jsclownfish
Posts: 378
Joined: Mon Oct 24, 2011 7:52 pm
Location: Saint Louis

Lee's Feature Complete PDE

Post 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
rimai
Posts: 12881
Joined: Fri Mar 18, 2011 6:47 pm

Re: Lee's Feature Complete PDE

Post 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.
Roberto.
User avatar
lnevo
Posts: 5430
Joined: Fri Jul 20, 2012 9:42 am

Lee's Feature Complete PDE

Post 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 :)
User avatar
lnevo
Posts: 5430
Joined: Fri Jul 20, 2012 9:42 am

Lee's Feature Complete PDE

Post 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.
User avatar
lnevo
Posts: 5430
Joined: Fri Jul 20, 2012 9:42 am

Lee's Feature Complete PDE

Post 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.
rimai
Posts: 12881
Joined: Fri Mar 18, 2011 6:47 pm

Re: Lee's Feature Complete PDE

Post 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.
Roberto.
User avatar
lnevo
Posts: 5430
Joined: Fri Jul 20, 2012 9:42 am

Lee's Feature Complete PDE

Post 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.
binder
Posts: 2871
Joined: Fri Mar 18, 2011 6:20 pm
Location: Illinois
Contact:

Re: Lee's Feature Complete PDE

Post 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.
User avatar
lnevo
Posts: 5430
Joined: Fri Jul 20, 2012 9:42 am

Lee's Feature Complete PDE

Post 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);
  }  
}
User avatar
lnevo
Posts: 5430
Joined: Fri Jul 20, 2012 9:42 am

Re: Lee's Feature Complete PDE

Post by lnevo »

My new version is finally in production and posted :) Lots of new goodies!
User avatar
lnevo
Posts: 5430
Joined: Fri Jul 20, 2012 9:42 am

Re: Lee's Feature Complete PDE

Post 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.
User avatar
lnevo
Posts: 5430
Joined: Fri Jul 20, 2012 9:42 am

Lee's Feature Complete PDE

Post by lnevo »

Post Reply