Particle.publish() a float variable

Hi,

I'm a beginner, please bear with me.

I'm trying to extend the powershield example "batterymonitor". I want it to publish the battery SOC using particle.publish()

I followed many examples and could not come up with any code that would build. I did plenty of searching and ended up here:

first of all, in that topic, the OP posted code that started with this line:

#include "Particle.h"

Is that necessary, and if so, what does it do? I know I need to include the "PowerShield/PowerShield.h", but not sure what the other one is for.

The topic linked above makes both "double" type variables into particle.variables. I want to take it a step further and use particle.publish(). From what I understand, I need to use sprintf to convert the "double" variables into character strings that can be published. I also tried it using "float" type variables (as the example code in the battery monitor sketch uses float variables)

sprintf(stateOfCharge,"%d",batteryMonitor.getSoC()); Particle.publish("Batterysoc",stateOfCharge);

I can't seem to write the sprintf command in a way that doesn't end up in an error.

Here is another thread with seemingly similar issues, and seems like it never did get resolved.

Basically, my question here is: school me on double/float variables and pushing them out using particle.publish(). Everything in the documentation just pushes strings of text out, which is admittedly very easy and works well. But I could not find any documented examples of pushing out actual meaningful data pulled from a sensor.

Thanks!!

From my knowledge, perhaps you can put your float into a string using the String() function?

Particle.publish("Batterysoc", String(stateOfCharge));

Edit: Had a typo in stateOfCharge, fixed.

2 Likes

Well that kind of worked, but it just pushed out zeros into the log.

Here is my current code, I get this error: power_shield_test.cpp:30:13: error: expected primary-expression before ā€˜.ā€™ token
float cellVoltage = batteryMonitor.getVCell();
^

#include "PowerShield/PowerShield.h"
#include "Particle.h"

PowerShield batteryMonitor;

void setup() {
    
    Serial.begin(9600); 
    // This essentially starts the I2C bus
    batteryMonitor.begin(); 
    // This sets up the fuel gauge
    batteryMonitor.quickStart();
    // Wait for it to settle down
    delay(500);
}

void loop() {
    
    // Read the volatge of the LiPo
    float cellVoltage = batteryMonitor.getVCell();
    // Read the State of Charge of the LiPo
    float stateOfCharge = batteryMonitor.getSoC();
    
    // Publish the state of charge and cell voltages as strings
    particle.publish("Batterysoc", String(stateOfCharge));
    particle.publish("Batteryvolt", String(cellVoltage));
    
    // wait 10 seconds
    delay(10000);

}

#include "Particle.h" is a header file that includes a load of other header files to have access to all the variables, functions and classes you want to commonly use on a Particle device - just like #include "Arduino.h" for Arduinos.
For .INO files this is usually done for you by the preprocessor.

Currently Particle.variable() does not support float, so youā€™d have to use a double variable.

If you want to use a float with sprintf() or String::format(), youā€™d use "%f" instead of "%d" which is meant for int.

But since the printf() family of functions is actually a C thing and not Particle specific youā€™d find tons of info all over the web
e.g.
http://www.cplusplus.com/reference/cstdio/printf/

Your error

error: power_shield_test.cpp:30:13: error: expected primary-expression before '.' token
float cellVoltage = batteryMonitor.getVCell();

A thing with error messages in .INO files is that the preprocessor messes up the code excerpt you get with the error. You need to look at the line number and not the quoted line of code.

In your case it might actually be the lowercase p in particle.publish() - itā€™s supposed to be Particle.publish()

Or it might come from the preprocessor getting confused somehow.
To overcome this, you could either add or remove an empty first line in your code (donā€™t ask why :confused: ), or
add this at the top

#pragma SPARK_NO_PREPROCESSOR
1 Like

YES. It was the capital P.

Thanks so much! I didnā€™t realize things were so case sensitive.

Cheers!!

Just in case anyone comes back here and reads this, I want to finish the thread with ā€œknown workingā€ code.

Seems like Iā€™m not the first person to want to extend this example so hopefully this comes in handy for someone!

I added code to deep sleep the photon at the end of the loop. Be careful with deep sleep. I thought it was in milliseconds, and ended up putting the photon to sleep for a whole day. Deep sleep makes it tricky to flash, because the build IDE will say ā€œsuccessā€, but with your photon asleep, nothing flashes. Safe mode gets you out of that jambā€¦

// This #include statement was automatically added by the Particle IDE.
#include "PowerShield/PowerShield.h"
#include "Particle.h"

PowerShield batteryMonitor;

void setup() {
    
    Serial.begin(9600); 
    // This essentially starts the I2C bus
    batteryMonitor.begin(); 
    // This sets up the fuel gauge
    batteryMonitor.quickStart();
    // Wait for it to settle down
    delay(500);

}

void loop() {
    
        // Read the volatge of the LiPo
    float cellVoltage = batteryMonitor.getVCell();
    // Read the State of Charge of the LiPo
    float stateOfCharge = batteryMonitor.getSoC();
    
    // Publish the state of charge as a string
    Particle.publish("Batterysoc", String(stateOfCharge));
    Particle.publish("Batteryvolt", String(cellVoltage));
    
    // 1 second delay, without it, it seemed to only successfully send the first string before sleeping
    delay(1000);
    
    // deep sleep for 60 seconds. 
    System.sleep(SLEEP_MODE_DEEP, 60);
    
}
2 Likes

awesome find. I couldnā€™t figure out why the publish function was not working till I saw your post and added the 1 sec delay and it worked :slight_smile: