sim800 cme erro2 when i pass at commands through code arduino esp32 - c++

I am trying to push sensor data to aws cloud database through sim800 gsm module.
I am able to do it by entering the at commands manually via serial monitor but when i incorporate the at commands in the code to automate the process so I don't have to enter commands manually I am getting cme error 3.
Please guide how to solve or identify the problem.
Code
#include <Arduino.h> //Arduino librabry...optional
#include <SPI.h>//SPI communication library
#define TINY_GSM_MODEM_SIM800
#include <TinyGsmClient.h>//library with GSM commands
HardwareSerial SerialGSM(1);
TinyGsm modemGSM(SerialGSM);
const int BAUD_RATE = 115200;
//Pin definition for RX and TX GPIO2 and GPIO4 are the pins in ESP32 Wroom
const int RX_PIN = 4, TX_PIN = 2;
//const char *APN = "";
//const char *USER = "";
//const char *PASSWORD = "";
//Initialize the gsm
void setupGSM() {
SerialGSM.begin(BAUD_RATE, SERIAL_8N1, RX_PIN, TX_PIN, false);
delay(3000);
Serial.println(modemGSM.getModemInfo());
delay(1000);
}
String sendAT(String command)
{
String response = "";
SerialGSM.println(command);
// aguardamos até que haja resposta do SIM800L
while(!SerialGSM.available());
response = SerialGSM.readString();
Serial.println(response);
return response;
}
void setup() {
Serial.begin(BAUD_RATE);
Serial.println("Starting the device");
Serial.println("Initializing GSM device");
setupGSM();
delay(5000);
SerialGSM.println("AT+CMEE=1");
}
unsigned long start;
void loop() {
//SerialGSM.println("AT+CMEE?");
sendAT("AT+CMEE?");
// SerialGSM.write("AT+COPS?\r\n");
delay(100);
//SerialGSM.println("AT+CSQ");
sendAT("AT+CSQ");
// if(SerialGSM.available()){
// Serial.write(SerialGSM.read());
// }
delay(100);
// SerialGSM.println("AT+SAPBR=3,1,\"CONTYPE\",\"GPRS\"");
sendAT("AT+SAPBR=3,1,\"CONTYPE\",\"GPRS\"");
delay(1000);
// SerialGSM.println("AT+SAPBR=3,1,\"APN\",\"www\"");
sendAT("AT+SAPBR=3,1,\"APN\",\"www\"");
delay(1000);
//SerialGSM.println("AT+SAPBR=1,1");
sendAT("AT+SAPBR=1,1");
delay(2000);
//SerialGSM.println("AT+HTTPINIT");
sendAT("AT+HTTPINIT");
delay(1000);
//SerialGSM.println("AT+HTTPPARA=\"CID\",1");
sendAT("AT+HTTPPARA=\"CID\",1");
delay(1000);
//SerialGSM.println("AT+HTTPPARA=\"URL\",\"http://ec2-18-217-119-145.us-east-2.compute.amazonaws.com:8000/?light=0&var=1&var2=2&var3=3&var4=4\"");
sendAT("AT+HTTPPARA=\"URL\",\"http://ec2-18-217-119-145.us-east-2.compute.amazonaws.com:8000/?light=0&var=1&var2=2&var3=3&var4=4\"");
delay(1000);
//SerialGSM.println("AT+HTTPACTION=0");
sendAT("AT+HTTPACTION=0");
delay(2000);
//start=millis();
//
// while(millis()-start<1000)
// {
// if(SerialGSM.available()){
// Serial.write(SerialGSM.read());
// }
// }
}

Related

How to control a linear actuator with an ESP32 and a BME280 sensor

I'm trying to program an EPS32 board to open and close a linear actuator depending of the temperature a BME 280 sensor gets. It is for an automated gardening project :)
My code is functional but I would like to perfect it.
The actuator is currently connected with two GPIO pin, one to open and he other to close.
GOALS:
Switch off relays when not used.
Replace the use of delay() with millis()
Currently, the actuator is opening when temperature is above 27c°. Relay is on for 7 seconds which let the time to the actuator to go full course. Then, the relay is switch off.
But if the temperature stay above 27, the "if" part of the loop is going on an on, meaning it turn on for 7 seconds, switch off for 7 seconds and so on... I would like to switch all relays off when not needed to save energy and extend components life.
I suppose there might be something to do with && or even the analogRead() function to get the state of the actuator and apply actions from that but it is too complicated for me.
To open the actuator, I decided to time the course of the actuator and let the relay on for that timing with a delay() function. There is probably a different approach to this ( with analogRead() I suppose) but I find it simple and working. I would like to replace delay() with millis() function in order not to block the rest of the script (I plan to add fans, water valves, a float switch sensor...).
May you show me the way ?
#include <Adafruit_BME280.h>
#include <WiFi.h>
const char* ssid = "#####"; // ESP32 and ESP8266 uses 2.4GHZ wifi only
const char* password = "#####";
//MQTT Setup Start
#include <PubSubClient.h>
#define mqtt_server "####.###.##.##"
WiFiClient espClient;
PubSubClient client(espClient);
#define mqttActuator "growShed/Acuator"
#define mqttTemp1 "growShed/temp1"
int actuatorUp = 15; //GPIO de l'actuator
int actuatorDown = 2; //GPIO de l'actuator
int actuatorUpread = (!digitalRead(actuatorUp)); //read state of gpio : on or off
int actuatorDownread = (!digitalRead(actuatorDown)); //read state of gpio : on or off
//MQTT Setup End
Adafruit_BME280 bme1; // I2C
//utiliser les virgules sur les capteurs suivants
float temp1, hum1, pres1;
//gestion des délais entre chaque captations de data
unsigned long millisNow1 = 0; //for delay purposes (laisser 0)
unsigned int sendDelay1 = 2000; //delay before sending sensor info via MQTT
//gestion des délais entre chaque captations de data
unsigned long millisNow3 = 0; //for delay purposes (laisser 0)
unsigned int sendDelay3 = 7000; //delay before sending sensor info via MQTT
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
Serial.println();
// begin Wifi connect
Serial.println("Connecting to ");
Serial.println(ssid);
WiFi.mode(WIFI_STA);
WiFi.disconnect();
delay(2000);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.println(".");
}
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address (wifi RaspPi) : ");
Serial.println(WiFi.localIP());
//end Wifi connect
client.setServer(mqtt_server, 1883);
//BME
delay(5000);
unsigned status;
status = bme1.begin(0x76);
if (!status) {
Serial.println("Could not find a valid BME280 sensor, check wiring, address, sensor ID!");
Serial.print("SensorID was: 0x"); Serial.println(bme1.sensorID(),16);
Serial.print(" ID of 0xFF probably means a bad address, a BMP 180 or BMP 085\n");
Serial.print(" ID of 0x56-0x58 represents a BMP 280,\n");
Serial.print(" ID of 0x60 represents a BME 280.\n");
Serial.print(" ID of 0x61 represents a BME 680.\n");
while (1);
}
//Acuator
pinMode(actuatorUp, OUTPUT);
digitalWrite(actuatorDown, HIGH); //Begin with actuator switched off
pinMode(actuatorDown, OUTPUT);
digitalWrite(actuatorUp, HIGH); //Begin with actuator switched off
//End Actuator
}
bool getValues() {
temp1 = round(bme1.readTemperature()); //rounded values
actuatorUpread = (digitalRead(actuatorUp)); //inverted value as the relay is inverted
Serial.print("BME 1 Temperature = ");
Serial.print(temp1);
Serial.println(" °C");
Serial.print("État de l'actuator haut = ");
Serial.println(actuatorUpread);
Serial.print("État de l'actuator bas = ");
Serial.print(actuatorDownread);
Serial.println();
}
void reconnect() {
// Loop until we're reconnected
int counter = 0;
while (!client.connected()) {
if (counter==5){
ESP.restart();
}
counter+=1;
Serial.println("Attempting MQTT connection...");
// Attempt to connect
if (client.connect("growTentController")) {
Serial.println("connected");
} else {
Serial.println("failed, rc=");
Serial.println(client.state());
Serial.println(" try again in 5 seconds");
// Wait 10 seconds before retrying
delay(5000);
}
}
}
void loop() {
// put your main code here, to run repeatedly:
if (!client.connected()){
reconnect();
}
if (millis() > millisNow1 + sendDelay1){
if (getValues()) {
client.publish(mqttTemp1, String(temp1).c_str(),true);
client.publish(mqttActuator, String(actuatorUpread).c_str(),true);
millisNow1 = millis();
}
}
//Acuator moving according to BME280 temperature sensor
temp1 = bme1.readTemperature();
if (millis() > millisNow3 + sendDelay3){
if ((temp1 > 27)){
digitalWrite(actuatorUp, LOW);
delay(7000); // approx the time it take to execute the full course of the acuator.
digitalWrite(actuatorUp, HIGH);
}
else {
digitalWrite(actuatorDown, LOW);
delay(7000); // approx the time it take to execute the full course of the acuator
digitalWrite(actuatorDown, HIGH);
}
millisNow3 = millis();
}
}
I think this is what you want to do. This uses a state variable to keep track of what state the actuator is in.
When the actuator is closed, the loop will check the temperature and, if the temperature goes above 27 degrees, it will start opening the actuator. Then the loop will simply monitor the time using millis() until the actuator is open - so you can put other code in the loop for other sensors.
The same happens if the actuator is open, it will close the actuator when the temperature is lower than 26 degrees (kept a degree difference here to stop the code constantly triggering if the temperature hovers around 27 degrees).
Currently this will read the temperature on every iteration of the loop whilst the actuator is either open or closed - so I've put a small delay at the end of the loop to restrict this.
Please note - I have not tested any of the changes in the code as I don't have the hardware to hand. But it compiles, and should give you an idea of how you can use a state model with millis() to handle this sort of thing without delaying the loop.
#include <Adafruit_BME280.h>
#include <WiFi.h>
const char* ssid = "#####"; // ESP32 and ESP8266 uses 2.4GHZ wifi only
const char* password = "#####";
//MQTT Setup Start
#include <PubSubClient.h>
#define mqtt_server "####.###.##.##"
WiFiClient espClient;
PubSubClient client(espClient);
#define mqttActuator "growShed/Acuator"
#define mqttTemp1 "growShed/temp1"
int actuatorUp = 15; //GPIO de l'actuator
int actuatorDown = 2; //GPIO de l'actuator
int actuatorUpread = (!digitalRead(actuatorUp)); //read state of gpio : on or off
int actuatorDownread = (!digitalRead(actuatorDown)); //read state of gpio : on or off
//MQTT Setup End
Adafruit_BME280 bme1; // I2C
//utiliser les virgules sur les capteurs suivants
float temp1, hum1, pres1;
//gestion des délais entre chaque captations de data
unsigned long millisNow1 = 0; //for delay purposes (laisser 0)
unsigned int sendDelay1 = 2000; //delay before sending sensor info via MQTT
//gestion des délais entre chaque captations de data
unsigned long millisNow3 = 0; //for delay purposes (laisser 0)
unsigned int sendDelay3 = 7000; //delay before sending sensor info via MQTT
// The states the actuator can be in.
enum ActuatorState
{
OPENING,
OPEN,
CLOSING,
CLOSED
};
ActuatorState actuatorState;
// When opening or closing the actuator - this is the time to stop.
unsigned long actuatorEndTime = 0 ;
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
Serial.println();
// begin Wifi connect
Serial.println("Connecting to ");
Serial.println(ssid);
WiFi.mode(WIFI_STA);
WiFi.disconnect();
delay(2000);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.println(".");
}
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address (wifi RaspPi) : ");
Serial.println(WiFi.localIP());
//end Wifi connect
client.setServer(mqtt_server, 1883);
//BME
delay(5000);
unsigned status;
status = bme1.begin(0x76);
if (!status) {
Serial.println("Could not find a valid BME280 sensor, check wiring, address, sensor ID!");
Serial.print("SensorID was: 0x"); Serial.println(bme1.sensorID(),16);
Serial.print(" ID of 0xFF probably means a bad address, a BMP 180 or BMP 085\n");
Serial.print(" ID of 0x56-0x58 represents a BMP 280,\n");
Serial.print(" ID of 0x60 represents a BME 280.\n");
Serial.print(" ID of 0x61 represents a BME 680.\n");
while (1);
}
//Acuator
pinMode(actuatorUp, OUTPUT);
digitalWrite(actuatorDown, HIGH); //Begin with actuator switched off
pinMode(actuatorDown, OUTPUT);
digitalWrite(actuatorUp, HIGH); //Begin with actuator switched off
actuatorState = CLOSED ;
//End Actuator
}
bool getValues() {
temp1 = round(bme1.readTemperature()); //rounded values
actuatorUpread = (digitalRead(actuatorUp)); //inverted value as the relay is inverted
Serial.print("BME 1 Temperature = ");
Serial.print(temp1);
Serial.println(" °C");
Serial.print("État de l'actuator haut = ");
Serial.println(actuatorUpread);
Serial.print("État de l'actuator bas = ");
Serial.print(actuatorDownread);
Serial.println();
}
void reconnect() {
// Loop until we're reconnected
int counter = 0;
while (!client.connected()) {
if (counter==5){
ESP.restart();
}
counter+=1;
Serial.println("Attempting MQTT connection...");
// Attempt to connect
if (client.connect("growTentController")) {
Serial.println("connected");
} else {
Serial.println("failed, rc=");
Serial.println(client.state());
Serial.println(" try again in 5 seconds");
// Wait 10 seconds before retrying
delay(5000);
}
}
}
void loop() {
// put your main code here, to run repeatedly:
if (!client.connected()){
reconnect();
}
if (millis() > millisNow1 + sendDelay1){
if (getValues()) {
client.publish(mqttTemp1, String(temp1).c_str(),true);
client.publish(mqttActuator, String(actuatorUpread).c_str(),true);
millisNow1 = millis();
}
}
//Acuator moving according to BME280 temperature sensor
switch ( actuatorState ) {
case OPEN:
// Does it need closing (use value lower than 27 so we're not constantly opening and
// closing the actuator if the temperature is floating around 27)
temp1 = bme1.readTemperature();
if ( temp1 < 26 ) {
digitalWrite(actuatorDown, LOW);
actuatorState = CLOSING;
actuatorEndTime = millis() + 7000 ;
}
break;
case CLOSED:
// Does it need opening?
temp1 = bme1.readTemperature();
if ( temp1 > 27 ) {
digitalWrite(actuatorUp, LOW);
actuatorState = OPENING;
actuatorEndTime = millis() + 7000;
}
break ;
case OPENING:
// Is it fully open?
if ( millis() >= actuatorEndTime ) {
digitalWrite(actuatorUp, HIGH);
actuatorState = OPEN ;
}
break ;
case CLOSING:
// Is it fully closed?
if ( millis() >= actuatorEndTime ) {
digitalWrite(actuatorDown, HIGH);
actuatorState = CLOSED ;
}
break ;
}
// small delay to run the loop - and do the temperature check 5 times per second.
delay(200);
}

ESP32 Bluetooth connection status

I am running into some problems finding a solution when it comes to performing some form of Bluetooth connection check for my project that will allow me to have a connection status light.
My project consists of creating a Bluetooth speaker that has Led Strips controlled over Bluetooth serial (an app will be made to handle this) and audio stream over Bluetooth from a single ESP32.
I have found plenty of examples and had success with performing an spp callback event, however, of course this only works if I connect to the Bluetooth serial side of things through my 'Serial Bluetooth Terminal' app on my phone. If I just go into my phone Bluetooth list and connect to the audio side of things, nothing is registered, which isn't very useful for a Bluetooth speaker!
Basically I really need some help finding a way of registering that a device has connected to the Bluetooth audio so that I can have some form of indication light to tell the user that they are successfully connected to the speaker to play music.
Below is my code:
#include <btAudio.h> //<-------this is the library that I am using to handle Bluetooth audio to an external I2s DAC
#include "BluetoothSerial.h"
#include <FastLED.h>
TaskHandle_t Task1;
//POWER/BT-LIGHT-SETUP----------------------------------------
int powerPinR = 4;
int powerPinG = 16;
int powerPinB = 17;
bool BTisConnected;
//FAST-LED-STUFF----------------------------------------------
CRGB leds[NUM_STRIPS][NUM_LEDS];
CRGB leds_temp[NUM_STRIPS][NUM_LEDS/2];
//BLUETOOTH-SETUP---------------------------------------------
btAudio audio = btAudio("");
BluetoothSerial SerialBT;
//CONNECTION-CHECK--------------------------------------------
void callback(esp_spp_cb_event_t event, esp_spp_cb_param_t*param){
if(event == ESP_SPP_SRV_OPEN_EVT){
Serial.println("Client Connected");
BTisConnected = true;
}
else {
BTisConnected = false;
}
}
//------------------------------------------------------------
void setup() {
//CORE-1-INITIALISE
xTaskCreatePinnedToCore(
codeForTask1, /* Task function. */
"Task_1", /* name of task. */
1000, /* Stack size of task */
NULL, /* parameter of the task */
1, /* priority of the task */
&Task1, /* Task handle to keep track of created task */
0); /* Core */
//POWER/BLUETOOTH-CONNECTION-LIGHT-SETUP
pinMode(powerPinR, OUTPUT);
pinMode(powerPinG, OUTPUT);
pinMode(powerPinB, OUTPUT);
digitalWrite (powerPinR, HIGH);
digitalWrite (powerPinG, HIGH);
digitalWrite (powerPinB, HIGH);
//COOLDOWN-DELAY
delay(3000);
//AUDIO-INITIALISE
audio.begin();
int bck = 26;
int ws = 27;
int dout = 25;
audio.I2S(bck, dout, ws);
//LED-STRIP-SETUP-&-CLEAR-ALL
FastLED.addLeds<WS2812B,STRIP1PIN,GRB>(leds[0], NUM_LEDS);
FastLED.addLeds<WS2812B,STRIP2PIN,GRB>(leds[1], NUM_LEDS);
FastLED.clear();
FastLED.show();
//SERIAL-INITIALISE-&-CLIENT-CONNECTION-CHECK
Serial.begin(115200);
SerialBT.begin("Pilot"); //<-----BLUETOOTH NAME
SerialBT.register_callback(callback); //<-- SerialBT connection check works perfectly, but nothing for audio connection! :(
}
//CORE-0-VOID-LOOP--------------------------------------------
void codeForTask1( void * parameter )
{
for (;;) {
manageData();
delay(10);
}
}
//CORE-1-VOID-LOOP--------------------------------------------
void loop() {
BTconnectionCheck();
playScene();
}
//MANAGE-INCOMING-BLUETOOTH-SERIAL-DATA-----------------------------------------------
void manageData() {
//READ FROM SERIAL AND PARSE OUT ** READ FROM SERIAL AND PARSE OUT ** READ FROM SERIAL AND PARSE OUT **
char rawData[100] = "";
char keyword[] = "Mydata=";
if (SerialBT.available() > 0) {//new data in
size_t byteCount = SerialBT.readBytesUntil('\n', rawData, sizeof(rawData) - 1); //read in data to buffer
rawData[byteCount] = NULL;//put an end character on the data
const char delimiter[] = ",";
char parsedStrings[5][8]; //first number = how many bits of data - 2nd number = max size of eeach data
int dataCount = 0;
int dataPosition = 0;
char *token = strtok(&rawData[dataPosition], delimiter);//look for first piece of data after keyword until comma
if (token != NULL && strlen(token) < sizeof(parsedStrings[0])) {
strncpy(parsedStrings[0], token, sizeof(parsedStrings[0]));
dataCount++;
} else {
Serial.println("token to big");
strcpy(parsedStrings[0], NULL);
}
for (int i = 1; i < 5; i++) {
token = strtok(NULL, delimiter);
if (token != NULL && strlen(token) < sizeof(parsedStrings[i])) {
strncpy(parsedStrings[i], token, sizeof(parsedStrings[i]));
dataCount++;
} else {
Serial.println("token to big");
strcpy(parsedStrings[i], NULL);
}
}
if (dataCount == 5) {
scene = atoi (parsedStrings[0]);
hue = atoi(parsedStrings[1]);
saturation = atoi(parsedStrings[2]);
brightness = atoi(parsedStrings[3]);
eventInterval = atol (parsedStrings[4]);
}
}
}
//BLUETOOTH-CONNECTION-CHECK---------------------------------------------------------
void BTconnectionCheck(){
SerialBT.register_callback(callback);
if (BTisConnected == true){
bluetoothConnected();
}
else {
bluetoothSearch();
}
}
void bluetoothSearch(){
digitalWrite (powerPinR, LOW);
digitalWrite (powerPinG, LOW);
digitalWrite (powerPinB, HIGH);
}
void bluetoothConnected(){
digitalWrite (powerPinR, HIGH);
digitalWrite (powerPinG, LOW);
digitalWrite (powerPinB, HIGH);
}
I have cut lots of the code to do with the LEDs out but its still quite long, If it would help to have a more condensed version then I will chop it down further. Or if it helps to have the full code then I can also post it.
Any help would be greatly appreciated as I am well and truly stuck with this one and its a pretty important part of the project.
Thanks in advance!

Entering multiple SPI interfaces

I am having a problem with my code for arduino m0 (using microchip SAMD21). There are two SPI interfaces, first classic and second with int variable in front of the pin name, int MISO, for instance. Does someone know, how to control this classic SPI interface?
I have also attached my code.
PS: Code stucks in begin function of OZONE2CLICK sensor...
#include "Arduino.h"
#include <MQ131.h>
// include RFM69 library
#include <SPI.h>
// Local
#define PC_BAUDRATE 56700
#define MS_DELAY 0 // Number of milliseconds between data sending and LED signalization
#define LED_DELAY 100
#define Serial SerialUSB
// SD card
#define sd_cs_pin 35 // set SD's chip select pin (according to the circuit)
float PPMO2;
float PPBO2;
float MGM3O2;
float UGM3O2;
const byte pinSS = 2; //cs pin
const byte pinRDY = 12;
const byte pinSCK = 13;
const byte O2Pin = 10;
#define DcPin 8
// SD card file
File file; // SD library variable
// LEDS
#define D13_led_pin 42 // D13 LED
#define M_led_pin 36 // MLED
// Local variables
int idCounter = 1;
bool isBmeOk = true;
bool isSdOk = true;
bool isRadioOk = true;
bool isGpsConnected = true;
void OZONE2CLICKCalibrate ()
{
Serial.println("2");
//MQ131.begin(pinSS, pinRDY, O2Pin, LOW_CONCENTRATION, 10000); //(int _pinCS, int _pinRDY, int _pinPower, MQ131Model _model, int _RL)
Serial.println("99");
Serial.println("Calibration in progress...");
MQ131.calibrate();
Serial.println("Calibration done!");
Serial.print("R0 = ");
Serial.print(MQ131.getR0());
Serial.println(" Ohms");
Serial.print("Time to heat = ");
Serial.print(MQ131.getTimeToRead());
Serial.println(" s");
}
void OZONE2CLICKMeasure ()
{
Serial.println("Sampling...");
MQ131.sample();
Serial.print("Concentration O3 : ");
PPMO2 = MQ131.getO3(PPM);
Serial.print(PPMO2);
Serial.println(" ppm");
Serial.print("Concentration O3 : ");
PPBO2 = MQ131.getO3(PPB);
Serial.print(PPBO2);
Serial.println(" ppb");
Serial.print("Concentration O3 : ");
MGM3O2 = MQ131.getO3(MG_M3);
Serial.print(MGM3O2);
Serial.println(" mg/m3");
Serial.print("Concentration O3 : ");
UGM3O2 = MQ131.getO3(UG_M3);
Serial.print(UGM3O2);
Serial.println(" ug/m3");
}
void setup()
{
Serial.begin(PC_BAUDRATE);
// wait for the Arduino serial (on your PC) to connect
// please, open the Arduino serial console (right top corner)
// note that the port may change after uploading the sketch
// COMMENT OUT FOR USAGE WITHOUT A PC!
// while(!Serial);
Serial.println("openCanSat PRO");
Serial.print("Node ");
Serial.print(MYNODEID,DEC);
Serial.println(" ready");
// begin communication with the BME280 on the previously specified address
// print an error to the serial in case the sensor is not found
if (!bme.begin(BME280_ADDRESS_OPEN_CANSAT))
{
isBmeOk = false;
Serial.println("Could not find a valid BME280 sensor, check wiring!");
return;
}
// begin communication with the INA219
ina219.begin();
// check of Gps is connected
Wire.beginTransmission(0x42); // 42 is addres of GPS
int error = Wire.endTransmission();
if (error != 0)
{
isGpsConnected = false;
}
// begin communication with gps
gps.begin();
// Uncomment when you want to see debug prints from GPS library
// gps.debugPrintOn(57600);
if(!radio.initialize(FREQUENCY, MYNODEID, NETWORKID))
{
isRadioOk = false;
Serial.println("RFM69HW initialization failed!");
}
else
{
radio.setFrequency(FREQUENCYSPECIFIC);
radio.setHighPower(true); // Always use this for RFM69HW
}
pinMode(D13_led_pin, OUTPUT);
}
void loop()
{
pinMode(SS, OUTPUT);
digitalWrite(SS, HIGH);
pinMode(DcPin, OUTPUT);
pinMode(O2Pin, OUTPUT);
digitalWrite(DcPin, HIGH);
digitalWrite(O2Pin, HIGH);
delay(10000);
OZONE2CLICKCalibrate();
OZONE2CLICKMeasure();
}
It looks the code opening the SPI connection is commented out:
MQ131.begin(pinSS, pinRDY, O2Pin, LOW_CONCENTRATION, 10000);
You need to configure the SPI connection to get any data from your device.
Refer to reference code from the manufacturer or library you're using to make sure your programming against it correctly.
Please format your code with predictable spacing. This is pretty hard to read.
Since you're using C++, prefer to use:
constexpr <type> NAME = <value>;
rather than macros:
#define NAME (<value>)
Since this is a bare metal compilation, using return in the setup() or loop() functions does not stop them. You probably want something more like while (true) {}. This will loop the code indefinitely, rather than proceed in a bad state.
i.e.:
void stop_forever() {
Serial.println("fatal error detected, stoping forever.");
while (true) {}
}
// then, use it later:
// ...
if (error) {
stop_forever();
}
// ...

'dustDensity' is not captured

I'm trying to merge some code from another Arduino project into my current project. What i'm try to do is post the readings that I get from my current project to a web server, so that I can access it from my laptop or mobile device.
When I try to merge server code, I get the error 'dustDensity' is not captured. Not really sure as to why this is happening, and would appreciate some help to get around this issue.
Trying to compile this code in Arduino IDE but it won't.
#include <WiFi.h>
#include <ESPAsyncWebServer.h>
#include <SPIFFS.h>
#include <WiFi.h>
#include <ESPAsyncWebServer.h>
#include <SPIFFS.h>
#define USE_AVG
#define LED_BUILTIN 13
// Replace with your network credentials
const char* ssid = "ssid";
const char* password = "password";
// Create AsyncWebServer object on port 80
AsyncWebServer server(80);
// Arduino pin numbers.
const int sharpLEDPin = 18; // Arduino digital pin 7 connect to sensor LED.
const int sharpVoPin = 25; // Arduino analog pin 5 connect to sensor Vo.
// For averaging last N raw voltage readings.
#ifdef USE_AVG
#define N 100
static unsigned long VoRawTotal = 0;
static int VoRawCount = 0;
#endif // USE_AVG
// Set the typical output voltage in Volts when there is zero dust.
static float Voc = 0.6;
// Use the typical sensitivity in units of V per 100ug/m3.
const float K = 0.5;
/////////////////////////////////////////////////////////////////////////////
// Helper functions to print a data value to the serial monitor.
void printValue(String text, unsigned int value, bool isLast = false) {
Serial.print(text);
Serial.print("=");
Serial.print(value);
if (!isLast) {
Serial.print(", ");
}
}
void printFValue(String text, float value, String units, bool isLast = false) {
Serial.print(text);
Serial.print("=");
Serial.print(value);
Serial.print(units);
if (!isLast) {
Serial.print(", ");
}
}
/////////////////////////////////////////////////////////////////////////////
// Arduino setup function.
void setup() {
// Set LED pin for output.
pinMode(sharpLEDPin, OUTPUT);
pinMode(LED_BUILTIN, OUTPUT);
// Start the hardware serial port for the serial monitor.
Serial.begin(9600);
// Wait two seconds for startup.
delay(2000);
Serial.println("");
Serial.println("GP2Y1014AU0F Demo");
Serial.println("=================");
}
// Arduino main loop.
void loop() {
// Turn on the dust sensor LED by setting digital pin LOW.
digitalWrite(sharpLEDPin, LOW);
// Wait 0.28ms before taking a reading of the output voltage as per spec.
delayMicroseconds(280);
// Record the output voltage. This operation takes around 100 microseconds.
int VoRaw = analogRead(sharpVoPin);
// Turn the dust sensor LED off by setting digital pin HIGH.
digitalWrite(sharpLEDPin, HIGH);
// Wait for remainder of the 10ms cycle = 10000 - 280 - 100 microseconds.
delayMicroseconds(9620);
// Print raw voltage value (number from 0 to 1023).
#ifdef PRINT_RAW_DATA
printValue("VoRaw", VoRaw, true);
Serial.println("");
#endif // PRINT_RAW_DATA
// Use averaging if needed.
float Vo = VoRaw;
#ifdef USE_AVG
VoRawTotal += VoRaw;
VoRawCount++;
if ( VoRawCount >= N ) {
Vo = 1.0 * VoRawTotal / N;
VoRawCount = 0;
VoRawTotal = 0;
} else {
return;
}
#endif // USE_AVG
// Compute the output voltage in Volts.
Vo = Vo / 1024.0 * 5.0;
printFValue("Vo", Vo*1000.0, "mV");
// Convert to Dust Density in units of ug/m3.
float dV = Vo - Voc;
if ( dV < 0 ) {
dV = 0;
Voc = Vo;
}
float dustDensity = dV / K * 100.0;
printFValue("DustDensity", dustDensity, "ug/m3", true);
Serial.println("");
if (dustDensity > 85.0) {
digitalWrite(LED_BUILTIN,HIGH);
}
else {
digitalWrite(LED_BUILTIN,LOW);
}
if(!SPIFFS.begin()){
Serial.println("An Error has occurred while mounting SPIFFS");
return;
}
// Connect to Wi-Fi
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.println("Connecting to WiFi..");
}
// Print ESP32 Local IP Address
Serial.println(WiFi.localIP());
// Route for root / web page
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
request->send(SPIFFS, "/index.html");
});
server.on("/temperature", HTTP_GET, [](AsyncWebServerRequest *request){
request->send_P(200, "text/plain", dustDensity().c_str());
});
server.on("/humidity", HTTP_GET, [](AsyncWebServerRequest *request){
request->send_P(200, "text/plain", VoRaw().c_str());
});
// Start server
server.begin();
} // END PROGRAM
So not sure, why it won't compile. I'm trying to send dustDensity to a website from my ESP32.
Your code is currently
server.on("/temperature", HTTP_GET, [](AsyncWebServerRequest *request){
request->send_P(200, "text/plain", dustDensity().c_str());
});
This code:
[](AsyncWebServerRequest *request){
request->send_P(200, "text/plain", dustDensity().c_str());
}
is a "lambda expression". It's a function that won't be evaluated until request->send_P() is called. That means that dustDensity won't be defined at that point. For it to be available to the function it has to be "captured", which means that you must tell the lambda expression explicitly to make it available.
You'll also need to turn it into a C-string or String since the method wants a string argument.
So you need to rewrite this code to look more like this:
server.on("/temperature", HTTP_GET, [dustDensity](AsyncWebServerRequest *request){
request->send(200, "text/plain", String(dustDensity()));
});
The changes here are:
- add dustDensity to the brackets in the lambda so that it's captured and available inside the function
- change send_P to send because send_P is meant for sending strings stored in PROGMEM
- make a String from dustDensity so that send() has some text to send
ESPAsyncWebServer is extensively documented with lots of examples. I highly recommend reading the documentation if you're using it.

Arduino XBee sending data API

I want to send data from an end device to a coordinator with XBee and Arduino. But, the Arduino reboots when sending data (sending data was aborted). What could the problem be?
/* Transmit */
#include <SoftwareSerial.h>
#include <XBee.h>
int end = 1;
int alim_XbeeRS = A7;
int RX_XBee = 14;
int TX_XBee = 15;
XBee xbee = XBee();
//Allume le périphérique
void powerOn(SoftwareSerial portcom)
{
portcom.begin(57600);
digitalWrite(alim_XbeeRS, HIGH);
}
void setup ()
{
SoftwareSerial XbeeRS(RX_XBee,TX_XBee);
Serial.begin(57600);
XbeeRS.begin(57600);
pinMode(RX_XBee, INPUT); // Rx
pinMode(TX_XBee, OUTPUT); // Tx
pinMode(alim_XbeeRS, OUTPUT);
powerOn(XbeeRS);
xbee.setSerial(XbeeRS);
delay(5000);
Serial.println("XBee OP");
}
void loop()
{
if (end == 1)
{
Serial.println("sending");
ZBTxRequest _zbTx;
uint8_t payload[] = {'Y','E','S','\0'};
XBeeAddress64 address = XBeeAddress64 (0x13A200,0x4081B77C );
_zbTx = ZBTxRequest(address, payload, sizeof(payload));
Serial.println("sending");
xbee.send(_zbTx); // The program blocks here
}
else
{
Serial.println("waiting");
xbee.readPacket(100);
if (xbee.getResponse().isAvailable())
{
Serial.println("waiting 1");
if( xbee.getResponse().getApiId() == ZB_RX_RESPONSE)
{
Serial.println("waiting 2");
ZBRxResponse _rx;
xbee.getResponse().getZBRxResponse(_rx);
uint8_t* response= new uint8_t[50];
for(int i=0; i<_rx.getDataLength(); i++)
{
response[i] = _rx.getData()[i];
Serial.println(char(response[i]));
}
}
}
}
}
EDIT (additional information):
It doesn't change anything if I change the value type in the payload. About the baud rate, both of XBees are configured to 57600 baud. Here is the XBee's configuration:
ENDEVICE
COORDINATOR
The result from the serial port of this device is:
Finally, I use the Arduino ATmega 1284P. I really have no idea what kind of problem could do this.
There is some trouble :/
First, the default coordinator ADD is 0x0 0x0, so the line where
XBeeAddress64 address = XBeeAddress64 (0x13A200,0x4081B77C );
should be
XBeeAddress64 address = XBeeAddress64 (0x0,0x0 );
Then, is the Xbee at 57600 baud too?
To get an ACK, you can use:
if (xbee.readPacket(1000))
{
if (xbee.getResponse().getApiId() == ZB_TX_STATUS_RESPONSE)
{
xbee.getResponse().getZBTxStatusResponse(txStatus);
if (txStatus.getDeliveryStatus() == SUCCESS)
{
//It's sent
}
}
It could be from you payload too. You better use a hexadecimal value or int to be sure of what you send.
EDIT:
I see you don't use the last version of Xctu. Try it and test the direct communication between them to see if you can have direct contact between Coordinator and Routeur/End device.