Browse Source

Initial working version

master
Lukas Bachschwell 3 years ago
commit
1a1df572fd
  1. 36
      lib/readme.txt
  2. 32
      platformio.ini
  3. 7
      src/mac_config.h
  4. 109
      src/reciever.cpp
  5. 272
      src/remote.cpp

36
lib/readme.txt

@ -0,0 +1,36 @@
This directory is intended for the project specific (private) libraries.
PlatformIO will compile them to static libraries and link to executable file.
The source code of each library should be placed in separate directory, like
"lib/private_lib/[here are source files]".
For example, see how can be organized `Foo` and `Bar` libraries:
|--lib
| |--Bar
| | |--docs
| | |--examples
| | |--src
| | |- Bar.c
| | |- Bar.h
| |--Foo
| | |- Foo.c
| | |- Foo.h
| |- readme.txt --> THIS FILE
|- platformio.ini
|--src
|- main.c
Then in `src/main.c` you should use:
#include <Foo.h>
#include <Bar.h>
// rest H/C/CPP code
PlatformIO will find your libraries automatically, configure preprocessor's
include paths and build them.
More information about PlatformIO Library Dependency Finder
- http://docs.platformio.org/page/librarymanager/ldf.html

32
platformio.ini

@ -0,0 +1,32 @@
; PlatformIO Project Configuration File
;
; Build options: build flags, source filter
; Upload options: custom upload port, speed and extra flags
; Library options: dependencies, extra library storages
; Advanced options: extra scripting
;
; Please visit documentation for the other options and examples
; http://docs.platformio.org/page/projectconf.html
[env:remote]
platform = espressif32
board = esp32doit-devkit-v1
framework = arduino
src_filter = +<remote.cpp>
monitor_baud = 115200
[env:reciever]
platform = espressif32
board = esp32doit-devkit-v1
framework = arduino
src_filter = +<reciever.cpp>
monitor_baud = 115200
lib_deps =
# Using a library name
ServoESP32

7
src/mac_config.h

@ -0,0 +1,7 @@
//mac addresses
// reciever mac:
uint8_t mac_reciever[] = {0x30, 0xae, 0xa4, 0x04, 0x21, 0x2d};
// remote macStr
uint8_t mac_remote[] = {0x24, 0x0a, 0xc4, 0x82, 0x51, 0x70};

109
src/reciever.cpp

@ -0,0 +1,109 @@
// ESPNOWSkate Reciever by Lukas Bachschwell this device SLAVE =D
#include <Servo.h>
#include "Arduino.h"
#include "SSD1306.h"
#include <esp_now.h>
#include <WiFi.h>
static const int esc1pin = 15;
static const int esc2pin = 13;
Servo esc1;
Servo esc2;
SSD1306 display(0x3c, 5, 4);
//#define pairingMode
#define FAILSAFE 90
#define CONNECTION_TIMEOUT 200
#define CHANNEL 1
long lastPacket = 0;
bool isConnected = false;
// ESPNOW Functions ############################
//
// config AP
void configDeviceAP(bool hidden) {
bool result = WiFi.softAP("ESK8", "ESK8_Password+vD8z2YAvoDBW?Zx", CHANNEL, hidden);
if (!result) {
Serial.println("AP Config failed.");
} else {
Serial.println("AP Config Success. Broadcasting with AP: " + String("ESK8"));
}
}
void writeServos(uint8_t firstServo, uint8_t secondServo) {
isConnected = true;
esc1.write(firstServo);
esc2.write(secondServo);
}
// callback when data is recv from Master
void OnDataRecv(const uint8_t *mac_addr, const uint8_t *data, int data_len) {
char macStr[18];
snprintf(macStr, sizeof(macStr), "%02x:%02x:%02x:%02x:%02x:%02x",
mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]);
Serial.print("Last Packet Recv from: "); Serial.println(macStr);
uint8_t recData[2];
memcpy(recData, data, data_len);
Serial.print("Last Packet Recv Data: "); Serial.println(recData[0]); Serial.print(" "); Serial.print(recData[1]); Serial.print(" len:"); Serial.println(data_len);
lastPacket = millis();
isConnected = true;
// Could check mac here for some security
writeServos(recData[0], recData[1]);
display.clear();
char buf[25];
sprintf(buf, "1: %i | 2: %i", recData[0], recData[1]);
display.drawString(2, 0, buf);
display.display();
}
// end ESPNOW functions
void setup() {
Serial.begin(115200);
Serial.println("ESPNowSkate Reciever");
display.init();
display.flipScreenVertically();
display.setFont(ArialMT_Plain_16);
esc1.attach(esc1pin);
esc2.attach(esc2pin);
//Set device in AP mode to begin with
WiFi.mode(WIFI_AP);
// configure device AP mode
#ifdef pairingMode
configDeviceAP(false);
#else
configDeviceAP(true);
#endif
Serial.print("AP MAC: "); Serial.println(WiFi.softAPmacAddress());
// Init ESPNow
if (esp_now_init() == ESP_OK) {
Serial.println("ESPNow Init Success");
}
else {
Serial.println("ESPNow Init Failed");
ESP.restart();
}
// Once ESPNow is successfully Init, we will register for recv CB to
// get recv packer info.
esp_now_register_recv_cb(OnDataRecv);
}
void loop() {
if(isConnected) {
if(millis() - lastPacket > CONNECTION_TIMEOUT ) {
isConnected = false;
writeServos(FAILSAFE, FAILSAFE);
}
}
}

272
src/remote.cpp

@ -0,0 +1,272 @@
// ESPNOWSkate by Lukas Bachschwell this device MASTER =D
#include <Arduino.h>
#include <esp_now.h>
#include <WiFi.h>
#include <SSD1306.h>
#include "mac_config.h"
// Global copy of slave
esp_now_peer_info_t slave;
#define CHANNEL 3
#define PRINTSCANRESULTS 0
#define DELETEBEFOREPAIR 0
#define POT_MAX 3900
#define TRIM_LOW 180
#define TRIM_HIGH 31
//#define pairingMode
#define leverPin 36
SSD1306 display(0x3c, 4, 15);
// ESPNOW functions ##############################
// Scan for slaves in AP mode
#ifdef pairingMode
void ScanForSlave() {
int8_t scanResults = WiFi.scanNetworks();
// reset on each scan
bool slaveFound = 0;
memset(&slave, 0, sizeof(slave));
Serial.println("");
if (scanResults == 0) {
Serial.println("No WiFi devices in AP Mode found");
} else {
Serial.print("Found "); Serial.print(scanResults); Serial.println(" devices ");
for (int i = 0; i < scanResults; ++i) {
// Print SSID and RSSI for each device found
String SSID = WiFi.SSID(i);
int32_t RSSI = WiFi.RSSI(i);
String BSSIDstr = WiFi.BSSIDstr(i);
if (PRINTSCANRESULTS) {
Serial.print(i + 1);
Serial.print(": ");
Serial.print(SSID);
Serial.print(" (");
Serial.print(RSSI);
Serial.print(")");
Serial.println("");
}
delay(10);
// Check if the current device starts with `Slave`
if (SSID.indexOf("ESK8") == 0) {
// SSID of interest
Serial.println("Found a Slave.");
Serial.print(i + 1); Serial.print(": "); Serial.print(SSID); Serial.print(" ["); Serial.print(BSSIDstr); Serial.print("]"); Serial.print(" ("); Serial.print(RSSI); Serial.print(")"); Serial.println("");
// Get BSSID => Mac Address of the Slave
int mac[6];
if ( 6 == sscanf(BSSIDstr.c_str(), "%x:%x:%x:%x:%x:%x%c", &mac[0], &mac[1], &mac[2], &mac[3], &mac[4], &mac[5] ) ) {
for (int ii = 0; ii < 6; ++ii ) {
slave.peer_addr[ii] = (uint8_t) mac[ii];
}
}
slave.channel = CHANNEL; // pick a channel
slave.encrypt = 0; // no encryption
slaveFound = 1;
// we are planning to have only one slave in this example;
// Hence, break after we find one, to be a bit efficient
break;
}
}
}
if (slaveFound) {
Serial.println("Slave Found, processing..");
} else {
Serial.println("Slave Not Found, trying again.");
}
// clean up ram
WiFi.scanDelete();
}
#endif
void deletePeer() {
const esp_now_peer_info_t *peer = &slave;
const uint8_t *peer_addr = slave.peer_addr;
esp_err_t delStatus = esp_now_del_peer(peer_addr);
Serial.print("Slave Delete Status: ");
if (delStatus == ESP_OK) {
// Delete success
Serial.println("Success");
} else if (delStatus == ESP_ERR_ESPNOW_NOT_INIT) {
// How did we get so far!!
Serial.println("ESPNOW Not Init");
} else if (delStatus == ESP_ERR_ESPNOW_ARG) {
Serial.println("Invalid Argument");
} else if (delStatus == ESP_ERR_ESPNOW_NOT_FOUND) {
Serial.println("Peer not found.");
} else {
Serial.println("Not sure what happened");
}
}
// Check if the slave is already paired with the master.
// If not, pair the slave with master
bool manageSlave() {
if (slave.channel == CHANNEL) {
if (DELETEBEFOREPAIR) {
deletePeer();
}
Serial.print("Slave Status: ");
const esp_now_peer_info_t *peer = &slave;
const uint8_t *peer_addr = slave.peer_addr;
// check if the peer exists
bool exists = esp_now_is_peer_exist(peer_addr);
if ( exists) {
// Slave already paired.
Serial.println("Already Paired");
return true;
} else {
// Slave not paired, attempt pair
esp_err_t addStatus = esp_now_add_peer(peer);
if (addStatus == ESP_OK) {
// Pair success
Serial.println("Pair success");
return true;
} else if (addStatus == ESP_ERR_ESPNOW_NOT_INIT) {
// How did we get so far!!
Serial.println("ESPNOW Not Init");
return false;
} else if (addStatus == ESP_ERR_ESPNOW_ARG) {
Serial.println("Invalid Argument");
return false;
} else if (addStatus == ESP_ERR_ESPNOW_FULL) {
Serial.println("Peer list full");
return false;
} else if (addStatus == ESP_ERR_ESPNOW_NO_MEM) {
Serial.println("Out of memory");
return false;
} else if (addStatus == ESP_ERR_ESPNOW_EXIST) {
Serial.println("Peer Exists");
return true;
} else {
Serial.println("Not sure what happened");
return false;
}
}
} else {
// No slave found to process
Serial.println("No Slave found to process");
return false;
}
}
// send data
void sendData() {
uint8_t esc1 = map(analogRead(leverPin), 0, POT_MAX, TRIM_LOW, TRIM_HIGH);
uint8_t esc2 = esc1;
const uint8_t data[] = { esc1, esc2 }; // no mixture for the normal mode
const uint8_t *peer_addr = slave.peer_addr;
Serial.print("Sending: "); Serial.println(esc1);
esp_err_t result = esp_now_send(peer_addr, data, sizeof(data));
Serial.print("Send Status: ");
if (result == ESP_OK) {
Serial.println("Success");
} else if (result == ESP_ERR_ESPNOW_NOT_INIT) {
// How did we get so far!!
Serial.println("ESPNOW not Init.");
} else if (result == ESP_ERR_ESPNOW_ARG) {
Serial.println("Invalid Argument");
} else if (result == ESP_ERR_ESPNOW_INTERNAL) {
Serial.println("Internal Error");
} else if (result == ESP_ERR_ESPNOW_NO_MEM) {
Serial.println("ESP_ERR_ESPNOW_NO_MEM");
} else if (result == ESP_ERR_ESPNOW_NOT_FOUND) {
Serial.println("Peer not found.");
} else {
Serial.println("Not sure what happened");
}
}
// callback when data is sent from Master to Slave
void OnDataSent(const uint8_t *mac_addr, esp_now_send_status_t status) {
char macStr[18];
snprintf(macStr, sizeof(macStr), "%02x:%02x:%02x:%02x:%02x:%02x",
mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]);
Serial.print("Last Packet Sent to: "); Serial.println(macStr);
Serial.print("Last Packet Send Status: "); Serial.println(status == ESP_NOW_SEND_SUCCESS ? "Delivery Success" : "Delivery Fail");
}
void setup() {
Serial.begin(115200);
//Set device in STA mode to begin with
WiFi.mode(WIFI_STA);
Serial.println("ESPNowSkate");
// reset the screen
pinMode(16, OUTPUT);
digitalWrite(16, LOW); // set GPIO16 low to reset OLED
delay(50);
digitalWrite(16, HIGH);
Serial.println("ESPNowSkate Sender");
display.init();
display.flipScreenVertically();
display.setFont(ArialMT_Plain_10);
display.setTextAlignment(TEXT_ALIGN_LEFT);
display.drawString(5, 5, "ESPNOW Test");
display.display();
// This is the mac address of the Master in Station Mode
Serial.print("STA MAC: "); Serial.println(WiFi.macAddress());
if (esp_now_init() == ESP_OK) {
Serial.println("ESPNow Init Success");
}
else {
Serial.println("ESPNow Init Failed");
ESP.restart();
}
// Once ESPNow is successfully Init, we will register for Send CB to
// get the status of Trasnmitted packet
esp_now_register_send_cb(OnDataSent);
//ScanForSlave();
// Retrieve Slave from config:
for (int i = 0; i < 6; ++i ) {
slave.peer_addr[i] = (uint8_t) mac_reciever[i];
}
slave.channel = CHANNEL; // pick a channel
slave.encrypt = 0; // no encryption
}
void loop() {
char buf[10];
sprintf(buf, "%i", map(analogRead(leverPin), 0, POT_MAX, TRIM_LOW, TRIM_HIGH));
//Serial.println(analogRead(leverPin));
display.clear();
display.drawString(3, 0, buf);
display.display();
// If Slave is found, it would be populate in `slave` variable
// We will check if `slave` is defined and then we proceed further
if (slave.channel == CHANNEL) { // check if slave channel is defined
// `slave` is defined
// Add slave as peer if it has not been added already
bool isPaired = manageSlave();
if (isPaired) {
// pair success or already paired
// Send data to device
sendData();
} else {
// slave pair failed
Serial.println("Slave not found / paired!");
}
}
else {
// No slave found to process
}
delay(20);
}
Loading…
Cancel
Save