Hi all,
in my project i'm trying to send Beacons data read from a Arduino Nano 33 Iot configured in central mode to Arduino Cloud.I've set two simple thing and modified the sketch proposed by the editor.
Beacons data are received correctly but when i try to send them to the Arduino Cloud through the beacondata property nothing happen. It seems that the call of the function ArduinoCloud.update() "blocks" the others lines of code.
The problem disappears by removing the line ArduinoCloud.update() but obviously nothing is sent to the Cloud.
The problem is that there is no support for using WiFi and BLE at the same time on the NINA module of you Nano 33 IoT. The solution is to use one at a time. That is a bit awkward, but it is possible:
#include "arduino_secrets.h"
#include <WiFiNINA.h>
#include "utility/wifi_drv.h"
#include "thingProperties.h"
#include <ArduinoBLE.h>
const byte maximumBeaconCount = 5;
const byte maximumBeacondataLength = 18;
const unsigned int BLEPeripheralScanTimeout = 1000; // (ms) if no new BLE peripherals have been discovered by the expiration of the timeout, send beacondata to Arduino IoT Cloud
const unsigned int dataSyncWaitDuration = 4000; // (ms) time to wait for Arduino IoT Cloud to sync data so the beacondata will be updated in the dashboard. Experimentally determined.
const unsigned int minimumPropertyUpdateInterval = 550; // (ms) Arduino IoT Cloud allows updating properties once every 500 ms at a minimum
enum class states {
activateBLE,
startBLEPeripheralScan,
recordBLEPeripheralAddresses,
deactivateBLE,
activateWiFi,
connectToWiFi,
waitForDataSync,
sendAdditionalBeacondata,
waitPropertyUpdateInterval,
deactivateWiFi,
};
static String beacondataArray[maximumBeaconCount];
static byte beacondataCount;
void setup() {
// Initialize serial and wait for port to open:
Serial.begin(9600);
const unsigned int timestamp = millis();
while (!Serial && millis() - timestamp < 1500);
initProperties();
ArduinoCloud.begin(ArduinoIoTPreferredConnection);
setDebugMessageLevel(1);
ArduinoCloud.printDebugInfo();
// Allocate memory for the beacon address Strings
for (byte beacondataArrayIndex = 0; beacondataArrayIndex < sizeof(beacondataArray) / sizeof(beacondataArray[0]); beacondataArrayIndex++) {
beacondataArray[beacondataArrayIndex].reserve(maximumBeacondataLength);
}
}
void loop() {
static states state = states::activateBLE;
static unsigned long timestamp;
switch (state) {
case states::activateBLE:
{
if (BLE.begin()) {
state = states::startBLEPeripheralScan;
}
else {
Serial.println("ERROR: unable to start BLE");
}
} break;
case states::startBLEPeripheralScan:
{
BLE.scan();
state = states::recordBLEPeripheralAddresses;
} break;
case states::recordBLEPeripheralAddresses:
{
if (BLEDevice peripheral = BLE.available()) {
beacondataArray[beacondataCount] = peripheral.address();
Serial.print("Found BLE peripheral with address: ");
Serial.println(beacondataArray[beacondataCount]);
beacondataCount++;
if (beacondataCount >= sizeof(beacondataArray) / sizeof(beacondataArray[0])) {
// beacondataArray is full
state = states::deactivateBLE;
}
timestamp = millis();
}
else if (beacondataCount > 0 && millis() - timestamp > BLEPeripheralScanTimeout) {
// No more peripherals are available to discover
state = states::deactivateBLE;
}
} break;
case states::deactivateBLE:
{
BLE.stopScan();
BLE.end();
state = states::activateWiFi;
} break;
case states::activateWiFi:
{
wiFiDrv.wifiDriverDeinit();
wiFiDrv.wifiDriverInit();
beacondata = "";
ArduinoCloud.connect();
state = states::connectToWiFi;
} break;
case states::connectToWiFi:
{
ArduinoCloud.update();
if (ArduinoCloud.connected()) {
timestamp = millis();
state = states::waitForDataSync;
}
} break;
case states::waitForDataSync:
{
ArduinoCloud.update();
if (millis() - timestamp >= dataSyncWaitDuration) {
state = states::sendAdditionalBeacondata;
}
} break;
case states::sendAdditionalBeacondata:
{
setBeacondata();
ArduinoCloud.update();
if (beacondataCount == 0) {
// All data was sent
state = states::deactivateWiFi;
}
else {
timestamp = millis();
state = states::waitPropertyUpdateInterval;
}
} break;
case states::waitPropertyUpdateInterval:
{
if (millis() - timestamp >= minimumPropertyUpdateInterval) {
state = states::sendAdditionalBeacondata;
}
} break;
case states::deactivateWiFi:
{
ArduinoCloud.disconnect();
state = states::activateBLE;
} break;
default:
{
Serial.println("ERROR: state default case reached!");
} break;
}
}
void setBeacondata() {
// Set the value of the Arduino IoT Cloud property variable
beacondata = beacondataArray[--beacondataCount];
Serial.print("Sending: ");
Serial.println(beacondata);
}
Please let me know if you have any problems or questions.