Peristaltic Doser - Doser set amount over 24hr period

So regarding retained variables, according tot he documentation it seems pretty straight forward. Does this look correct? This is all above setup. It verifies fine. The thumb cell hardware hasn’t arrived yet, so I can’t test.

STARTUP(System.enableFeature(FEATURE_RETAINED_MEMORY));
typedef struct {
    int onTime;
    int offTime;
    float totalDose;
    float doseRate; // mL/min
    int connectedPin;
    int calibrationEnd = 90000; // a vaule greater than "now" can ever be
    int numberOfDoses; //number of doses in 24hr period
} Channel;

 void updateChannel(Channel c);
 float now;
 
    retained int onTime;
    retained int offTime;
    retained float totalDose;
    retained float doseRate;
    retained int connectedPin;
    retained int numerOfDoses;
 
char getRelay1[75];
char getRelay2[75];
char getRelay3[75];
char getRelay4[75];

Channel channels[4];

Back to the List!

Doser To Do List

  1. Manual ON/OFF
  2. Calibrate 60 Seconds ON
  3. Refresh Current Settings
  4. setupChannels with Set Button
    Listed in order of string command
    • Channel#
    • time (convert seconds to 24hr TOD)
    • dose rate (determined through calibration = total amount dosed divided by 60)
    • doses over 24hr period
    • total dose per 24hr period
  5. Retained Variables
  6. Optional - In priority
    -variable doses over 24hr period.
    -CSS for cleaner visuals
    -Support for stepper motors
    -HTML formatting for mobile devices
  7. Pumps - Give customer multiple vendors for different grades of pumps.
    Options:
    -High Quality / Low Quality
    -AC & DC
    -Stepper
    -Variable speed
  8. Enclosures
  9. Power Supply
  10. Thorough writeup for “How To” with vendor list and cost breakdown.

@Ric thanks again, got the numberOfDoses working as well as the retained variables. Thumb cell and hardware showed up today, works perfectly!

You helped me setup the calibration function, which works, but I’m thinking it would be nice to have that outside of the string so I can set that separately. In other words, I can run the calibration function, input the calculated doseRate, click a set button and that would be set into the programming. Does that make sense? How hard might that be to implement?

Easy and you already got all the info how to do that. Just get at it.

1 Like

So here's what I did, and it verifies with one exception, I'll mention that at the end.

I removed this from the setupChannel string:

c->doseRate = atof(strtok_r(NULL, "," , &rmdr));

and created this above the setupChannel:

`float doseRate(String cmd) {
    char *rmdr;
    char *stringArgs = (char*)cmd.c_str();
    int index = atoi(strtok_r(stringArgs, ",", &rmdr));
    Channel* c = &channels[index];
    return 1;
}

Now the code verifies fine, I haven't actually tested it yet. However, in order to get the code to verify I had to remove retained float doseRate; otherwise I get this error:

multi-channel_doser.cpp:18:20: error: 'float doseRate' redeclared as different kind of symbol
int numberOfDoses; //number of doses in 24hr period
^
multi-channel_doser.cpp:6:7: error: previous declaration of 'float doseRate(String)'
float doseRate(String cmd);

Can you explain why you

What do the error messages tell you and what could you do about it (apart from blindly removing stuff)?

I’m not sure to be honest…the way I interpret the error is: I’ve declared this once, and I’m declaring it again. So the only thing I can come up with is that in my retained variables, I’m redeclaring it again. But at the same time, I need that info retained in case of a power outtage.

Try looking at the code lines referenced in both error messages (before you blindly removed one of them) and use some of your gray cells.

1 Like

Thanks for the encouragement, I made the following changes and it verified:

Added this to setup:
Particle.function("setDoseRate", setDoseRate);

And changed the string command:

float setDoseRate(String cmd) {
    char *rmdr;
    char *stringArgs = (char*)cmd.c_str();
    int index = atoi(strtok_r(stringArgs, ",", &rmdr));
    Channel* c = &channels[index];
    c->doseRate = atof(rmdr);
    return 1;
}

Yup, that was my point

BTW: Actually your function should be int setDoseRate(String cmd) and not float. Not sure why this works, but it should not and you are not getting a float as return value when calling that Particle.function() anyway.

1 Like

Good catch, thank you.

Yesterday you posted that you got the retained variables to work, but looking at the code you wrote, that can’t be true. How did you test that the retained variables are working? You’ve created a completely new set of variables (the ones marked retained) which are not the same variables that are being set in the setupChannel function; those variables are members of the Channel struct. The only thing that needs to be retained in the channels array.

2 Likes

Hey Ric,

I just followed the documentation on this site. I have the battery attached to vBat. I plugged numbers for the each channel, unplugged the power…came back a few minutes later and plugged it back in, did a particle get string for each channel and all the settings refreshed as I had plugged them in.

Everything verified fine…however, with your recommendation, I removed all the additional variables, tested it again, and it still works fine.

Thank you as always Ric!

Hmm… still don’t see how that could have possibly worked. What do you have marked as retained now?

I’m on my phone so I couldn’t copy the text. But see the screenshot below for what I did.

Ok, that makes sense with the way you tested, but your pumps wouldn’t actually work with that code, because the channels array will be lost when the power goes down. You need to retain the array,

retained Channel channels[4];
1 Like

Good to know! Thanks Ric. I probably would have figured out it didn’t work when I finally tested everything in full.

I have all the hardware and pumps to build it out but I want to wait until I have the web page working properly as well.

Two questions...

  1. When I send a command string to the photon, it immediately turns the relay on and off for a few seconds before returning to a normal state. Any idea why? Here's the log:

channel#: 1, onTime: 10000, totalDose: 1000.000000, numberOfDoses: 10
37868.00
Fired Relay 1
Turned off Relay 1
37873.00
Fired Relay 1
Turned off Relay 1
37878.00
Fired Relay 1
Turned off Relay 1
37883.00
Fired Relay 1
Turned off Relay 1

I then did channels 2,3,4 and the same thing happened..just curious why this is happening.

  1. I noticed that if I pressed the reset button on the photon, none of the settings were retained, is that normal?

Look at the onTime that you are sending, and look at the updateChannel method, and see if you can figure it out.

By "none of the settings", do you mean that the retained variables are not being retained? If so, that is not normal.

Ok will do. I’m not at home any more though.

And regarding the reset button…yes none of the variables are retained when I press the reset button.