MediaTek-Labs / aws_mbedtls_mqtt

The source code to use mbedTLS library to connect to AWS mqtt IOT server.
62 stars 34 forks source link

Crash when read analog sensor #4

Open ghost opened 8 years ago

ghost commented 8 years ago

hey guys, it's me again. I am testing the kit.

I found another issue, when I try to call analogRead(), the system will crash. I try to read the real temperature from the the Grove - Temperature Sensor, which is a analog sensor.

ps: digitalWrite is ok.

ssizebra commented 8 years ago

Just in case that you may not be aware about this. The analogRead() is an Arduino layer API, and should be used in the Arduino thread. In other word, the analogRead() (or any other Arduino layer API) cannot be used with the LTask.remoteCall(). Please make sure that the analogRead() is not inside LTask.remoteCall().

ghost commented 8 years ago

Thanks for quick reply. Yep, I put the analogRead() at loop(), not LTask.remoteCall(). It will crash as well. Please have try, there're may analog sensor was consisted in the kit. Thanks.

JasonMTK commented 8 years ago

Hi,

For the analogRead function, it is correctly suggested by kakadumtk. It must be called outside the LTask.remoteCall(). Here I made a modification to the original sample code and it could run successfully:

I read the value in loop() function and then pass it to nativeloop(). You could take a try either.

Thanks.

void loop() { int aa[1]; aa[0] =analogRead(A0); LTask.remoteCall(nativeLoop, (void*)aa); delay(2000); }

int subscribe_MQTT(int32_t (callbackHandler)(MQTTCallbackParams), char \ sTopic) { int rc = NONE_ERROR; MQTTSubscribeParams subParams; subParams.mHandler = callbackHandler; subParams.pTopic = sTopic; subParams.qos = qos;

Serial.print("Subscribing..."); rc = aws_iot_mqtt_subscribe(&subParams); if (NONE_ERROR != rc) { Serial.println("failed in iot_mqtt_subscribe."); } Serial.println("Ok"); return rc; }

int publish_MQTT(char * topic, char * message) { int rc = NONE_ERROR;

// Message setup MQTTMessageParams Msg; Msg.qos = QOS_0; Msg.isRetained = false; Msg.pPayload = (void *) message; Msg.PayloadLen = strlen(message); Serial.print("publishMQTT - Payload length: "); Serial.println(Msg.PayloadLen);

// Publish setup MQTTPublishParams Params; Params.pTopic = topic; Params.MessageParams = Msg;

rc = aws_iot_mqtt_yield(1000); //please don't try to put it lower than 1000, otherwise it may going to timeout easily and no response
Serial.println("-->sleep"); delay(1000);

// Publish Serial.print("Publishing..."); rc = aws_iot_mqtt_publish(&Params);

if(NONE_ERROR != rc){ Serial.println("error"); } else { Serial.println("Ok"); } Serial.flush(); return rc; }

boolean nativeLoop(void* user_data) {

int *bb = (int*)user_data;
sprintf(mqtt_message, "%s : and read valie is %d ", "hello from SDK", *bb);

Serial.println("Pub Loop: publish:");
Serial.flush();

rc = publish_MQTT("mtktestTopic5", mqtt_message);

Serial.println("Pub Loop: published");
Serial.flush();

}

ghost commented 8 years ago

Thanks for the quick reply. I am using the Shadow example. Please try my code at

https://github.com/loovee/aws_mbedtls_mqtt/blob/master/shadow_analog/shadow_analog.ino

Thanks.

JasonMTK commented 8 years ago

Hi,

I have modified the code based on my working example, you may raplace the IP_ADDRESS for your own server, since current firmware still not support IP resolve function.

/* Web client

This sketch connects to a website using Wi-Fi functionality on MediaTek LinkIt platform.

Change the macro WIFI_AP, WIFI_PASSWORD, WIFI_AUTH and SITE_URL accordingly.

created 13 July 2010 by dlf (Metodo2 srl) modified 31 May 2012 by Tom Igoe modified 20 Aug 2014 by MediaTek Inc.

*/

include

include

include

include

include

include

include

include

include "aws_iot_mqtt_interface.h"

include "aws_iot_version.h"

include "aws_iot_shadow_interface.h"

include "aws_iot_shadow_json_data.h"

include "aws_iot_json_utils.h"

include "aws_iot_log.h"

include "aws_mtk_iot_config.h"

ifdef connect

undef connect

endif

include

include

include

define TEMP_EN 1

if TEMP_EN

const int B=4275; // B value of the thermistor const int R0 = 100000; // R0 = 100k const int pinTempSensor = A0; // Grove - Temperature Sensor connect to A5

endif

float getTemp() {

if TEMP_EN

float a = analogRead(pinTempSensor);
Serial.print("111 and a is ");
Serial.println(a);
a = a_5.0/3.3;
float R = 1023.0/((float)a)-1.0;
R = 100000.0_R;
float t=1.0/(log(R/100000.0)/B+1/298.15)-273.15;//convert to temperature via datasheet ;
return t;

else

return 21.7;

endif

}

/**

char cafileName[] = AWS_IOT_ROOT_CA_FILENAME; char clientCRTName[] = AWS_IOT_CERTIFICATE_FILENAME; char clientKeyName[] = AWS_IOT_PRIVATE_KEY_FILENAME;

define ROOMTEMPERATURE_UPPERLIMIT 32.0f

define ROOMTEMPERATURE_LOWERLIMIT 25.0f

define STARTING_ROOMTEMPERATURE ROOMTEMPERATURE_LOWERLIMIT

define MAX_LENGTH_OF_UPDATE_JSON_BUFFER 200

static void simulateRoomTemperature(float *pRoomTemperature){ static float deltaChange;

if(*pRoomTemperature >= ROOMTEMPERATURE_UPPERLIMIT){
    deltaChange = -0.5f;
}else if(*pRoomTemperature <= ROOMTEMPERATURE_LOWERLIMIT){
    deltaChange = 0.5f;
}

*pRoomTemperature+= deltaChange;

}

QoSLevel qos = QOS_0; int32_t i; IoT_Error_t rc;

LWiFiClient c;

typedef struct { double temperature; bool windowOpen; } ShadowReported;

ShadowReported reported;

typedef struct { bool windowOpen; } ShadowDesired;

ShadowDesired desired;

char shadowTxBuffer[256]; char deltaBuffer[256];

void ShadowUpdateStatusCallback(const char pThingName, ShadowActions_t action, Shadow_Ack_Status_t status, const char pReceivedJsonDocument, void *pContextData) {

// if (pReceivedJsonDocument != NULL) { // DEBUG("Received JSON %s\n", pReceivedJsonDocument); // } if (status == SHADOW_ACK_TIMEOUT) { Serial.println("Update Timeout--"); } else if (status == SHADOW_ACK_REJECTED) { Serial.println("Update RejectedXX"); } else if (status == SHADOW_ACK_ACCEPTED) { Serial.println("Update Accepted !!"); } }

void windowActuate_Callback(const char _pJsonString, uint32_t JsonStringDataLen, jsonStructt *pContext) { if (pContext != NULL) { Serial.print("Delta - Window state changed to "); Serial.println((bool *)(pContext->pData)); } }

MQTTClient_t mqttClient; char *pJsonStringToUpdate; float temperature = 0.0; char JsonDocumentBuffer[MAX_LENGTH_OF_UPDATE_JSON_BUFFER]; size_t sizeOfJsonDocumentBuffer;

bool windowOpen = false; jsonStruct_t windowActuator; jsonStruct_t temperatureHandler; ShadowParameters_t sp;

// invoked in main thread context void bearer_callback(VMINT handle, VMINT event, VMUINT data_account_id, void *user_data) { if (VM_BEARER_WOULDBLOCK == g_bearer_hdl) { g_bearer_hdl = handle; }

switch (event)
{
    case VM_BEARER_DEACTIVATED:
        break;
    case VM_BEARER_ACTIVATING:
        break;
    case VM_BEARER_ACTIVATED:
          LTask.post_signal();
          break;
    case VM_BEARER_DEACTIVATING:
        break;
    default:
        break;
}

}

boolean mqtt_start(void* ctx) { /\ Add your code here **/

          rc = NONE_ERROR;
          i = 0;
      aws_iot_mqtt_init(&mqttClient);

          sizeOfJsonDocumentBuffer = sizeof(JsonDocumentBuffer) / sizeof(JsonDocumentBuffer[0]);

          windowActuator.cb = windowActuate_Callback;
          windowActuator.pData = &windowOpen;
          windowActuator.pKey = "windowOpen";
          windowActuator.type = SHADOW_JSON_BOOL;

          temperatureHandler.cb = NULL;
          temperatureHandler.pKey = "temperature";
          temperatureHandler.pData = &temperature;
          temperatureHandler.type = SHADOW_JSON_FLOAT;

          sp = ShadowParametersDefault;
      sp.pMyThingName = AWS_IOT_MY_THING_NAME;
          sp.pMqttClientId = AWS_IOT_MQTT_CLIENT_ID;
      sp.pHost = HostAddress;
      sp.port = port;
      sp.pClientCRT = AWS_IOT_CERTIFICATE_FILENAME;
      sp.pClientKey = AWS_IOT_PRIVATE_KEY_FILENAME;
      sp.pRootCA = AWS_IOT_ROOT_CA_FILENAME;

          Serial.print("  . Shadow Init... ");
          rc = aws_iot_shadow_init(&mqttClient);
          if (NONE_ERROR != rc) {
            Serial.println("Error in connecting...");
          }
          Serial.println("ok");

          rc = aws_iot_shadow_connect(&mqttClient, &sp);

      if (NONE_ERROR != rc) {
    Serial.println("Shadow Connection Error");
      }

          rc = aws_iot_shadow_register_delta(&mqttClient, &windowActuator);

          if (NONE_ERROR != rc) {
    Serial.println("Shadow Register Delta Error");
      }

          temperature = STARTING_ROOMTEMPERATURE;

// while (NONE_ERROR == rc) { // publish_Shadow("111", "222"); // }

          Serial.println("  . mqtt_start finished...ok");

// if (NONE_ERROR != rc) { // Serial.println("An error occurred in the loop."); // } // // Serial.println("Disconnecting"); // rc = aws_iot_shadow_disconnect(&mqttClient); // // if (NONE_ERROR != rc) { // ERROR("Disconnect error"); // }

          /************************ End for your own code ************************/ 
          return true;

}

boolean bearer_open(void* ctx){
g_bearer_hdl = vm_bearer_open(VM_TCP_APN_WIFI, NULL, bearer_callback); if(g_bearer_hdl >= 0) return true; return false; }

VMINT wifiResolveCallback(vm_soc_dns_result *pDNS) { IN_ADDR addr; addr.S_un.s_addr = pDNS->address[0]; CONNECT_IP_ADDRESS = inet_ntoa(addr); LTask.post_signal(); return 0; }

boolean wifiResolveDomainName(void userData) { VMCHAR domainName = (VMCHAR *)userData; vm_soc_dns_result dns; IN_ADDR addr;

VMINT resolveState = vm_soc_get_host_by_name(VM_TCP_APN_WIFI, domainName, &dns, &wifiResolveCallback);

if (resolveState > 0) { // not done yet return false; }

switch (resolveState) { case VM_E_SOC_SUCCESS: // Get IP address successfully, result is filled. addr.S_un.s_addr = dns.address[0]; CONNECT_IP_ADDRESS = inet_ntoa(addr);

return true;

case VM_E_SOC_WOULDBLOCK: // wait response from network, result could be gotten from callback. // need to wait, return directly // so MMI message loop may continue. return false; case VM_E_SOC_INVAL: // invalid arguments: null domain_name, etc. case VM_E_SOC_ERROR: // unspecified error case VM_E_SOC_LIMIT_RESOURCE: // socket resources not available case VM_E_SOC_INVALID_ACCOUNT: // invalid data account id return true; } }

void setup() { LWiFi.begin(); Serial.begin(9600);

while(!Serial) delay(100);

// keep retrying until connected to AP Serial.print(" . Connecting to AP..."); while (0 == LWiFi.connect(WIFI_AP, LWiFiLoginInfo(WIFI_AUTH, WIFI_PASSWORD))) { delay(1000); } Serial.println("ok");

LTask.remoteCall(&wifiResolveDomainName, (void*)HostAddress);

// CONNECT_IP_ADDRESS = IP_ADDRESS; CONNECT_PORT = port;

LTask.remoteCall(&bearer_open, NULL); LTask.remoteCall(&mqtt_start, NULL); }

void loop() { int aa[1]; aa[0] =analogRead(A0); Serial.println("nativeLoop go"); Serial.flush(); updateTemp(); LTask.remoteCall(nativeLoop, (void*)aa); delay(2000); }

int publish_Shadow(char * topic, char * message) { int rc = NONE_ERROR;

rc = aws_iot_shadow_yield(&mqttClient, 1000); //please don't try to put it lower than 1000, otherwise it may going to timeout easily and no response
delay(1000); Serial.println("======================================================================================="); Serial.print("On Device: window state "); if (windowOpen) Serial.println("true"); else Serial.println("false"); // increment temperature randomly simulateRoomTemperature(&temperature);

            if (temperature > 20)
        windowOpen = true;
            rc = aws_iot_shadow_init_json_document(JsonDocumentBuffer, sizeOfJsonDocumentBuffer);
            if (rc == NONE_ERROR) {
      rc = aws_iot_shadow_add_reported(JsonDocumentBuffer, sizeOfJsonDocumentBuffer, 2, &temperatureHandler, &windowActuator);
      if (rc == NONE_ERROR) {
        rc = aws_iot_finalize_json_document(JsonDocumentBuffer, sizeOfJsonDocumentBuffer);
                    if (rc == NONE_ERROR){
            Serial.print("Update Shadow: ");
                        Serial.println(JsonDocumentBuffer);
                rc = aws_iot_shadow_update(&mqttClient, AWS_IOT_MY_THING_NAME, JsonDocumentBuffer, ShadowUpdateStatusCallback, NULL, 4, true);
                        Serial.print(" rc for aws_iot_shadow_update is ");
                        Serial.println(rc);
                    }
      }
            }
    Serial.println("*****************************************************************************************");

return rc; }

char mqtt_message[2048]; boolean nativeLoop(void* user_data) {

int *bb = (int*)user_data;
sprintf(mqtt_message, "%s : and read valie is %d ", "hello from SDK", *bb);

Serial.println("publish_MQTT go");
publish_Shadow("mtkTopic5", mqtt_message);
Serial.flush();

}

void updateTemp() { static unsigned long timer_t = millis();

// update per 2000ms
if(millis()-timer_t > 2000)
{
    Serial.println("get tmp");
    timer_t = millis();
    temperature = getTemp();
    Serial.print("update temp: ");
    Serial.println(temperature);
}

}