Trouble with Particle.variable() and Particle.publish

Ok nothing shows up in Console I think I have tried everything

// This #include statement was automatically added by the Particle IDE.
#include <MPU6050.h>

// This #include statement was automatically added by the Particle IDE.
#include <DS18B20.h>
#include <math.h>


int ledPin = D7;

// MPU variables:
MPU6050 accelgyro;
int16_t ax, ay, az;
int16_t gx, gy, gz;

const int      MAXRETRY          = 4;
const uint32_t msSAMPLE_INTERVAL = 2500;
const uint32_t msMETRIC_PUBLISH  = 30000;

DS18B20  ds18b20(D3, true); //Sets Pin D2 for Water Temp Sensor and 
                            // this is the only sensor on bus
char     szInfo[64];
double   celsius;
double   fahrenheit;
int Yaxis;
uint32_t msLastMetric;
uint32_t msLastSample;



void setup() {
    pinMode(ledPin, OUTPUT);

    Wire.begin();
    Serial.begin(9600);

    // The following line will wait until you connect to the Spark.io using serial and hit enter. This gives
    // you enough time to start capturing the data when you are ready instead of just spewing data to the UART.
    //
    // So, open a serial connection using something like:
    // screen /dev/tty.usbmodem1411 9600
    while(!Serial.available()) SPARK_WLAN_Loop();
    
    Serial.println("Initializing I2C devices...");
    accelgyro.initialize();

    // Cerify the connection:
    Serial.println("Testing device connections...");
    Serial.println(accelgyro.testConnection() ? "MPU6050 connection successful" : "MPU6050 connection failed");
    
   
    Particle.variable("sg1",&ay );
    Particle.variable("tempferm", &fahrenheit, DOUBLE);
   
    
}

void loop() {
    // read raw accel/gyro measurements from device
    accelgyro.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);
   
   
    
   
    getTemp();
  
    publishData();
 
    delay(3000);
}

void publishData(){
  sprintf(szInfo, "%2.2f", fahrenheit);
  Particle.publish("dsTmp", szInfo,PRIVATE);
  Particle.publish("angle",ay);
  Particle.publish("temp",fahrenheit);
  
  
   Serial.print("a/g:\t");
    Serial.print(ax); Serial.print("\t");
    Serial.print(ay); Serial.print("\t");
    Serial.print(az); Serial.print("\t");
    Serial.print(gx); Serial.print("\t");
    Serial.print(gy); Serial.print("\t");
    Serial.println(gz);
    
    Serial.println(fahrenheit);
}

void getTemp(){
  float _temp;
  int   i = 0;

  do {
    _temp = ds18b20.getTemperature();
  } while (!ds18b20.crcCheck() && MAXRETRY > i++);

  if (i < MAXRETRY) {
    celsius = _temp;
    fahrenheit = ds18b20.convertToFahrenheit(_temp);
   
  }
  else {
    celsius = fahrenheit = NAN;
    Serial.println("Invalid reading");
  }
  msLastSample = millis();
}

BTW all the serial communications come thru

thanks steve

If that's the case, then there's nothing more we can do. Unless you haven't tried everything, in which case we could make suggestions, but since we don't know what you've actually tried, we might just tell you things you already tried. See the pattern ;)?

You're having trouble with Particle variable and publish? Nothing shows up in the console?

Long story short:
What have you tried so far?
What are you expecting it to do?
What doesn't it do?
What does it do?

Also, try placing those variables at the start of the setup.

@murmsk, one thing for sure is you need to read the documentation on Particle.variable() since you are using deprecated (old) syntax. Same applies to Spark_WLAN_Loop() which is now Particle.process(). Lastly, on of your Particle.publish() is set for PRIVATE but the others will be on the public waterhose which may already exist there. You should set all three to PRIVATE. Again, read the Particle.publish() documentation as I believe you are not following the proper syntax.

1 Like

In addition to what @peekay123 and @Moors7 have said, you're trying to publish data that is typed as int16_t and double which is not allowed. I think you're also exceeding the publish rate limit.

After Edit:

I tested publishing 3 times with a 3 second delay between the bursts, and that seems to be ok, so you're not violating the publish rate limit.

2 Likes

ok I have simplified things and am using the published example for the mpu6050 . Yes I know it includes some old syntax but one thing at a time.

Moors7 I should have stated I have tried everything I know . Which is very limited so I ask for help


I started with the published example for using the MPU6050 accel board and it works.

I have tried to add a Particle.variable as described in the reference. I understand part of my problem is not understanding data types as well as I need to. I know int16_t is a c++ 16bit integer I assumed it would be looked at the same as any variable defined int. That seems to be wrong
 so what is the difference? and why is it important?

I added the statement

Particle.variable(“sg1”,int(ay)); which as I understand it defines the Particle.variable sg1 and assigns it the value of the variable “ay”. Now “ay” is a int16_t so I have to change it to a int .

this statement is placed in the beginning of of setup.

the result is I can see sg1 in the console but its value is 0
the reported value for ay via serial is 16000 ±

sg1 (bool) = 0

I dont unterstand the booean either as I assume bool means boolean???

Thanks steve

Here is the code in its entirety

#include <MPU6050.h>
//#include <math.h>
// This #include statement was automatically added by the Particle IDE.
//#include <DS18B20.h>

// Once you import this library into an app on the web based IDE, modify the code to look something like the following.
// This code is a heavily modified version of the MPU6050_raw.ino example found elsewhere in this repo.
// This code has been tested against the MPU-9150 breakout board from Sparkfun.


int ledPin = D7;

// MPU variables:
MPU6050 accelgyro;
int16_t ax, ay, az;
int16_t gx, gy, gz;
char angl;


bool ledState = false;
void toggleLed() {
    ledState = !ledState;
    digitalWrite(ledPin, ledState);
}

void setup() {
    pinMode(ledPin, OUTPUT);
    Particle.variable("sg1",int(ay));

    Wire.begin();
    Serial.begin(9600);

    // The following line will wait until you connect to the Spark.io using serial and hit enter. This gives
    // you enough time to start capturing the data when you are ready instead of just spewing data to the UART.
    //
    // So, open a serial connection using something like:
    // screen /dev/tty.usbmodem1411 9600
    while(!Serial.available()) SPARK_WLAN_Loop();
    
    Serial.println("Initializing I2C devices...");
    accelgyro.initialize();

    // Cerify the connection:
    Serial.println("Testing device connections...");
    Serial.println(accelgyro.testConnection() ? "MPU6050 connection successful" : "MPU6050 connection failed");
    
}

void loop() {
    // read raw accel/gyro measurements from device
    accelgyro.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);
    angl= char(ay);
    Particle.publish("angle",angl);
    Serial.print("a/g:\t");
    Serial.print(ax); Serial.print("\t");
    Serial.print(ay); Serial.print("\t");
    Serial.print(az); Serial.print("\t");
    Serial.print(gx); Serial.print("\t");
    Serial.print(gy); Serial.print("\t");
    Serial.println(gz);
    
    toggleLed();
    delay(5000);
}

I wouldn't use that casting method in my Particle.variable()

There are three supported data types:
INT
DOUBLE
STRING (maximum string length is 622 bytes)

so why not just use

int ax, ay, az, gx, gy, gz;

you've got some memory to work with!

1 Like

when I tried that I got errors, I assume the library requires int16_t ???

Ill try again

s

I get the following compile error

mpu6050.ino:55:54: no matching function for call to ‘MPU6050::getMotion6(int*, int*, int*, int*, int*, int*)’

right:

void getMotion6(int16_t* ax, int16_t* ay, int16_t* az, int16_t* gx, int16_t* gy, int16_t* gz);

not wanting to slow things down, but you can try creating a 2nd set of variables for the Particle.variable() and copying them after your call to get motion:

uint16_t ax, ay, az, gx, gy, gz;
int s_ax, s_ay, s_az, s_gx, s_gy, s_gz;  // shadow variables for Particle function

...

...
Particle.variable("sg1", s_ay);
...
...
accelgyro.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);
s_ax = ax;  // implicit casting here
s_ay = ay;
s_az = az;
//... etc

tried it and there is no change.

Why does the console suggest its boolean?

s

I have had times where I was unable to see events in the console for a device, and logging out and back into the console made it so that I could see them again. I don’t know what the cause was, if it was on my computer or in the cloud, but it’s happened more than once.

J

Tried what exactly? Did you change your Particle.variable definition to,

Particle.variable("sg1", s_ay);

What @BulldogLowell posted should gave worked.

Data is just stored as a series of bytes in memory. By typing something as a int16_t, you're saying "get the two bytes starting at the address pointed to by the variable ay, and interpret it as a number". Whereas, if you type it as an int (on the Photon), you're saying to get 4 bytes starting at that address.

Where are you seeing this?

2 Likes

@Ric, how have you tried that out? Did you try his original code or did you just set up a sample sketch?
Normally three events in three seconds should work, but when also counting the system events generated on startup (depending on system version 1, 2 or 3) you might initially violate the limit and without 4 seconds of radio silence won't get out of that.
To prevent that, one could add a delay(4000) at the end of setup() or just have a delay(4000) in loop().

Instead of the two sets of integers I'd stick with only one but use this instead

int ax, ay, az, gx, gy, gz;
...
  Particle.variable("sg1", ay);
  ...
  accelgyro.getMotion6((int16_t*)&ax, (int16_t*)&ay, (int16_t*)&az, (int16_t*)&gx, (int16_t*)&gy, (int16_t*)&gz);

This only introduces some extra effort at compile time but no work at runtime.

1 Like

I just set up a simple sketch with three publishes, so I didn't take into account the initial system events.

1 Like

Now I am really confused,

I made the suggested changes
accelgyro.getMotion6((int16_t*)&ax, (int16_t*)&ay, (int16_t*)&az, (int16_t*)&gx, (int16_t*)&gy, (int16_t*)&gz);
and it didnt work initially then it did don’t know why?
I was getting useful data from both the temp sensor and position sensor Yea!!! even the Particle.publish began to showup even tho the values were wrong. I made a few changes with regard to casting the data to char in the Particle.publish lines of code and now I am back to getting values of 0 from the Particle.variables
so I changed everything back and im still getting values of 0

s

It would help to see what code you’re using now. One thing I saw in one of your older posts definitely won’t work,

angl= char(ay);

You can’t just cast a int16_t to a char and expect it to work. For one thing, the publish needs a char*, not a char. You need to do something similar to what you did in your first post to convert a number to a char* (but with %d not %f),

sprintf(szInfo, "%2.2f", fahrenheit);
1 Like

sorry I forgot to post it

// This #include statement was automatically added by the Particle IDE.
#include <MPU6050.h>

// This #include statement was automatically added by the Particle IDE.
#include <DS18B20.h>
#include <math.h>


int ledPin = D7;

// MPU variables:
MPU6050 accelgyro;
int ax, ay, az;
int gx, gy, gz;
int SG;

const int      MAXRETRY          = 4;
const uint32_t msSAMPLE_INTERVAL = 2500;
const uint32_t msMETRIC_PUBLISH  = 30000;

DS18B20  ds18b20(D3, true); //Sets Pin D2 for Water Temp Sensor and 
                            // this is the only sensor on bus
char     szInfo[64];
double   celsius;
double   fahrenheit;
int Yaxis;

uint32_t msLastMetric;
uint32_t msLastSample;



void setup() {
    
   
    Particle.variable("specgrav", SG);
    Particle.variable("tempferm", fahrenheit);
    pinMode(ledPin, OUTPUT);
    Wire.begin();
    Serial.begin(9600);
    STARTUP(WiFi.selectAntenna(ANT_AUTO));

    // The following line will wait until you connect to the Spark.io using serial and hit enter. This gives
    // you enough time to start capturing the data when you are ready instead of just spewing data to the UART.
    //
    // So, open a serial connection using something like:
    // screen /dev/tty.usbmodem1411 9600
    while(!Serial.available()) SPARK_WLAN_Loop();
    
    Serial.println("Initializing I2C devices...");
    accelgyro.initialize();

    // Cerify the connection:
    Serial.println("Testing device connections...");
    Serial.println(accelgyro.testConnection() ? "MPU6050 connection successful" : "MPU6050 connection failed");
  
}

void loop() {
    SG=6;
    // read raw accel/gyro measurements from device
    accelgyro.getMotion6((int16_t*)&ax, (int16_t*)&ay, (int16_t*)&az, (int16_t*)&gx, (int16_t*)&gy, (int16_t*)&gz);
    
    
  sprintf(szInfo, "%2.2f", fahrenheit); 
  Particle.publish("dsTmp", szInfo,PRIVATE);
  delay(100);
  Particle.publish("SG", SG);
  delay(100);
  Particle.publish("temp", fahrenheit);
  delay(100);
    
   
    getTemp();
  
    publishData();
 
  
 
    delay(5000);
}

void publishData(){
 

  
   Serial.print("a/g:\t");
    Serial.print(ax); Serial.print("\t");
    Serial.print(ay); Serial.print("\t");
    Serial.print(az); Serial.print("\t");
    Serial.print(gx); Serial.print("\t");
    Serial.print(gy); Serial.print("\t");
    Serial.println(gz);
    
    Serial.println(fahrenheit);
}

void getTemp(){
  float _temp;
  int   i = 0;

  do {
    _temp = ds18b20.getTemperature();
  } while (!ds18b20.crcCheck() && MAXRETRY > i++);

  if (i < MAXRETRY) {
    celsius = _temp;
    fahrenheit = ds18b20.convertToFahrenheit(_temp);
   
  }
  else {
    celsius = fahrenheit = NAN;
    Serial.println("Invalid reading");
  }
  msLastSample = millis();
}

in the previous code I even assigned a value of 6 to SG and that doesn’t post

Of course it doesn't; you can't publish an int (or a double like fahrenheit). The data argument must be a string or a char*

What results do you get with this code? Do all the Serial.print statements print the correct values? Does the "dsTmp" publish give correct values?