Particle Variable always return 0

Hi,

I am using Particle Photon and my setup has these lines:

void setup() 
{
    Particle.variable("Hour",  time_hour);
    Particle.variable("Minute", time_min);
    Particle.variable("Second", time_sec);
    Particle.variable("Intensity", backupVariables.intensity);
    Particle.variable("Time Format", backupVariables.timeFormat);
    Particle.variable("Time Mismatch", temp_number);
    Particle.function("Watch Mode", watchMode);
    Particle.function("Display Intensity", displayCtrl);
    
   <Couple of other lines which are doing things as expected>
}

The problem I see is that when I check the values of variables in the console.particle.io or in the Android app it always comes as ‘0’. Whereas the same variables are visible correctly in the display. However, the exposed particle functions are working as expected.

It used to work before and suddenly stopped working. Is there and limitation of how many variable or how many time I can update these variables?

Thanks,
Rahul

@madjapne, one obvious issue is the use of spaces in your variable names. As per docs:

Note: Only use letters, numbers, underscores and dashes in variable names. Spaces and special characters may be escaped by different tools and libraries causing unexpected results.

The same applies to Particle.functions. Revisit your variable and function names and see if that helps.

2 Likes

Hi @peekay123,

Thanks for your inputs. I tried fixing the variable name but it’s still the same.

You can have a look at this: https://go.particle.io/shared_apps/5ee23b0cefb25a0016f28e4c

Thanks,
Rahul

There are some changes I’d suggest
e.g. this

    switch (timeMin)
    {
        case 0:
            display.println("00");
            break;
        case 1:
            display.println("01");
            break;
        case 2:
            display.println("02");
            break;
            case 3:
            display.println("03");
            break;
        case 4:
            display.println("04");
            break;
        case 5:
            display.println("05");
            break;
        case 6:
            display.println("06");
            break;
        case 7:
            display.println("07");
            break;
        case 8:
            display.println("08");
            break;
        case 9:
            display.println("09"); 
            break;
        default:
            display.println(timeMin);
            break;
    }

can simply condensed into this

  char str[8]
  snprintf(str, sizeof(str), "%02d", timeMin);
  display.println(str);

but even more simple would be using a string that comprises of both timeHour and timeMin like this

  char str[8]
  snprintf(str, sizeof(str), "%02d:%02d", timeHour, timeMin);
  display.println(str);

and to go even further we can even drop timeHour and timeMin entirely this way

  display.println(Time.format("%H:%M"));

You may want to use int instead of uint8_t for your exposed variables.

Also you don’t want to have multiple calls like this

    timeHour = Time.hour();
    timeMin = Time.minute();
    timeSec = Time.second();

as each consecutive request may happen after a flip of a second potentially causing inconsistent components.
e.g.

    timeHour = Time.hour();  // at 05:59:59 -> timeHour  = 5
    timeMin = Time.minute(); // at 06:00:00 -> timeMin = 0
    timeSec = Time.second(); // at 06:00:00 -> timeSec = 0

better would be this

    int now = Time.now(); 
    timeHour = Time.hour(now);
    timeMin = Time.minute(now);
    timeSec = Time.second(now);

Furthermore why are you advancing your time variables “manually” and not just sticking with re-requesting the values from the Time object?
The Software Timer is potentially less accurate than the RTC on the device.

3 Likes

@madjapne, besides @ScruffR’s most excellent comments, the line if(backupVariables.timeFormat > 1) in setup won’t quite work the way you think. Since timeFormat is declared as an int, for a blank/unwritten value in EEPROM, the value will be 0xFFFF or -1 which is not > 1. This will cause your default values NOT to be setup and written to EEPROM.

3 Likes

Hi
@ScruffR & @peekay123, thanks for your great comments.
@ScruffR the way you suggested me to modify the big switch case statement worked and I have implemented the same. However, I was printing a colon ‘:’ between the two numbers and hence printed the minutes and hours in separate statements.

Regarding time, thanks for letting me know about the new method. The reason I wasn’t requesting the time from the Time object was that I wasn’t sure how much data would it consume if I let it run freely, therefore I used the internal timer and use this logic to sync the time once every minute:

    /* When second is '30' that is midway the minute then update the time if 
    internal time is off by more than 2 seconds. We are doing this here as if 
    we do when second is '0' then there might be cases where the used will see 
    the time going back by a minute if the internal time is ahead of actual time.*/
    if(timeSec == 30)
    {
        tempTimeSec = Time.second();
        if((tempTimeSec > 32) || (tempTimeSec < 28))
        {
            getTime(backupVariable);
        }
    }

Please let me know if I am wrong.

@peekay123 thanks for your suggestion about the potential error, I have modified the code like this (expected value is ‘1’ or ‘0’:

    /* if the value from the EEPROM is unexpected then update the EEPROM */
    if((backupVariable != 1) && (backupVariable != 0))
    {
        backupVariable = 0;
        EEPROM.put(EEPROM_ADDR, backupVariable);
    }

My final code is available @ https://go.particle.io/shared_apps/5ee3af50441e4a000c1ec53a

Thank you both for your inputs.

It doesn't use any data from the cloud as long your code merely requests the time from the free running RTC. Only active cloud syncs (Particle.syncTime() or automatically when the device reconnects after connection loss) would actually reach out to the cloud to correct the RTC.
So no need for your own free running timer and that seconds check.
BTW, the Photon has an unlimited data quota with the Particle cloud.

I realised that you printed the colon in a different font size after I suggested the above, but if that is not absolutely required, I'd just have the colon as part of the string to print (as in my suggested code).

In order to check validity of your EEPROM data I usually use a magic number to check for and in "critical" use-cases also a hash for the entire structure.

1 Like

Hi @ScruffR,

Thanks for your inputs, it really helped me to reduce the code length and fix some of the other issues.

I'll close this case for now.

Once again I would like to thank you and for helping me out.

Thanks,
Rahul

1 Like

This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.