Browse Source

Initial

master
Englebert 2 years ago
commit
3320819a67
  1. 39
      include/README
  2. 46
      lib/README
  3. 14
      platformio.ini
  4. BIN
      src/.main.cpp.swp
  5. BIN
      src/.main.h.swp
  6. 252
      src/main.cpp
  7. 76
      src/main.h
  8. 11
      test/README

39
include/README

@ -0,0 +1,39 @@
This directory is intended for project header files.
A header file is a file containing C declarations and macro definitions
to be shared between several project source files. You request the use of a
header file in your project source file (C, C++, etc) located in `src` folder
by including it, with the C preprocessing directive `#include'.
```src/main.c
#include "header.h"
int main (void)
{
...
}
```
Including a header file produces the same results as copying the header file
into each source file that needs it. Such copying would be time-consuming
and error-prone. With a header file, the related declarations appear
in only one place. If they need to be changed, they can be changed in one
place, and programs that include the header file will automatically use the
new version when next recompiled. The header file eliminates the labor of
finding and changing all the copies as well as the risk that a failure to
find one copy will result in inconsistencies within a program.
In C, the usual convention is to give header files names that end with `.h'.
It is most portable to use only letters, digits, dashes, and underscores in
header file names, and at most one dot.
Read more about using header files in official GCC documentation:
* Include Syntax
* Include Operation
* Once-Only Headers
* Computed Includes
https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html

46
lib/README

@ -0,0 +1,46 @@
This directory is intended for project specific (private) libraries.
PlatformIO will compile them to static libraries and link into executable file.
The source code of each library should be placed in a an own separate directory
("lib/your_library_name/[here are source files]").
For example, see a structure of the following two libraries `Foo` and `Bar`:
|--lib
| |
| |--Bar
| | |--docs
| | |--examples
| | |--src
| | |- Bar.c
| | |- Bar.h
| | |- library.json (optional, custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html
| |
| |--Foo
| | |- Foo.c
| | |- Foo.h
| |
| |- README --> THIS FILE
|
|- platformio.ini
|--src
|- main.c
and a contents of `src/main.c`:
```
#include <Foo.h>
#include <Bar.h>
int main (void)
{
...
}
```
PlatformIO Library Dependency Finder will find automatically dependent
libraries scanning project source files.
More information about PlatformIO Library Dependency Finder
- https://docs.platformio.org/page/librarymanager/ldf.html

14
platformio.ini

@ -0,0 +1,14 @@
; 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
; https://docs.platformio.org/page/projectconf.html
[env:esp32dev]
platform = espressif32
board = esp32dev
framework = arduino

BIN
src/.main.cpp.swp

BIN
src/.main.h.swp

252
src/main.cpp

@ -0,0 +1,252 @@
#include <Arduino.h>
#include "main.h"
void setup() {
Serial.begin(115200);
// initialize EEPROM with predefined size
EEPROM.begin(EEPROM_SIZE);
// Loading channel from memory
channel = EEPROM.read(0);
Serial.print("ESPNow on Channel: ");
Serial.println(channel);
// Loading allow address
allow_address[0] = EEPROM.read(1);
allow_address[1] = EEPROM.read(2);
allow_address[2] = EEPROM.read(3);
allow_address[3] = EEPROM.read(4);
allow_address[4] = EEPROM.read(5);
allow_address[5] = EEPROM.read(6);
Serial.print("Allowed MAC: ");
printMAC(allow_address);
Serial.println();
pinMode(LED_INDICATOR, OUTPUT);
pinMode(BUTTON_SYNC, INPUT);
WiFi.mode(WIFI_AP_STA);
Serial.print("Master Node MAC: ");
Serial.println(WiFi.macAddress());
esp_now_deinit(); // Cleaning Up
WiFi.mode(WIFI_STA);
esp_wifi_set_promiscuous(true);
esp_wifi_set_channel(channel, WIFI_SECOND_CHAN_NONE);
esp_wifi_set_promiscuous(false);
WiFi.disconnect();
delay(100);
initESP_NOW();
// Task Setup
xTaskCreatePinnedToCore(
taskButton,
"TaskButton", // Name of the process
8192, // This stack size can be checked & adjusted by reading the Stack Highwater
NULL,
4, // Priority
NULL,
CPU_0
);
/**
xTaskCreatePinnedToCore(
taskDemo,
"TaskDemo", // Name of the process
8192, // This stack size can be checked & adjusted by reading the Stack Highwater
NULL,
4, // Priority
NULL,
CPU_1
);
**/
}
void taskDemo(void *pvParameters) {
(void) pvParameters;
for(;;) {
vTaskDelay(1000);
// WiFi.softAPmacAddress(pairingData.mac_address);
pairingData.channel = channel;
Serial.println("Task Demo - send response");
esp_now_send(broadcast_address, (uint8_t *) &pairingData, sizeof(pairingData));
}
}
void taskButton(void *pvParameters) {
(void) pvParameters;
uint32_t last_check = 0;
for(;;) {
if((uint32_t)(millis() - last_check) > 100) {
// LOW = PRESS, HIGH = RELEASE
if(digitalRead(BUTTON_SYNC) == 0) {
// Autosync mode:
// 1. Change to channel 1 (default)
// 2. Capture the mac address and register it
esp_wifi_set_promiscuous(true);
esp_wifi_set_channel(DEFAULT_CHANNEL, WIFI_SECOND_CHAN_NONE);
esp_wifi_set_promiscuous(false);
sync_mode = true;
Serial.println("### SYNC MODE ###");
digitalWrite(LED_INDICATOR, HIGH);
// initESP_NOW();
}
last_check = millis();
}
vTaskDelay(100);
}
}
void printMAC(const uint8_t * mac_addr) {
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(macStr);
}
/***
bool addPeer(const uint8_t *peer_addr) { // Add pairing
memset(&slave, 0, sizeof(slave));
const esp_now_peer_info_t *peer = &slave;
memcpy(slave.peer_addr, peer_addr, 6);
slave.channel = channel; // pick a channel
slave.encrypt = 0; // no encryption
// check if the peer exists
bool exists = esp_now_is_peer_exist(slave.peer_addr);
if(exists) {
// Slave already paired.
Serial.println("Already Paired");
return true;
} else {
esp_err_t addStatus = esp_now_add_peer(peer);
if(addStatus == ESP_OK) {
// Pair success
Serial.println("Pair success");
return true;
} else {
Serial.println("Pair failed");
return false;
}
}
}
***/
void OnDataSent(const uint8_t *mac_addr, esp_now_send_status_t status) {
Serial.print("Last Packet Send Status: ");
Serial.print(status == ESP_NOW_SEND_SUCCESS ? "Delivery Success to " : "Delivery Fail to ");
printMAC(mac_addr);
Serial.println();
if(sync_mode) {
// Rebooting...
ESP.restart();
}
}
void OnDataRecv(const uint8_t * mac_addr, const uint8_t *incomingData, int len) {
Serial.print(len);
Serial.print(" bytes of data received from : ");
printMAC(mac_addr);
Serial.println();
String payload;
uint8_t type = incomingData[0]; // first message byte is the type of message
switch(type) {
case DATA: // the message is data type
memcpy(&incomingReadings, incomingData, sizeof(incomingReadings));
/***
// create a JSON document with received data and send it by event to the web page
root["id"] = incomingReadings.id;
root["temperature"] = incomingReadings.temp;
root["humidity"] = incomingReadings.hum;
root["readingId"] = String(incomingReadings.readingId);
serializeJson(root, payload);
Serial.print("event send :");
serializeJson(root, Serial);
events.send(payload.c_str(), "new_readings", millis());
***/
Serial.println();
break;
case PAIRING: // the message is a pairing request
Serial.print("Request FROM: ");
printMAC(mac_addr);
Serial.println();
if(!sync_mode) {
Serial.println("Sync MODE not allowed.");
return;
}
memcpy(&pairingData, incomingData, sizeof(pairingData));
Serial.print("On Channel: ");
Serial.println(pairingData.channel);
// Store the macaddress and next load will only receive from the specific mac address
memcpy(peer_info.peer_addr, mac_addr, 6);
peer_info.channel = 0;
peer_info.encrypt = false;
if(esp_now_add_peer(&peer_info) != ESP_OK) {
Serial.println("Error Adding Peer");
}
Serial.println("Returning response");
esp_now_send(mac_addr, (uint8_t *) &pairingData, sizeof(pairingData));
// Store into EEPROM
// Channel
EEPROM.write(0, pairingData.channel);
// Mac Address
EEPROM.write(1, mac_addr[0]);
EEPROM.write(2, mac_addr[1]);
EEPROM.write(3, mac_addr[2]);
EEPROM.write(4, mac_addr[3]);
EEPROM.write(5, mac_addr[4]);
EEPROM.write(6, mac_addr[5]);
EEPROM.commit();
// Switing back to normal mode.
sync_mode = false;
digitalWrite(LED_INDICATOR, LOW);
break;
}
}
void initESP_NOW(){
// Init ESP-NOW
if(esp_now_init() != ESP_OK) {
Serial.println("Error initializing ESP-NOW");
return;
}
esp_now_register_send_cb(OnDataSent);
memcpy(peer_info.peer_addr, broadcast_address, 6);
peer_info.channel = 0;
peer_info.encrypt = false;
esp_now_register_recv_cb(OnDataRecv);
Serial.println(WiFi.localIP());
Serial.print("Wi-Fi Channel: ");
Serial.println(WiFi.channel());
}
void loop() {
}

76
src/main.h

@ -0,0 +1,76 @@
#ifndef MAIN_H
#define MAIN_H
// CPU NAMES
#define CPU_1 1
#define CPU_0 0
// PINS
#define LED_INDICATOR 2 // Default LED light
#define BUTTON_SYNC 0 // Default Push Button
// VERSION
#define VERSION_MAJOR 0
#define VERSION_MINOR 0
#define VERSION_BUILD 1
#include <Arduino.h>
#include <EEPROM.h>
#include "esp_wifi.h"
#include <esp_now.h>
#include <WiFi.h>
typedef struct struct_data {
uint8_t message_type;
uint16_t throttle;
uint16_t yaw;
uint16_t roll;
uint16_t pitch;
bool aux[9];
} struct_data;
typedef struct struct_pairing {
uint8_t message_type;
uint8_t channel;
} struct_pairing;
enum PairingStatus {
NOT_PAIRED,
PAIR_REQUEST,
PAIR_REQUESTED,
PAIR_PAIRED
};
enum MessageType {
PAIRING,
DATA
};
#define DEFAULT_CHANNEL 1
#define EEPROM_SIZE 7 // define the number of bytes you want to access
esp_now_peer_info_t slave;
int channel = 1;
bool sync_mode = false;
struct_data incomingReadings;
struct_pairing pairingData;
/// uint8_t broadcast_address[] = { 0x78, 0x21, 0x84, 0x8d, 0xd9, 0x38 };
uint8_t broadcast_address[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
uint8_t allow_address[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
esp_now_peer_info_t peer_info;
// Task Handler
// void taskScreen(void *pvParameters);
// void taskSpeak(void *pvParameters);
void taskButton(void *pvParameters);
void taskDemo(void *pvParameters);
// Functions
void printMAC(const uint8_t * mac_addr);
void initESP_NOW();
void OnDataSent(const uint8_t *mac_addr, esp_now_send_status_t status);
void OnDataRecv(const uint8_t * mac_addr, const uint8_t *incomingData, int len);
#endif

11
test/README

@ -0,0 +1,11 @@
This directory is intended for PlatformIO Test Runner and project tests.
Unit Testing is a software testing method by which individual units of
source code, sets of one or more MCU program modules together with associated
control data, usage procedures, and operating procedures, are tested to
determine whether they are fit for use. Unit testing finds problems early
in the development cycle.
More information about PlatformIO Unit Testing:
- https://docs.platformio.org/en/latest/advanced/unit-testing/index.html
Loading…
Cancel
Save