Initial push
This commit is contained in:
@@ -0,0 +1,51 @@
|
||||
#include <Arduino.h>
|
||||
#include <WiFi.h>
|
||||
#include <lwip/sockets.h>
|
||||
|
||||
#define _SSID "ESP32-AP1"
|
||||
#define _PASSWD "PASS0000"
|
||||
#define UDP_PORT 6666
|
||||
|
||||
#define MTU 100000
|
||||
|
||||
IPAddress apIP(192,168,178,1);
|
||||
IPAddress subnetMask(255,255,255,0);
|
||||
|
||||
static int udp_sock;
|
||||
|
||||
void udp_task(void* /*args*/) {
|
||||
struct sockaddr_in sourceAddr;
|
||||
socklen_t addrLen = sizeof(sourceAddr);
|
||||
static uint8_t udp_buf[MTU];
|
||||
|
||||
while (true) {
|
||||
int len = recvfrom(udp_sock, udp_buf, MTU - 1, 0, (struct sockaddr*)&sourceAddr, &addrLen);
|
||||
if (len > 0) {
|
||||
udp_buf[len] = '\n';
|
||||
Serial.write(udp_buf, len + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
while (!Serial) { delay(10); }
|
||||
|
||||
WiFi.mode(WIFI_AP);
|
||||
WiFi.softAPConfig(apIP, apIP, subnetMask);
|
||||
WiFi.softAP(_SSID, _PASSWD, /*channel*/1, /*hidden*/false, /*maxConn*/4);
|
||||
|
||||
udp_sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
||||
struct sockaddr_in localAddr;
|
||||
memset(&localAddr, 0, sizeof(localAddr));
|
||||
localAddr.sin_family = AF_INET;
|
||||
localAddr.sin_port = htons(UDP_PORT);
|
||||
localAddr.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||
bind(udp_sock, (struct sockaddr*)&localAddr, sizeof(localAddr));
|
||||
|
||||
xTaskCreatePinnedToCore(udp_task, "UDPReceiver", 4096, nullptr, 5, nullptr, 1);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
vTaskDelay(pdMS_TO_TICKS(1000));
|
||||
}
|
||||
@@ -0,0 +1,220 @@
|
||||
#include <WiFi.h>
|
||||
#include <WiFiUdp.h>
|
||||
|
||||
#define DEBUG
|
||||
|
||||
// #define MBS2_1 // AP hosting ESP32-AP2
|
||||
#define MBS2_2 // Client connected to ESP32-AP1
|
||||
|
||||
#ifdef MBS2_1
|
||||
#ifdef MBS2_2
|
||||
#undef MBS2_2
|
||||
#endif
|
||||
#endif
|
||||
#ifdef MBS2_2
|
||||
#ifdef MBS2_1
|
||||
#undef MBS2_1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef MBS2_1
|
||||
#define _NAME "MBS2_1"
|
||||
#define ap_ssid "ESP32-AP2"
|
||||
#define ap_passwd "PASS0000"
|
||||
IPAddress apIP(192, 168, 178, 1);
|
||||
IPAddress subnetMask(255, 255, 255, 0);
|
||||
#endif
|
||||
|
||||
#ifdef MBS2_2
|
||||
#define _NAME "MBS2_2"
|
||||
#define base_ssid "ESP32-AP1"
|
||||
#define base_passwd "PASS0000"
|
||||
#endif
|
||||
|
||||
#define MAX_PACKET_SIZE 1500
|
||||
#define UDP_PORT 6666
|
||||
|
||||
WiFiUDP udp;
|
||||
|
||||
IPAddress localIP = IPAddress();
|
||||
|
||||
void (*routeMBS)(void);
|
||||
|
||||
#pragma region Access Point Functions
|
||||
|
||||
#ifdef MBS2_1
|
||||
void init_wifi_access_point(){
|
||||
WiFi.mode(WIFI_AP);
|
||||
WiFi.softAPConfig(apIP, apIP, subnetMask);
|
||||
WiFi.softAP(ap_ssid, ap_passwd, /* channel */ 1, /* hidden */ false, /* maxConn */ 4);
|
||||
}
|
||||
|
||||
char *receive(){
|
||||
int packetSize = udp.parsePacket();
|
||||
if(packetSize <= 0) return NULL;
|
||||
packetSize = packetSize > MAX_PACKET_SIZE ? MAX_PACKET_SIZE: packetSize;
|
||||
char *buffer = (char*)malloc(packetSize + 1);
|
||||
|
||||
udp.read(buffer, packetSize);
|
||||
buffer[packetSize] = '\0';
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
void send(char *buf){
|
||||
Serial.write(buf);
|
||||
Serial2.write(buf);
|
||||
}
|
||||
|
||||
String readSerialUntil(const String& delimiter) {
|
||||
String res = "";
|
||||
unsigned long start = millis();
|
||||
|
||||
while (!res.endsWith(delimiter) && (millis() - start < 1000)) {
|
||||
if (Serial.available()) {
|
||||
char c = Serial.read();
|
||||
res += c;
|
||||
start = millis();
|
||||
} else {
|
||||
// yield the CPU so the watchdog won’t fire
|
||||
taskYIELD();
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
void doSerialReading(){
|
||||
if(Serial.available()){
|
||||
Serial2.print(readSerialUntil("\n"));
|
||||
}
|
||||
}
|
||||
|
||||
void MBS2_1_loop(){
|
||||
#ifdef DEBUG
|
||||
/*
|
||||
To debug loop through instances
|
||||
MBS2_1 Serial2 out -> MBS2_1 Serial2 in UDP out
|
||||
*/
|
||||
doSerialReading();
|
||||
#endif
|
||||
char *recv = receive();
|
||||
if(recv != NULL){
|
||||
log(String("Received: "));
|
||||
log(recv);
|
||||
send(recv);
|
||||
free(recv);
|
||||
recv = NULL;
|
||||
}
|
||||
free(recv); // NULL free is safe
|
||||
vTaskDelay(pdMS_TO_TICKS(1));
|
||||
}
|
||||
#endif // #ifdef MBS2_1
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#pragma region Client (Base Station) Functions
|
||||
|
||||
#ifdef MBS2_2
|
||||
IPAddress apIP(192,168,178,1);
|
||||
|
||||
void init_wifi_base_station_connection(){
|
||||
WiFi.mode(WIFI_STA);
|
||||
WiFi.begin(base_ssid, base_passwd);
|
||||
|
||||
#ifdef DEBUG
|
||||
size_t start = millis();
|
||||
#endif
|
||||
while(WiFi.status() != WL_CONNECTED){ // while esps aren't connected nothing can run either
|
||||
#ifdef DEBUG
|
||||
log(String("Trying to connect to: ") + String(base_ssid) + String("\nTime: ") + String(millis() - start));
|
||||
Serial.flush();
|
||||
#endif
|
||||
// Serial.println("Trying to connect to: " + this->base_ssid + "\nTime: " + String(millis() - start) + "/" + String(connection_timeout));
|
||||
delay(50);
|
||||
}
|
||||
|
||||
if(WiFi.status() == WL_CONNECTED){
|
||||
localIP = WiFi.localIP();
|
||||
}
|
||||
}
|
||||
|
||||
void send(const String& msg){
|
||||
udp.beginPacket(apIP, UDP_PORT);
|
||||
udp.write((uint8_t*)msg.c_str(), msg.length());
|
||||
udp.endPacket();
|
||||
}
|
||||
|
||||
String readSerialUntil(const String& delimiter) {
|
||||
String res = "";
|
||||
unsigned long start = millis();
|
||||
|
||||
while (!res.endsWith(delimiter) && (millis() - start < 1000)) {
|
||||
if (Serial2.available()) {
|
||||
char c = Serial2.read();
|
||||
res += c;
|
||||
start = millis();
|
||||
} else {
|
||||
// yield the CPU so the watchdog won’t fire
|
||||
taskYIELD();
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
void MBS2_2_loop(){
|
||||
if(Serial2.available()){
|
||||
String recv = readSerialUntil("\n");
|
||||
log("Received: " + recv);
|
||||
send(recv);
|
||||
}
|
||||
// always give os a tick
|
||||
vTaskDelay(pdMS_TO_TICKS(1));
|
||||
}
|
||||
#endif // #ifdef MBS2_2
|
||||
|
||||
#pragma endregion
|
||||
|
||||
void log(String buf){
|
||||
#ifdef DEBUG
|
||||
Serial.println(buf);
|
||||
#endif
|
||||
}
|
||||
|
||||
void log(char *buf){
|
||||
#ifdef DEBUG
|
||||
Serial.write(buf);
|
||||
#endif
|
||||
}
|
||||
|
||||
void setup() {
|
||||
#ifdef DEBUG
|
||||
Serial.begin(115200);
|
||||
#endif
|
||||
Serial2.begin(115200, SERIAL_8N1, 18, 17);
|
||||
|
||||
#ifdef MBS2_1
|
||||
init_wifi_access_point();
|
||||
routeMBS = MBS2_1_loop;
|
||||
#endif
|
||||
|
||||
#ifdef MBS2_2
|
||||
init_wifi_base_station_connection();
|
||||
routeMBS = MBS2_2_loop;
|
||||
#endif
|
||||
|
||||
udp.begin(UDP_PORT);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
#ifdef DEBUG
|
||||
static size_t start = millis();
|
||||
if(millis() - start >= 1000){
|
||||
log(String(_NAME));
|
||||
start = millis();
|
||||
}
|
||||
#endif
|
||||
routeMBS();
|
||||
taskYIELD();
|
||||
}
|
||||
@@ -0,0 +1,191 @@
|
||||
#include <Arduino.h>
|
||||
#include <WiFi.h>
|
||||
#include <lwip/sockets.h>
|
||||
|
||||
#define _PASSWD "PASS0000"
|
||||
#define UDP_PORT 6666
|
||||
|
||||
#define MTU 100000
|
||||
|
||||
WiFiUDP udp;
|
||||
SemaphoreHandle_t netw_mtx;
|
||||
|
||||
String SSIDs[] = { "ESP32-AP1", "ESP32-AP2" };
|
||||
int scanStatus = WIFI_SCAN_FAILED;
|
||||
unsigned long lastScanRequest = 0;
|
||||
int otherRSSI = -9999;
|
||||
String otherSSID = "";
|
||||
|
||||
String readSerialUntil(const String& delimiter) {
|
||||
String res = "";
|
||||
unsigned long start = millis();
|
||||
|
||||
while (!res.endsWith(delimiter) && (millis() - start < 1000)) {
|
||||
if (Serial.available()) {
|
||||
char c = Serial.read();
|
||||
res += c;
|
||||
start = millis();
|
||||
} else {
|
||||
// yield the CPU so the watchdog won’t fire
|
||||
taskYIELD();
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
int findSSIDIndex(const String &ssid, size_t network_count) {
|
||||
for(int i = 0; i < network_count; i++) {
|
||||
if(WiFi.SSID(i) == ssid) return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int getSignalStrengthFromStation(const String& ssid) {
|
||||
if(ssid == "") {
|
||||
if(WiFi.isConnected()) {
|
||||
return WiFi.RSSI();
|
||||
} else {
|
||||
return -9999;
|
||||
}
|
||||
}
|
||||
size_t found_network_count = WiFi.scanNetworks(false);
|
||||
int index = -1;
|
||||
if((index = findSSIDIndex(ssid, found_network_count)) == -1) return -9999;
|
||||
return WiFi.RSSI(index);
|
||||
}
|
||||
|
||||
String getAvailableInfo() {
|
||||
String ret = "{\"type\":\"text\",\"IP\":\"";
|
||||
ret += WiFi.localIP().toString();
|
||||
ret += "\",\"Base Station\":\"";
|
||||
ret += WiFi.SSID();
|
||||
ret += "\",\"RSSI\":\"";
|
||||
ret += WiFi.RSSI();
|
||||
ret += "\",\"Other Network\":\"";
|
||||
ret += otherSSID;
|
||||
ret += "\",\"Other RSSI\":\"";
|
||||
ret += otherRSSI;
|
||||
ret += "\"}\n";
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void send_udp(void *args){
|
||||
String* msg = static_cast<String*>(args);
|
||||
udp.beginPacket(WiFi.gatewayIP(), UDP_PORT);
|
||||
udp.write((uint8_t*)msg->c_str(), msg->length());
|
||||
udp.endPacket();
|
||||
}
|
||||
|
||||
void invoke_fn_mtx(SemaphoreHandle_t mtx, void (*fn)(void*), void* args){
|
||||
xSemaphoreTake(mtx, portMAX_DELAY);
|
||||
fn(args);
|
||||
xSemaphoreGive(mtx);
|
||||
}
|
||||
|
||||
void changeNetwork(){
|
||||
if (otherRSSI < -1000) return;
|
||||
if(WiFi.RSSI() < otherRSSI - 3){
|
||||
String networkSwitchJson = "{\"type\": \"info\", \"data\": \"netsw\"}";
|
||||
invoke_fn_mtx(netw_mtx, send_udp, (void*)&networkSwitchJson);
|
||||
|
||||
String prevSSID = WiFi.SSID();
|
||||
otherRSSI = WiFi.RSSI();
|
||||
udp.stop();
|
||||
WiFi.disconnect();
|
||||
WiFi.begin(otherSSID, _PASSWD);
|
||||
if (WiFi.waitForConnectResult() == WL_CONNECTED) {
|
||||
udp.begin(UDP_PORT);
|
||||
otherSSID = prevSSID;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void udp_task(void* /*args*/) {
|
||||
int start = millis();
|
||||
while(true){
|
||||
if(Serial.available()){
|
||||
String recv = readSerialUntil("\n");
|
||||
invoke_fn_mtx(netw_mtx, send_udp, (void*)&recv);
|
||||
}
|
||||
|
||||
if(millis() - start >= 1000){
|
||||
if(scanStatus == WIFI_SCAN_FAILED && millis() - lastScanRequest > 10000){
|
||||
scanStatus = WiFi.scanNetworks(true);
|
||||
lastScanRequest = millis();
|
||||
}
|
||||
int n = WiFi.scanComplete();
|
||||
if(n >= 0){
|
||||
for(int i = 0; i < n; i++){
|
||||
if(WiFi.SSID(i) == otherSSID){
|
||||
otherRSSI = WiFi.RSSI(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
WiFi.scanDelete();
|
||||
scanStatus = WIFI_SCAN_FAILED;
|
||||
}
|
||||
|
||||
String recv = getAvailableInfo();
|
||||
invoke_fn_mtx(netw_mtx, send_udp, (void*)&recv);
|
||||
start = millis();
|
||||
}
|
||||
|
||||
vTaskDelay(pdMS_TO_TICKS(1));
|
||||
}
|
||||
}
|
||||
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
while (!Serial) { delay(10); }
|
||||
|
||||
netw_mtx = xSemaphoreCreateMutex();
|
||||
|
||||
WiFi.mode(WIFI_STA);
|
||||
|
||||
int ap1_rssi = -9999;
|
||||
int ap2_rssi = -9999;
|
||||
|
||||
int n = WiFi.scanNetworks();
|
||||
for(int i = 0; i < n; i++){
|
||||
String ssid = WiFi.SSID(i);
|
||||
int rssi = WiFi.RSSI(i);
|
||||
|
||||
if(ssid == SSIDs[0]) ap1_rssi = rssi;
|
||||
if(ssid == SSIDs[1]) ap2_rssi = rssi;
|
||||
}
|
||||
|
||||
WiFi.scanDelete();
|
||||
|
||||
if(ap1_rssi >= ap2_rssi){
|
||||
WiFi.begin(SSIDs[0], _PASSWD);
|
||||
otherSSID = SSIDs[1];
|
||||
otherRSSI = ap2_rssi;
|
||||
}
|
||||
else{
|
||||
WiFi.begin(SSIDs[1], _PASSWD);
|
||||
otherSSID = SSIDs[0];
|
||||
otherRSSI = ap1_rssi;
|
||||
}
|
||||
|
||||
if(WiFi.waitForConnectResult() != WL_CONNECTED)
|
||||
Serial.println("WiFi-Verbindung fehlgeschlagen!");
|
||||
else{
|
||||
Serial.print("Verbunden mit ");
|
||||
Serial.print(WiFi.SSID());
|
||||
Serial.print(" (RSSI ");
|
||||
Serial.print(WiFi.RSSI());
|
||||
Serial.println(" dBm)");
|
||||
}
|
||||
|
||||
udp.begin(UDP_PORT);
|
||||
|
||||
xTaskCreatePinnedToCore( udp_task, "UDPReceiver", 4096, nullptr, 5, nullptr, 1);
|
||||
}
|
||||
|
||||
|
||||
void loop() {
|
||||
changeNetwork();
|
||||
vTaskDelay(pdMS_TO_TICKS(1000));
|
||||
}
|
||||
Reference in New Issue
Block a user