Store WIFI Credentials - arduino

When I call WiFi.begin(ssid, pass), it saves your credentials. So next time your sketch runs, it will connect automatically.
But if I call WiFi.config(IP, Gate, Subnet) before that, it connects without using the DHCP server.
But after restart it's using DHCP again.
It seems to me that the WiFi.config parameters are not stored anywhere for further usage. Am I right? What should I do to store them?

To store WiFi credentials and IP settings, you would use SPIFFS. I suggest you also to store SSID and pass in a file despite WiFi core stores it.
Here is basic file operation on SPIFFS to store some data on it :
#include "FS.h"
SPIFFS.begin();
File configFile = SPIFFS.open("config.txt", "w+");
if (configFile)
{
configFile.println(IP);
configFile.println(WiFi.SSID());
// and so on ..
}
configFile.close();
Please consider the file r/w operation options declared in the SPIFFS doc.
Here is also a good config file example with JSON.

Related

How to send hx711 data to remote database server using a nodemcu?

I want to create a digital scale and view it's readings live in my website. I am using a nodemcu for this purpose. I have created a small program that reads the data from a hx711 amp which is connected to 2 loadcells. Now I want to take that data and send it to a database server and then pull the data into my website. I have searched a lot and followed a lot of tutorials but cannot understand how to get the data from the loadcell to the database. Here is my code that can read the loadcells :
#include "HX711.h"
#define calibration_factor 895000 //random value, i can adjust it later
#define DOUT D1
#define CLK D2
HX711 scale(DOUT, CLK);
void setup(){
Serial.begin(115200);
Serial.println("Claibrate");
scale.set_scale(calibration_factor);
scale.tare();
Serial.println("OK");
}
void loop(){
Serial.print("Reading");
Serial.print(scale.get_units(), 3);
Serial.println("kg");
}
This is my first time doing a iot project so please help me somebody and also let me know if I missed out some vital info.
I'm not sure what the exact issue is here, or maybe you are just getting started, but here are a couple of suggestions:
if you want to store time series data, InfluxDB is nice and fast, simple and appropriate. So you would install InfluxDB ideally on your web-server host, or possibly on a PC or a Raspberry Pi somewhere on your network. Then send your readings from the NodeMCU with the InfluxDB client like this
you might like to use Redis which is extremely fast and lightweight. So you could run that on your web-server host, or some other PC or Raspberry Pi on your network and use a Redis client on NodeMCU to push the readings into a Redis LIST where your web-server could pick them up from. This is nice and easy because you can inject data into Redis and also read it straight from the command-line which is great for testing and debugging. Example here.
if you want to use some other database, you could use MQTT on your NodeMCU to send your readings to a broker, such as Mosquitto installed and running on your web-server host. You could then have a "bridge" that subscribes to the "weight" topic and when readings arrive, it could then push them into any database you like. Example here.

Facing issue with file download using ESP32 webserver

I am developing code for ESP32 (16MB) using PlatformIO with Arduino framework, On ESP32, I am using both Bluetooth as well as Wi-Fi connectivity. When Mobile App is connected with Bluetooth of ESP32 data will be sent on mobile using Bluetooth on BLE characteristics (working perfectly fine), and when Bluetooth is not connected data will be logged in .json file (have used SPIFFS library for this and file creation is working fine). When user wants to have log data, ESP32 will create Wi-Fi Access Point (AP) (used WiFi.h) and by connecting to that AP user should be able to download .json file by accessing link "192.168.4.1/download" on browser. Once the file will be downloaded on Mobile App user will access link "192.168.4.1/finisheddownload" and file will be deleted from ESP32.
after successfully connecting to AP of ESP32, while I access link "192.168.4.1/download" from browser, the code gets stuck at that point or sometimes it reboots the ESP32 and performs nothing and if I access "192.168.4.1/finisheddownload", it successfully deletes the file. My file size is around 10MB but even I perform this action when file size is of 1KB it behaves same. I have tested the same code on ESP32 (4MB) module and was able to download file for around 50KB.
I am not sure whether it is the issue of memory or library which I am using or limitation of ESP32. I am attaching code snippet along with memory partition I have used, please guide.
Error when ESP32 gets reboot after accessing link for file download:
abort() was called at PC 0x401d844b on core 1
Backtrace: 0x40092b60:0x3ffcf8e0 0x40092d91:0x3ffcf900 0x401d844b:0x3ffcf920 0x401d8492:0x3ffcf940 0x401bf359:0x3ffcf960 0x401bf0dc:0x3ffcf980 0x400fa67e:0x3ffcf9a0 0x400fa75a:0x3ffcf9d0 0x400e62b9:0x3ffcf9f0 0x400d23e4:0x3ffcfa20 0x400d27e3:0x3ffcfa40 0x400d2ed7:0x3ffcfa70 0x400d35f1:0x3ffcfa90 0x400e9151:0x3ffcfb10 0x4008f275:0x3ffcfb30
Rebooting...
rst:0xc (SW_CPU_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:2
load:0x3fff0018,len:4
load:0x3fff001c,len:1044
load:0x40078000,len:8896
load:0x40080400,len:5828
entry 0x400806ac
Code snippet:
void downloadfile(){ //function to download file on mobile App
delay(500);
do{
BLEAdvertising *pAdvertising = pServer->getAdvertising();
pAdvertising->stop();
if(!SPIFFS.begin()){
Serial.println("An Error has occurred while mounting SPIFFS");
return;
}
WiFi.mode(WIFI_AP);
delay(100);
Serial.print("Setting soft-AP ... ");
Serial.println(WiFi.softAP("ESP32","123456789") ? "Ready" : "Failed!");
Serial.print("Soft-AP IP address = ");
Serial.println(WiFi.softAPIP());
delay(100);
// send a file when /download is requested
server.on("/download", HTTP_ANY, [](AsyncWebServerRequest *request){
request->send(SPIFFS, "/file1.json", "text/plain", true);
});
server.on("/finisheddownload", HTTP_GET, [](AsyncWebServerRequest *request){
logfile.del_file();
request->send(200, "text/html", "Download complete response");
delay(500);
Actual_filexist = 0;
WiFi.softAPdisconnect(true);
BLEAdvertising *pAdvertising = pServer->getAdvertising();
pAdvertising->start();
delay(500);
});
server.begin();
delay(500);
}while(Actual_filexist == 1);
}
memory partition:
#name Type Subtype Offset Size Flags
nvs data nvs 0x9000 0x7000
app0 app ota_0 0x10000 0x2A0000
eeprom data 0x99 0x2F0000 0x1A8CE0
spiffs data spiffs 0x498CE0 0xA7D8C0
Memory usage:
RAM: [== ] 19.9% (used 65292 bytes from 327680 bytes)
Flash: [====== ] 60.1% (used 1654361 bytes from 2752512 bytes)
Thank you....
You're using ESPAsyncWebServer. Its documentation explicitly states that you should not call delay() or yield() or any function that calls them in callbacks from the web server (Important things to remember. You're calling delay() twice in the /finisheddownload handler.
You're also calling WiFi.softAPdisconnect() in the handler before the handler can return, which means you're turning off Wifi before the callback returns and potentially before the response is sent to the browser. It's not safe to do this in the callback.
You need to do as little as possible in the callback from the web server. Rewrite that handler to set a flag which loop() will inspect so that all of the work it does except for the call to request->send() is actually done in loop().

How to get date and time of uploaded firmware?

I have some kind of smart home on multiple esp8266, and I periodically update code of their firmwares via Arduino OTA.
And sometimes I forget to upload actual code on them. For example, I don't remember, if I uploaded a new version of firmware to esp8266, that serves in toilet :) .
Each of Arduino esp8266 firmware is *.bin file, if I understood it correctly. Each of file has time of creation.
And question is - does esp8266 store date and time of firmware, uploaded via OTA (or update) and is there any Arduino program method to get that date and time?
// Provided by compiler at compile time.
const char compile_date[] = __DATE__ " " __TIME__;
Serial.print("Compile timestamp: ");
Serial.println(compile_date);
Or add a Webserver endpoint that returns it, like http://device-ip/info
If you use an IDE like Visualcode you might be able to setup an auto build number define.
Personally I'm working on an ESP Manager. A small wrapper you include in your sketch, which establishes your Wifi, broadcasts it's firmwareId and mac address. A python server listens for these, compares them to a list of devices by mac and what firmware they should be running and if there is a missmatch, flashes them OTA. You can see from it's logs what everything is running.
I have it working, but not checked in yet, PM me if interested, or maybe I'll comment back with a link later.
You should make a function that returns the version and set the version each time before upload.
For example:
const String version = "3.51";
then return it to serial, html page dedicated, OTA Server Page method or mqtt.
I think there is no easy way like you are trying.

Arduino Local Network DHCP Failed

Hi there,
I will search and tried lots of solution for our problem but none of works. This will be a long post so be ready.
Our System:
We have an arduino uno r3 clone and ethernet shield wiznet w5100,
This Arduino makes a http post request to a windows web service.
According to response arduino will make something that is not revelant to question.
So in our test environment, we will install a windows webservice to our windows machine and plug this machine to our local network. Then plug arduino to our local network too. than with our server ip ,arduino made an dhcp request get ip from our modem-router and can call webservices from our server.
From now on everything works fine.
Here is some sample code from our arduino.(I only use this extra library for arduino:"RestClient.h"
#include <Ethernet.h>
#include <SPI.h>
#include "RestClient.h"
RestClient client = RestClient("192.168.100.17",51200);
String response;
String PostData;
void setup()
{
Serial.begin(9600);
byte mac[] = { 0x04, 0xD6, 0x2E, 0x81, 0x01, 0xB0 };
if ( Ethernet.begin(mac) == 0) {
Serial.println("Failed to configure Ethernet using DHCP");
}
delay(1000);
Serial.println(Ethernet.localIP());
}
void postDataToServer(long rfidnumber,int rfidsource){
String postedRFIDNumber=String(rfidnumber);
postedRFIDNumber="000"+postedRFIDNumber;
response = "";
PostData="RFID="+postedRFIDNumber+"&SOURCE="+rfidsource;
const char * myPost = PostData.c_str();
int statusCode =
client.post("/sqlpublish/TTSWebService.asmx/INSERT_INDEXRFID",myPost,&response);
}
We need to install our system to a company. This Company has its own local network. they have very restricted local network. You can connect their network but can not go to the "www" without their permissions. But that is not problem. We will use only local connection for our web services because we will also use an windows server which will inside local network.
This is a picture of their network system schema:
In this picture switches is missing but you can simply guess they uses lots of swtiches .Because company is very wide and have lots of device.
So if I connect any device to their local network , this device first call dhcp protocals get ip from Windows DHCP Server and then can communicate in the local network with other devices. But can not get through the internet modem because of the firewall in the router.
Then We will setup our system like this:
In this setup switch models are : "AVAYA".
VSP7000 XLS
ERS4826 GTS-PWR+
ERS3549 GTS-PWR+
Firewall is: Watchguard Firebox M300
When we setup the system something weird is going on. First of all when I connect my PC(My Device) to local network I can call webservices in the windows server. But Arduino cannot get IP from DHCP Server, and naturaly cannot connect to web services. So we think that "ok we can give IP static". Than we will give IP to our Arduino manually. After that weird things started to begin. When Arduino try to conenct our Windows webservices it only get response some times. Roughly 1 of 20 has got response from server anything else get time out connection.And also succeded response time also too long.
If we ping our static arduino IP From another Device(For example Device_1), It get response sometimes again. (Same Amount)
So then we try to narrow down our problem.
First Of All We Change the setup like this for once to make sure problem in local network.
And Normaly all systems works perfectly. So our Modem's DHCP server make it works perfectly.(Also in this setup If I give Ip static it worked too).
So there is these possibilties for connection error.
1-Firewall
2-Switch problem
3-Arduino Clon Problem.
1-Firewall
When We talked about the problem with system admin, He told ust every local network connection and port is open in the firewall. He is probably right because any pc connect to local network can call the web sevice.
2-Switch problem
This Question, talks about it as a solution it says use static ip, bu in our case it did not solve the problem.
In this Question jdr5ca answer make sense but ı hve no idea how can test the problem or solve the problem
In this Question answer tried but not working.
Lastly this post , but it is so general. and also what ı should use replace for "arping" in windows.
3-Arduino Clon Problem.
next week we try it with with original arduino ,
I will inform everybody.
SO, any suggestion,tool, or some diagnostic tool for the problem I'm open all the suggestion.
Apparently Our Problem is a specific switch model!
Here is the model: https://www.zyxel.com/tr/tr/products_services/es_108a.shtml?t=p (zyxel ES-108E)
When we directly connect arduino to zyxel switch, and ping arduino from another device in the network only some of pings successful.(Roughly %15 succeeded).
But if we use another switch model or don't directly connect to zyxel switch, it works fine.
I dont know why it is not working with zyxel but problem is the switch!

Unable to connect AWS IoT to Arduino Yun using Basic Pub/Sub example

I am trying to establish a connection from Amazon Web Service IoT (Internet of Things) to my Arduino Yun. I followed a tutorial about sending and receiving messages using "BasicPubSub" Arduino example, but it would say:
Failed to Connect!
-13
And this means "CONNECT_CREDENTIAL_NOT_FOUND". I have the correct credentials and information in the header file and also have the correct files, which are: xxx-certificate.pem.crt, xxx-private.pem.key, and root_certificate.pem in a directory, "/root/certs/", when I SSH into the Arduino Yun. The following is my header file:
#ifndef config_usr_h
#define config_usr_h
// Copy and paste your configuration into this file
//===============================================================
#define AWS_IOT_MQTT_HOST "xxx.iot.us-east-1.amazonaws.com" // endpoint
#define AWS_IOT_MQTT_PORT 8883
#define AWS_IOT_CLIENT_ID "client_id" // client ID
#define AWS_IOT_MY_THING_NAME "thing_name" // thing name
#define AWS_IOT_ROOT_CA_FILENAME "root_certificate.pem" // root-CA filename
#define AWS_IOT_CERTIFICATE_FILENAME "xxx-certificate.pem.crt" // your certificate filename
#define AWS_IOT_PRIVATE_KEY_FILENAME "xxx-private.pem.key" // private key
//===============================================================
// SDK config, DO NOT modify it
#define AWS_IOT_PATH_PREFIX "../certs/"
#define AWS_IOT_ROOT_CA_PATH AWS_IOT_PATH_PREFIX AWS_IOT_ROOT_CA_FILENAME // use this in config call
#define AWS_IOT_CERTIFICATE_PATH AWS_IOT_PATH_PREFIX AWS_IOT_CERTIFICATE_FILENAME // use this in config call
#define AWS_IOT_PRIVATE_KEY_PATH AWS_IOT_PATH_PREFIX AWS_IOT_PRIVATE_KEY_FILENAME // use this in config call
#endif
So my problem is that the Arduino Yun is not recognizing the files in the directory "/root/certs/" where the credentials are to connect to AWS IoT. Please help me on this issue. Thank you in advance.
For anybody else that hits this, I just encountered this when running a previously working bit of code based on the ThingSample. With the newest api (2.1.0), from what I can work out it seems that the place to put the certs folder has changed. The folder should be in /root/AWS-IoT-Python-Runtime/runtime/certs. The setup script did NOT put the certs in that folder unfortunately.

Resources