esp32 + ota + doublereset

This commit is contained in:
2023-09-27 14:09:52 +02:00
parent 3fc594b824
commit 31fea83a3a
17 changed files with 1516 additions and 483 deletions

View File

@@ -0,0 +1,2 @@
#include "esphome.h"

View File

@@ -1,19 +1,23 @@
Anode0Pin 5=PD5= PIN 11 (ANT0) ==> GPIO10
Anode1Pin 7=PD7= PIN 13 (ANT1) ==> GPIO3
Anode2Pin 8=PB0= PIN 14 (ANT2) ==> GPIO8
Anode0Pin 5=PD5= PIN 11 (ANT0) ==> GPIO5 gr - ok
Anode1Pin 7=PD7= PIN 13 (ANT1) ==> GPIO13 gr - ok
Anode2Pin 8=PB0= PIN 14 (ANT2) ==> GPIO17 gr - ok
LEpin=10=PB2= PIN 16 (LE) ==> GPIO7
LEpin=10=PB2= PIN 16 (LE) ==> GPIO22 gr - ok
MOSI=PB3 PIN 17 (MOSI) ==> GPIO6
SCK=PB5 PIN 19 (SCK) ==> GPIO5
MOSI=PB3 PIN 17 (MOSI) ==> GPIO23 gr - ok
SCK=PB5 PIN 19 (SCK) ==> GPIO18 gr - ok
SDA=PC4 PIN 27 (SDA) ==> GPIO0
SCL=PC5 PIN 28 (SCL) ==> GPIO1
SDA=PC4 PIN 27 (SDA) ==> x
SCL=PC5 PIN 28 (SCL) ==> x
MODE=A0 =PC0 PIN 23 (SW1) ==> x
DOWN=A1 =PC1 PIN 24 (SW2) ==> GPIO4
UP=A2 =PC2 PIN 25 (SW3) ==> GPIO2
MODE=A0 =PC0 PIN 23 (SW1) ==> GPIO16 pa - ok
DOWN=A1 =PC1 PIN 24 (SW2) ==> GPIO4 pa - ok
UP=A2 =PC2 PIN 25 (SW3) ==> GPIO2 pa - ok
LEDR=9=PB1 PIN 15 (PWM2) x
LEDG=6=PD6 PIN 12 (PWM1) x
LEDB=3=PD3. PIN 5 (PWM3) x
LEDR=9=PB1 PIN 15 (PWM2) ==> GPIO25 ye - ok
LEDG=6=PD6 PIN 12 (PWM1) ==> GPIO26 ye - ok
LEDB=3=PD3 PIN 5 (PWM3) ==> GPIO27 ye - ok
GND pin 8 ok
VCC PIN 7 ok

View File

@@ -8,16 +8,19 @@
; Please visit documentation for the other options and examples
; https://docs.platformio.org/page/projectconf.html
[env:seeed_xiao_esp32c3]
[env:esp32]
platform = espressif32
board = seeed_xiao_esp32c3
board = esp32dev
framework = arduino
monitor_speed = 115200
lib_deps =
paulstoffregen/Time@^1.6.1
jchristensen/Timezone@^1.2.4
ESPNtpClient
build_src_filter = ${env.build_src_filter}
khoih-prog/ESP_WifiManager@^1.12.1
LittleFS
#jandrassy/ArduinoOTA@^1.0.11
lib_ldf_mode = deep+
build_flags =
-DCORE_DEBUG_LEVEL=3
-DNDEF_DEBUG=1
-DNDEF_DEBUG=1
upload_protocol = espota
upload_port = nixie_clock.local

View File

@@ -1,17 +1,14 @@
#include "clock.h"
bool RTC_present;
bool NTPinit = false;
// Central European Time (Frankfurt, Paris)
bool RTC_present = false;
bool provider_Set = false;
// // Central European Time (Frankfurt, Paris)
TimeChangeRule CEST = {"CEST", Last, Sun, Mar, 2, 120}; // Central European Summer Time
TimeChangeRule CET = {"CET ", Last, Sun, Oct, 3, 60}; // Central European Standard Time
Timezone myTZ(CEST, CET);
TimeChangeRule *tcr;
bool timeIsSet()
{
return RTC_present;
@@ -29,31 +26,34 @@ void printDateTime(time_t t, const char *tz)
time_t getLocalTime()
{
if(!getWifiStatus) return 0;
time_t utc = getNtpTime();
if(!getWifiStatus()) return 0;
time_t utc;
time(&utc);
time_t local = myTZ.toLocal(utc, &tcr);
printDateTime(local,tcr -> abbrev);
printDateTime(utc,"UTC");
return utc;
return local;
}
void initClock()
{
initWifi();
getLocalTime();
}
void loopClock()
{
if(getWifiStatus())
if(getWifiStatus())
{
if(!NTPinit && getWifiStatus())
if(getWifiStatus() & !provider_Set)
{
initNTP();
setSyncProvider(getLocalTime);
setSyncInterval(300);
NTPinit = true;
setSyncInterval(10);
provider_Set = true;
log_i("timesync provider set");
}
RTC_present = timeStatus ? timeSet: true, false;
}
else

View File

@@ -1,17 +1,12 @@
#pragma once
#include <Arduino.h>
#include "ntp.h"
#include "TimeLib.h"
#include "connection.h"
#include "util.h"
#include <Timezone.h> // https://github.com/JChristensen/Timezone
#include <ESPNtpClient.h>
void initClock();
void loopClock();
String getTimeNow();
String updateDateString();
// bool isValidDate();
bool timeIsSet();

View File

@@ -0,0 +1,16 @@
#include "connection.h"
bool printed = false;
bool wifiConnected = false;
bool getWifiStatus()
{
wifiConnected = WiFi.status() == WL_CONNECTED;
if(!printed && wifiConnected)
{
log_i("IP number assigned by DHCP is %s",WiFi.localIP());
printed = true;
}
return wifiConnected;
}

View File

@@ -0,0 +1,6 @@
#pragma once
#include "Arduino.h"
#include <WiFi.h>
bool getWifiStatus();

View File

@@ -0,0 +1,41 @@
#pragma once
#define Anode0Pin 5
#define Anode1Pin 13
#define Anode2Pin 17
#define mosiPin 23
#define misoPin 19
#define sckPin 18
#define LEpin 22
#define upPin 2
#define downPin 4
#define modePin 16
#define ledRPin 25
#define ledGPin 26
#define ledBPin 27
#define Anode0ON digitalWrite(Anode0Pin,HIGH)
#define Anode0OFF digitalWrite(Anode0Pin,LOW)
#define Anode1ON digitalWrite(Anode1Pin,HIGH)
#define Anode1OFF digitalWrite(Anode1Pin,LOW)
#define Anode2ON digitalWrite(Anode2Pin,HIGH)
#define Anode2OFF digitalWrite(Anode2Pin,LOW)
#define TimeIndex 0
#define DateIndex 1
// #define AlarmIndex 2
// #define hModeIndex 3
// #define TimeHoursIndex 4
// #define TimeMintuesIndex 5
// #define TimeSecondsIndex 6
// #define DateDayIndex 7
// #define DateMonthIndex 8
// #define DateYearIndex 9
// #define AlarmHourIndex 10
// #define AlarmMinuteIndex 11
// #define AlarmSecondIndex 12
// #define Alarm01 13
// #define hModeValueIndex 14

View File

@@ -1,83 +1,9 @@
#include <Arduino.h>
#include "clock.h"
#include <SPI.h>
#include <Wire.h>
#define Anode0Pin 10
#define Anode1Pin 3
#define Anode2Pin 8
#define Anode0ON digitalWrite(Anode0Pin,HIGH)
#define Anode0OFF digitalWrite(Anode0Pin,LOW)
#define Anode1ON digitalWrite(Anode1Pin,HIGH)
#define Anode1OFF digitalWrite(Anode1Pin,LOW)
#define Anode2ON digitalWrite(Anode2Pin,HIGH)
#define Anode2OFF digitalWrite(Anode2Pin,LOW)
#define mosiPin 5
#define misoPin 9
#define sckPin 6
#define LEpin 7
#define TimeIndex 0
#define DateIndex 1
// #define AlarmIndex 2
// #define hModeIndex 3
// #define TimeHoursIndex 4
// #define TimeMintuesIndex 5
// #define TimeSecondsIndex 6
// #define DateDayIndex 7
// #define DateMonthIndex 8
// #define DateYearIndex 9
// #define AlarmHourIndex 10
// #define AlarmMinuteIndex 11
// #define AlarmSecondIndex 12
// #define Alarm01 13
// #define hModeValueIndex 14
String updateDateString();
String updateDisplayString();
// void doDotBlink();
// void checkAlarmTime();
// String PreZero(int digit);
word doEditBlink(int pos);
// byte decToBcd(byte val);
String antiPoisoning2(String fromStr, String toStr);
// String getTimeNow();
String antiPoisoning2(String fromStr, String toStr);
bool doTest();
// void getRTCTime();
void modesChanger();
void doIndication();
const word fpsLimit=16666; // 1/60*1.000.000 //limit maximum refresh rate on 60 fps
String stringToDisplay="000000";// Conten of this string will be displayed on tubes (must be 6 chars length)
int menuPosition=0; // 0 - time
// 1 - date
// 2 - alarm
// 3 - 12/24 hours mode
// 0 1 2 3 4 5 6 7 8 9
//word SymbolArray[10]={65534, 65533, 65531, 65527, 65519, 65503, 65471, 65407, 65279, 65023};
word SymbolArray[10]={1022, 1021, 1019, 1015, 1007, 991, 959, 895, 767, 511};
byte dotPattern=B00000000; //bit mask for separeting dots
//B00000000 - turn off up and down dots
//B1100000 - turn off all dots
int teststate = -1;
String testStringArray[12]={"000000","111111","222222","333333","444444","555555","666666","777777","888888","999999","",""};
unsigned long startOfTest;
#include "defines.h"
#include "wifimanager.h"
#include "tubes.h"
#include "ota.h"
/*******************************************************************************************************
Init Programm
@@ -88,252 +14,34 @@ void setup()
Serial.begin(115200);
log_i("init hardware");
initTubes();
pinMode(ledRPin, OUTPUT);
pinMode(ledGPin, OUTPUT);
pinMode(ledBPin, OUTPUT);
pinMode(LEpin, OUTPUT);
// SPI setup
SPI.begin(mosiPin,misoPin,sckPin); //
SPI.setDataMode (SPI_MODE3); // Mode 3 SPI
SPI.setClockDivider(SPI_CLOCK_DIV128); // SCK = 16MHz/128= 125kHz
pinMode(Anode0Pin, OUTPUT);
pinMode(Anode1Pin, OUTPUT);
pinMode(Anode2Pin, OUTPUT);
digitalWrite(ledRPin, 0);
digitalWrite(ledGPin, 0);
digitalWrite(ledBPin, 0);
log_i("init clock");
setupwifiman();
initClock();
initOTA();
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
while(!timeIsSet())
{
doTest();
loopClock();
}
log_i("init done, GO!");
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
}
//antipoisoning transaction
bool modeChangedByUser=false;
bool transactionInProgress=false;
#define timeModePeriod 60000
#define dateModePeriod 5000
long modesChangePeriod=timeModePeriod;
//antipoisoning end
/***************************************************************************************************************
MAIN Programm
***************************************************************************************************************/
void loop() {
loopClock();
if ((menuPosition==TimeIndex) || (modeChangedByUser==false) ) modesChanger();
doIndication();
static bool updateDateTime=false;
switch (menuPosition)
{
case TimeIndex: //time mode
if (!transactionInProgress) stringToDisplay=updateDisplayString();
break;
case DateIndex: //date mode
if (!transactionInProgress) stringToDisplay=updateDateString();
dotPattern=B01000000;//turn on lower dots
break;
}
}
int dlay=500;
// bool test=1;
byte strIndex=-1;
// bool digitsLock=false;
bool doTest()
{
if(!timeIsSet()) return true;
if(teststate == -1)
{
Serial.println(F("Start Test"));
startOfTest=millis();
teststate = 0;
Serial.println(testStringArray[10]);
}
// byte b=1;
if ((millis()-startOfTest)>dlay)
{
startOfTest=millis();
strIndex=strIndex+1;
if (strIndex==10) dlay=3000;
stringToDisplay=testStringArray[strIndex];
Serial.print("stringToDisplay=");
Serial.println(stringToDisplay);
Serial.print("strIndex=");
Serial.println(strIndex);
Serial.print("i=");
Serial.println(teststate);
if (strIndex==11) strIndex = -1;
}
doIndication();
return false;
}
void doIndication()
{
static byte b=1;
static unsigned long lastTimeInterval1Started;
if ((micros()-lastTimeInterval1Started)>5000)
{
lastTimeInterval1Started=micros();
Anode0OFF; Anode1OFF; Anode2OFF;
unsigned long var32;
unsigned long tmpVar;
int curTube=b*2-2;
var32=SymbolArray[stringToDisplay.substring(curTube, curTube+1).toInt()];
tmpVar=SymbolArray[stringToDisplay.substring(curTube+1, curTube+2).toInt()];
var32 |= tmpVar<<10;
digitalWrite(LEpin, LOW); // allow data input (Transparent mode)
SPI.transfer(var32>>16); //[A3][A2][A1][A0][RC9][RC8][RC7][RC6] - A5-A0 - anodes
SPI.transfer(var32>>8); //[RC5][RC4][RC3][RC2][RC1][RC0][LC9][RC8] - RC9-RC0 - Right tubes cathodes
SPI.transfer(var32);
digitalWrite(LEpin, HIGH); // latching data
switch (b)
{
case 1:{Anode0ON; Anode1OFF; Anode2OFF; break;};
case 2:{Anode0OFF; Anode1ON; Anode2OFF; break;};
case 3:{Anode0OFF; Anode1OFF; Anode2ON; break;};
}
b=b+1;
if (b==4) {b=1;}
}
}
void doDotBlink()
{
static unsigned long lastTimeBlink=millis();
static bool dotState=0;
if ((millis()-lastTimeBlink)>1000)
{
lastTimeBlink=millis();
dotState=!dotState;
if (dotState)
{
dotPattern=B11000000;
/*digitalWrite(pinUpperDots, HIGH);
digitalWrite(pinLowerDots, HIGH);*/
}
else
{
dotPattern=B00000000;
/*digitalWrite(pinUpperDots, LOW);
digitalWrite(pinLowerDots, LOW);*/
}
}
}
byte decToBcd(byte val){
// Convert normal decimal numbers to binary coded decimal
return ( (val/10*16) + (val%10) );
}
byte bcdToDec(byte val) {
// Convert binary coded decimal to normal decimal numbers
return ( (val/16*10) + (val%16) );
}
void modesChanger()
{
static unsigned long lastTimeModeChanged=millis();
static unsigned long lastTimeAntiPoisoningIterate=millis();
if ((millis()-lastTimeModeChanged)>modesChangePeriod)
{
lastTimeModeChanged=millis();
if (menuPosition==TimeIndex) {menuPosition=DateIndex; modesChangePeriod=dateModePeriod;}
else {menuPosition=TimeIndex; modesChangePeriod=timeModePeriod;}
if (modeChangedByUser==true)
{
menuPosition=TimeIndex;
}
modeChangedByUser=false;
}
if ((millis()-lastTimeModeChanged)<2000)
{
if ((millis()-lastTimeAntiPoisoningIterate)>100)
{
lastTimeAntiPoisoningIterate=millis();
if (menuPosition==TimeIndex)
stringToDisplay=antiPoisoning2(updateDateString(), getTimeNow());
else stringToDisplay=antiPoisoning2(getTimeNow(), updateDateString());
// Serial.println("StrTDInToModeChng="+stringToDisplay);
}
} else transactionInProgress=false;
}
String antiPoisoning2(String fromStr, String toStr)
{
//static bool transactionInProgress=false;
//byte fromDigits[6];
static byte toDigits[6];
static byte currentDigits[6];
static byte iterationCounter=0;
if (!transactionInProgress)
{
transactionInProgress=true;
for (int i=0; i<6; i++)
{
currentDigits[i]=fromStr.substring(i, i+1).toInt();
toDigits[i]=toStr.substring(i, i+1).toInt();
}
}
for (int i=0; i<6; i++)
{
if (iterationCounter<10) currentDigits[i]++;
else if (currentDigits[i]!=toDigits[i]) currentDigits[i]++;
if (currentDigits[i]==10) currentDigits[i]=0;
}
iterationCounter++;
if (iterationCounter==20)
{
iterationCounter=0;
transactionInProgress=false;
}
String tmpStr;
for (int i=0; i<6; i++)
tmpStr+=currentDigits[i];
return tmpStr;
}
String updateDisplayString()
{
static unsigned long lastTimeStringWasUpdated;
if ((millis()-lastTimeStringWasUpdated)>1000)
{
lastTimeStringWasUpdated=millis();
return getTimeNow();
}
return stringToDisplay;
loopTubes();
loopOTA();
}

View File

@@ -1,117 +0,0 @@
#include "ntp.h"
static const char ntpServerName[] = "us.pool.ntp.org";
// const int timeZone = 2;
// unsigned int localPort = 8888; // local port to listen for UDP packets
const char *ssid = "iot";
const char *password = "Rijnstraat214";
// const int NTP_PACKET_SIZE = 48; // NTP time is in the first 48 bytes of message
// byte packetBuffer[NTP_PACKET_SIZE]; //buffer to hold incoming & outgoing packets
// const unsigned int remotePort = 123;
bool printed = false;
bool wifiConnected = false;
// WiFiUDP Udp;
// bool timeUpdated()
// {
// return _timeupdated;
// }
void initWifi()
{
log_i("init wifi");
WiFi.begin(ssid, password);
}
void initNTP()
{
log_i("init ntp");
NTP.setTimeZone(TZ_Etc_UTC);
NTP.begin();
// Udp.begin(localPort);
}
bool getWifiStatus()
{
wifiConnected = WiFi.status() == WL_CONNECTED;
if(!printed && wifiConnected)
{
Serial.print("IP number assigned by DHCP is ");
Serial.println(WiFi.localIP());
printed = true;
}
return wifiConnected;
}
// // send an NTP request to the time server at the given address
// void sendNTPpacket(IPAddress &address)
// {
// // set all bytes in the buffer to 0
// memset(packetBuffer, 0, NTP_PACKET_SIZE);
// // Initialize values needed to form NTP request
// // (see URL above for details on the packets)
// packetBuffer[0] = 0b11100011; // LI, Version, Mode
// packetBuffer[1] = 0; // Stratum, or type of clock
// packetBuffer[2] = 6; // Polling Interval
// packetBuffer[3] = 0xEC; // Peer Clock Precision
// // 8 bytes of zero for Root Delay & Root Dispersion
// packetBuffer[12] = 49;
// packetBuffer[13] = 0x4E;
// packetBuffer[14] = 49;
// packetBuffer[15] = 52;
// // all NTP fields have been given values, now
// // you can send a packet requesting a timestamp:
// Udp.beginPacket(address, 123); // NTP requests are to port 123
// Udp.write(packetBuffer, NTP_PACKET_SIZE);
// Udp.endPacket();
// }
time_t getNtpTime()
{
static int last = 0;
if ((millis () - last) > 1000) {
last = millis ();
Serial.println (NTP.getTimeDateStringUs ());
}
return NTP.getLastNTPSync();
// IPAddress ntpServerIP; // NTP server's ip address
// while (Udp.parsePacket() > 0)
// ; // discard any previously received packets
// Serial.println("Transmit NTP Request");
// // get a random server from the pool
// WiFi.hostByName(ntpServerName, ntpServerIP);
// Serial.print(ntpServerName);
// Serial.print(": ");
// Serial.println(ntpServerIP);
// sendNTPpacket(ntpServerIP);
// uint32_t beginWait = millis();
// while (millis() - beginWait < 3000)
// {
// int size = Udp.parsePacket();
// if (size >= NTP_PACKET_SIZE)
// {
// Serial.printf("Receive NTP Response in %dms \n",(millis() - beginWait));
// Udp.read(packetBuffer, NTP_PACKET_SIZE); // read packet into the buffer
// unsigned long secsSince1900;
// // convert four bytes starting at location 40 to a long integer
// secsSince1900 = (unsigned long)packetBuffer[40] << 24;
// secsSince1900 |= (unsigned long)packetBuffer[41] << 16;
// secsSince1900 |= (unsigned long)packetBuffer[42] << 8;
// secsSince1900 |= (unsigned long)packetBuffer[43];
// return secsSince1900 - 2208988800UL * SECS_PER_HOUR;
// }
// }
// Serial.println("No NTP Response :-(");
// return 0; // return 0 if unable to get the time
}

View File

@@ -1,17 +0,0 @@
#pragma once
#include "Arduino.h"
#include <WiFi.h>
#include <WiFiUdp.h>
#include <TimeLib.h>
#include <ESPNtpClient.h>
void initNTP();
void initWifi();
void loopNTP();
time_t getNtpTime();
bool getWifiStatus();
bool timeUpdated();

View File

@@ -0,0 +1,63 @@
#include "ota.h"
void initOTA() {
Serial.begin(115200);
Serial.println("Booting");
// WiFi.mode(WIFI_STA);
// WiFi.begin(ssid, password);
while (WiFi.waitForConnectResult() != WL_CONNECTED) {
Serial.println("Connection Failed! Rebooting...");
delay(5000);
ESP.restart();
}
// Port defaults to 3232
// ArduinoOTA.setPort(3232);
// Hostname defaults to esp3232-[MAC]
ArduinoOTA.setHostname("nixie_clock");
// No authentication by default
// ArduinoOTA.setPassword("admin");
// Password can be set with it's md5 value as well
// MD5(admin) = 21232f297a57a5a743894a0e4a801fc3
// ArduinoOTA.setPasswordHash("21232f297a57a5a743894a0e4a801fc3");
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()
Serial.println("Start updating " + type);
})
.onEnd([]() {
Serial.println("\nEnd");
})
.onProgress([](unsigned int progress, unsigned int total) {
Serial.printf("Progress: %u%%\r", (progress / (total / 100)));
})
.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();
Serial.println("Ready");
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
}
void loopOTA() {
ArduinoOTA.handle();
}

View File

@@ -0,0 +1,9 @@
#pragma once
#include <WiFi.h>
#include <ESPmDNS.h>
#include <WiFiUdp.h>
#include <ArduinoOTA.h>
void initOTA();
void loopOTA();

View File

@@ -0,0 +1,246 @@
#include "tubes.h"
const word fpsLimit=16666; // 1/60*1.000.000 //limit maximum refresh rate on 60 fps
String stringToDisplay="000000";// Conten of this string will be displayed on tubes (must be 6 chars length)
int menuPosition=0; // 0 - time
// 1 - date
// 2 - alarm
// 3 - 12/24 hours mode
// 0 1 2 3 4 5 6 7 8 9
//word SymbolArray[10]={65534, 65533, 65531, 65527, 65519, 65503, 65471, 65407, 65279, 65023};
word SymbolArray[10]={1022, 1021, 1019, 1015, 1007, 991, 959, 895, 767, 511};
byte dotPattern=B00000000; //bit mask for separeting dots
//B00000000 - turn off up and down dots
//B1100000 - turn off all dots
int teststate = -1;
String testStringArray[12]={"000000","111111","222222","333333","444444","555555","666666","777777","888888","999999","",""};
unsigned long startOfTest;
bool modeChangedByUser=false;
bool transactionInProgress=false;
#define timeModePeriod 60000
#define dateModePeriod 5000
long modesChangePeriod=timeModePeriod;
static unsigned long lastTimeInterval1Started;
int dlay=500;
// bool test=1;
byte strIndex=-1;
// bool digitsLock=false;
bool doTest()
{
if(!timeIsSet()) return true;
if(teststate == -1)
{
Serial.println(F("Start Test"));
startOfTest=millis();
teststate = 0;
Serial.println(testStringArray[10]);
}
// byte b=1;
if ((millis()-startOfTest)>dlay)
{
startOfTest=millis();
strIndex=strIndex+1;
if (strIndex==10) dlay=3000;
stringToDisplay=testStringArray[strIndex];
Serial.print("stringToDisplay=");
Serial.println(stringToDisplay);
Serial.print("strIndex=");
Serial.println(strIndex);
Serial.print("i=");
Serial.println(teststate);
if (strIndex==11) strIndex = -1;
}
doIndication();
return false;
}
String antiPoisoning2(String fromStr, String toStr)
{
//static bool transactionInProgress=false;
//byte fromDigits[6];
static byte toDigits[6];
static byte currentDigits[6];
static byte iterationCounter=0;
if (!transactionInProgress)
{
transactionInProgress=true;
for (int i=0; i<6; i++)
{
currentDigits[i]=fromStr.substring(i, i+1).toInt();
toDigits[i]=toStr.substring(i, i+1).toInt();
}
}
for (int i=0; i<6; i++)
{
if (iterationCounter<10) currentDigits[i]++;
else if (currentDigits[i]!=toDigits[i]) currentDigits[i]++;
if (currentDigits[i]==10) currentDigits[i]=0;
}
iterationCounter++;
if (iterationCounter==20)
{
iterationCounter=0;
transactionInProgress=false;
}
String tmpStr;
for (int i=0; i<6; i++)
tmpStr+=currentDigits[i];
return tmpStr;
}
void modesChanger()
{
static unsigned long lastTimeModeChanged=millis();
static unsigned long lastTimeAntiPoisoningIterate=millis();
if ((millis()-lastTimeModeChanged)>modesChangePeriod)
{
lastTimeModeChanged=millis();
if (menuPosition==TimeIndex) {menuPosition=DateIndex; modesChangePeriod=dateModePeriod;}
else {menuPosition=TimeIndex; modesChangePeriod=timeModePeriod;}
if (modeChangedByUser==true)
{
menuPosition=TimeIndex;
}
modeChangedByUser=false;
}
if ((millis()-lastTimeModeChanged)<2000)
{
if ((millis()-lastTimeAntiPoisoningIterate)>100)
{
lastTimeAntiPoisoningIterate=millis();
if (menuPosition==TimeIndex)
stringToDisplay=antiPoisoning2(updateDateString(), getTimeNow());
else stringToDisplay=antiPoisoning2(getTimeNow(), updateDateString());
// Serial.println("StrTDInToModeChng="+stringToDisplay);
}
} else transactionInProgress=false;
}
String updateDisplayString()
{
static unsigned long lastTimeStringWasUpdated;
if ((millis()-lastTimeStringWasUpdated)>1000)
{
lastTimeStringWasUpdated=millis();
return getTimeNow();
}
return stringToDisplay;
}
void doIndication()
{
static byte b=1;
if ((millis()-lastTimeInterval1Started)>3)
{
lastTimeInterval1Started=millis();
log_v("update tubes");
Anode0OFF; Anode1OFF; Anode2OFF;
unsigned long var32;
unsigned long tmpVar;
int curTube=b*2-2;
var32=SymbolArray[stringToDisplay.substring(curTube, curTube+1).toInt()];
tmpVar=SymbolArray[stringToDisplay.substring(curTube+1, curTube+2).toInt()];
var32 |= tmpVar<<10;
digitalWrite(LEpin, LOW); // allow data input (Transparent mode)
SPI.transfer(var32>>16); //[A3][A2][A1][A0][RC9][RC8][RC7][RC6] - A5-A0 - anodes
SPI.transfer(var32>>8); //[RC5][RC4][RC3][RC2][RC1][RC0][LC9][RC8] - RC9-RC0 - Right tubes cathodes
SPI.transfer(var32);
digitalWrite(LEpin, HIGH); // latching data
switch (b)
{
case 1:{Anode0ON; Anode1OFF; Anode2OFF; break;};
case 2:{Anode0OFF; Anode1ON; Anode2OFF; break;};
case 3:{Anode0OFF; Anode1OFF; Anode2ON; break;};
}
b=b+1;
if (b==4) {b=1;}
}
}
void doDotBlink()
{
static unsigned long lastTimeBlink=millis();
static bool dotState=0;
if ((millis()-lastTimeBlink)>1000)
{
lastTimeBlink=millis();
dotState=!dotState;
if (dotState)
{
dotPattern=B11000000;
}
else
{
dotPattern=B00000000;
}
}
}
void initTubes()
{
pinMode(LEpin, OUTPUT);
// SPI setup
SPI.begin(sckPin,misoPin,mosiPin); //
SPI.setDataMode (SPI_MODE3); // Mode 3 SPI
SPI.setClockDivider(SPI_CLOCK_DIV128); // SCK = 16MHz/128= 125kHz
pinMode(Anode0Pin, OUTPUT);
pinMode(Anode1Pin, OUTPUT);
pinMode(Anode2Pin, OUTPUT);
}
void loopTubes()
{
if ((menuPosition==TimeIndex) || (modeChangedByUser==false) ) modesChanger();
doIndication();
static bool updateDateTime=false;
switch (menuPosition)
{
case TimeIndex: //time mode
if (!transactionInProgress) stringToDisplay=updateDisplayString();
break;
case DateIndex: //date mode
if (!transactionInProgress) stringToDisplay=updateDateString();
dotPattern=B01000000;//turn on lower dots
break;
}
}

View File

@@ -0,0 +1,15 @@
#pragma once
#include <Arduino.h>
#include "defines.h"
#include <SPI.h>
#include "clock.h"
void initTubes();
void loopTubes();
void doIndication();
void doDotBlink();
bool doTest();

View File

@@ -0,0 +1,756 @@
#include "wifimanager.h"
#ifdef ESP32
WiFiMulti wifiMulti;
#if USE_LITTLEFS
FS* filesystem = &FileFS;
#elif USE_SPIFFS
FS* filesystem = &SPIFFS;
#else
FS* filesystem = &FFat;
#endif
#endif
//DoubleResetDetector drd(DRD_TIMEOUT, DRD_ADDRESS);
DoubleResetDetector* drd;//////
// Onboard LED I/O pin on NodeMCU board
const int PIN_LED = 2; // D4 on NodeMCU and WeMos. GPIO2/ADC12 of ESP32. Controls the onboard LED.
// Indicates whether ESP has WiFi credentials saved from previous session, or double reset detected
bool initialConfig = false;
WM_Config WM_config;
#if ( USE_DHCP_IP )
// Use DHCP
#if (_WIFIMGR_LOGLEVEL_ > 3)
#warning Using DHCP IP
#endif
IPAddress stationIP = IPAddress(0, 0, 0, 0);
IPAddress gatewayIP = IPAddress(192, 168, 2, 1);
IPAddress netMask = IPAddress(255, 255, 255, 0);
#else
// Use static IP
#if (_WIFIMGR_LOGLEVEL_ > 3)
#warning Using static IP
#endif
#ifdef ESP32
IPAddress stationIP = IPAddress(192, 168, 2, 232);
#else
IPAddress stationIP = IPAddress(192, 168, 2, 186);
#endif
IPAddress gatewayIP = IPAddress(192, 168, 2, 1);
IPAddress netMask = IPAddress(255, 255, 255, 0);
#endif
////////////////////////////////////////////
#define USE_CONFIGURABLE_DNS true
IPAddress dns1IP = gatewayIP;
IPAddress dns2IP = IPAddress(8, 8, 8, 8);
#define USE_CUSTOM_AP_IP false
// New in v1.4.0
IPAddress APStaticIP = IPAddress(192, 168, 232, 1);
IPAddress APStaticGW = IPAddress(192, 168, 232, 1);
IPAddress APStaticSN = IPAddress(255, 255, 255, 0);
// Must be placed before #include <ESP_WiFiManager.h>, or default port 80 will be used
//#define HTTP_PORT 8080
#include <ESP_WiFiManager.h> //https://github.com/khoih-prog/ESP_WiFiManager
// Redundant, for v1.8.0 only
//#include <ESP_WiFiManager-Impl.h> //https://github.com/khoih-prog/ESP_WiFiManager
// SSID and PW for Config Portal
String ssid = "ESP_" + String(ESP_getChipId(), HEX);
String password;
// SSID and PW for your Router
String Router_SSID;
String Router_Pass;
// Function Prototypes
uint8_t connectMultiWiFi();
///////////////////////////////////////////
// New in v1.4.0
/******************************************
* // Defined in ESP_WiFiManager.h
typedef struct
{
IPAddress _ap_static_ip;
IPAddress _ap_static_gw;
IPAddress _ap_static_sn;
} WiFi_AP_IPConfig;
typedef struct
{
IPAddress _sta_static_ip;
IPAddress _sta_static_gw;
IPAddress _sta_static_sn;
#if USE_CONFIGURABLE_DNS
IPAddress _sta_static_dns1;
IPAddress _sta_static_dns2;
#endif
} WiFi_STA_IPConfig;
******************************************/
WiFi_AP_IPConfig WM_AP_IPconfig;
WiFi_STA_IPConfig WM_STA_IPconfig;
void initAPIPConfigStruct(WiFi_AP_IPConfig &in_WM_AP_IPconfig)
{
in_WM_AP_IPconfig._ap_static_ip = APStaticIP;
in_WM_AP_IPconfig._ap_static_gw = APStaticGW;
in_WM_AP_IPconfig._ap_static_sn = APStaticSN;
}
void initSTAIPConfigStruct(WiFi_STA_IPConfig &in_WM_STA_IPconfig)
{
in_WM_STA_IPconfig._sta_static_ip = stationIP;
in_WM_STA_IPconfig._sta_static_gw = gatewayIP;
in_WM_STA_IPconfig._sta_static_sn = netMask;
#if USE_CONFIGURABLE_DNS
in_WM_STA_IPconfig._sta_static_dns1 = dns1IP;
in_WM_STA_IPconfig._sta_static_dns2 = dns2IP;
#endif
}
void displayIPConfigStruct(WiFi_STA_IPConfig in_WM_STA_IPconfig)
{
LOGERROR3(F("stationIP ="), in_WM_STA_IPconfig._sta_static_ip, ", gatewayIP =", in_WM_STA_IPconfig._sta_static_gw);
LOGERROR1(F("netMask ="), in_WM_STA_IPconfig._sta_static_sn);
#if USE_CONFIGURABLE_DNS
LOGERROR3(F("dns1IP ="), in_WM_STA_IPconfig._sta_static_dns1, ", dns2IP =", in_WM_STA_IPconfig._sta_static_dns2);
#endif
}
void configWiFi(WiFi_STA_IPConfig in_WM_STA_IPconfig)
{
#if USE_CONFIGURABLE_DNS
// Set static IP, Gateway, Subnetmask, DNS1 and DNS2. New in v1.0.5
WiFi.config(in_WM_STA_IPconfig._sta_static_ip, in_WM_STA_IPconfig._sta_static_gw, in_WM_STA_IPconfig._sta_static_sn, in_WM_STA_IPconfig._sta_static_dns1, in_WM_STA_IPconfig._sta_static_dns2);
#else
// Set static IP, Gateway, Subnetmask, Use auto DNS1 and DNS2.
WiFi.config(in_WM_STA_IPconfig._sta_static_ip, in_WM_STA_IPconfig._sta_static_gw, in_WM_STA_IPconfig._sta_static_sn);
#endif
}
///////////////////////////////////////////
uint8_t connectMultiWiFi()
{
#if ESP32
// For ESP32, this better be 0 to shorten the connect time.
// For ESP32-S2/C3, must be > 500
#if ( USING_ESP32_S2 || USING_ESP32_C3 )
#define WIFI_MULTI_1ST_CONNECT_WAITING_MS 500L
#else
// For ESP32 core v1.0.6, must be >= 500
#define WIFI_MULTI_1ST_CONNECT_WAITING_MS 800L
#endif
#else
// For ESP8266, this better be 2200 to enable connect the 1st time
#define WIFI_MULTI_1ST_CONNECT_WAITING_MS 2200L
#endif
#define WIFI_MULTI_CONNECT_WAITING_MS 500L
uint8_t status;
//WiFi.mode(WIFI_STA);
LOGERROR(F("ConnectMultiWiFi with :"));
if ( (Router_SSID != "") && (Router_Pass != "") )
{
LOGERROR3(F("* Flash-stored Router_SSID = "), Router_SSID, F(", Router_Pass = "), Router_Pass );
LOGERROR3(F("* Add SSID = "), Router_SSID, F(", PW = "), Router_Pass );
wifiMulti.addAP(Router_SSID.c_str(), Router_Pass.c_str());
}
for (uint8_t i = 0; i < NUM_WIFI_CREDENTIALS; i++)
{
// Don't permit NULL SSID and password len < MIN_AP_PASSWORD_SIZE (8)
if ( (String(WM_config.WiFi_Creds[i].wifi_ssid) != "") && (strlen(WM_config.WiFi_Creds[i].wifi_pw) >= MIN_AP_PASSWORD_SIZE) )
{
LOGERROR3(F("* Additional SSID = "), WM_config.WiFi_Creds[i].wifi_ssid, F(", PW = "), WM_config.WiFi_Creds[i].wifi_pw );
}
}
LOGERROR(F("Connecting MultiWifi..."));
//WiFi.mode(WIFI_STA);
#if !USE_DHCP_IP
// New in v1.4.0
configWiFi(WM_STA_IPconfig);
//////
#endif
int i = 0;
status = wifiMulti.run();
delay(WIFI_MULTI_1ST_CONNECT_WAITING_MS);
while ( ( i++ < 20 ) && ( status != WL_CONNECTED ) )
{
status = WiFi.status();
if ( status == WL_CONNECTED )
break;
else
delay(WIFI_MULTI_CONNECT_WAITING_MS);
}
if ( status == WL_CONNECTED )
{
LOGERROR1(F("WiFi connected after time: "), i);
LOGERROR3(F("SSID:"), WiFi.SSID(), F(",RSSI="), WiFi.RSSI());
LOGERROR3(F("Channel:"), WiFi.channel(), F(",IP address:"), WiFi.localIP() );
}
else
{
LOGERROR(F("WiFi not connected"));
// To avoid unnecessary DRD
drd->loop();
#if ESP8266
ESP.reset();
#else
ESP.restart();
#endif
}
return status;
}
#if USE_ESP_WIFIMANAGER_NTP
void printLocalTime()
{
#if ESP8266
static time_t now;
now = time(nullptr);
if ( now > 1451602800 )
{
Serial.print("Local Date/Time: ");
Serial.print(ctime(&now));
}
#else
struct tm timeinfo;
getLocalTime( &timeinfo );
// Valid only if year > 2000.
// You can get from timeinfo : tm_year, tm_mon, tm_mday, tm_hour, tm_min, tm_sec
if (timeinfo.tm_year > 100 )
{
Serial.print("Local Date/Time: ");
Serial.print( asctime( &timeinfo ) );
}
#endif
}
#endif
void heartBeatPrint()
{
#if USE_ESP_WIFIMANAGER_NTP
printLocalTime();
#else
static int num = 1;
if (WiFi.status() == WL_CONNECTED)
Serial.print(F("H")); // H means connected to WiFi
else
Serial.print(F("F")); // F means not connected to WiFi
if (num == 80)
{
Serial.println();
num = 1;
}
else if (num++ % 10 == 0)
{
Serial.print(F(" "));
}
#endif
}
void check_WiFi()
{
if ( (WiFi.status() != WL_CONNECTED) )
{
Serial.println(F("\nWiFi lost. Call connectMultiWiFi in loop"));
connectMultiWiFi();
}
}
void check_status()
{
static ulong checkstatus_timeout = 0;
static ulong checkwifi_timeout = 0;
static ulong current_millis;
#define WIFICHECK_INTERVAL 1000L
#if USE_ESP_WIFIMANAGER_NTP
#define HEARTBEAT_INTERVAL 60000L
#else
#define HEARTBEAT_INTERVAL 10000L
#endif
current_millis = millis();
// Check WiFi every WIFICHECK_INTERVAL (1) seconds.
if ((current_millis > checkwifi_timeout) || (checkwifi_timeout == 0))
{
check_WiFi();
checkwifi_timeout = current_millis + WIFICHECK_INTERVAL;
}
// Print hearbeat every HEARTBEAT_INTERVAL (10) seconds.
if ((current_millis > checkstatus_timeout) || (checkstatus_timeout == 0))
{
heartBeatPrint();
checkstatus_timeout = current_millis + HEARTBEAT_INTERVAL;
}
}
int calcChecksum(uint8_t* address, uint16_t sizeToCalc)
{
uint16_t checkSum = 0;
for (uint16_t index = 0; index < sizeToCalc; index++)
{
checkSum += * ( ( (byte*) address ) + index);
}
return checkSum;
}
bool loadConfigData()
{
File file = FileFS.open(CONFIG_FILENAME, "r");
LOGERROR(F("LoadWiFiCfgFile "));
memset((void*) &WM_config, 0, sizeof(WM_config));
// New in v1.4.0
memset((void*) &WM_STA_IPconfig, 0, sizeof(WM_STA_IPconfig));
//////
if (file)
{
file.readBytes((char *) &WM_config, sizeof(WM_config));
// New in v1.4.0
file.readBytes((char *) &WM_STA_IPconfig, sizeof(WM_STA_IPconfig));
//////
file.close();
LOGERROR(F("OK"));
if ( WM_config.checksum != calcChecksum( (uint8_t*) &WM_config, sizeof(WM_config) - sizeof(WM_config.checksum) ) )
{
LOGERROR(F("WM_config checksum wrong"));
return false;
}
// New in v1.4.0
displayIPConfigStruct(WM_STA_IPconfig);
//////
return true;
}
else
{
LOGERROR(F("failed"));
return false;
}
}
void saveConfigData()
{
File file = FileFS.open(CONFIG_FILENAME, "w");
LOGERROR(F("SaveWiFiCfgFile "));
if (file)
{
WM_config.checksum = calcChecksum( (uint8_t*) &WM_config, sizeof(WM_config) - sizeof(WM_config.checksum) );
file.write((uint8_t*) &WM_config, sizeof(WM_config));
displayIPConfigStruct(WM_STA_IPconfig);
// New in v1.4.0
file.write((uint8_t*) &WM_STA_IPconfig, sizeof(WM_STA_IPconfig));
//////
file.close();
LOGERROR(F("OK"));
}
else
{
LOGERROR(F("failed"));
}
}
unsigned long drdtimeout;
void setupwifiman()
{
// put your setup code here, to run once:
// initialize the LED digital pin as an output.
pinMode(PIN_LED, OUTPUT);
Serial.begin(115200);
while (!Serial);
delay(200);
Serial.print(F("\nStarting ConfigOnDoubleReset with DoubleResetDetect using ")); Serial.print(FS_Name);
Serial.print(F(" on ")); Serial.println(ARDUINO_BOARD);
Serial.println(ESP_WIFIMANAGER_VERSION);
Serial.println(ESP_DOUBLE_RESET_DETECTOR_VERSION);
#if defined(ESP_WIFIMANAGER_VERSION_MIN)
if (ESP_WIFIMANAGER_VERSION_INT < ESP_WIFIMANAGER_VERSION_MIN)
{
Serial.print("Warning. Must use this example on Version equal or later than : ");
Serial.println(ESP_WIFIMANAGER_VERSION_MIN_TARGET);
}
#endif
Serial.setDebugOutput(false);
if (FORMAT_FILESYSTEM)
FileFS.format();
// Format FileFS if not yet
#ifdef ESP32
if (!FileFS.begin(true))
#else
if (!FileFS.begin())
#endif
{
#ifdef ESP8266
FileFS.format();
#endif
Serial.println(F("SPIFFS/LittleFS failed! Already tried formatting."));
if (!FileFS.begin())
{
// prevents debug info from the library to hide err message.
delay(100);
#if USE_LITTLEFS
Serial.println(F("LittleFS failed!. Please use SPIFFS or EEPROM. Stay forever"));
#else
Serial.println(F("SPIFFS failed!. Please use LittleFS or EEPROM. Stay forever"));
#endif
while (true)
{
delay(1);
}
}
}
drd = new DoubleResetDetector(DRD_TIMEOUT, DRD_ADDRESS);
unsigned long startedAt = millis();
// New in v1.4.0
initAPIPConfigStruct(WM_AP_IPconfig);
initSTAIPConfigStruct(WM_STA_IPconfig);
//////
//Local intialization. Once its business is done, there is no need to keep it around
// Use this to default DHCP hostname to ESP8266-XXXXXX or ESP32-XXXXXX
//ESP_WiFiManager ESP_wifiManager;
// Use this to personalize DHCP hostname (RFC952 conformed)
ESP_WiFiManager ESP_wifiManager("ConfigOnDoubleReset");
#if USE_CUSTOM_AP_IP
//set custom ip for portal
// New in v1.4.0
ESP_wifiManager.setAPStaticIPConfig(WM_AP_IPconfig);
//////
#endif
ESP_wifiManager.setMinimumSignalQuality(-1);
// From v1.0.10 only
// Set config portal channel, default = 1. Use 0 => random channel from 1-13
ESP_wifiManager.setConfigPortalChannel(0);
//////
#if !USE_DHCP_IP
// Set (static IP, Gateway, Subnetmask, DNS1 and DNS2) or (IP, Gateway, Subnetmask). New in v1.0.5
// New in v1.4.0
ESP_wifiManager.setSTAStaticIPConfig(WM_STA_IPconfig);
//////
#endif
// New from v1.1.1
#if USING_CORS_FEATURE
ESP_wifiManager.setCORSHeader("Your Access-Control-Allow-Origin");
#endif
// We can't use WiFi.SSID() in ESP32 as it's only valid after connected.
// SSID and Password stored in ESP32 wifi_ap_record_t and wifi_config_t are also cleared in reboot
// Have to create a new function to store in EEPROM/SPIFFS for this purpose
Router_SSID = ESP_wifiManager.WiFi_SSID();
Router_Pass = ESP_wifiManager.WiFi_Pass();
//Remove this line if you do not want to see WiFi password printed
Serial.println("ESP Self-Stored: SSID = " + Router_SSID + ", Pass = " + Router_Pass);
// SSID/PWD to uppercase
ssid.toUpperCase();
password = "nixie";
bool configDataLoaded = false;
// From v1.1.0, Don't permit NULL password
if ( (Router_SSID != "") && (Router_Pass != "") )
{
LOGERROR3(F("* Add SSID = "), Router_SSID, F(", PW = "), Router_Pass);
wifiMulti.addAP(Router_SSID.c_str(), Router_Pass.c_str());
ESP_wifiManager.setConfigPortalTimeout(240); //If no access point name has been previously entered disable timeout.
Serial.println(F("Got ESP Self-Stored Credentials. Timeout 120s for Config Portal"));
}
if (loadConfigData())
{
configDataLoaded = true;
ESP_wifiManager.setConfigPortalTimeout(240); //If no access point name has been previously entered disable timeout.
Serial.println(F("Got stored Credentials. Timeout 120s for Config Portal"));
#if USE_ESP_WIFIMANAGER_NTP
if ( strlen(WM_config.TZ_Name) > 0 )
{
LOGERROR3(F("Current TZ_Name ="), WM_config.TZ_Name, F(", TZ = "), WM_config.TZ);
#if ESP8266
configTime(WM_config.TZ, "pool.ntp.org");
#else
//configTzTime(WM_config.TZ, "pool.ntp.org" );
configTzTime(WM_config.TZ, "time.nist.gov", "0.pool.ntp.org", "1.pool.ntp.org");
#endif
}
else
{
Serial.println(F("Current Timezone is not set. Enter Config Portal to set."));
}
#endif
}
else
{
// Enter CP only if no stored SSID on flash and file
Serial.println(F("Open Config Portal without Timeout: No stored Credentials."));
initialConfig = true;
}
if (drd->detectDoubleReset())
{
// DRD, disable timeout.
ESP_wifiManager.setConfigPortalTimeout(0);
Serial.println(F("Open Config Portal without Timeout: Double Reset Detected"));
initialConfig = true;
}
if (initialConfig)
{
Serial.print(F("Starting configuration portal @ "));
#if USE_CUSTOM_AP_IP
Serial.print(APStaticIP);
#else
Serial.print(F("192.168.4.1"));
#endif
#if defined(HTTP_PORT_TO_USE)
Serial.print(F(":")); Serial.print(HTTP_PORT_TO_USE);
#endif
Serial.print(F(", SSID = "));
Serial.print(ssid);
Serial.print(F(", PWD = "));
Serial.println(password);
digitalWrite(PIN_LED, LED_ON); // turn the LED on by making the voltage LOW to tell us we are in configuration mode.
//sets timeout in seconds until configuration portal gets turned off.
//If not specified device will remain in configuration mode until
//switched off via webserver or device is restarted.
//ESP_wifiManager.setConfigPortalTimeout(600);
#if DISPLAY_STORED_CREDENTIALS_IN_CP
// New. Update Credentials, got from loadConfigData(), to display on CP
ESP_wifiManager.setCredentials(WM_config.WiFi_Creds[0].wifi_ssid, WM_config.WiFi_Creds[0].wifi_pw,
WM_config.WiFi_Creds[1].wifi_ssid, WM_config.WiFi_Creds[1].wifi_pw);
#endif
// Starts an access point
if (!ESP_wifiManager.startConfigPortal((const char *) ssid.c_str(), (const char *) password.c_str()))
Serial.println(F("Not connected to WiFi but continuing anyway."));
else
{
Serial.println(F("WiFi connected...yeey :)"));
}
// Stored for later usage, from v1.1.0, but clear first
memset(&WM_config, 0, sizeof(WM_config));
for (uint8_t i = 0; i < NUM_WIFI_CREDENTIALS; i++)
{
String tempSSID = ESP_wifiManager.getSSID(i);
String tempPW = ESP_wifiManager.getPW(i);
if (strlen(tempSSID.c_str()) < sizeof(WM_config.WiFi_Creds[i].wifi_ssid) - 1)
strcpy(WM_config.WiFi_Creds[i].wifi_ssid, tempSSID.c_str());
else
strncpy(WM_config.WiFi_Creds[i].wifi_ssid, tempSSID.c_str(), sizeof(WM_config.WiFi_Creds[i].wifi_ssid) - 1);
if (strlen(tempPW.c_str()) < sizeof(WM_config.WiFi_Creds[i].wifi_pw) - 1)
strcpy(WM_config.WiFi_Creds[i].wifi_pw, tempPW.c_str());
else
strncpy(WM_config.WiFi_Creds[i].wifi_pw, tempPW.c_str(), sizeof(WM_config.WiFi_Creds[i].wifi_pw) - 1);
// Don't permit NULL SSID and password len < MIN_AP_PASSWORD_SIZE (8)
if ( (String(WM_config.WiFi_Creds[i].wifi_ssid) != "") && (strlen(WM_config.WiFi_Creds[i].wifi_pw) >= MIN_AP_PASSWORD_SIZE) )
{
LOGERROR3(F("* Add SSID = "), WM_config.WiFi_Creds[i].wifi_ssid, F(", PW = "), WM_config.WiFi_Creds[i].wifi_pw );
wifiMulti.addAP(WM_config.WiFi_Creds[i].wifi_ssid, WM_config.WiFi_Creds[i].wifi_pw);
}
}
#if USE_ESP_WIFIMANAGER_NTP
String tempTZ = ESP_wifiManager.getTimezoneName();
if (strlen(tempTZ.c_str()) < sizeof(WM_config.TZ_Name) - 1)
strcpy(WM_config.TZ_Name, tempTZ.c_str());
else
strncpy(WM_config.TZ_Name, tempTZ.c_str(), sizeof(WM_config.TZ_Name) - 1);
const char * TZ_Result = ESP_wifiManager.getTZ(WM_config.TZ_Name);
if (strlen(TZ_Result) < sizeof(WM_config.TZ) - 1)
strcpy(WM_config.TZ, TZ_Result);
else
strncpy(WM_config.TZ, TZ_Result, sizeof(WM_config.TZ_Name) - 1);
if ( strlen(WM_config.TZ_Name) > 0 )
{
LOGERROR3(F("Saving current TZ_Name ="), WM_config.TZ_Name, F(", TZ = "), WM_config.TZ);
#if ESP8266
configTime(WM_config.TZ, "pool.ntp.org");
#else
//configTzTime(WM_config.TZ, "pool.ntp.org" );
configTzTime(WM_config.TZ, "time.nist.gov", "0.pool.ntp.org", "1.pool.ntp.org");
#endif
}
else
{
LOGERROR(F("Current Timezone Name is not set. Enter Config Portal to set."));
}
#endif
// New in v1.4.0
ESP_wifiManager.getSTAStaticIPConfig(WM_STA_IPconfig);
//////
saveConfigData();
}
digitalWrite(PIN_LED, LED_OFF); // Turn led off as we are not in configuration mode.
startedAt = millis();
if (!initialConfig)
{
// Load stored data, the addAP ready for MultiWiFi reconnection
if (!configDataLoaded)
loadConfigData();
for (uint8_t i = 0; i < NUM_WIFI_CREDENTIALS; i++)
{
// Don't permit NULL SSID and password len < MIN_AP_PASSWORD_SIZE (8)
if ( (String(WM_config.WiFi_Creds[i].wifi_ssid) != "") && (strlen(WM_config.WiFi_Creds[i].wifi_pw) >= MIN_AP_PASSWORD_SIZE) )
{
LOGERROR3(F("* Add SSID = "), WM_config.WiFi_Creds[i].wifi_ssid, F(", PW = "), WM_config.WiFi_Creds[i].wifi_pw );
wifiMulti.addAP(WM_config.WiFi_Creds[i].wifi_ssid, WM_config.WiFi_Creds[i].wifi_pw);
}
}
if ( WiFi.status() != WL_CONNECTED )
{
Serial.println(F("ConnectMultiWiFi in setup"));
connectMultiWiFi();
}
}
Serial.print(F("After waiting "));
Serial.print((float) (millis() - startedAt) / 1000);
Serial.print(F(" secs more in setup(), connection result is "));
if (WiFi.status() == WL_CONNECTED)
{
Serial.print(F("connected. Local IP: "));
Serial.println(WiFi.localIP());
}
else
Serial.println(ESP_wifiManager.getStatus(WiFi.status()));
drdtimeout=millis();
}
void loopwifiman()
{
// Call the double reset detector loop method every so often,
// so that it can recognise when the timeout expires.
// You can also call drd.stop() when you wish to no longer
// consider the next reset as a double reset.
drd->loop();
// put your main code here, to run repeatedly
check_status();
}

View File

@@ -0,0 +1,303 @@
#pragma once
/****************************************************************************************************************************
ConfigOnDoubleReset.ino
For ESP8266 / ESP32 boards
ESP_WiFiManager is a library for the ESP8266/ESP32 platform (https://github.com/esp8266/Arduino) to enable easy
configuration and reconfiguration of WiFi credentials using a Captive Portal. Inspired by:
http://www.esp8266.com/viewtopic.php?f=29&t=2520
https://github.com/chriscook8/esp-arduino-apboot
https://github.com/esp8266/Arduino/blob/master/libraries/DNSServer/examples/CaptivePortalAdvanced/
Modified from Tzapu https://github.com/tzapu/WiFiManager
and from Ken Taylor https://github.com/kentaylor
Built by Khoi Hoang https://github.com/khoih-prog/ESP_WiFiManager
Licensed under MIT license
*****************************************************************************************************************************/
/****************************************************************************************************************************
This example will open a configuration portal when the reset button is pressed twice.
This method works well on Wemos boards which have a single reset button on board. It avoids using a pin for launching the configuration portal.
How It Works
1) ESP8266
Save data in RTC memory
2) ESP32
Save data in EEPROM from address 256, size 512 bytes (both configurable)
So when the device starts up it checks this region of ram for a flag to see if it has been recently reset.
If so it launches a configuration portal, if not it sets the reset flag. After running for a while this flag is cleared so that
it will only launch the configuration portal in response to closely spaced resets.
Settings
There are two values to be set in the sketch.
DRD_TIMEOUT - Number of seconds to wait for the second reset. Set to 10 in the example.
DRD_ADDRESS - The address in ESP8266 RTC RAM to store the flag. This memory must not be used for other purposes in the same sketch. Set to 0 in the example.
This example, originally relied on the Double Reset Detector library from https://github.com/datacute/DoubleResetDetector
To support ESP32, use ESP_DoubleResetDetector library from //https://github.com/khoih-prog/ESP_DoubleResetDetector
*****************************************************************************************************************************/
void loopwifiman();
void setupwifiman();
#if !( defined(ESP8266) || defined(ESP32) )
#error This code is intended to run on the ESP8266 or ESP32 platform! Please check your Tools->Board setting.
#endif
#define ESP_WIFIMANAGER_VERSION_MIN_TARGET "ESP_WiFiManager v1.12.0"
#define ESP_WIFIMANAGER_VERSION_MIN 1012000
// Use from 0 to 4. Higher number, more debugging messages and memory usage.
#define _WIFIMGR_LOGLEVEL_ 1
// To not display stored SSIDs and PWDs on Config Portal, select false. Default is true
// Even the stored Credentials are not display, just leave them all blank to reconnect and reuse the stored Credentials
//#define DISPLAY_STORED_CREDENTIALS_IN_CP false
#include <FS.h>
//Ported to ESP32
#ifdef ESP32
#include <esp_wifi.h>
#include <WiFi.h>
#include <WiFiClient.h>
// From v1.1.0
#include <WiFiMulti.h>
// LittleFS has higher priority than SPIFFS
#if ( defined(ESP_ARDUINO_VERSION_MAJOR) && (ESP_ARDUINO_VERSION_MAJOR >= 2) )
#define USE_LITTLEFS true
#define USE_SPIFFS false
#elif defined(ARDUINO_ESP32C3_DEV)
// For core v1.0.6-, ESP32-C3 only supporting SPIFFS and EEPROM. To use v2.0.0+ for LittleFS
#define USE_LITTLEFS false
#define USE_SPIFFS true
#endif
#if USE_LITTLEFS
// Use LittleFS
#include "FS.h"
// Check cores/esp32/esp_arduino_version.h and cores/esp32/core_version.h
//#if ( ESP_ARDUINO_VERSION >= ESP_ARDUINO_VERSION_VAL(2, 0, 0) ) //(ESP_ARDUINO_VERSION_MAJOR >= 2)
#if ( defined(ESP_ARDUINO_VERSION_MAJOR) && (ESP_ARDUINO_VERSION_MAJOR >= 2) )
#if (_WIFIMGR_LOGLEVEL_ > 3)
#warning Using ESP32 Core 1.0.6 or 2.0.0+
#endif
// The library has been merged into esp32 core from release 1.0.6
#include <LittleFS.h> // https://github.com/espressif/arduino-esp32/tree/master/libraries/LittleFS
#define FileFS LittleFS
#define FS_Name "LittleFS"
#else
#if (_WIFIMGR_LOGLEVEL_ > 3)
#warning Using ESP32 Core 1.0.5-. You must install LITTLEFS library
#endif
// The library has been merged into esp32 core from release 1.0.6
#include <LITTLEFS.h> // https://github.com/lorol/LITTLEFS
#define FileFS LITTLEFS
#define FS_Name "LittleFS"
#endif
#elif USE_SPIFFS
#include <SPIFFS.h>
#define FileFS SPIFFS
#define FS_Name "SPIFFS"
#else
// Use FFat
#include <FFat.h>
#define FileFS FFat
#define FS_Name "FFat"
#endif
//////
#define LED_BUILTIN 2
#define LED_ON HIGH
#define LED_OFF LOW
#else
#include <ESP8266WiFi.h> //https://github.com/esp8266/Arduino
//needed for library
#include <DNSServer.h>
#include <ESP8266WebServer.h>
// From v1.1.0
#include <ESP8266WiFiMulti.h>
ESP8266WiFiMulti wifiMulti;
#define USE_LITTLEFS true
#if USE_LITTLEFS
#include <LittleFS.h>
FS* filesystem = &LittleFS;
#define FileFS LittleFS
#define FS_Name "LittleFS"
#else
FS* filesystem = &SPIFFS;
#define FileFS SPIFFS
#define FS_Name "SPIFFS"
#endif
//////
#define ESP_getChipId() (ESP.getChipId())
#define LED_ON LOW
#define LED_OFF HIGH
#endif
// These defines must be put before #include <ESP_DoubleResetDetector.h>
// to select where to store DoubleResetDetector's variable.
// For ESP32, You must select one to be true (EEPROM or SPIFFS)
// For ESP8266, You must select one to be true (RTC, EEPROM, SPIFFS or LITTLEFS)
// Otherwise, library will use default EEPROM storage
#ifdef ESP32
// These defines must be put before #include <ESP_DoubleResetDetector.h>
// to select where to store DoubleResetDetector's variable.
// For ESP32, You must select one to be true (EEPROM or SPIFFS)
// Otherwise, library will use default EEPROM storage
#if USE_LITTLEFS
#define ESP_DRD_USE_LITTLEFS true
#define ESP_DRD_USE_SPIFFS false
#define ESP_DRD_USE_EEPROM false
#elif USE_SPIFFS
#define ESP_DRD_USE_LITTLEFS false
#define ESP_DRD_USE_SPIFFS true
#define ESP_DRD_USE_EEPROM false
#else
#define ESP_DRD_USE_LITTLEFS false
#define ESP_DRD_USE_SPIFFS false
#define ESP_DRD_USE_EEPROM true
#endif
#else //ESP8266
// For DRD
// These defines must be put before #include <ESP_DoubleResetDetector.h>
// to select where to store DoubleResetDetector's variable.
// For ESP8266, You must select one to be true (RTC, EEPROM, SPIFFS or LITTLEFS)
// Otherwise, library will use default EEPROM storage
#if USE_LITTLEFS
#define ESP_DRD_USE_LITTLEFS true
#define ESP_DRD_USE_SPIFFS false
#else
#define ESP_DRD_USE_LITTLEFS false
#define ESP_DRD_USE_SPIFFS true
#endif
#define ESP_DRD_USE_EEPROM false
#define ESP8266_DRD_USE_RTC false
#endif
#define DOUBLERESETDETECTOR_DEBUG false
#include <ESP_DoubleResetDetector.h> //https://github.com/khoih-prog/ESP_DoubleResetDetector
// Number of seconds after reset during which a
// subseqent reset will be considered a double reset.
#define DRD_TIMEOUT 10
// RTC Memory Address for the DoubleResetDetector to use
#define DRD_ADDRESS 0
// From v1.1.0
// You only need to format the filesystem once
//#define FORMAT_FILESYSTEM true
#define FORMAT_FILESYSTEM false
#define MIN_AP_PASSWORD_SIZE 8
#define SSID_MAX_LEN 32
//From v1.0.10, WPA2 passwords can be up to 63 characters long.
#define PASS_MAX_LEN 64
typedef struct
{
char wifi_ssid[SSID_MAX_LEN];
char wifi_pw [PASS_MAX_LEN];
} WiFi_Credentials;
typedef struct
{
String wifi_ssid;
String wifi_pw;
} WiFi_Credentials_String;
#define NUM_WIFI_CREDENTIALS 2
// Assuming max 491 chars
#define TZNAME_MAX_LEN 50
#define TIMEZONE_MAX_LEN 50
typedef struct
{
WiFi_Credentials WiFi_Creds [NUM_WIFI_CREDENTIALS];
char TZ_Name[TZNAME_MAX_LEN]; // "America/Toronto"
char TZ[TIMEZONE_MAX_LEN]; // "EST5EDT,M3.2.0,M11.1.0"
uint16_t checksum;
} WM_Config;
#define CONFIG_FILENAME F("/wifi_cred.dat")
//////
// Use false if you don't like to display Available Pages in Information Page of Config Portal
// Comment out or use true to display Available Pages in Information Page of Config Portal
// Must be placed before #include <ESP_WiFiManager.h>
#define USE_AVAILABLE_PAGES true //false
// From v1.0.10 to permit disable/enable StaticIP configuration in Config Portal from sketch. Valid only if DHCP is used.
// You'll loose the feature of dynamically changing from DHCP to static IP, or vice versa
// You have to explicitly specify false to disable the feature.
//#define USE_STATIC_IP_CONFIG_IN_CP false
// Use false to disable NTP config. Advisable when using Cellphone, Tablet to access Config Portal.
// See Issue 23: On Android phone ConfigPortal is unresponsive (https://github.com/khoih-prog/ESP_WiFiManager/issues/23)
#define USE_ESP_WIFIMANAGER_NTP true
// Just use enough to save memory. On ESP8266, can cause blank ConfigPortal screen
// if using too much memory
#define USING_AFRICA false
#define USING_AMERICA false
#define USING_ANTARCTICA false
#define USING_ASIA false
#define USING_ATLANTIC false
#define USING_AUSTRALIA false
#define USING_EUROPE true
#define USING_INDIAN false
#define USING_PACIFIC false
#define USING_ETC_GMT false
// Use true to enable CloudFlare NTP service. System can hang if you don't have Internet access while accessing CloudFlare
// See Issue #21: CloudFlare link in the default portal (https://github.com/khoih-prog/ESP_WiFiManager/issues/21)
#define USE_CLOUDFLARE_NTP false
// New in v1.0.11
#define USING_CORS_FEATURE true
////////////////////////////////////////////
// Use USE_DHCP_IP == true for dynamic DHCP IP, false to use static IP which you have to change accordingly to your network
#if (defined(USE_STATIC_IP_CONFIG_IN_CP) && !USE_STATIC_IP_CONFIG_IN_CP)
// Force DHCP to be true
#if defined(USE_DHCP_IP)
#undef USE_DHCP_IP
#endif
#define USE_DHCP_IP true
#else
// You can select DHCP or Static IP here
#define USE_DHCP_IP true
//#define USE_DHCP_IP false
#endif