aws / aws-iot-device-sdk-arduino-yun

SDK for connecting to AWS IoT from an Arduino Yún.
Apache License 2.0
163 stars 77 forks source link

Tried to add a few extra variables to the json but keep getting a error #31

Closed OtisHarrison24 closed 7 years ago

OtisHarrison24 commented 7 years ago

Wanted to add a few extra variables to the json but keep getting an error. Am i treating the different variable correctly

#include <aws_iot_mqtt.h>
#include <aws_iot_version.h>
#include "aws_iot_config.h"

aws_iot_mqtt_client myClient;
char JSON_buf[400];
char float_buf[5];
char float_buf1[5];
char float_buf2[5];
char float_buf3[5];
char float_buf4[5];
char float_buf5[5];
char float_buf6[5];
char float_buf7[5];
float reportedTemp = 70.0;
float desiredTemp = 70.0;
float TRHtemp = 0;
float TRHhumid = 0;
float BMP = 0;
float BMPtemp = 0;
float BMPalt = 0;
float CO2 = 0;
float Therm = 0;

int cnt = 0;
int rc = 1;
bool success_connect = false;

bool print_log(const char* src, int code) {
  bool ret = true;
  if(code == 0) {
    #ifdef AWS_IOT_DEBUG
       Serial.print(F("[LOG] command: "));
       Serial.print(src);
       Serial.println(F(" completed."));
    #endif
    ret = true;
   }
  else {
    #ifdef AWS_IOT_DEBUG
      Serial.print(F("[ERR] command: "));
      Serial.print(src);
      Serial.print(F(" code: "));
      Serial.println(code);
    #endif
    ret = false;
   }
  Serial.flush();
  return ret;
}

void msg_callback_delta(char* src, unsigned int len, Message_status_t flag) {
  if(flag == STATUS_NORMAL) {
    // Get Temp section in delta messages
    print_log("getDeltaKeyValue", myClient.getDeltaValueByKey(src, "Temp", JSON_buf, 50));
    desiredTemp = String(JSON_buf).toFloat();
  }
}

void setup() {
  Serial.begin(115200);
  while(!Serial);

  char curr_version[80];
  snprintf_P(curr_version, 80, PSTR("AWS IoT SDK Version(dev) %d.%d.%d-%s\n"), VERSION_MAJOR, VERSION_MINOR, VERSION_PATCH, VERSION_TAG);
  Serial.println(curr_version);

  if(print_log("setup", myClient.setup(AWS_IOT_CLIENT_ID))) {
    if(print_log("config", myClient.config(AWS_IOT_MQTT_HOST, AWS_IOT_MQTT_PORT, AWS_IOT_ROOT_CA_PATH, AWS_IOT_PRIVATE_KEY_PATH, AWS_IOT_CERTIFICATE_PATH))) {
      if(print_log("connect", myClient.connect())) {
        success_connect = true;
        print_log("shadow init", myClient.shadow_init(AWS_IOT_MY_THING_NAME));
        print_log("register thing shadow delta function", myClient.shadow_register_delta_func(AWS_IOT_MY_THING_NAME, msg_callback_delta));
      }
    }
  }
}

void loop() {
  if(success_connect) {
    // If the desired temperature is set to a higher value, start heating.
    if(desiredTemp - reportedTemp > 0.001) {reportedTemp += 0.1;}
    // If the desired temperature is set to a lower value, start cooling.
    else if(reportedTemp - desiredTemp > 0.001) {reportedTemp -= 0.1;}
    TRHtemp = random(10, 100);
    TRHhumid = random(10, 100);
    BMP = random(10, 100);
    BMPtemp = random(10, 100);
    BMPalt = random(10, 100);
    CO2 = random(10, 100);
    Therm = random(10, 100);

    dtostrf(reportedTemp, 4, 1, float_buf);
    dtostrf(TRHtemp, 4, 1, float_buf1);
    dtostrf(TRHhumid, 4, 1, float_buf2);
    dtostrf(BMP, 4, 1, float_buf3);
    dtostrf(BMPtemp, 4, 1, float_buf4);
    dtostrf(BMPalt, 4, 1, float_buf5);
    dtostrf(CO2, 4, 1, float_buf6);
    dtostrf(Therm, 4, 1, float_buf7);
    float_buf[4] = '\0';
    float_buf1[4] = '\0';
    float_buf2[4] = '\0';
    float_buf3[4] = '\0';
    float_buf4[4] = '\0';
    float_buf5[4] = '\0';
    float_buf6[4] = '\0';
    float_buf7[4] = '\0';

    sprintf_P(JSON_buf, PSTR("{\"state\":{\"reported\":{\"TRHtemp\":%s,\"TRHhumid\":%s,\"BMP\":%s,\"BMPtemp\":%s,\"BMPalt\":%s,\"CO2\":%s,\"Therm\":%s}}}"), float_buf1,float_buf2,float_buf3,float_buf4,float_buf5,float_buf6,float_buf7);
    print_log("shadow update", myClient.shadow_update(AWS_IOT_MY_THING_NAME, JSON_buf, strlen(JSON_buf), NULL, 5));
    if(myClient.yield()) {
      Serial.println("Yield failed.");
    }
    delay(1000); // check for incoming delta per 1000 ms
  }
}
liuszeng commented 7 years ago

Hi @OtisHarrison24 ,

Thanks for providing the code snippet.

AVRLibc does not really let you to convert a float number to string. As an alternative, you will need to use dtostrf(...) to do it separately. That's why you are seeing dtostrf(reportedTemp, 4, 1, float_buf) and sprintf_P(...) in the SDK example.

Note that you need to be careful about the precision you want for your float number. You also need to make sure that you are providing enough buffer space to hold the output string. For more details, you can checkout the API description here: http://www.atmel.com/webdoc/AVRLibcReferenceManual/group__avr__stdlib_1ga060c998e77fb5fc0d3168b3ce8771d42.html

Ideally, you should be able to reuse the buffer to convert the float number to string. As mentioned earlier, you will need to make sure that the size of the buffer is always enough.

Thanks, Liusu

OtisHarrison24 commented 7 years ago

@liuszeng When I try use the above code I get a setup error. Does a random float need more space?

liuszeng commented 7 years ago

Hi @OtisHarrison24 ,

Can you provide the following information?

  1. Memory consumption when you compile this sketch in your Arduino IDE. You should be able to see it at the bottom of the IDE.
  2. According to the API specs for random(), it is returning a long type number. Check out the precision used here and whether your buffer is enough for that. Right now the input parameters you specified for dtostrf says that the minimum field width length for the converted string is 4 and the precision is 1 (0.1).

Thanks, Liusu