Closed ejri closed 3 years ago
SNTP is the time server. Most WIFI routers will also allow SNTP to the gateway address. You have the ntpServer commented out in the code. Verify your devices time. Probably need to add manual clock sync to the ntpServer.
Thank you for getting back to me.
I added the ntpServer bit to add a manual clock sync to the ntpServer, but that didn't seem to work. Over wifi, there's not need to add a manual clock sync.
This code over wifi works.
///// WIFI
#include <WiFi.h>
#include "Esp32MQTTClient.h"
//////////////////////////// Accelerometer ////////////////////
// Include Wire Library for I2C
#include <Wire.h>
// Amazing MPU6050 library by rfetick.
#include <MPU6050_light.h>
MPU6050 mpu(Wire);
const int MPU = 0x68;
int16_t roll1, pitch1, yaw1, roll2, pitch2, yaw2, roll3, pitch3, yaw3, roll4, pitch4, yaw4, roll5, pitch5, yaw5;
//////////////////////////// Accelerometer ////////////////////
void TCA9548A(uint8_t bus)
{
Wire.beginTransmission(0x70);
Wire.write(1 << bus);
Wire.endTransmission();
}
//=============================================================================
#define INTERVAL 15000 //10seconds intervals sending messages
#define MESSAGE_MAX_LEN 400
// Please input the SSID and password of WiFi
const char *ssid = "";
const char *password = "";
/// Primaty Connection String///
/*String containing Hostname, Device Id & Device Key in the format: */
/* "HostName=<host_name>;DeviceId=<device_id>;SharedAccessKey=<device_key>" */
/* "HostName=<host_name>;DeviceId=<device_id>;SharedAccessSignature=<device_sas_token>" */
static const char *connectionString = "";
//const char *messageData = "{\"messageId\":%d, \"Temperature\":%f, \"Humidity\":%f}";
const char *DeviceID = "GreenSpaceTree1";
const char *messageData = "{\"DeviceID\":\"GreenSpaceTree1\",\"TreeType\":\"Cedar\" ,\"messageId\":%d, \"roll1\":%d, \"pitch1\":%d, \"yaw1\":%d, \"roll2\":%d, \"pitch2\":%d, \"yaw2\":%d, \"roll3\":%d, \"pitch3\":%d, \"yaw3\":%d, \"roll4\":%d, \"pitch4\":%d, \"yaw4\":%d, \"roll5\":%d, \"pitch5\":%d, \"yaw5\":%d}";
static bool hasIoTHub = false;
static bool hasWifi = false;
int messageCount = 1;
static bool messageSending = true;
static uint64_t send_interval_ms;
static void SendConfirmationCallback(IOTHUB_CLIENT_CONFIRMATION_RESULT result)
{
if (result == IOTHUB_CLIENT_CONFIRMATION_OK)
{
Serial.println("Send Confirmation Callback finished.");
}
}
static void MessageCallback(const char *payLoad, int size)
{
Serial.println("Message callback:");
Serial.println(payLoad);
}
static void DeviceTwinCallback(DEVICE_TWIN_UPDATE_STATE updateState, const unsigned char *payLoad, int size)
{
char *temp = (char *)malloc(size + 1);
if (temp == NULL)
{
return;
}
memcpy(temp, payLoad, size);
temp[size] = '\0';
// Display Twin message.
Serial.println(temp);
free(temp);
}
static int DeviceMethodCallback(const char *methodName, const unsigned char *payload, int size, unsigned char **response, int *response_size)
{
LogInfo("Try to invoke method %s", methodName);
const char *responseMessage = "\"Successfully invoke device method\"";
int result = 200;
if (strcmp(methodName, "start") == 0)
{
LogInfo("Start sending temperature and humidity data");
messageSending = true;
}
else if (strcmp(methodName, "stop") == 0)
{
LogInfo("Stop sending temperature and humidity data");
messageSending = false;
}
else
{
LogInfo("No method %s found", methodName);
responseMessage = "\"No method found\"";
result = 404;
}
*response_size = strlen(responseMessage) + 1;
*response = (unsigned char *)strdup(responseMessage);
return result;
}
void setup()
{
Serial.begin(115200);
Serial.println("ESP32 Device");
Serial.println("Initializing...");
Serial.println(" > WiFi");
Serial.println("Starting connecting WiFi.");
delay(10);
WiFi.mode(WIFI_AP);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED)
{
delay(500);
Serial.print(".");
hasWifi = false;
}
hasWifi = true;
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
Serial.println(" > IoT Hub");
if (!Esp32MQTTClient_Init((const uint8_t *)connectionString, true))
{
hasIoTHub = false;
Serial.println("Initializing IoT hub failed.");
return;
}
hasIoTHub = true;
Esp32MQTTClient_SetSendConfirmationCallback(SendConfirmationCallback);
Esp32MQTTClient_SetMessageCallback(MessageCallback);
Esp32MQTTClient_SetDeviceTwinCallback(DeviceTwinCallback);
Esp32MQTTClient_SetDeviceMethodCallback(DeviceMethodCallback);
Serial.println("Start sending events.");
randomSeed(analogRead(0));
//send_interval_ms = millis(); // moved to after adding the accelerometer
Wire.begin();
// deleted initializing sensor data to shorten the code a bit for github
//// start count///
send_interval_ms = millis();
}
void loop()
{
if (hasWifi && hasIoTHub)
{
if (messageSending &&
(int)(millis() - send_interval_ms) >= INTERVAL)
{
// deleted grabbing sensor data to shorten the code a bit for github
// get MPU6050 data /////
// get MPU6050 data /////
char messagePayload[MESSAGE_MAX_LEN];
snprintf(messagePayload, MESSAGE_MAX_LEN, messageData, messageCount++, roll1, pitch1, yaw1, roll2, pitch2, yaw2, roll3, pitch3, yaw3, roll4, pitch4, yaw4, roll5, pitch5, yaw5);
Serial.println(messagePayload);
EVENT_INSTANCE *message = Esp32MQTTClient_Event_Generate(messagePayload, MESSAGE);
Esp32MQTTClient_SendEventInstance(message);
send_interval_ms = millis();
}
else
{
Esp32MQTTClient_Check();
}
}
delay(5000);
}
It appears that the issue in the cellular connection code is the callback during initialization.
Serial.println(" > IoT Hub");
if (!Esp32MQTTClient_Init((const uint8_t *)connectionString, true))
{
hasIoTHub = false;
Serial.println("Initializing IoT hub failed.");
return;
}
hasIoTHub = true;
Esp32MQTTClient_SetSendConfirmationCallback(SendConfirmationCallback);
Esp32MQTTClient_SetMessageCallback(MessageCallback);
Esp32MQTTClient_SetDeviceTwinCallback(DeviceTwinCallback);
Esp32MQTTClient_SetDeviceMethodCallback(DeviceMethodCallback);
You might want to turn tracing on
bool Esp32MQTTClient_Init(const uint8_t* deviceConnString, bool hasDeviceTwin, bool traceOn
)
it seems that the ESP32's onboard clock needs to sync to NTP as soon as it gets a wifi connection. This is essential for it to be functional. With GSM, we're not connecting to wifi so it keeps waiting for a wifi connection in order to know/sync the time, but that never happens.
It seems to have nothing to do with initializing the MQTTClient.
However, in order to take advantage of the esp32 other features, such as deepsleep, power saving modes, etc, it relies on the internal clock, which doesn't get initiated. This also affects any other libraries that relies on time, including Esp32MQTTClient_Init, etc...
Manually setting the clock seems to work to initialize it.
#include <ESP32Time.h>
ESP32Time internal_time;
void setup()
{
internal_time.setTime(30, 24, 15, 17, 1, 2021); // 17th Jan 2021 15:24:30
//internal_time.setTime(1609459200); // 1st Jan 2021 00:00:00
}
void loop()
{
Serial.println(internal_time.getTime("%A, %B %d %Y %H:%M:%S")); // (String) returns time with specified format
// formating options http://www.cplusplus.com/reference/ctime/strftime/
struct tm timeinfo = internal_time.getTimeStruct();
//Serial.println(&timeinfo, "%A, %B %d %Y %H:%M:%S"); // (tm struct) Sunday, January 17 2021 07:24:38
delay(1000);
}
However, it seems that it has issues with TCP IP, which may be needed to be initialized manually, though it does get a local IP address (AT+CIFSR?). Will be looking more into this in the upcoming days...
> IoT Hub
Info: Initializing SNTP
Info: SNTP initialization complete
Info: IoT Hub SDK for C, version 1.1.23
assertion "Invalid mbox" failed: file "/home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/lwip/lwip/src/api/tcpip.c", line 267, function: tcpip_callback_with_block
abort() was called at PC 0x400fab97 on core 1
ELF file SHA256: 0000000000000000
Backtrace: 0x40088414:0x3ffb1bf0 0x40088691:0x3ffb1c10 0x400fab97:0x3ffb1c30 0x400e876a:0x3ffb1c60 0x400e8729:0x3ffb1c80 0x400e8325:0x3ffb1cc0 0x400d522d:0x3ffb1d10 0x400d6424:0x3ffb1d70 0x401320c7:0x3ffb1df0 0x400e000c:0x3ffb1e10 0x400de615:0x3ffb1e40 0x400deb59:0x3ffb1eb0 0x400da689:0x3ffb1ed0 0x400d4e8d:0x3ffb1f00 0x400d4721:0x3ffb1f40 0x400e35d2:0x3ffb1fb0 0x40089692:0x3ffb1fd0
Rebooting...
looks like an issue in your lwip networking layer. Try and update to a newer lwip version?
https://github.com/lwip-tcpip/lwip/blob/master/src/api/tcpip.c
updated working code: https://github.com/ejri/sensor_networks_azure/blob/main/Esp32/Device/SimpleMQTT_esp32_azure_iothub_5G/SimpleMQTT_esp32_azure_iothub_5G.ino
Note: even though wifi doesn't actually connect:
Hey,
Issue: I have an issue when trying to connect to Azure IoT Hub over cellular. The (ESP32) board connects perfectly fine with Azure over wifi, but doesn't connect over cellular. Device-to-cloud messaging examples work over cellular for other cloud services.
Hardware I'm using a LilyGO-T-SIM7000G board (ESP32 with a LTE-Cat module onboard) to connect to Azure IoT Hub.
Also using: AzureIoTHub - Azure IoT Hub library for Arduino VSChina/ESP32_AzureIoT_Arduino
Error: With Azure over GSM the last thing I see is:
Attempted solution: Azure initiates a cloud to device call on startup (default, can't be changed it seems). However, since the gsm IP is private, Azure can't connect to the ESP unless the device sends a (device-to-cloud) message first.
In order to initiate a device-to-cloud communication, the ESP would need a ATECC508 (and ssl) module in order to send a message through Azure's MQTT broker.
example Arduino NB 1500 example
Initiating an HTTP post request from the device to prompt a callback from the cloud didn't seem to work either.
Any ideas?
Arduino Code: