How to follow sketch upload progress on Arduino? - upload

When we upload a sketch to Arduino using OTA, we can follow upload progression using the following script and do some display accordingly.
How can we achieve the same using wired sketch upload?
ArduinoOTA.onStart([]() {
String type;
if (ArduinoOTA.getCommand() == U_FLASH)
type = "sketch";
else // U_SPIFFS
type = "filesystem";
// NOTE: if updating SPIFFS this would be the place to unmount SPIFFS using SPIFFS.end()
drawProgressBarOTA(0, "Receiving update");
});
ArduinoOTA.onEnd([]() {
drawProgressBarOTA(100, "Rebooting");
ESP.restart();
});
ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
drawProgressBarOTA((progress / (total / 100)));
});
ArduinoOTA.onError([](ota_error_t error) {
Serial.printf("Error[%u]: ", error);
if (error == OTA_AUTH_ERROR) Serial.println("Auth Failed");
else if (error == OTA_BEGIN_ERROR) Serial.println("Begin Failed");
else if (error == OTA_CONNECT_ERROR) Serial.println("Connect Failed");
else if (error == OTA_RECEIVE_ERROR) Serial.println("Receive Failed");
else if (error == OTA_END_ERROR) Serial.println("End Failed");
});
ArduinoOTA.begin();

Related

crash while reading the socket data - recv() - in objective-c

I'm trying to read data from the socket and it works fine most of the time.
When I run the app for longer duration - app crashes and crashlytics points the crash to readingSocket() - this function just reads raw data from socket.
Below is code of readingSocket()
-(bool) readingSocket:(NSMutableData*)dataIn readBytes:(ssize_t)quantity error:(NSError **)error {
ssize_t readBytesNow = 0;
ssize_t grossRead= 0;
[dataIn setLength:0];
if (error != nil) {
*error = nil;
}
char *buffer = new char[6144];
do {
ssize_t readBytes = (quantity - grossRead);
readBytesNow = recv((int)raw_Socket, buffer, readBytes , MSG_DONTWAIT);
if (readBytesNow == 0) {
NSLog(#" read error");
delete[] buffer;
return false;
}
Else if (bytesRead < 0) {
if (errno == EAGAIN) {
[NSThread sleepForTimeInterval:0.5f];
NSLog(#" EAGAIN error");
continue;
}
else {
// if error != nil
delete[] buffer;
return false;
}
}
else if (readBytesNow > 0) {
grossRead += readBytesNow;
// doing some operations
}
} while (grossRead < quantity);
delete[] buffer;
return true;
}
I'm already doing so many checks after reading but not sure where could the probable cause for the crash or exception ??
any other better way to handle exception in my above code ?
I can't comment without 50 reputation (new user here), so here goes my comment as an answer.
Warning: I have no idea of the language your code is written, but I'm using my instincts as a C++ programmer (and probably mediocre one at it).
First thing I noticed was this piece of code:
if (error != nil) {
*error = nil;
}
In C world, this would be similar to checking if a pointer is null, but assigning null as its value afterwards.
Second thing to note is this construct:
-(bool) readingSocket:(NSMutableData*)dataIn readBytes:(ssize_t)quantity error:(NSError **)error {
...
char *buffer = new char[6144];
...
ssize_t readBytes = (quantity - grossRead);
When quantity > 6144 i.e. once in a blue moon, your network stack might read more than 6144 bytes which would result in a buffer overflow.
Tangential comments:
1) I think you should note that EAGAIN and EWOULDBLOCK may be the same value but not guaranteed. You might consider checking for both of them if you are not certain that your platform behaves exactly as you think.
An example link to Linux documentation
2) Your logic,
if (readBytesNow == 0) {
...
} Else if (bytesRead < 0) {
...
} else if (readBytesNow > 0) {
...
}
although being verbose, is unnecessary. You can use
if (readBytesNow == 0) {
...
} Else if (bytesRead < 0) {
...
} else {
...
}
to be sure you are not getting an additional comparison. This comparison might get optimised out anyway, but writing this way makes more sense. I had to look again to see "if I am missing something".
Hope these help.

ESP8266 WeMos D1 using deepsleep drains too much battery

I've developed a fingerprint sensor using NodeMCU D1 mini powered by a 1000mah battery.
Everything seems working correctly except for battery energy consumption.
I have read several topic where user says that using deepsleep fuction on NodeMCU 1000mah battery should last more than 3 month but mine doesn't reach 2 days.
This is my circuit schematic
I also report here my code snipped that I'm currently using. The circuit should wake up from deepsleep when the button is pressed and start reading the fingerprint sensor. If it detect a valid fingerprint, a message is sent to MQTT broker.
#include <Adafruit_Fingerprint.h>
#include <ESP8266WiFi.h>
#include <PubSubClient.h>
const char* _ssid = "ZZZXXXYYY";
const char* _password = "pass";
const char* mqttServer = "IPADDRESS";
const int mqttPort = 1883;
const char* mqttUser = "USER";
const char* mqttPassword = "PASS";
long initialMillis = 0;
unsigned int raw=0;
// On Leonardo/Micro or others with hardware serial, use those! #0 is green wire, #1 is white
// uncomment this line:
//#define mySerial Serial
// For UNO and others without hardware serial, we must use software serial...
// pin #2 is IN from sensor (GREEN wire)
// pin #3 is OUT from arduino (WHITE wire)
// comment these two lines if using hardware serial
SoftwareSerial mySerial(4, 5);
WiFiClient espClient;
PubSubClient client(espClient);
Adafruit_Fingerprint finger = Adafruit_Fingerprint(&mySerial);
void setup()
{
Serial.begin(9600);
pinMode(A0, INPUT);
// Connect to Fingerprint. Set the data rate for the sensor serial port
finger.begin(57600);
delay(5);
if (finger.verifyPassword()) {
Serial.println("Found fingerprint sensor!");
} else {
Serial.println("Did not find fingerprint sensor :(");
ESP.deepSleep(10 * 1000000);
}
finger.getTemplateCount();
// Connect to WIFI
WiFi.mode(WIFI_STA);
WiFi.begin(_ssid, _password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
// Connect to MQTT
client.setServer(mqttServer, mqttPort);
while (!client.connected()) {
Serial.println("Connecting to MQTT...");
if (client.connect("ESPFingerprint", mqttUser, mqttPassword )) {
Serial.println("Connected to MQTT server");
} else {
Serial.print("failed with state ");
Serial.print(client.state());
delay(2000);
}
}
// Calculate battery percentage
raw = analogRead(A0);
String bLevel = "{\"Battery\":" + String(raw) + "}";
Serial.print("Battery: ");
Serial.print(raw);
Serial.print(" -> ");
Serial.println(bLevel);
initialMillis = millis();
client.publish("tele/fingerprint/LWT", "Online");
client.publish("tele/fingerprint/STATE", (char*)bLevel.c_str(), true);
Serial.print("MQTT subscribed: ");
Serial.println(WiFi.localIP());
}
void loop()
{
unsigned long currentMillis = millis();
int fid = getFingerprintIDez();
if(fid != -1) {
String fpIdstr = String(fid);
client.publish("cmnd/fingerprint/RESULT", (char*)fpIdstr.c_str());
Serial.println("Fingerprint correct. Going to sleep.");
client.publish("tele/fingerprint/LWT", "Offline");
// trigger disconnection from MQTT broker to correctly send the message before going to sleep
client.disconnect();
espClient.flush();
// wait until connection is closed completely
while(client.state() != -1){
delay(10);
}
ESP.deepSleep(0);
}
else if(currentMillis - initialMillis >= 15000){
Serial.println("Timeout expired. Going to sleep.");
client.publish("tele/fingerprint/LWT", "Offline");
ESP.deepSleep(0);
}
delay(50); //don't ned to run this at full speed.
}
uint8_t getFingerprintID() {
uint8_t p = finger.getImage();
switch (p) {
case FINGERPRINT_OK:
Serial.println("Image taken");
break;
case FINGERPRINT_NOFINGER:
Serial.println("No finger detected");
return p;
case FINGERPRINT_PACKETRECIEVEERR:
Serial.println("Communication error");
return p;
case FINGERPRINT_IMAGEFAIL:
Serial.println("Imaging error");
return p;
default:
Serial.println("Unknown error");
return p;
}
// OK success!
p = finger.image2Tz();
switch (p) {
case FINGERPRINT_OK:
Serial.println("Image converted");
break;
case FINGERPRINT_IMAGEMESS:
Serial.println("Image too messy");
return p;
case FINGERPRINT_PACKETRECIEVEERR:
Serial.println("Communication error");
return p;
case FINGERPRINT_FEATUREFAIL:
Serial.println("Could not find fingerprint features");
return p;
case FINGERPRINT_INVALIDIMAGE:
Serial.println("Could not find fingerprint features");
return p;
default:
Serial.println("Unknown error");
return p;
}
// OK converted!
p = finger.fingerFastSearch();
if (p == FINGERPRINT_OK) {
Serial.println("Found a print match!");
} else if (p == FINGERPRINT_PACKETRECIEVEERR) {
Serial.println("Communication error");
return p;
} else if (p == FINGERPRINT_NOTFOUND) {
Serial.println("Did not find a match");
return p;
} else {
Serial.println("Unknown error");
return p;
}
// found a match!
Serial.print("Found ID #"); Serial.print(finger.fingerID);
Serial.print(" with confidence of "); Serial.println(finger.confidence);
return finger.fingerID;
}
// returns -1 if failed, otherwise returns ID #
int getFingerprintIDez() {
uint8_t p = finger.getImage();
if (p != FINGERPRINT_OK) return -1;
p = finger.image2Tz();
if (p != FINGERPRINT_OK) return -1;
p = finger.fingerFastSearch();
if (p != FINGERPRINT_OK) return -1;
// found a match!
Serial.print("Found ID #"); Serial.print(finger.fingerID);
Serial.print(" with confidence of "); Serial.println(finger.confidence);
return finger.fingerID;
}
Can somebody let me know if there is something wrong in my code or circuit?

I'm not able to reconnect to WiFi automatically after interruption in the router when using ESP8266

Here is my code to connect to a WiFi network using EPS8266. I connected a DHT sensor to ESP. I'm able to get data when there is no interruption if interruption occurs at the router I'm not getting sensor data and also I'm not able to reconnect to the WiFi network
static void wifi_task(void * pvParameters) {
uint8_t status = 0;
uint8_t retries = 30;
struct sdk_station_config config = {
.ssid = "CloveIOT",
.password = "CloveIOT",
};
printf("WiFi: connecting to WiFi\n\r");
sdk_wifi_set_opmode(STATION_MODE);
sdk_wifi_station_set_config( & config);
while (1) {
while ((status != STATION_GOT_IP) && (retries)) {
status = sdk_wifi_station_get_connect_status();
printf("%s: status = %d\n\r", __func__, status);
if (status == STATION_WRONG_PASSWORD) {
printf("WiFi: wrong password\n\r");
break;
} else if (status == STATION_NO_AP_FOUND) {
printf("WiFi: AP not found\n\r");
break;
} else if (status == STATION_CONNECT_FAIL) {
printf("WiFi: connection failed\r\n");
break;
}
vTaskDelay(1000 / portTICK_PERIOD_MS);
--retries;
}
if (status == STATION_GOT_IP) {
printf("WiFi: Connected\n\r");
xSemaphoreGive(wifi_alive);
taskYIELD();
}
while ((status = sdk_wifi_station_get_connect_status()) == STATION_GOT_IP) {
xSemaphoreGive(wifi_alive);
taskYIELD();
}
printf("WiFi: disconnected\n\r");
sdk_wifi_station_disconnect();
vTaskDelay(1000 / portTICK_PERIOD_MS);
}
}
I had the same issue, now I am using this WiFi connection method which works well.
Before using delay(1200); it did not work and stalled on WiFi.status() != WL_CONNECTED.
void connectWiFi() {
WiFi.disconnect();
delay(1200);
WiFi.mode(WIFI_STA);
Serial.println(F("connectWiFi"));
WiFi.begin(ssid, password);
// wait for connection
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(F("."));
}
Serial.println(F(""));
Serial.print(F("Connected to "));
Serial.println(ssid);
Serial.print(F("IP address: "));
Serial.println(WiFi.localIP());
}

How to create certificate request with OpenSSL library

I am trying to create certificate request programmatically in iOS using openSSL. I got testKey.pem(private key) and test.csr finally and the first works well in linux(by openssl command), however test.csr seams strange and cannot be recognized and used properly. here is my code in OC.
- (void)genCertReq {
if (!X509_REQ_set_version(csr.req, csr.ver)) {
LOG(#"set_version failed");
goto error;
}
[self fillDN];
/* subject name */
if (!X509_REQ_set_subject_name(csr.req, csr.subject)) {
LOG(#"subject_name failed");
goto error;
}
rsaPair = RSA_generate_key(bits, e, NULL, NULL);
const char *keyPathChar = [SPFileManager openFile:testKey];
BIO *bp = NULL;
bp = BIO_new_file(keyPathChar, "w");
PEM_write_bio_RSAPrivateKey(bp, rsaPair, NULL, NULL, 0, NULL, NULL);
BIO_free(bp);
/* pub key */
if (1 != EVP_PKEY_assign_RSA(evpKey, rsaPair)) {
LOG(#"assign_RSA failed");
goto error;
}
if (!X509_REQ_set_pubkey(csr.req, evpKey)) {
LOG(#"set_pubkey failed");
goto error;
}
/* attribute */
csr.md = EVP_sha1();
if (!X509_REQ_digest(csr.req, csr.md, (unsigned char *)csr.mdout, (unsigned int *)&csr.mdlen)) {
LOG(#"req_digest failed");
goto error;
}
if (!X509_REQ_sign(csr.req, evpKey, csr.md)) {
LOG(#"req_sign failed");
goto error;
}
const char *csrPathChar = [SPFileManager openFile:csrName];
bp = BIO_new_file(csrPathChar, "w");
PEM_write_bio_X509_REQ(bp, csr.req);
BIO_free(bp);
OpenSSL_add_all_algorithms();
if (X509_REQ_verify(csr.req, evpKey) < 0) {
LOG(#"req_verify failed");
goto error;
}
X509_REQ_free(csr.req);
return;
error:
X509_REQ_free(csr.req);
return;
}
testKey.pem is in PKCS1 format and looks like --BEGIN RSA PRIVATE KEY---, and test.csr looks like ---BEGIN CERTIFICATE REQUEST--- which however I don't think is right.
Any help will be appreciated, thanks.

ARDUINO tweet many times

I want to tweet corresponding to a situation which means I need to tweet many times. I did like this:
void loop() {
checkState();
}
void tweet() {
Serial.println("Connecting to Twitter");
if (twitter.post("input is greater than 5")) {
Serial.print(dataString);
int status = twitter.wait();
if (status == 200) {
Serial.println("Successful");
} else {
Serial.println("Tweet failed.");
Serial.println(status);
}
} else {
Serial.println("Connection to Twitter failed");
}
Serial.println("30 Seconds timeout started");
delay(3000);
}
void checkState() {
// read input and append to the string:
char analogPin = 0;
char input = analogRead(analogPin);
dataString = input;
if (input >= 1023) {
tweet();
delay(2000);
}
}
But it doesn't work. Do you have any suggestion?

Resources