NEW
This commit is contained in:
98
hardware/ESP_ARDUINO/core/OTA.h
Normal file
98
hardware/ESP_ARDUINO/core/OTA.h
Normal file
@@ -0,0 +1,98 @@
|
||||
#ifdef ESP32
|
||||
#include <WiFi.h>
|
||||
#include <ESPmDNS.h>
|
||||
#else
|
||||
#include <ESP8266WiFi.h>
|
||||
#include <ESP8266mDNS.h>
|
||||
#endif
|
||||
|
||||
#include <WiFiUdp.h>
|
||||
#include <ArduinoOTA.h>
|
||||
#include <TelnetStream.h>
|
||||
|
||||
#if defined(ESP32_RTOS) && defined(ESP32)
|
||||
void ota_handle( void * parameter ) {
|
||||
for (;;) {
|
||||
ArduinoOTA.handle();
|
||||
delay(3500);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void setupOTA(const char* nameprefix, const char* ssid, const char* password) {
|
||||
// Configure the hostname
|
||||
uint16_t maxlen = strlen(nameprefix) + 7;
|
||||
char *fullhostname = new char[maxlen];
|
||||
uint8_t mac[6];
|
||||
WiFi.macAddress(mac);
|
||||
snprintf(fullhostname, maxlen, "%s-%02x%02x%02x", nameprefix, mac[3], mac[4], mac[5]);
|
||||
ArduinoOTA.setHostname(fullhostname);
|
||||
delete[] fullhostname;
|
||||
|
||||
// Configure and start the WiFi station
|
||||
WiFi.mode(WIFI_STA);
|
||||
WiFi.begin(ssid, password);
|
||||
|
||||
// Wait for connection
|
||||
while (WiFi.waitForConnectResult() != WL_CONNECTED) {
|
||||
Serial.println("Connection Failed! Rebooting...");
|
||||
delay(5000);
|
||||
ESP.restart();
|
||||
}
|
||||
|
||||
// Port defaults to 3232
|
||||
// ArduinoOTA.setPort(3232); // Use 8266 port if you are working in Sloeber IDE, it is fixed there and not adjustable
|
||||
|
||||
// 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([]() {
|
||||
//NOTE: make .detach() here for all functions called by Ticker.h library - not to interrupt transfer process in any way.
|
||||
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);
|
||||
});
|
||||
|
||||
ArduinoOTA.onEnd([]() {
|
||||
Serial.println("\nEnd");
|
||||
});
|
||||
|
||||
ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
|
||||
Serial.printf("Progress: %u%%\r", (progress / (total / 100)));
|
||||
});
|
||||
|
||||
ArduinoOTA.onError([](ota_error_t error) {
|
||||
Serial.printf("Error[%u]: ", error);
|
||||
if (error == OTA_AUTH_ERROR) Serial.println("\nAuth Failed");
|
||||
else if (error == OTA_BEGIN_ERROR) Serial.println("\nBegin Failed");
|
||||
else if (error == OTA_CONNECT_ERROR) Serial.println("\nConnect Failed");
|
||||
else if (error == OTA_RECEIVE_ERROR) Serial.println("\nReceive Failed");
|
||||
else if (error == OTA_END_ERROR) Serial.println("\nEnd Failed");
|
||||
});
|
||||
|
||||
ArduinoOTA.begin();
|
||||
TelnetStream.begin();
|
||||
|
||||
Serial.println("OTA Initialized");
|
||||
Serial.print("IP address: ");
|
||||
Serial.println(WiFi.localIP());
|
||||
|
||||
#if defined(ESP32_RTOS) && defined(ESP32)
|
||||
xTaskCreate(
|
||||
ota_handle, /* Task function. */
|
||||
"OTA_HANDLE", /* String with name of task. */
|
||||
10000, /* Stack size in bytes. */
|
||||
NULL, /* Parameter passed as input of the task */
|
||||
1, /* Priority of the task. */
|
||||
NULL); /* Task handle. */
|
||||
#endif
|
||||
}
|
||||
45
hardware/ESP_ARDUINO/core/RFID.h
Normal file
45
hardware/ESP_ARDUINO/core/RFID.h
Normal file
@@ -0,0 +1,45 @@
|
||||
#ifndef RFID_h
|
||||
#define RFID_h
|
||||
|
||||
#include "logger.h"
|
||||
|
||||
|
||||
class RFID
|
||||
{
|
||||
private:
|
||||
|
||||
public:
|
||||
RFID () {} // CONSTRUCTOR
|
||||
|
||||
// function ro validate
|
||||
bool validate (String tag){
|
||||
bool r;
|
||||
r = false;
|
||||
if ((tag.length() == 16) || // RUND
|
||||
(tag.length() == 36)) // Eckig
|
||||
{r = true;}
|
||||
else {
|
||||
logger.log(0, "WRONG TAG");
|
||||
logger.log(0, tag);
|
||||
logger.log(0, String(tag.length()));
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
String toHex (int c){
|
||||
String r;
|
||||
if (c < 15) {
|
||||
r = '0';
|
||||
r = r+ String ( c, HEX )[0];
|
||||
} else {
|
||||
|
||||
r = String ( c, HEX )[0];
|
||||
r = r+ String ( c, HEX )[1];
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
262
hardware/ESP_ARDUINO/core/bluetooth.h
Normal file
262
hardware/ESP_ARDUINO/core/bluetooth.h
Normal file
@@ -0,0 +1,262 @@
|
||||
#ifndef BLUETOOTH_h
|
||||
#define BLUETOOTH_h
|
||||
|
||||
#include <NimBLEDevice.h>
|
||||
#include "logger.h"
|
||||
|
||||
|
||||
|
||||
static bool doConnect = false;
|
||||
static uint32_t scanTime = 0;
|
||||
|
||||
static NimBLEAdvertisedDevice* advDevice;
|
||||
|
||||
static void scanEndedCB(NimBLEScanResults results){
|
||||
logger.log(5, "Scan Ended" );
|
||||
} // END SCANENDEDCB
|
||||
|
||||
|
||||
|
||||
|
||||
class ClientCallbacks : public NimBLEClientCallbacks {
|
||||
void onConnect(NimBLEClient* pClient) {
|
||||
logger.log(5, "Connected");
|
||||
};
|
||||
|
||||
void onDisconnect(NimBLEClient* pClient) {
|
||||
logger.log(5, "Disconnected - Starting Scan" );
|
||||
NimBLEDevice::getScan()->start(scanTime, scanEndedCB);
|
||||
};
|
||||
bool onConnParamsUpdateRequest(NimBLEClient* pClient, const ble_gap_upd_params* params) {
|
||||
if(params->itvl_min < 24) { /** 1.25ms units */
|
||||
return false;
|
||||
} else if(params->itvl_max > 40) { /** 1.25ms units */
|
||||
return false;
|
||||
} else if(params->latency > 2) { /** Number of intervals allowed to skip */
|
||||
return false;
|
||||
} else if(params->supervision_timeout > 100) { /** 10ms units */
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
uint32_t onPassKeyRequest(){
|
||||
return 123456;
|
||||
};
|
||||
|
||||
bool onConfirmPIN(uint32_t pass_key){
|
||||
return true;
|
||||
};
|
||||
void onAuthenticationComplete(ble_gap_conn_desc* desc){
|
||||
|
||||
if(!desc->sec_state.encrypted) {
|
||||
logger.log(5, "Encrypt connection failed.");
|
||||
NimBLEDevice::getClientByID(desc->conn_handle)->disconnect();
|
||||
return;
|
||||
}
|
||||
};
|
||||
};// END CLIENTCALLBACK
|
||||
|
||||
class AdvertisedDeviceCallbacks: public NimBLEAdvertisedDeviceCallbacks {
|
||||
private:
|
||||
LOGGER logger;
|
||||
|
||||
|
||||
void onResult(NimBLEAdvertisedDevice* advertisedDevice) {
|
||||
|
||||
logger.log(5, advertisedDevice->toString().c_str() );
|
||||
if(advertisedDevice->isAdvertisingService(NimBLEUUID::fromString("0x180F") ))
|
||||
{
|
||||
logger.log(5, "Service Found");
|
||||
NimBLEDevice::getScan()->stop();
|
||||
advDevice = advertisedDevice;
|
||||
doConnect = true;
|
||||
}
|
||||
};
|
||||
}; // END ADVERTISED CALLBACK
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class BLUETOOTH
|
||||
{
|
||||
private:
|
||||
|
||||
ClientCallbacks clientCB;
|
||||
|
||||
|
||||
|
||||
static void notifyCB(NimBLERemoteCharacteristic* pRemoteCharacteristic, uint8_t* pData, size_t length, bool isNotify){
|
||||
std::string str = (isNotify == true) ? "Notification" : "Indication";
|
||||
str += " from ";
|
||||
/** NimBLEAddress and NimBLEUUID have std::string operators */
|
||||
str += std::string(pRemoteCharacteristic->getRemoteService()->getClient()->getPeerAddress());
|
||||
str += ": Service = " + std::string(pRemoteCharacteristic->getRemoteService()->getUUID());
|
||||
str += ", Characteristic = " + std::string(pRemoteCharacteristic->getUUID());
|
||||
str += ", Value = " + std::string((char*)pData, length);
|
||||
logger.log(5,"NOTIFY CALLBACK ");
|
||||
logger.log(5,str.c_str());
|
||||
} // END NOTIFYCB
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool connectToServer() {
|
||||
logger.log(5,"Connected To Server");
|
||||
NimBLEClient* pClient = nullptr;
|
||||
if(NimBLEDevice::getClientListSize()) {
|
||||
pClient = NimBLEDevice::getClientByPeerAddress(advDevice->getAddress());
|
||||
|
||||
if(pClient){
|
||||
|
||||
if(!pClient->connect(advDevice, false)) {
|
||||
logger.log(5,"Reconnect Failed");
|
||||
return false;
|
||||
}
|
||||
logger.log(5,"Reconnected Client");
|
||||
}
|
||||
else {
|
||||
|
||||
pClient = NimBLEDevice::getDisconnectedClient();
|
||||
}
|
||||
}
|
||||
|
||||
if(!pClient) {
|
||||
if(NimBLEDevice::getClientListSize() >= NIMBLE_MAX_CONNECTIONS) {
|
||||
logger.log(5,"Max clients reached");
|
||||
return false;
|
||||
}
|
||||
|
||||
pClient = NimBLEDevice::createClient();
|
||||
pClient->setClientCallbacks(&clientCB, false);
|
||||
|
||||
pClient->setConnectionParams(12,12,0,51);
|
||||
|
||||
/** Set how long we are willing to wait for the connection to complete (seconds), default is 30. */
|
||||
pClient->setConnectTimeout(5);
|
||||
logger.log(5,advDevice->toString().c_str());
|
||||
if (!pClient->connect(advDevice)) {
|
||||
|
||||
NimBLEDevice::deleteClient(pClient);
|
||||
logger.log(5,"Failed to connect, deleted client");
|
||||
Serial.println("Failed to connect, deleted client");
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if(!pClient->isConnected()) {
|
||||
if (!pClient->connect(advDevice)) {
|
||||
logger.log(5,"Failed to connect");
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
logger.log(5,"Connected to");
|
||||
logger.log(5,pClient->getPeerAddress().toString().c_str());
|
||||
|
||||
/** Now we can read/write/subscribe the charateristics of the services we are interested in */
|
||||
NimBLERemoteService* pSvc = nullptr;
|
||||
NimBLERemoteCharacteristic* pChr = nullptr;
|
||||
NimBLERemoteDescriptor* pDsc = nullptr;
|
||||
|
||||
pSvc = pClient->getService(NimBLEUUID::fromString("0x181D"));
|
||||
if(pSvc) { /** make sure it's not null */
|
||||
logger.log(5,"Service found");
|
||||
|
||||
|
||||
pChr = pSvc->getCharacteristic(NimBLEUUID::fromString("0x2A9D"));
|
||||
|
||||
if(pChr) { /** make sure it's not null */
|
||||
logger.log(5,"Charactheristic found");
|
||||
|
||||
if(pChr->canRead()) {
|
||||
logger.log(5,"Can read");
|
||||
|
||||
|
||||
Serial.print(pChr->getUUID().toString().c_str());
|
||||
Serial.print(" Value: ");
|
||||
Serial.println(pChr->readValue().c_str());
|
||||
}
|
||||
|
||||
|
||||
/** registerForNotify() has been deprecated and replaced with subscribe() / unsubscribe().
|
||||
* Subscribe parameter defaults are: notifications=true, notifyCallback=nullptr, response=false.
|
||||
* Unsubscribe parameter defaults are: response=false.
|
||||
*/
|
||||
if(pChr->canNotify()) {
|
||||
logger.log(5,"Can Notify");
|
||||
|
||||
//if(!pChr->registerForNotify(notifyCB)) {
|
||||
if(!pChr->subscribe(true, notifyCB)) {
|
||||
/** Disconnect if subscribe failed */
|
||||
pClient->disconnect();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if(pChr->canIndicate()) {
|
||||
logger.log(5,"Can indicate");
|
||||
|
||||
|
||||
/** Send false as first argument to subscribe to indications instead of notifications */
|
||||
//if(!pChr->registerForNotify(notifyCB, false)) {
|
||||
if(!pChr->subscribe(false, notifyCB)) {
|
||||
/** Disconnect if subscribe failed */
|
||||
pClient->disconnect();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
logger.log(5,"Service not found");
|
||||
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public:
|
||||
BLUETOOTH () {} // CONSTRUCTOR
|
||||
|
||||
void setup (){
|
||||
|
||||
NimBLEDevice::init("");
|
||||
NimBLEDevice::setSecurityAuth(/*BLE_SM_PAIR_AUTHREQ_BOND | BLE_SM_PAIR_AUTHREQ_MITM |*/ BLE_SM_PAIR_AUTHREQ_SC);
|
||||
NimBLEDevice::setPower(ESP_PWR_LVL_P9); /** +9db */
|
||||
NimBLEScan* pScan = NimBLEDevice::getScan();
|
||||
pScan->setAdvertisedDeviceCallbacks(new AdvertisedDeviceCallbacks());
|
||||
pScan->setInterval(45);
|
||||
pScan->setWindow(15);
|
||||
pScan->setActiveScan(true);
|
||||
pScan->start(scanTime, scanEndedCB);
|
||||
} // setup()
|
||||
|
||||
void loop (){
|
||||
if(doConnect){
|
||||
Serial.println("doCOnnect=true");
|
||||
if(connectToServer()) {
|
||||
logger.log(1, "Connected to BLE");
|
||||
|
||||
Serial.println("Success! we should now be getting notifications, scanning for more!");
|
||||
} else {
|
||||
Serial.println("Failed to connect, starting scan");
|
||||
}
|
||||
NimBLEDevice::getScan()->start(scanTime,scanEndedCB);
|
||||
|
||||
}
|
||||
doConnect = false;
|
||||
|
||||
|
||||
} // loop()
|
||||
};
|
||||
#endif
|
||||
108
hardware/ESP_ARDUINO/core/core.ino
Normal file
108
hardware/ESP_ARDUINO/core/core.ino
Normal file
@@ -0,0 +1,108 @@
|
||||
// pip install pyserial
|
||||
// MQTT JOEL GÄhwiller
|
||||
// Telnetstream Andrassi
|
||||
|
||||
#include "bluetooth.h"
|
||||
|
||||
#include <WiFi.h>
|
||||
#include <ArduinoOTA.h>
|
||||
#include <MQTT.h>
|
||||
#include "RFID.h"
|
||||
#include "logger.h"
|
||||
#define rxRFID 15 // COM2: 16 -- 18
|
||||
#define txRFID 2 // COM2: 17 -- 19
|
||||
#define GPIO6 6
|
||||
|
||||
const char* ssid = "coral";
|
||||
const char* password = "135798642";
|
||||
const char* OTApassword = "135798642";
|
||||
IPAddress apIP(192, 168, 200, 1);
|
||||
IPAddress Gateway(192, 168, 200, 100);
|
||||
IPAddress MQTTserver(192, 168, 200, 2);
|
||||
|
||||
|
||||
unsigned long StartTime = millis();
|
||||
|
||||
|
||||
WiFiClient net;
|
||||
MQTTClient client;
|
||||
RFID rfid;
|
||||
int loopCounter = 0;
|
||||
|
||||
String buffer;
|
||||
unsigned long TimeStamp;
|
||||
bool readProgress;
|
||||
|
||||
BLUETOOTH bt;
|
||||
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
bt.setup();
|
||||
|
||||
WiFi.mode(WIFI_AP_STA);
|
||||
WiFi.softAPConfig(apIP, Gateway, IPAddress(255, 255, 255, 0));
|
||||
WiFi.softAP(ssid, password);
|
||||
|
||||
pinMode(rxRFID, INPUT);
|
||||
pinMode(txRFID, OUTPUT);
|
||||
Serial2.begin(57600, SERIAL_8N1,rxRFID,txRFID );
|
||||
|
||||
client.begin(MQTTserver, net);
|
||||
client.setTimeout (500);
|
||||
|
||||
ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
|
||||
});
|
||||
ArduinoOTA.setHostname("Coral");
|
||||
ArduinoOTA.setPassword(OTApassword);
|
||||
ArduinoOTA.begin();
|
||||
|
||||
logger.setup();
|
||||
buffer = "";
|
||||
readProgress = false;
|
||||
|
||||
Serial.println("END SETUP");
|
||||
}
|
||||
|
||||
void loop() {
|
||||
logger.loop();
|
||||
bt.loop();
|
||||
ArduinoOTA.handle();
|
||||
|
||||
|
||||
|
||||
|
||||
// ********************** READ RFID ******************
|
||||
|
||||
if (!logger.serialBridge)
|
||||
{
|
||||
while (Serial2.available()) {
|
||||
ArduinoOTA.handle();
|
||||
buffer = buffer + rfid.toHex ( Serial2.read() );
|
||||
TimeStamp = millis();
|
||||
readProgress = true;
|
||||
}
|
||||
if (((millis() - TimeStamp)>200) && readProgress) // ABORT WHEN TIMEOUT
|
||||
{
|
||||
if (rfid.validate (buffer)) {
|
||||
buffer.toUpperCase();
|
||||
client.publish("tag", buffer);
|
||||
logger.log(5, buffer);
|
||||
}
|
||||
buffer = "";
|
||||
readProgress = false;
|
||||
}
|
||||
|
||||
// ************ CALCULATE LOOP TIME ************************
|
||||
loopCounter++;
|
||||
if (loopCounter > 10000) {
|
||||
unsigned long delta = millis() - StartTime;
|
||||
char buf[50];
|
||||
sprintf(buf, "Loop time: %lu - %lu - %lu", millis(), StartTime, delta);
|
||||
logger.log(5, buf);
|
||||
StartTime = millis();
|
||||
loopCounter = 0;
|
||||
if (!client.connected()) { client.connect("coral", "public", "public"); }
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
6
hardware/ESP_ARDUINO/core/debug
Executable file
6
hardware/ESP_ARDUINO/core/debug
Executable file
@@ -0,0 +1,6 @@
|
||||
#!/bin/bash
|
||||
|
||||
while [ 1=1 ]
|
||||
do
|
||||
nc 192.168.200.1 23
|
||||
done
|
||||
100
hardware/ESP_ARDUINO/core/logger.h
Normal file
100
hardware/ESP_ARDUINO/core/logger.h
Normal file
@@ -0,0 +1,100 @@
|
||||
#ifndef LOGGER_h
|
||||
#define LOGGER_h
|
||||
#include <TelnetStream.h>
|
||||
|
||||
#define versionString "1.3"
|
||||
#define BLUELED 2
|
||||
|
||||
|
||||
|
||||
class LOGGER
|
||||
{
|
||||
private:
|
||||
unsigned long StartTime = millis();
|
||||
int counter = 0;
|
||||
int loglevel = 0;
|
||||
|
||||
public:
|
||||
LOGGER () {} // CONSTRUCTOR
|
||||
bool serialBridge = false;
|
||||
|
||||
void writeTelnet()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
void setup (){
|
||||
pinMode(BLUELED, OUTPUT);
|
||||
digitalWrite(BLUELED, LOW);
|
||||
TelnetStream.begin();
|
||||
}
|
||||
|
||||
void loop (){
|
||||
if ( serialBridge ){
|
||||
while (Serial2.available()) { TelnetStream.print ( Serial2.read() ); }
|
||||
Serial2.print( TelnetStream.read() );
|
||||
} else {
|
||||
|
||||
switch (TelnetStream.read()) {
|
||||
case 'h':
|
||||
TelnetStream.println("HELP");
|
||||
TelnetStream.println("i: info");
|
||||
TelnetStream.println("l: toggle LED - not working");
|
||||
TelnetStream.println("r: revisions");
|
||||
TelnetStream.println("s: turn on serial bridge");
|
||||
TelnetStream.println("");
|
||||
TelnetStream.println("0-5: set Log Level");
|
||||
TelnetStream.println("0: system");
|
||||
TelnetStream.println("3: debug");
|
||||
TelnetStream.println("5: verbose");
|
||||
break;
|
||||
case 's':
|
||||
TelnetStream.println( "Turning on serialBridge" );
|
||||
serialBridge = true;
|
||||
break;
|
||||
|
||||
case 'i':
|
||||
TelnetStream.print( "Version: " );
|
||||
TelnetStream.println( versionString );
|
||||
TelnetStream.print( "Loglevel: " );
|
||||
TelnetStream.println( loglevel );
|
||||
break;
|
||||
case 'r':
|
||||
TelnetStream.println( "Revisions: " );
|
||||
TelnetStream.println( "1.1 - BLE, no Diag " );
|
||||
TelnetStream.println( "1.0 - Initial Release " );
|
||||
break;
|
||||
|
||||
case 'l':
|
||||
digitalWrite(BLUELED, !digitalRead(BLUELED));
|
||||
break;
|
||||
|
||||
case '0':
|
||||
loglevel = 0;
|
||||
break;
|
||||
case '3':
|
||||
loglevel = 3;
|
||||
break;
|
||||
case '5':
|
||||
loglevel = 5;
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
void log(int ll, String buffer )
|
||||
{
|
||||
if ( ll<= loglevel) { TelnetStream.println( buffer );
|
||||
Serial.println (buffer);
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
LOGGER logger;
|
||||
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user