Counting Problems

Note that there is evidence of a regression in 0.4.6 in this area, so if possible, build against 0.4.5.

Noted, hence the "I’ll try to" :wink:

1 Like

The code compiles with 0.4.6 but not with 0.4.5. Here is the code:

#include "HttpClient/HttpClient.h"
#include "application.h"

SYSTEM_MODE(SEMI_AUTOMATIC);
SYSTEM_THREAD(ENABLED);
STARTUP(System.enableFeature(FEATURE_RETAINED_MEMORY));

//Settings
String DeviceID = System.deviceID();
String TargetHostName = "yyy.yyy.com";


int val = 0;
int inPin  = D1;
int outPin = D7;
int PreviousMinute = -1;
int ThisMinute = -1;
bool SensorState = false;
bool PreviousSensorState = false;
retained int PulseCount = 0;
retained int TotalPulseCount = 0;
retained bool WentToDeepSleep = false;
String PacketData = "";
String DeviceTime = "";
String PreviousResponseBody = "";
int ResponseStatus = 0;
bool success;
unsigned long PreviousTime = millis();

uint8_t retry_count = 0;
unsigned long old_time = millis();
unsigned long PulsePeriod = 0;
double CurrentPower = 0;
double incPower = 0;
double AveragePower = 0;
int TimeStamp;

unsigned long button_time = 0;  
unsigned long last_button_time = 0;
unsigned long PreviousPowerPublish = millis();

HttpClient http;
http_header_t headers[] = {
    { "Accept" , "*/*"},
    { NULL, NULL }
};
http_request_t request;
http_response_t response;

void setup() {
    delay(5000);
    if(!WentToDeepSleep) {
        WentToDeepSleep = true;
        System.sleep(SLEEP_MODE_DEEP,10); //go to deep sleep at least once so that retained variables work
    }    
    
    pinMode(outPin, OUTPUT);
    pinMode(inPin,  INPUT);
    
    attachInterrupt(inPin, IncrementPulseCount, FALLING);

    Time.zone(2);
    WiFi.on();
}

void loop() {
    if(millis() - old_time >= 2000){        
        if(retry_count < 10){
            if(!WiFi.ready()){
                WiFi.connect();
                retry_count++;
            }
            else if (!Particle.connected()){
                Particle.connect();
                retry_count++;
            }
        }
        else{
            WiFi.off();
            retry_count = 0;
            WiFi.on();
        }
        old_time = millis();
    }    

    //Transmit Pulsecount at the turn of the minute//
    ThisMinute = Time.minute();
    if(ThisMinute != PreviousMinute) {
        TimeStamp = Time.now();
        DeviceTime = URLEncode(Time.format(TimeStamp, "%y%m%d%H%M%S"));
        

        //***Using HTTP Client***
        PacketData = DeviceID + ";" + String(PulseCount) + ";" + DeviceTime + ";" + String(TotalPulseCount) + ";" + String(AveragePower);
        request.hostname = TargetHostName;
        request.port = 80;
        request.path = "/spark_receiver.ashx?PD=" + PacketData;
        http.get(request, response, headers);
        ResponseStatus = response.status;
        /////////////////////////

        if((response.body != PreviousResponseBody) && (response.body.substring(0,2) == "OK") && (ResponseStatus == 200)) {
            //only reset if connection was successful
            if(PulseCount > 0) {
                AveragePower = (incPower / PulseCount);
            }
            PulseCount = 0;
            incPower = 0;
            PreviousResponseBody = response.body;
            success = Particle.publish("TotalPulseCount", String(TotalPulseCount) , 60, PRIVATE);
            success = Particle.publish("AveragePower", String(AveragePower) , 60, PRIVATE);
        }
        else {
            success = Particle.publish("Upload Failed");
        }
        PreviousMinute = ThisMinute;
    }
    /////////////////////////////////////////////////
}

void IncrementPulseCount() {
    button_time = millis();
    //check to see if increment() was called in the last 250 milliseconds
    if (button_time - last_button_time > 250) {
        PulseCount++;
        TotalPulseCount++;
        if(TotalPulseCount >= 999999) {
            TotalPulseCount = 0; 
        }
        PulsePeriod = millis() - PreviousTime;
        CurrentPower = (3600000 / (double)PulsePeriod);
        incPower += CurrentPower;
        PreviousTime = button_time;
        last_button_time = button_time;
    }
}

String URLEncode(const char* msg){
    const char *hex = "0123456789abcdef";
    String encodedMsg = "";

    while (*msg!='\0'){
        if( ('a' <= *msg && *msg <= 'z')
                || ('A' <= *msg && *msg <= 'Z')
                || ('0' <= *msg && *msg <= '9') ) {
            encodedMsg += *msg;
        } else {
            encodedMsg += '%';
            encodedMsg += hex[*msg >> 4];
            encodedMsg += hex[*msg & 15];
        }
        msg++;
    }
    return encodedMsg;
}

The problem with this code is that it goes offline regularly once every two minutes:

FWIW, I was able to run this code successfully through wifi interruptions, sans all the retained memory stuff, and built against the latest develop branch of system firmware (which fixes the issues @AndyW mentioned). The counts published after a reconnect indicated that counting was happening even while the device was disconnected. It’s likely that the SOSes plaguing reconnection attempts in 0.4.6 were causing your variables to reset, and I’m not sure if retained memory would help with resets like that.

2 Likes

Can you be more clear on that? Which version did you use and what program did you use? I am asking so that I can make the exact same test and make confirm whether the problem is in my code or my device. Thanks!

It appears to me (I could be wrong) that SYSTEM_THREAD(ENABLED) and the HttpClient Library are not compatible. Unless I disable SYSTEM_THREAD, the device starts going offline and online again every two minutes without a miss. This only appears to happen when I am using the HttpClient library to upload readings to my API. Can anyone confirm that?

If you’re able to build locally, we have a fix for that in https://github.com/spark/firmware/pull/664

Sorry, I was building against commit 96c7f734af1e346ac006e3905469d990d5e86aaa (which won’t help much if you’re not building locally :frowning: ) and the program is in this gist:

All I did was take your code and remove the deep sleep and retained memory stuff.

1 Like