Arduino: If/Else issues - arduino

Situation: I have a webpage that has two buttons on it. One sends to the PubNub channel a JSON string of {"lightRight":"1"} and one sends {"lightRight":"0"}, regardless of what I do in the Arduino Sketch I cannot make it into the "on" portion of the void light function.
I know from the serial output of the arduino that I am receiving communication from the web page. If I flip my boolean values to off then I am able to get the "LED HIGH" output but then no longer can I get the "led low".
The code I am trying to adapt can be found here.
https://gist.github.com/ianjennings/ada8fb1a91a486a0c73e
It is very possible I have hacked out to much code from the examples that is why I am including it, but running the stock code I cannot seem to get this to work.
I am not a developer, so I am very sorry if I do not call things as their proper terms. I will learn from correction.
#include <PubNub.h>
#include <SPI.h>
#include <EthernetV2_0.h>
#include <string.h>
#include <Servo.h>
byte mac[] = { MAC was here };
byte gateway[] = { Gate was here };
byte subnet[] = { Sub was here };
IPAddress ip(IP was here);
char pubkey[] = "Key was here";
char subkey[] = "Key was here";
char channel[] = "Channel was here";
int lightRight = 5;
int lightRoom = 6;
int lightGarage = 7;
int i;
EthernetClient *client;
#define W5200_CS 3
#define SDCARD_CS 4
void setup()
{
pinMode(SDCARD_CS,OUTPUT);
digitalWrite(SDCARD_CS,HIGH);
Serial.begin(9600);
Serial.println("Serial set up");
while (!Ethernet.begin(mac)) {
Serial.println("Ethernet setup error");
blink(1000, 999999);
delay(1000);
}
Serial.println("Ethernet set up");
PubNub.begin(pubkey, subkey);
Serial.println("PubNub set up");
pinMode(lightRight, OUTPUT);
pinMode(lightRoom, OUTPUT);
pinMode(lightGarage, OUTPUT);
// blink(100, 5);
reset();
}
//void flash(int ledPin)
//{
// for (int i = 0; i < 3; i++) {
// Serial.println("flash");
// digitalWrite(ledPin, HIGH);
// delay(100);
// digitalWrite(ledPin, LOW);
// delay(100);
// }
//}
void loop()
{
Ethernet.maintain();
PubSubClient *client;
Serial.println("waiting for a message (subscribe)");
client = PubNub.subscribe(channel);
if (!client) {
Serial.println("subscription error");
return;
}
String messages[10];
boolean inside_command = false;
int num_commands = 0;
String message = "";
char c;
while (client->wait_for_data()) {
c = client->read();
if(inside_command && c != '"') {
messages[num_commands] += c;
}
if(c == '"') {
if(inside_command) {
num_commands = num_commands + 1;
inside_command = false;
} else {
inside_command = true;
}
}
message += c;
}
client->stop();
for (i = 0; i < num_commands; i++){
int colonIndex = messages[i].indexOf(':');
String subject = messages[i].substring(0, colonIndex);
String valueString = messages[i].substring(colonIndex + 1, messages[i].length());
boolean value = false;
if(valueString == "1") {
value = true;
}
if(subject == "lightRight") {
light(lightRight, value);
}
if(subject == "lightRoom") {
light(lightRoom, value);
}
if(subject == "lightGarage") {
light(lightGarage, value);
}
if(subject == "blink") {
blink(100, valueString.toInt());
}
Serial.println(subject);
Serial.println(value);
}
Serial.print(message);
Serial.println();
delay(2000);
}
void light(int ledPin, boolean on) {
if(on) {
digitalWrite(ledPin, HIGH);
Serial.println("LED HIGH");
} else {
digitalWrite(ledPin, LOW);
Serial.println("led low");
}
}
void reset() {
Serial.println("Void reset");
light(lightRight, false);
light(lightRoom, false);
light(lightGarage, false);
}
void on() {
Serial.println("Void on");
light(lightRight, true);
light(lightRoom, true);
light(lightGarage, true);
}
void off() {
Serial.println("Void off");
light(lightRight, false);
light(lightRoom, false);
light(lightGarage, false);
}
void blink(int delayn, int count) {
for (int j=0; j <= count; j++){
on();
delay(delayn);
off();
delay(delayn);
}
}

That example expects the PubNub publish to be "lightRight:1" and not {"lightRight": "1"}.

Related

ESP32: Add micro sd card reader on 2nd SPI bus

I am trying to create a music box for my son, but i am having some trouble getting the SD card to work.
The idea is that when we scan a RFID tag we should get the corresponding mp3 file from the SD card.
I am using:
a ESP32 DOIT DEVKIT V1
RFID reader is a RFID-RC522
Micro SD card reader has no brand or model number on it. It just says "Micro sd card adapter" on the back and has 6 pins: cs, sck, mosi, miso, vcc, gnd
My problem is that both the RFID reader and the Micro SD Card reader should use SPI.
With the following code the RFID Card is working well. I just have no idea on how to add the SD Card reader (i have tried using the same pins as the rfid reader and also the HSPI pins, but without success!)
Any help is much appreciated!
#include <SPI.h>
#include <MFRC522.h>
#include <WiFi.h>
#include <ESPAsyncWebServer.h>
#include <WebSocketsServer.h>
#include <ArduinoJson.h>
#include "web_index.h"
// Constants
const char *ssid = "****";
const char *password = "****";
const int dns_port = 53;
const int http_port = 80;
const int ws_port = 1337;
// Globals
AsyncWebServer server(80);
WebSocketsServer webSocket = WebSocketsServer(1337);
char msg_buf[10];
// Tag reader variables
#define RFID_RC522_RST_PIN 27
#define RFID_RC522_SDA_PIN 5
MFRC522 mfrc522(RFID_RC522_SDA_PIN, RFID_RC522_RST_PIN);
bool rfid_tag_present_prev = false;
bool rfid_tag_present = false;
int _rfid_error_counter = 0;
bool _tag_found = false;
// Volume Variables
int VOLUME = 15;
int VOLUME_NORMAL_MAX = 30;
int VOLUME_LIMIT_MAX = 15;
int VOLUME_MAX = VOLUME_NORMAL_MAX;
int VOLUME_MIN = 0;
int VOLUME_CHANGE_AMOUNT = 1;
bool VOLUME_IS_LIMITED = false;
// Player variables
bool IS_PLAYING = false;
String TRACK_NAME = "-";
String ARTIST_NAME = "-";
// Button variables
const int BUTTON_VOL_DOWN_PIN = 34;
bool BUTTON_VOL_DOWN_STATE = HIGH;
bool BUTTON_VOL_DOWN_PREV_STATE = HIGH;
const int BUTTON_VOL_UP_PIN = 35;
bool BUTTON_VOL_UP_STATE = HIGH;
bool BUTTON_VOL_UP_PREV_STATE = HIGH;
const int BUTTON_STOP_PIN = 32;
bool BUTTON_STOP_STATE = HIGH;
bool BUTTON_STOP_PREV_STATE = HIGH;
const int BUTTON_NEXT_PIN = 33;
bool BUTTON_NEXT_STATE = HIGH;
bool BUTTON_NEXT_PREV_STATE = HIGH;
// Tag IDs
String TAG_TEST = "93 44 5C 92";
String TAG_BACH = "9C CD 69 0F";
/***********************************************************
Functions
*/
void volumeDecrease() {
if (VOLUME > VOLUME_MIN) {
VOLUME = VOLUME - VOLUME_CHANGE_AMOUNT;
broadcastUpdate();
}
}
void volumeIncrease() {
if (VOLUME < VOLUME_MAX) {
VOLUME = VOLUME + VOLUME_CHANGE_AMOUNT;
broadcastUpdate();
} else {
VOLUME = VOLUME_MAX;
broadcastUpdate();
}
}
void updateVolumeLimitState(bool state) {
VOLUME_IS_LIMITED = state;
broadcastUpdate();
}
void broadcastUpdate() {
DynamicJsonDocument doc(1024);
doc["volume"] = VOLUME;
doc["volume_min"] = VOLUME_MIN;
doc["volume_max"] = VOLUME_MAX;
doc["volume_is_limited"] = VOLUME_IS_LIMITED;
doc["is_playing"] = IS_PLAYING;
doc["track_name"] = TRACK_NAME;
doc["artist_name"] = ARTIST_NAME;
char json_string[1024];
serializeJson(doc, json_string);
webSocket.broadcastTXT(json_string);
}
void handleWsTextMessage(uint8_t client_num, uint8_t * payload) {
if ( strcmp((char *)payload, "getValues") == 0 ) {
broadcastUpdate();
} else if ( strcmp((char *)payload, "volume_down_button_click") == 0 ) {
volumeDecrease();
} else if ( strcmp((char *)payload, "volume_up_button_click") == 0 ) {
volumeIncrease();
} else if ( strcmp((char *)payload, "volume_limit_checkbox_on") == 0 ) {
updateVolumeLimitState(true);
} else if ( strcmp((char *)payload, "volume_limit_checkbox_off") == 0 ) {
updateVolumeLimitState(false);
} else { // Message not recognized
Serial.println("[%u] Message not recognized");
}
}
// Callback: receiving any WebSocket message
void onWebSocketEvent(uint8_t client_num, WStype_t type, uint8_t * payload, size_t length) {
// Figure out the type of WebSocket event
switch (type) {
// Client has disconnected
case WStype_DISCONNECTED:
Serial.printf("[%u] Disconnected!\n", client_num);
break;
// New client has connected
case WStype_CONNECTED:
{
IPAddress ip = webSocket.remoteIP(client_num);
Serial.printf("[%u] Connection from ", client_num);
Serial.println(ip.toString());
}
break;
// Handle text messages from client
case WStype_TEXT:
// Print out raw message
Serial.printf("[%u] Received text: %s\n", client_num, payload);
handleWsTextMessage(client_num, payload);
break;
// For everything else: do nothing
case WStype_BIN:
case WStype_ERROR:
case WStype_FRAGMENT_TEXT_START:
case WStype_FRAGMENT_BIN_START:
case WStype_FRAGMENT:
case WStype_FRAGMENT_FIN:
default:
break;
}
}
// Callback: send homepage
void onIndexRequest(AsyncWebServerRequest *request) {
const char* dataType = "text/html";
IPAddress remote_ip = request->client()->remoteIP();
Serial.println("[" + remote_ip.toString() +
"] HTTP GET request of " + request->url());
// request->send(SPIFFS, "/index.html", "text/html");
AsyncWebServerResponse *response = request->beginResponse_P(200, dataType, index_html_gz, index_html_gz_len);
response->addHeader("Content-Encoding", "gzip");
request->send(response);
}
// Callback: send 404 if requested file does not exist
void onPageNotFound(AsyncWebServerRequest *request) {
IPAddress remote_ip = request->client()->remoteIP();
Serial.println("[" + remote_ip.toString() +
"] HTTP GET request of " + request->url());
request->send(404, "text/plain", "Not found");
}
/***********************************************************
Main
*/
void handleButtons() {
// VOLUME DOWN BUTTON
bool buttonVolDownState = digitalRead(BUTTON_VOL_DOWN_PIN);
if (buttonVolDownState == LOW && BUTTON_VOL_DOWN_PREV_STATE == HIGH) {
Serial.println("button down pressed");
volumeDecrease();
BUTTON_VOL_DOWN_PREV_STATE = LOW;
} else if (buttonVolDownState == HIGH && BUTTON_VOL_DOWN_PREV_STATE == LOW) {
BUTTON_VOL_DOWN_PREV_STATE = HIGH;
}
// VOLUME UP BUTTON
bool buttonVolUpState = digitalRead(BUTTON_VOL_UP_PIN);
if (buttonVolUpState == LOW && BUTTON_VOL_UP_PREV_STATE == HIGH) {
Serial.println("button up pressed");
volumeIncrease();
BUTTON_VOL_UP_PREV_STATE = LOW;
} else if (buttonVolUpState == HIGH && BUTTON_VOL_UP_PREV_STATE == LOW) {
BUTTON_VOL_UP_PREV_STATE = HIGH;
}
// STOP BUTTON
bool buttonStopState = digitalRead(BUTTON_STOP_PIN);
if (buttonStopState == LOW && BUTTON_STOP_PREV_STATE == HIGH) {
Serial.println("button stop pressed");
volumeIncrease();
BUTTON_STOP_PREV_STATE = LOW;
} else if (buttonStopState == HIGH && BUTTON_STOP_PREV_STATE == LOW) {
BUTTON_STOP_PREV_STATE = HIGH;
}
// NEXT BUTTON
bool buttonNextState = digitalRead(BUTTON_NEXT_PIN);
if (buttonNextState == LOW && BUTTON_NEXT_PREV_STATE == HIGH) {
Serial.println("button next pressed");
volumeIncrease();
BUTTON_NEXT_PREV_STATE = LOW;
} else if (buttonNextState == HIGH && BUTTON_NEXT_PREV_STATE == LOW) {
BUTTON_NEXT_PREV_STATE = HIGH;
}
}
String getTagUid() {
String content = "";
byte letter;
for (byte i = 0; i < mfrc522.uid.size; i++) {
content.concat(String(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " "));
content.concat(String(mfrc522.uid.uidByte[i], HEX));
}
content.toUpperCase();
String tag_uid = content.substring(1);
Serial.println("Getting tag uid");
Serial.println(content.substring(1));
return content.substring(1);
}
void checkTagValidity(String tag_uid) {
if (tag_uid == TAG_TEST) {
Serial.println("BLUE TAG");
ARTIST_NAME = "Blue Tag";
TRACK_NAME = "Super Track name";
IS_PLAYING = true;
broadcastUpdate();
} else if (tag_uid == TAG_BACH) {
Serial.println("BACH");
} else {
Serial.println("UNKNOWN CARD: ");
Serial.print(tag_uid);
}
}
void setup() {
// Init buttons
pinMode(BUTTON_VOL_DOWN_PIN, INPUT_PULLUP);
pinMode(BUTTON_VOL_UP_PIN, INPUT_PULLUP);
pinMode(BUTTON_STOP_PIN, INPUT_PULLUP);
pinMode(BUTTON_NEXT_PIN, INPUT_PULLUP);
// Start Serial port
Serial.begin(115200);
// Init SPI bus (for the tag reader)
SPI.begin();
// Init the tag reader
mfrc522.PCD_Init();
// Start access point
WiFi.softAP(ssid, password);
// Print our IP address
Serial.println();
Serial.println("AP running");
Serial.print("My IP address: ");
Serial.println(WiFi.softAPIP());
// On HTTP request for root, provide index.html file
server.on("/", HTTP_GET, onIndexRequest);
// 404 page
server.onNotFound(onPageNotFound);
// Start web server
server.begin();
// Start WebSocket server and assign callback
webSocket.begin();
webSocket.onEvent(onWebSocketEvent);
}
void loop() {
// Check for button clicks
handleButtons();
// Look for and handle WebSocket data
webSocket.loop();
rfid_tag_present_prev = rfid_tag_present;
_rfid_error_counter += 1;
if (_rfid_error_counter > 2) {
_tag_found = false;
}
// Detect Tag without looking for collisions
byte bufferATQA[2];
byte bufferSize = sizeof(bufferATQA);
// Reset baud rates
mfrc522.PCD_WriteRegister(mfrc522.TxModeReg, 0x00);
mfrc522.PCD_WriteRegister(mfrc522.RxModeReg, 0x00);
// Reset ModWidthReg
mfrc522.PCD_WriteRegister(mfrc522.ModWidthReg, 0x26);
MFRC522::StatusCode result = mfrc522.PICC_RequestA(bufferATQA, &bufferSize);
if (result == mfrc522.STATUS_OK) {
if ( ! mfrc522.PICC_ReadCardSerial()) { //Since a PICC placed get Serial and continue
return;
}
_rfid_error_counter = 0;
_tag_found = true;
}
rfid_tag_present = _tag_found;
// rising edge
if (rfid_tag_present && !rfid_tag_present_prev) {
Serial.println("Tag found");
// Get tag uid
String tag_uid = getTagUid();
// Check if valid tag
checkTagValidity(tag_uid);
}
// falling edge
if (!rfid_tag_present && rfid_tag_present_prev) {
Serial.println("Tag gone");
ARTIST_NAME = "-";
TRACK_NAME = "-";
IS_PLAYING = false;
broadcastUpdate();
}
}
Thanks to the comments from #romkey and #RamyHx i got it to work using the same SPI pins.
My problem was that i was using the same pin for the CS of both devices. Once i change it to different CS pins for the rfid and sd card reader it started working.
For the RFID i have used the pin D2, and for the sd card reader i have used the pin D5.
For the rfid i have change #define RFID_RC522_SDA_PIN 5 into #define RFID_RC522_SDA_PIN 2.
For the sd card i have used the code here, which assumes we are using the default pins (with CS connected to pin D5).

Trying to understand ESP32 OTA over the GSM code

I am performing ESP32 OTA over the GSM. I have found some example code online, modified it slightly based on my board connections and was able to sucesfully perform a firmware update.
I use lilygo ESP32 GSM development board.
However, it frustrates me that I am not capable of understanding what really happens in the code at the low level. I really want to understand before I go any further with my project.
Full code for my OTA update:
#include <Update.h>
#define TINY_GSM_MODEM_SIM800
// Increase RX buffer
#define TINY_GSM_RX_BUFFER 1030
const char apn[] = "omnitel";
const char user[] = "omni";
const char pass[] = "omni";
#define MODEM_RST 5
#define MODEM_PWRKEY 4
#define MODEM_POWER_ON 23
#define MODEM_TX 27
#define MODEM_RX 26
#define LED_GPIO 13
#define LED_ON HIGH
#define LED_OFF LOW
#define SerialAT Serial1
#include <TinyGsmClient.h>
#include <CRC32.h>
#include "FS.h"
#include "SPIFFS.h"
#ifdef DUMP_AT_COMMANDS
#include <StreamDebugger.h>
StreamDebugger debugger(SerialAT, Serial);
TinyGsm modem(debugger);
#else
TinyGsm modem(SerialAT);
#endif
TinyGsmClient client(modem);
const char server[] = "myesptestserver.ddns.net";
const int port = 80;
const char resource[] = "/esp.bin"; //here de bin file
uint32_t knownCRC32 = 0x6f50d767;
uint32_t knownFileSize = 1024; // In case server does not send it
void setup()
{
SerialAT.begin(115200, SERIAL_8N1, MODEM_RX, MODEM_TX);
// Set console baud rate
Serial.begin(115200);
setupModem();
delay(10);
if (!SPIFFS.begin(true))
{
Serial.println("SPIFFS Mount Failed");
return;
}
SPIFFS.format();
listDir(SPIFFS, "/", 0);
// Set GSM module baud rate
delay(3000);
// Restart takes quite some time
// To skip it, call init() instead of restart()
Serial.println("Initializing modem...");
modem.restart();
String modemInfo = modem.getModemInfo();
Serial.print("Modem: ");
Serial.println(modemInfo);
// Unlock your SIM card with a PIN
//modem.simUnlock("1234");
}
void loop()
{
Serial.print("Waiting for network...");
if (!modem.waitForNetwork())
{
Serial.println(" fail");
delay(10000);
return;
}
Serial.println(" OK");
Serial.print("Connecting to ");
Serial.print(apn);
if (!modem.gprsConnect(apn, user, pass))
{
Serial.println(" fail");
delay(10000);
return;
}
Serial.println(" OK");
Serial.print("Connecting to ");
Serial.print(server);
// if you get a connection, report back via serial:
if (!client.connect(server, port))
{
Serial.println(" fail");
delay(10000);
return;
}
Serial.println(" OK");
// Make a HTTP request:
client.print(String("GET ") + resource + " HTTP/1.0\r\n");
client.print(String("Host: ") + server + "\r\n");
client.print("Connection: close\r\n\r\n");
long timeout = millis();
while (client.available() == 0)
{
if (millis() - timeout > 5000L)
{
Serial.println(">>> Client Timeout !");
client.stop();
delay(10000L);
return;
}
}
Serial.println("Reading header");
uint32_t contentLength = knownFileSize;
File file = SPIFFS.open("/update.bin", FILE_APPEND);
while (client.available())
{
String line = client.readStringUntil('\n');
line.trim();
//Serial.println(line); // Uncomment this to show response header
line.toLowerCase();
if (line.startsWith("content-length:"))
{
contentLength = line.substring(line.lastIndexOf(':') + 1).toInt();
}
else if (line.length() == 0)
{
break;
}
}
timeout = millis();
uint32_t readLength = 0;
CRC32 crc;
unsigned long timeElapsed = millis();
printPercent(readLength, contentLength);
while (readLength < contentLength && client.connected() && millis() - timeout < 10000L)
{
int i = 0;
while (client.available())
{
// read file data to spiffs
if (!file.print(char(client.read())))
{
Serial.println("Appending file");
}
//Serial.print((char)c); // Uncomment this to show data
//crc.update(c);
readLength++;
if (readLength % (contentLength / 13) == 0)
{
printPercent(readLength, contentLength);
}
timeout = millis();
}
}
file.close();
printPercent(readLength, contentLength);
timeElapsed = millis() - timeElapsed;
Serial.println();
client.stop();
Serial.println("stop client");
modem.gprsDisconnect();
Serial.println("gprs disconnect");
Serial.println();
float duration = float(timeElapsed) / 1000;
/*
Serial.print("Tamaño de Archivo: ");
Serial.println(contentLength);
Serial.print("Leido: ");
Serial.println(readLength);
Serial.print("Calculado. CRC32: 0x");
Serial.println(crc.finalize(), HEX);
Serial.print("Conocido CRC32: 0x");
Serial.println(knownCRC32, HEX);
Serial.print("Bajado en: ");
Serial.print(duration);
Serial.println("s");
Serial.println("Se genera una espera de 3 segundos");
for (int i = 0; i < 3; i++)
{
Serial.print(String(i) + "...");
delay(1000);
}
*/
//readFile(SPIFFS, "/update.bin");
updateFromFS();
// Do nothing forevermore
while (true)
{
delay(1000);
}
}
void appendFile(fs::FS &fs, const char *path, const char *message)
{
Serial.printf("Appending to file: %s\n", path);
File file = fs.open(path, FILE_APPEND);
if (!file)
{
Serial.println("Failed to open file for appending");
return;
}
if (file.print(message))
{
Serial.println("APOK");
}
else
{
Serial.println("APX");
}
}
void readFile(fs::FS &fs, const char *path)
{
Serial.printf("Reading file: %s\n", path);
File file = fs.open(path);
if (!file || file.isDirectory())
{
Serial.println("Failed to open file for reading");
return;
}
Serial.print("Read from file: ");
while (file.available())
{
Serial.write(file.read());
delayMicroseconds(100);
}
}
void writeFile(fs::FS &fs, const char *path, const char *message)
{
Serial.printf("Writing file: %s\n", path);
File file = fs.open(path, FILE_WRITE);
if (!file)
{
Serial.println("Failed to open file for writing");
return;
}
if (file.print(message))
{
Serial.println("File written");
}
else
{
Serial.println("Write failed");
}
}
void listDir(fs::FS &fs, const char *dirname, uint8_t levels)
{
Serial.printf("Listing directory: %s\n", dirname);
File root = fs.open(dirname);
if (!root)
{
Serial.println("Failed to open directory");
return;
}
if (!root.isDirectory())
{
Serial.println("Not a directory");
return;
}
File file = root.openNextFile();
while (file)
{
if (file.isDirectory())
{
Serial.print(" DIR : ");
Serial.println(file.name());
if (levels)
{
listDir(fs, file.name(), levels - 1);
}
}
else
{
Serial.print(" FILE: ");
Serial.print(file.name());
Serial.print(" SIZE: ");
Serial.println(file.size());
}
file = root.openNextFile();
}
}
void deleteFile(fs::FS &fs, const char *path)
{
Serial.printf("Deleting file: %s\n", path);
if (fs.remove(path))
{
Serial.println("File deleted");
}
else
{
Serial.println("Delete failed");
}
}
void updateFromFS()
{
File updateBin = SPIFFS.open("/update.bin");
if (updateBin)
{
if (updateBin.isDirectory())
{
Serial.println("Directory error");
updateBin.close();
return;
}
size_t updateSize = updateBin.size();
if (updateSize > 0)
{
Serial.println("Starting update");
performUpdate(updateBin, updateSize);
}
else
{
Serial.println("Error, archivo vacío");
}
updateBin.close();
// whe finished remove the binary from sd card to indicate end of the process
//fs.remove("/update.bin");
}
else
{
Serial.println("no such binary");
}
}
void performUpdate(Stream &updateSource, size_t updateSize)
{
if (Update.begin(updateSize))
{
size_t written = Update.writeStream(updateSource);
if (written == updateSize)
{
Serial.println("Writes : " + String(written) + " successfully");
}
else
{
Serial.println("Written only : " + String(written) + "/" + String(updateSize) + ". Retry?");
}
if (Update.end())
{
Serial.println("OTA finished!");
if (Update.isFinished())
{
Serial.println("Restart ESP device!");
ESP.restart();
}
else
{
Serial.println("OTA not fiished");
}
}
else
{
Serial.println("Error occured #: " + String(Update.getError()));
}
}
else
{
Serial.println("Cannot beggin update");
}
}
void printPercent(uint32_t readLength, uint32_t contentLength)
{
// If we know the total length
if (contentLength != -1)
{
Serial.print("\r ");
Serial.print((100.0 * readLength) / contentLength);
Serial.print('%');
}
else
{
Serial.println(readLength);
}
}
void setupModem()
{
#ifdef MODEM_RST
// Keep reset high
pinMode(MODEM_RST, OUTPUT);
digitalWrite(MODEM_RST, HIGH);
#endif
pinMode(MODEM_PWRKEY, OUTPUT);
pinMode(MODEM_POWER_ON, OUTPUT);
// Turn on the Modem power first
digitalWrite(MODEM_POWER_ON, HIGH);
// Pull down PWRKEY for more than 1 second according to manual requirements
digitalWrite(MODEM_PWRKEY, HIGH);
delay(100);
digitalWrite(MODEM_PWRKEY, LOW);
delay(1000);
digitalWrite(MODEM_PWRKEY, HIGH);
// Initialize the indicator as an output
pinMode(LED_GPIO, OUTPUT);
digitalWrite(LED_GPIO, LED_OFF);
}
From what I understand, the following part of the code reads my binary file that is stored in the server and read it into SPIFFS memory:
while (readLength < contentLength && client.connected() && millis() - timeout < 10000L)
{
int i = 0;
while (client.available())
{
// read file data to spiffs
if (!file.print(char(client.read())))
{
Serial.println("Appending file");
}
//Serial.print((char)c); // Uncomment this to show data
//crc.update(c);
readLength++;
if (readLength % (contentLength / 13) == 0)
{
printPercent(readLength, contentLength);
}
timeout = millis();
}
}
Then the updateFromFS() function is executed, which checks whether the binary is all good and then calls another function performUpdate(updateBin, updateSize);
void updateFromFS()
{
File updateBin = SPIFFS.open("/update.bin");
if (updateBin)
{
if (updateBin.isDirectory())
{
Serial.println("Directory error");
updateBin.close();
return;
}
size_t updateSize = updateBin.size();
if (updateSize > 0)
{
Serial.println("Starting update");
performUpdate(updateBin, updateSize);
}
else
{
Serial.println("Error, archivo vacío");
}
updateBin.close();
// whe finished remove the binary from sd card to indicate end of the process
//fs.remove("/update.bin");
}
else
{
Serial.println("no such binary");
}
}
in the performUpdate(updateBin, updateSize), 2 functions from Arduino Update Library are being called ( Update.begin(updateSize) and Update.writeStream(updateSource) ) and that is where I cant follow anymore...
void performUpdate(Stream &updateSource, size_t updateSize)
{
if (Update.begin(updateSize))
{
size_t written = Update.writeStream(updateSource);
if (written == updateSize)
{
Serial.println("Writes : " + String(written) + " successfully");
}
else
{
Serial.println("Written only : " + String(written) + "/" + String(updateSize) + ". Retry?");
}
if (Update.end())
{
Serial.println("OTA finished!");
if (Update.isFinished())
{
Serial.println("Restart ESP device!");
ESP.restart();
}
else
{
Serial.println("OTA not fiished");
}
}
else
{
Serial.println("Error occured #: " + String(Update.getError()));
}
}
else
{
Serial.println("Cannot beggin update");
}
}
I have found this Update library source code :
https://github.com/espressif/arduino-esp32/blob/master/libraries/Update/src/Updater.cpp
But it seems that this is beyond my knowledge to understand what really is going on in this code.
First of all, we pass only 1 variable to .begin method, but the function prototype requires more than that:
bool UpdateClass::begin(size_t size, int command, int ledPin, uint8_t ledOn, const char *label)
And then I am trying to understand what happens in function Update.writeStream(updateSource) but cant..
If anyone could shed some light here I would appreciate a lot! Thanks in advance...
The algorithm downloads the new firmware (.bin) from the cloud to the device's local memory and makes the firmware change with the UpdateClass library
(I see the texts in Spanish if you want we speak in Spanish)
Check the .h (only one argument required)
https://github.com/espressif/arduino-esp32/blob/master/libraries/Update/src/Update.h
/*
Call this to check the space needed for the update
Will return false if there is not enough space
*/
bool begin(size_t size=UPDATE_SIZE_UNKNOWN, int command = U_FLASH, int ledPin = -1, uint8_t ledOn = LOW, const char *label = NULL);
You could use the OTAdrive library and use it for OTA updates.
Check here for the esp32 gsm modem OTA example.

Arduino TTL jpeg Serial Camera and esp8266 wifi Wi-Fi module

I'm writing a code to take pictures if the distance is more than a certain distance after measuring the distance.
And send the distance data to Thingspeak, Store the photos on the SD card.
However, the program keeps stopping in the middle.
Serial moniter capture
Distance measurement and Thingspeak server data transfer / camera shooting were developed separately.
The two source codes worked normally independently.
But when the two codes are combined, there is an error.
Parts for Use : Arduino Uno, esp8266 wifi module, TTL Serial JPEG Camera with NTSC Video, 2Y0A21 Infrared Distance Sensor, Micro SD card adapter
#include <SoftwareSerial.h>
#include <stdlib.h>
#include <Adafruit_VC0706.h>
#include <SPI.h>
#include <SD.h>
#define DEBUG true
#define chipSelect 10
const int distancePin = 0;
String apiKey = "39R00EYW0BTKK5JJ";
SoftwareSerial esp8266(2, 3); //TX/RX
#if ARDUINO >= 100
SoftwareSerial cameraconnection = SoftwareSerial(4, 5); //TX/RX
#else
NewSoftSerial cameraconnection = NewSoftSerial(4, 5);
#endif
Adafruit_VC0706 cam = Adafruit_VC0706(&cameraconnection);
int defaultDistance = 0;
int temp = 0;
void ThingspeakSendData(String alarmData);
void Snapshots();
void setup() {
#if !defined(SOFTWARE_SPI)
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
if (chipSelect != 53) pinMode(53, OUTPUT); // SS on Mega
#else
if (chipSelect != 10) pinMode(10, OUTPUT); // SS on Uno, etc.
#endif
#endif
Serial.begin(9600);
Serial.println("VC0706 Camera snapshot test");//the program keeps stopping in the middle.
if (cam.begin()) {
Serial.println("Camera Found:");
}
else {
Serial.println("No camera found?");
return;
}
char *reply = cam.getVersion();
if (reply == 0) {
Serial.print("Failed to get version");
}
else {
Serial.println("-----------------");
Serial.print(reply);
Serial.println("-----------------");
}
cam.setImageSize(VC0706_640x480);
uint8_t imgsize = cam.getImageSize();
Serial.print("Image size: ");
if (imgsize == VC0706_640x480) Serial.println("640x480");
if (imgsize == VC0706_320x240) Serial.println("320x240");
if (imgsize == VC0706_160x120) Serial.println("160x120");
esp8266.begin(9600);
sendData("AT+RST\r\n", 2000, DEBUG); //reset module
sendData("AT+CWMODE=1\r\n", 1000, DEBUG); //dual mode로 설정
sendData("AT+CWJAP=\"0sangsiljangnim\",\"123456788\"\r\n", 5000, DEBUG);
// 2Y0A21
analogReference(DEFAULT);
pinMode(distancePin, INPUT);
// distancePin 2Y0A21
int raw = analogRead(distancePin);
int volt = map(raw, 0, 1023, 0, 5000);
int distance = (21.61 / (volt - 0.1696)) * 1000;
defaultDistance = distance;
Serial.println("Default : " + defaultDistance);
}
void loop() {
// distancePin 2Y0A21
int raw = analogRead(distancePin);
int volt = map(raw, 0, 1023, 0, 5000);
int distance = (21.61 / (volt - 0.1696)) * 1000;
Serial.println(distance);
if (distance < defaultDistance)
{
String alarmData = "1";
esp8266.listen();
ThingspeakSendData(alarmData);
cameraconnection.listen();
Snapshots();
}
else if (distance == defaultDistance)
{
String alarmData = "0";
esp8266.listen();
ThingspeakSendData(alarmData);
}
delay(3000);
}
void ThingspeakSendData(String alarmData) {
String cmd = "AT+CIPSTART=\"TCP\",\"";
cmd += "184.106.153.149";
cmd += "\",80";
esp8266.println(cmd);
if (esp8266.find("Error")) {
Serial.println("AT+CIPSTART error");
return;
}
String getStr = "GET /update?api_key=";
getStr += apiKey;
getStr += "&field1=";
getStr += String(alarmData);
getStr += "\r\n\r\n";
// Send Data
cmd = "AT+CIPSEND=";
cmd += String(getStr.length());
esp8266.println(cmd);
if (esp8266.find(">")) {
esp8266.print(getStr);
}
else {
esp8266.println("AT+CIPCLOSE");
// alert uesp8266
Serial.println("AT+CIPCLOSE");
}
}
String sendData(String command, const int timeout, boolean debug) {
String response = "";
esp8266.print(command);
long int time = millis();
while ((time + timeout) > millis()) {
while (esp8266.available()) {
char c = esp8266.read();
response += c;
}
}
if (debug) {
Serial.print(response);
}
return response;
}
void Snapshots() {
Serial.println("Snap in 3 secs...");
delay(3000);
if (!cam.takePicture())
Serial.println("Failed to snap!");
else
Serial.println("Picture taken!");
if (!SD.begin(chipSelect)) {
Serial.println("Card failed, or not present");
return;
}
char filename[13];
strcpy(filename, "IMAGE00.JPG");
for (int i = 0; i < 100; i++) {
filename[5] = '0' + i / 10;
filename[6] = '0' + i % 10;
if (!SD.exists(filename)) {
break;
}
}
File imgFile = SD.open(filename, FILE_WRITE);
uint16_t jpglen = cam.frameLength();
Serial.print("Storing ");
Serial.print(jpglen, DEC);
Serial.print(" byte image.");
int32_t time = millis();
pinMode(8, OUTPUT);
byte wCount = 0;
while (jpglen > 0) {
uint8_t *buffer;
uint8_t bytesToRead = min(32, jpglen);
buffer = cam.readPicture(bytesToRead);
imgFile.write(buffer, bytesToRead);
if (++wCount >= 64) {
Serial.print('.');
wCount = 0;
}
jpglen -= bytesToRead;
}
imgFile.close();
time = millis() - time;
Serial.println("done!");
Serial.print(time); Serial.println(" ms elapsed");
}

How can I get the value of +IPD response

The problem is the value of +IPD response isn't show up at the ReadLastEntryThingSpeak(), so my code isn't correct or I must add something? I have searched for many websites Arduino forum, Thingspeak forum, and others. But I didn't see any solution. :(
I have tried to do this system for 5 days and it doesn't work, why?
#include <SoftwareSerial.h>
#include <string.h>
#define esp8266 Serial1
#define SSID "test" // put here the name of your wifi network
#define PASS "lolman123"
#define IP "184.106.153.149"
int counter = 120;
String keep;
String valuetosend;
const byte maxDataLength = 30; // maxDataLength is the maximum length
allowed for received data.
char receivedChars[31] ;
boolean newData = false;
String GET = "GET /update?key=FYPW04TOYR3FX2QH&"; // put here your
thingspeak key
String GET1 = "field1=";
String readGET1 = "GET
https://api.thingspeak.com/channels/864152/fields/1/last";
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
esp8266.begin(115200);
esp8266.println("AT");
delay(5000);
if(esp8266.find("OK")){
connectWiFi();
Serial.println("WIFI CONNECTED");
}
pinMode(7, INPUT_PULLUP);
pinMode(8, INPUT_PULLUP);
newData = false;
}
void loop() {
// put your main code here, to run repeatedly:
int readBtn = digitalRead(7);
int readSend = digitalRead(8);
if (readBtn == 0)
{
ReadLastEntryThingSpeak();
}
if (readSend == 0)
{
WriteThingSpeak();
}
}
boolean connectWiFi(){
esp8266.println("AT+CWMODE=1");
delay(2000);
String cmd="AT+CWJAP=\"";
cmd+=SSID;
cmd+="\",\"";
cmd+=PASS;
cmd+="\"";
esp8266.println(cmd);
delay(5000);
if(esp8266.find("OK")){
Serial.println("OK");
return true;
}else{
Serial.println("KO");
return false;
}
}
void updateFunction(String valuetosend){
String cmd = "AT+CIPSTART=\"TCP\",\"";
cmd += IP;
cmd += "\",80";
esp8266.println(cmd);
delay(2000);
if(esp8266.find("Error")){
Serial.print("Error1");
return;
}
cmd = GET + GET1;
cmd += valuetosend;
cmd += "\r\n";
Serial.print(cmd);
esp8266.print("AT+CIPSEND=");
esp8266.println(cmd.length());
if(esp8266.find(">")){
esp8266.print(cmd);
}else{
esp8266.println("AT+CIPCLOSE");
}
}
void ReadLastEntryThingSpeak()
{
String cmd = "AT+CIPSTART=\"TCP\",\""; //connect to thingspeak
cmd += IP;
cmd += "\",80";
esp8266.println(cmd);
delay(2000);
if(esp8266.find("Error")){
Serial.print("Error1");
return;
}
cmd = readGET1;
cmd += "\r\n";
Serial.print(cmd);
esp8266.print("AT+CIPSEND=");
esp8266.println(cmd.length());
if(esp8266.find(">")){
esp8266.print(cmd);
}else{
esp8266.println("AT+CIPCLOSE");
}
delay(2000);
recvWithStartEndMarkers(); // check to see if we have
received any new commands
if (newData) { processCommand(); }
}
void WriteThingSpeak ()
{
String valuetosend = String(counter);
updateFunction(valuetosend);
}
void recvWithStartEndMarkers()
{
static boolean recvInProgress = false;
static byte ndx = 0;
char startMarker = ':';
char endMarker = 'C';
if (esp8266.available() > 0)
{
char rc = esp8266.read();
if (recvInProgress == true)
{
if (rc != endMarker)
{
if (ndx < maxDataLength) { receivedChars[ndx] = rc;
ndx++; }
}
else
{
receivedChars[ndx] = '\0'; // terminate the string
recvInProgress = false;
ndx = 0;
newData = true;
}
}
else if (rc == startMarker) { recvInProgress = true; }
}
}
void processCommand()
{
Serial.print("Recieved data = "); Serial.println(receivedChars);
newData = false;
}
I have the result of Received data = , but the actual output is Received data = 120.

Arduino Serial Returning unknown value

So right now that is my code, It is trying to read the different RGB Values for my LED Strip
However, When I get to where I ask for the green value, there is an unknown byte going through and it automatically goes straight to the else part in green();
I didn't input anything yet but Serial says there is something there. What is it?
#define REDPIN 5
#define GREENPIN 6
#define BLUEPIN 3
#define FADESPEED 5 // make this higher to slow down
void setup() {
pinMode(REDPIN, OUTPUT);
pinMode(GREENPIN, OUTPUT);
pinMode(BLUEPIN, OUTPUT);
Serial.begin(9600);
Serial.println("Starting Program....");
start();
}
int g = 0;
char val = 0;
String valstr = "";
void loop(){
if(Serial.available() > 0){
val = Serial.read();
if(val != '\n'){
valstr += val;
}
else{
Serial.println(valstr);
if (valstr != "Yes"){
valstr = "";
start();
}
else{
Serial.print("Now Asking for RGB values: \n");
Serial.println("What is green value: ");
green();
//
//
valstr = "";
// start();
}
valstr = "";
// green();
}
}
}
void start(){
Serial.print("Do you want a new color? Enter Yes/No: ");
}
char gbyte = 0;
String gstr = "";
boolean not_number;
int gnum = 256;
void green(){
if(Serial.available() > 0)
gbyte = Serial.read();
if ((gbyte >= '0') && (gbyte <= '9')) {
gstr += gbyte;
}
else if(gbyte == ' '){
Serial.println("This is not a number! \n");
Serial.println("Enter a valid number!");
gstr = "";
gbyte = Serial.read();
}
else{
Serial.println(gstr);
Serial.println("This is a number");
}
gstr += gbyte;
// gnum = gstr.toInt();
// if((gnum >= 0) && (gnum <= 255))
I think the issue is with the parsing of the integer from the serial port. Arduino has a built-in function for this :
https://www.arduino.cc/en/Reference/ParseInt

Resources