HttpClient to get data from website - and SOS blinking

Thanks again - I’ll think I get that volatile thing now. All variables within my function blink that are altered by an interupt, have to be ‘volatile’. Ok changed that :smile:

Also changed -hopefully all- String an placeholder things to better code :wink: that extra double quote and also the request.path problem should be copy and paste problems… changed them :smile:

At the moment the following code runs without any SOS for about an hour now…

//HTTP Client
            unsigned int nextTime = 0;    
            HttpClient http;
        
            // Headers currently need to be set at init, useful for API keys etc.
            http_header_t headers[] = {
                //  { "Content-Type", "application/json" },
                //  { "Accept" , "application/json" },
                { "Accept" , "*/*"},
                { NULL, NULL } // NOTE: Always terminate headers will NULL
            };
            
            http_request_t request;
            http_response_t response;
        
        
            byte TryNr = 129;                         
            int ReportIntervall = 15;                 
            byte minPulseWidth = 25;                  
            int AnzahlPulseProKwh = 2000;             
            int aktiveNutzung = 975;                  
            int passiveNutzung = 800;                 
        
            char resultstr[128];                      
            unsigned long PulseTime=0;                
            volatile int PulseCount=0;                
            int DifPulseCount=0;                      
            int OldPulseCount=0;                      
            unsigned long PulsePower=0;               
            volatile float kwhCount=0;                
            volatile float kwhCount_startup=0;         
            float kwhCount_overall=0;                 
            int Timestamp=0;                          
            String deviceID=Particle.deviceID();;     
            byte ConnectTry =1;
        
            int day_now = 0;
            int day_old = 0;
            int hour_now = 0;
            int hour_old =0; 
            int PassiveUsageCounter = 0;
            int ActiveUsageMessage;
            int PassiveUsageMessage;
            int UsageMessage;
            
        
        //Funktion blink 
        void blink() {
          if ( (millis() - PulseTime) > minPulseWidth) {
            PulseCount++;                                   
            kwhCount = PulseCount / AnzahlPulseProKwh ;     
            kwhCount_overall = kwhCount + kwhCount_startup; 
          }
        }
        
        //Funktion Setup, die einmalig am Anfang ausgeführt wird
        void setup() {
          pinMode(D3, INPUT);                           
          attachInterrupt(D3, blink, RISING);           
          
          Particle.publish("pmr-photon-1", String::format("1.0) Version: %d - gestarted", TryNr));
          Particle.variable("result", resultstr, STRING); 
          
          //http Client  
          uint32_t msTimeout;
        
          request.hostname = "www.__mywebsite__.xyz";
          request.port = 80;
          request.path = "/Testumgebung/Photon/index2.php?deviceID=" + deviceID + "&requestID=startupkwhlookup"; 
          msTimeout = millis(); // for timeout check
          do { // enter here anyway and try till success but max 60sec
            http.get(request, response, headers);   
            Particle.publish("pmr-photon-1", String::format("2.%d) Version: %d - Response.status: %d Response.body: %s", ConnectTry, TryNr, response.status, (const char*)response.body));
            ConnectTry = ConnectTry+1;
            delay(5000);
          } while(response.status != 200 && millis() - msTimeout < 60000);
        
          if(response.status == 200){
             kwhCount_startup = response.body.toFloat();
             kwhCount_overall = kwhCount + kwhCount_startup;
             Particle.publish("pmr-photon-1", String::format("2.%d) Version: %d - Response.body: %s kwhCount_overall: %.2f", ConnectTry, TryNr, response.status, (const char*)response.body, kwhCount_overall));
          }
        }
        
        //Loop
        void loop() {
          //kwhCount_overall = 0;    // removed
          Timestamp = Time.now();                            
          DifPulseCount = PulseCount - OldPulseCount;        
          PulsePower = DifPulseCount * 30 / ReportIntervall; 
          PulseTime = millis();                              
          OldPulseCount = PulseCount;                        
          
          day_now = Time.day();      //  if (day_now  != day_old )  { /*reset all*/ }
          hour_now = Time.hour();    //  if (hour_now != hour_old ) { /*reset all*/ }
          
          if (DifPulseCount >= aktiveNutzung) {Particle.publish("pmr-photon-1", "NUTZUNG (Aktiv)entdeckt"); ActiveUsageMessage=1;}
          else {ActiveUsageMessage=0;}
          
          if ((DifPulseCount >= passiveNutzung) && (DifPulseCount <= (aktiveNutzung-1) )) {PassiveUsageCounter++;}
          else {PassiveUsageCounter=0; PassiveUsageMessage=0;}
          
          if (PassiveUsageCounter>4) {Particle.publish("pmr-photon-1", "NUTZUNG (passiv) entdeckt: "+PassiveUsageCounter ); PassiveUsageMessage=2;}
          
          UsageMessage = ActiveUsageMessage+PassiveUsageMessage;
          
          //http Client
          request.hostname = "www.__mywebsite__.xyz";
          request.port = 80;
          request.path = String::format("/Testumgebung/Photon/index2.php?deviceID=%s&Timestamp=%d&PulseCount=%d&DifPulseCount=%d&kwhCount=%.2f&kwhCount_overall=%.2f&PulsePower=%d&UsageMessage=%s"
                                     , (const char*)deviceID
                                     , Timestamp 
                                     , PulseCount
                                     , DifPulseCount
                                     , kwhCount 
                                     , kwhCount_overall
                                     , PulsePower
                                     , (const char*)UsageMessage
                                     );                             
                                     
          Particle.publish("pmr-photon-1", String::format("3.0) Version: %d - kwh: %.2f - kwh_overall: %.2f - Difpulses: %d", TryNr, kwhCount, kwhCount_overall, DifPulseCount));
          sprintf(resultstr, "{\"data1\":%d,\"data2\":%d,\"data3\":%d,\"data4\":%d,\"data5\":%.2f,\"data6\":%d,\"data7\":%d}", Timestamp, PulseCount, DifPulseCount, ReportIntervall, kwhCount, PulsePower, UsageMessage);
         
          delay(ReportIntervall * 60 * 1000); //Publish every (10Sec = 10000, 60sec = 60000)
          
          //if (day_now != day_old) { kwhCount_overall=kwhCount_overall+kwhCount; EEPROM.put(0, kwhCount_overall); Particle.publish("power-meter-reporter", "EEPROM gespeichert:"+kwhCount_overall);}
          //day_old = day_now;
    } 

But there is one thing I don’t understand yet - maybe you can give me a hint again :wink:

The photon is going on- and offline in short periods…

A second photon is doing its work about 3meters away…could that be a problem?

That looks like a common problem when code is not dropping out of loop() or calling Particle.process() often enough to keep the cloud connection serviced.

The easiest way out of this is by adding SYSTEM_THREAD(ENABLED) at the top of your code.
But the cleaner solution would be to allow for cloud house keeping in your code.

And I still dislike sausage code lines like this :stuck_out_tongue_closed_eyes:

      if (DifPulseCount >= aktiveNutzung) {Particle.publish("pmr-photon-1", "NUTZUNG (Aktiv)entdeckt"); ActiveUsageMessage=1;}
      else {ActiveUsageMessage=0;}
1 Like

Ok, chaged that too - looks now like this:

if (DifPulseCount >= aktiveNutzung) {
Particle.publish("pmr-photon-1", "NUTZUNG (Aktiv)entdeckt"); ActiveUsageMessage=1;
}
else {
ActiveUsageMessage=0;
}

if ((DifPulseCount >= passiveNutzung) && (DifPulseCount <= (aktiveNutzung-1) )) {
PassiveUsageCounter++;
}
else {
PassiveUsageCounter=0; PassiveUsageMessage=0;
}

if (PassiveUsageCounter>4) {
Particle.publish("pmr-photon-1", "NUTZUNG (passiv) entdeckt: "+PassiveUsageCounter );
PassiveUsageMessage=2;
}

I added SYSTEM_THREAD(ENABLED) add top after the include.. but I didn't understand how "to allow for cloud house keeping"

And As I could see, that doesn't help:

and another thing I added - does not work as thought... (maybe again a placeholder problem) at the end I added a new variable at this line:

  Particle.publish("pmr-photon-1", String::format("3.%lu) Version: %d - kwh: %.2f - kwh_overall: %.2f - Difpulses: %d", ReportCounter, TryNr, kwhCount, kwhCount_overall, DifPulseCount));
  ReportCounter++;  

ReportCounter was declared as unsigned long ReportCounter = 1;
But it seems to count only from 0 to 9 and then again from 0 to 9....
What did I wrong?

That would be because then the cloud stuff would run in a dedicated thread that would not be slowed down by the application code that's running in another thread.

To say anything about ReportCounter it would be required to see the whole of the new code.
There could be multiple things.

The issue about the dis-/reconnect is odd tho'
Could you check if this happens with that device but other simple code too?

This is the code

    // This #include statement was automatically added by the Particle IDE.
    #include "HttpClient/HttpClient.h"
    
    SYSTEM_THREAD(ENABLED)
    
    
    //HTTP Client
        unsigned int nextTime = 0;    // Next time to contact the server
        HttpClient http;
    
        // Headers currently need to be set at init, useful for API keys etc.
        http_header_t headers[] = {
            //  { "Content-Type", "application/json" },
            //  { "Accept" , "application/json" },
            { "Accept" , "*/*"},
            { NULL, NULL } // NOTE: Always terminate headers will NULL
        };
        
        http_request_t request;
        http_response_t response;
    
    
        byte TryNr = 130;                         
        int ReportIntervall = 15;                 
        byte minPulseWidth = 25;                  
        int AnzahlPulseProKwh = 2000;             
        int aktiveNutzung = 975;                 
        int passiveNutzung = 800;                 
    
        char resultstr[128];                      
        unsigned long PulseTime=0;                
        volatile int PulseCount=0;                
        int DifPulseCount=0;                      
        int OldPulseCount=0;                      
        unsigned long PulsePower=0;               
        volatile float kwhCount=0;                
        volatile float kwhCount_startup=0;        
        float kwhCount_overall=0;                 
        int Timestamp=0;                          
        String deviceID=Particle.deviceID();;     
        byte ConnectTry =1;                       
        unsigned long ReportCounter = 1;          
    
        int day_now = 0;
        int day_old = 0;
        int hour_now = 0;
        int hour_old =0; 
        int PassiveUsageCounter = 0;
        int ActiveUsageMessage;
        int PassiveUsageMessage;
        int UsageMessage;
        
    void blink() {
      if ( (millis() - PulseTime) > minPulseWidth) {
        PulseCount++;                                   
        kwhCount = PulseCount / AnzahlPulseProKwh ;     
        kwhCount_overall = kwhCount + kwhCount_startup; 
      }
    }
    
    void setup() {
      pinMode(D3, INPUT);                           
      attachInterrupt(D3, blink, RISING);           
      
      Particle.publish("pmr-photon-1", String::format("1.0) Version: %d - gestarted", TryNr)); 
      Particle.variable("result", resultstr, STRING); //Versuch1
      
      //http Client
      uint32_t msTimeout;
    
      request.hostname = "www.website.xzy";
      request.port = 80;
      request.path = "/Testumgebung/Photon/index2.php?deviceID=" + deviceID + "&requestID=startupkwhlookup"; 
    
      msTimeout = millis(); // for timeout check
    
      do { // enter here anyway and try till success but max 60sec
        http.get(request, response, headers);   
        Particle.publish("pmr-photon-1", String::format("2.%d) Version: %d - Response.status: %d Response.body: %s", ConnectTry, TryNr, response.status, (const char*)response.body));
        ConnectTry = ConnectTry+1;
        delay(5000);
      } while(response.status != 200 && millis() - msTimeout < 60000);
    
      if(response.status == 200){
         kwhCount_startup = response.body.toFloat();
         kwhCount_overall = kwhCount + kwhCount_startup;
         Particle.publish("pmr-photon-1", String::format("2.%d) Version: %d - Response.body: %s kwhCount_overall: %.3f", ConnectTry, TryNr, response.status, (const char*)response.body, kwhCount_overall));
      }
    }
    
    //Loop
    void loop() {
      //kwhCount_overall = 0
      Timestamp = Time.now();                            
      DifPulseCount = PulseCount - OldPulseCount;        
      PulsePower = DifPulseCount * 30 / ReportIntervall; 
      PulseTime = millis();                              
      OldPulseCount = PulseCount;                        
      
      //Statistik-Dinge
      //Ermittlung des aktuellen Tages und Stunde
      day_now = Time.day();      //  if (day_now  != day_old )  { /*reset all*/ }
      hour_now = Time.hour();    //  if (hour_now != hour_old ) { /*reset all*/ }
      
      if (DifPulseCount >= aktiveNutzung) {
         Particle.publish("pmr-photon-1", "NUTZUNG (Aktiv)entdeckt"); ActiveUsageMessage=1;
      }
      else {
         ActiveUsageMessage=0;
      }
      
      if ((DifPulseCount >= passiveNutzung) && (DifPulseCount <= (aktiveNutzung-1) )) {
         PassiveUsageCounter++;
      }
      else {
         PassiveUsageCounter=0; PassiveUsageMessage=0;
      }
      
      if (PassiveUsageCounter>4) {
         Particle.publish("pmr-photon-1", "NUTZUNG (passiv) entdeckt: "+PassiveUsageCounter ); 
         PassiveUsageMessage=2;
      }
      
      UsageMessage = ActiveUsageMessage+PassiveUsageMessage;
      
      //http Client
      request.hostname = "www.website.xyz";
      request.port = 80;
    
      request.path = String::format("/Testumgebung/Photon/index2.php?deviceID=%s&Timestamp=%d&ReportCounter=%lu&PulseCount=%d&DifPulseCount=%d&kwhCount=%.2f&kwhCount_overall=%.2f&PulsePower=%d&UsageMessage=%s"
                                 , (const char*)deviceID
                                 , Timestamp 
                                 , ReportCounter
                                 , PulseCount
                                 , DifPulseCount
                                 , kwhCount 
                                 , kwhCount_overall
                                 , PulsePower
                                 , (const char*)UsageMessage
                                 );                             
      http.get(request, response, headers);                                 
      Particle.publish("pmr-photon-1", String::format("3.%lu) Version: %d - kwh: %.2f - kwh_overall: %.2f - Difpulses: %d", ReportCounter, TryNr, kwhCount, kwhCount_overall, DifPulseCount));
      ReportCounter++;  
      sprintf(resultstr, "{\"data1\":%d,\"data2\":%d,\"data3\":%d,\"data4\":%d,\"data5\":%.2f,\"data6\":%d,\"data7\":%d}", Timestamp, PulseCount, DifPulseCount, ReportIntervall, kwhCount, PulsePower, UsageMessage);
    
      delay(ReportIntervall * 60 * 1000); //Publish every (10Sec = 10000, 60sec = 60000)
      
      //if (day_now != day_old) { kwhCount_overall=kwhCount_overall+kwhCount; EEPROM.put(0, kwhCount_overall); Particle.publish("power-meter-reporter", "EEPROM gespeichert:"+kwhCount_overall);}
      //day_old = day_now;
    
    }

I will check the photon
with something simple…

is that too simple ? (one of my first tries)

// Blink an LED

int led1 = D7; 

void setup() {

  pinMode(led1, OUTPUT);
  Particle.publish("TimeSync","Rebooted",PRIVATE);
  // Unser Zeitzone
  Time.zone(+2);
}

void loop() {
  //Timesync immer zur vollen Stunde
  if ( Time.minute() == 0  && Time.second() == 0 ) {
  Particle.syncTime();
  Particle.publish("TimeSync",Time.timeStr(),PRIVATE); 
  }

  if ( Time.minute() == 00  && Time.second() == 00 ) {
  Particle.syncTime();
  Particle.publish("TimeSync00",Time.timeStr(),PRIVATE); 
  }
  
  // To blink the LED, first we'll turn it on...
  digitalWrite(led1, HIGH);
  
  // We'll leave it on for 1 second...
  delay(1000); 

  // Then we'll turn it off...
  digitalWrite(led1, LOW);

  // Wait 1 second...
  delay(1000); 
  //Particle.publish("TimeSync","done",PRIVATE);

  // And repeat!
}

Runs and has no connection loss till 15 Min…
Then the first connection loss happened…

This won't cure any of your issues, but I'll just repeat what I said earlier

Try this instead

Particle.publish("pmr-photon-1", String::format("NUTZUNG (passiv) entdeckt: %d" ,PassiveUsageCounter) );

I have surely removed that +PassiveUsageCounter earlier…but I’ll do it again… sorry…
changed to your example…

I flashed it again, and it comes to Particle.publish("pmr-photon-1", String::format("3.%lu) Version: %d - kwh: and that get published. About 170 sec. later the connection gets lost/reconnected… and so on

Without a server and comparable sensor data I can’t quite test this, but I can’t make out any reason for this behaviour :confused:

The only thing I could imagine is that you’re running into the Particle.publish() rate limit due to the constellation of your variables.
Try to have only one Particle.publish() statement and only build a combined message string. This way controling the limit will be easier.

1 Like

Dear ScruffR,

first of all thanks alot for your help ! I will try and test out that hint with the Particle.publish() rate normally I only have one publish every 15 minutes - only in the startup phase it is a bit higher.

Can other devices near to the photon be a problem? Mobile phones / wireless phones / pc’s / display…?

I’ll send you the server-adress as private message, and at theis time I use the photon without other sensor (it is not connected to anything else than power/wifi.

1 Like

May I bother you again?
The two variables kwhCount and kwhCout_overall are reported as 12345.00 everytime… the .00 is my problem the is nothing behind the dot… both are float…

   void blink() {
      if ( (millis() - PulseTime) > minPulseWidth) {
        PulseCount++;                                   
        kwhCount = PulseCount / AnzahlPulseProKwh ;     
        kwhCount_overall = kwhCount + kwhCount_startup; 
      }
    }

The problem here is that numerator and denominator of your division are both int so the result will be int too and that will be assigned to float.
In order to get a floating point result you’d need to cast at least one of them to (float) or (double).

I’d always go for double so try this

void blink() {
  if ( (millis() - PulseTime) > minPulseWidth) {
    PulseCount++;                                   
    kwhCount = (double)PulseCount / (double)AnzahlPulseProKwh;     
    kwhCount_overall = kwhCount + kwhCount_startup; 
  }
}

or just declare double AnzahlPulseProKwh = 2000.0;

1 Like

Thanks again, I didn’t not know that it is not enough to declare kwhCount as a float.
So I tried that: double AnzahlPulseProKwh - perfect

1 Like