Compare commits
5 Commits
e48daca357
...
8f9109cd77
Author | SHA1 | Date | |
---|---|---|---|
8f9109cd77 | |||
ebdb548599 | |||
465c5b186a | |||
960411167a | |||
4ee9a76291 |
BIN
docs/Assignments/week_11_Networking/image-10.jpg
Normal file
After Width: | Height: | Size: 89 KiB |
BIN
docs/Assignments/week_11_Networking/image-11.jpg
Normal file
After Width: | Height: | Size: 100 KiB |
BIN
docs/Assignments/week_11_Networking/image-12.jpg
Normal file
After Width: | Height: | Size: 90 KiB |
BIN
docs/Assignments/week_11_Networking/image-13.jpg
Normal file
After Width: | Height: | Size: 84 KiB |
BIN
docs/Assignments/week_11_Networking/image-14.jpg
Normal file
After Width: | Height: | Size: 110 KiB |
BIN
docs/Assignments/week_11_Networking/image-15.jpg
Normal file
After Width: | Height: | Size: 67 KiB |
BIN
docs/Assignments/week_11_Networking/image-16.jpg
Normal file
After Width: | Height: | Size: 75 KiB |
BIN
docs/Assignments/week_11_Networking/image-5.jpg
Normal file
After Width: | Height: | Size: 120 KiB |
BIN
docs/Assignments/week_11_Networking/image-6.jpg
Normal file
After Width: | Height: | Size: 25 KiB |
BIN
docs/Assignments/week_11_Networking/image-7.jpg
Normal file
After Width: | Height: | Size: 29 KiB |
BIN
docs/Assignments/week_11_Networking/image-8.jpg
Normal file
After Width: | Height: | Size: 90 KiB |
BIN
docs/Assignments/week_11_Networking/image-9.jpg
Normal file
After Width: | Height: | Size: 83 KiB |
@@ -32,3 +32,284 @@ When compiling the main side it worked fine but when compiling the secondary sid
|
||||
|
||||

|
||||
|
||||
After that we tried with an SPI screen and there we spent over 2.5 hours attempting to get it to work. Checking the wires multiple times. Trying another screen. Trying different example codes. We had everything correct according to the datasheet and the driver chip that was inside the board.
|
||||
|
||||

|
||||
|
||||
We also connected the serial monitor to it and read the data from it. It was sending a lot of commands so that was working but it is very hard to figure out if the commands are correct since they are machine instructions. So we ended the day there and got beers and a bar.
|
||||
|
||||
## Individual Assignment
|
||||
I kinda did my individual assignment in the [programming week](../week_4_programming/programming.md) since I was both programming the handheld controller and the flight controller at the same time. During that week I also set up the communication between the 2 devices using ESPNow. ESPNow is a protocol skip a lot of OSI layers thus minimizing the overhead. It doesn't do handshakes so it kind of works like UDP. It's also peer to peer so it doesn't need any network infrastructure making it completely decentralized.
|
||||
|
||||

|
||||
[Source: arduino](https://docs.arduino.cc/tutorials/nano-esp32/esp-now/)
|
||||
|
||||
|
||||
|
||||
|
||||
### Encrypted ESPNow
|
||||
To create secure ESPNow communication I used [this tutorial](https://randomnerdtutorials.com/esp32-esp-now-encrypted-messages/).
|
||||
|
||||
The code stays the same except for a few extra variables added. Some things also change with registering peers to
|
||||
|
||||
```cpp
|
||||
// PMK and LMK keys
|
||||
static const char* PMK_KEY_STR = "REPLACE_WITH_PMK_KEY";
|
||||
static const char* LMK_KEY_STR = "REPLACE_WITH_LMK_KEY";
|
||||
|
||||
|
||||
// Register the receiver board as peer
|
||||
memcpy(peerInfo.peer_addr, receiverAddress, 6);
|
||||
peerInfo.channel = 0;
|
||||
//Set the receiver device LMK key
|
||||
for (uint8_t i = 0; i < 16; i++) {
|
||||
peerInfo.lmk[i] = LMK_KEY_STR[i];
|
||||
}
|
||||
|
||||
// Set PMK key
|
||||
esp_now_set_pmk((uint8_t *)PMK_KEY_STR);
|
||||
|
||||
peerInfo.encrypt = true;
|
||||
```
|
||||
|
||||
The PMK and LMK need to be exactly 16 bytes so to count to amount of bytes I used in my key I used this website. Most of the time you can go for each character is 1 byte. But there are also some online tools available. https://tools.smikkelbakje.nl/text-statistics or https://mothereff.in/byte-counter
|
||||
They should be the same on each board you wanna communicate with. The only flaw about this protocol is that the devices that receive decrypted messages still interpret them as if they where encrypted and they use the data inside them.
|
||||
|
||||

|
||||
|
||||
|
||||
??? Sender example
|
||||
```cpp
|
||||
/*
|
||||
Rui Santos & Sara Santos - Random Nerd Tutorials
|
||||
Complete project details at https://RandomNerdTutorials.com/esp32-esp-now-encrypted-messages/
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files.
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
*/
|
||||
#include <esp_now.h>
|
||||
#include <WiFi.h>
|
||||
|
||||
// REPLACE WITH THE RECEIVER'S MAC Address
|
||||
uint8_t receiverAddress[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
|
||||
|
||||
// PMK and LMK keys
|
||||
static const char* PMK_KEY_STR = "REPLACE_WITH_PMK_KEY";
|
||||
static const char* LMK_KEY_STR = "REPLACE_WITH_LMK_KEY";
|
||||
|
||||
// Structure example to send data
|
||||
// Must match the receiver structure
|
||||
typedef struct struct_message {
|
||||
int counter;
|
||||
int x;
|
||||
int y;
|
||||
} struct_message;
|
||||
|
||||
// Create a struct_message called myData
|
||||
struct_message myData;
|
||||
|
||||
// Counter variable to keep track of number of sent packets
|
||||
int counter;
|
||||
|
||||
// Variable to save peerInfo
|
||||
esp_now_peer_info_t peerInfo;
|
||||
|
||||
// callback when data is sent
|
||||
void OnDataSent(const uint8_t *mac_addr, esp_now_send_status_t status) {
|
||||
Serial.print("\r\nLast Packet Send Status:\t");
|
||||
Serial.println(status == ESP_NOW_SEND_SUCCESS ? "Delivery Success" : "Delivery Fail");
|
||||
}
|
||||
|
||||
void setup() {
|
||||
// Init Serial Monitor
|
||||
Serial.begin(115200);
|
||||
|
||||
// Set device as a Wi-Fi Station
|
||||
WiFi.mode(WIFI_STA);
|
||||
|
||||
// Init ESP-NOW
|
||||
if (esp_now_init() != ESP_OK) {
|
||||
Serial.println("There was an error initializing ESP-NOW");
|
||||
return;
|
||||
}
|
||||
|
||||
// Set PMK key
|
||||
esp_now_set_pmk((uint8_t *)PMK_KEY_STR);
|
||||
|
||||
// Register the receiver board as peer
|
||||
memcpy(peerInfo.peer_addr, receiverAddress, 6);
|
||||
peerInfo.channel = 0;
|
||||
//Set the receiver device LMK key
|
||||
for (uint8_t i = 0; i < 16; i++) {
|
||||
peerInfo.lmk[i] = LMK_KEY_STR[i];
|
||||
}
|
||||
// Set encryption to true
|
||||
peerInfo.encrypt = true;
|
||||
|
||||
// Add receiver as peer
|
||||
if (esp_now_add_peer(&peerInfo) != ESP_OK){
|
||||
Serial.println("Failed to add peer");
|
||||
return;
|
||||
}
|
||||
|
||||
// Once ESPNow is successfully Init, we will register for Send CB to
|
||||
// get the status of transmitted packet
|
||||
esp_now_register_send_cb(OnDataSent);
|
||||
}
|
||||
void loop() {
|
||||
static unsigned long lastEventTime = millis();
|
||||
static const unsigned long EVENT_INTERVAL_MS = 5000;
|
||||
if ((millis() - lastEventTime) > EVENT_INTERVAL_MS) {
|
||||
lastEventTime = millis();
|
||||
|
||||
// Set values to send
|
||||
myData.counter = counter++;
|
||||
myData.x = random(0,50);
|
||||
myData.y = random(0,50);
|
||||
|
||||
// Send message via ESP-NOW
|
||||
esp_err_t result = esp_now_send(receiverAddress, (uint8_t *) &myData, sizeof(myData));
|
||||
if (result == ESP_OK) {
|
||||
Serial.println("Sent with success");
|
||||
}
|
||||
else {
|
||||
Serial.println("Error sending the data");
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
??? Receiver example
|
||||
```cpp
|
||||
/*
|
||||
Rui Santos & Sara Santos - Random Nerd Tutorials
|
||||
Complete project details at https://RandomNerdTutorials.com/esp32-esp-now-encrypted-messages/
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files.
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
*/
|
||||
#include <esp_now.h>
|
||||
#include <WiFi.h>
|
||||
|
||||
// REPLACE WITH YOUR MASTER MAC Address
|
||||
uint8_t masterMacAddress[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
|
||||
|
||||
// PMK and LMK keys
|
||||
static const char* PMK_KEY_STR = "REPLACE_WITH_PMK_KEY";
|
||||
static const char* LMK_KEY_STR = "REPLACE_WITH_LMK_KEY";
|
||||
|
||||
// Structure example to send data
|
||||
// Must match the sender structure
|
||||
typedef struct struct_message {
|
||||
int counter; // must be unique for each sender board
|
||||
int x;
|
||||
int y;
|
||||
} struct_message;
|
||||
|
||||
// Create a struct_message called myData
|
||||
struct_message myData;
|
||||
|
||||
// Function to print MAC address on Serial Monitor
|
||||
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.println(macStr);
|
||||
}
|
||||
|
||||
// Callback function executed when data is received
|
||||
void OnDataRecv(const uint8_t * mac_addr, const uint8_t *incomingData, int len) {
|
||||
|
||||
Serial.print("Packet received from: ");
|
||||
printMAC(mac_addr);
|
||||
|
||||
memcpy(&myData, incomingData, sizeof(myData));
|
||||
Serial.print("Bytes received: ");
|
||||
Serial.println(len);
|
||||
Serial.print("Packet number: ");
|
||||
Serial.println(myData.counter);
|
||||
Serial.print("X: ");
|
||||
Serial.println(myData.x);
|
||||
Serial.print("Y: ");
|
||||
Serial.println(myData.y);
|
||||
}
|
||||
void setup() {
|
||||
// Init Serial Monitor
|
||||
Serial.begin(115200);
|
||||
|
||||
// Set device as a Wi-Fi Station
|
||||
WiFi.mode(WIFI_STA);
|
||||
|
||||
// Init ESP-NOW
|
||||
if (esp_now_init() != ESP_OK) {
|
||||
Serial.println("There was an error initializing ESP-NOW");
|
||||
return;
|
||||
}
|
||||
|
||||
// Set the PMK key
|
||||
esp_now_set_pmk((uint8_t *)PMK_KEY_STR);
|
||||
|
||||
// Register the master as peer
|
||||
esp_now_peer_info_t peerInfo;
|
||||
memcpy(peerInfo.peer_addr, masterMacAddress, 6);
|
||||
peerInfo.channel = 0;
|
||||
// Setting the master device LMK key
|
||||
for (uint8_t i = 0; i < 16; i++) {
|
||||
peerInfo.lmk[i] = LMK_KEY_STR[i];
|
||||
}
|
||||
// Set encryption to true
|
||||
peerInfo.encrypt = true;
|
||||
|
||||
// Add master as peer
|
||||
if (esp_now_add_peer(&peerInfo) != ESP_OK){
|
||||
Serial.println("Failed to add peer");
|
||||
return;
|
||||
}
|
||||
|
||||
// Once ESPNow is successfully Init, we will register for recv CB to
|
||||
// get recv packer info
|
||||
esp_now_register_recv_cb(esp_now_recv_cb_t(OnDataRecv));
|
||||
}
|
||||
void loop() {
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
## Charging my new batteries
|
||||
This week I got my Li-Po batteries delivered.
|
||||
|
||||

|
||||
These batteries are amazing when you need lots of power quickly. But that also makes a bit more dangerous because they can discharge extremely quick. I already have a bit of experience with single cell li-po batteries. But not with multiple cell ones. To charge these you need a special charger that charges every battery cell separately otherwise a cell may go above 4.2 volts and get permanently damaged. We had one 5S Li-Po in the fablab but I didn't trust it because it had a nominal voltage of 11 volts. These cells also need to be checked every so often if the voltage doesn't drop too low.
|
||||
|
||||

|
||||
5s cell with a nominal voltage of 11 volts. According to [this guide](https://fpvfc.org/beginners-guide-to-lipo-batteries) a cell shouldn't go below 3.2 volts and any higher than 4.2 will significantly increase the risk of the battery bursting into flames.
|
||||
|
||||
3.2 * 5 cells = 15,6 volts
|
||||
the battery should be at a minimum of 15,6 volts to avoid damage to the cells. This battery was way under that (11 volts). So I ordered my own batteries because I didn't wanna work with a fire hazard.
|
||||
|
||||
Whenever I charged them I made sure to always be within eye sight of the batteries in case something happened. This is also described in the safety manuals.
|
||||
|
||||

|
||||

|
||||
|
||||
We also had a balanced Li-Po charger in the fablab. It is the IMAX B6 LiPro balance charger.
|
||||
|
||||

|
||||
|
||||
My LiPo batteries used XT-60 connectors and these weren't in the box. So I made my own connector.
|
||||
|
||||

|
||||
|
||||
The LiPo charger has a input range of 11-18 volts so I supplied that using my own power supply since there wasn't a charger in the box.
|
||||

|
||||
|
||||
When I first started charging I selected the LiPo charge function but that was wrong because it stopped as one cell reached 4.20 volts instead of all cells reaching 4.2. Then I started clicking through the menu's and found the balance function and that did charge them correctly. I also needed to configure how fast it charged. A good rule of thumb is 1C to 0,5C so 1x the capacity in MaH or half the capacity in 0,5 MaH
|
||||
|
||||

|
||||
|
||||
Whenever you are charging and press the right status button you can see the individual cell voltages.
|
||||
|
||||

|
||||
Here you see the battery I first charged normally without the balancing feature. Here you can see there are some big differences in the cells.
|
||||
|
||||
## Sources
|
||||
* https://randomnerdtutorials.com/esp32-esp-now-encrypted-messages/
|
||||
* https://fpvfc.org/beginners-guide-to-lipo-batteries
|
@@ -7,6 +7,7 @@ int normalizePot(int pin, int minValue);
|
||||
int mapPot(int normalizedValue);
|
||||
int analogReadMultiPlexer(int addressA, int addressB, int addressC, int addressD, int pin);
|
||||
void espNow();
|
||||
void readAllMultiPlexer();
|
||||
|
||||
const int MAXPWMVALUE = 1000;
|
||||
const int MINPWMVALUE = 2000;
|
||||
@@ -20,7 +21,7 @@ typedef struct struct_message
|
||||
int PWMCH3;
|
||||
int PWMCH4;
|
||||
} struct_message;
|
||||
struct_message myData; // declare the struct as myData
|
||||
struct_message JoystickData; // declare the struct as JoystickData
|
||||
|
||||
esp_now_peer_info_t peerInfo; // create a class object of the ESPNow class
|
||||
|
||||
@@ -35,23 +36,19 @@ void setup()
|
||||
pinMode(D8, OUTPUT);
|
||||
pinMode(D9, OUTPUT);
|
||||
pinMode(D0, INPUT);
|
||||
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
Serial.print("X:" + String(myData.PWMCH2));
|
||||
Serial.println(" Y:" + String(myData.PWMCH1));
|
||||
|
||||
|
||||
readAllMultiPlexer();
|
||||
// Set values to send
|
||||
myData.PWMCH1 = mapPot(analogReadMultiPlexer(0, 0, 0, 0, A0));
|
||||
myData.PWMCH2 = mapPot(analogReadMultiPlexer(1, 0, 0, 0, A0)); // test values
|
||||
myData.PWMCH3 = 1000;
|
||||
myData.PWMCH4 = 1000;
|
||||
JoystickData.PWMCH1 = mapPot(analogReadMultiPlexer(0, 0, 0, 0, A0)); //Right joystick Y
|
||||
JoystickData.PWMCH2 = mapPot(analogReadMultiPlexer(1, 0, 0, 0, A0)); // Right joystick X
|
||||
JoystickData.PWMCH3 = mapPot(analogReadMultiPlexer(0, 0, 0, 1, A0)); // left joystick Y
|
||||
JoystickData.PWMCH4 = mapPot(analogReadMultiPlexer(1, 0, 0, 1, A0)); // left joystick X
|
||||
|
||||
// Send message via ESP-NOW
|
||||
esp_err_t result = esp_now_send(broadcastAddress, (uint8_t *)&myData, sizeof(myData));
|
||||
esp_err_t result = esp_now_send(broadcastAddress, (uint8_t *)&JoystickData, sizeof(JoystickData));
|
||||
if (result == ESP_OK)
|
||||
{
|
||||
// Serial.println("Sent with success");
|
||||
@@ -60,7 +57,7 @@ void loop()
|
||||
{
|
||||
// Serial.println("Error sending the data");
|
||||
}
|
||||
delay(10); //delay to avoid hammering the radio and to save power/heat
|
||||
delay(10); // delay to avoid hammering the radio and to save power/heat
|
||||
}
|
||||
|
||||
int mapPot(int normalizedValue)
|
||||
@@ -92,7 +89,8 @@ int analogReadMultiPlexer(int addressA, int addressB, int addressC, int addressD
|
||||
return analogRead(pin);
|
||||
}
|
||||
|
||||
void espNow(){ // Set device as a Wi-Fi Station
|
||||
void espNow()
|
||||
{ // Set device as a Wi-Fi Station
|
||||
WiFi.mode(WIFI_STA);
|
||||
// Init ESP-NOW
|
||||
if (esp_now_init() != ESP_OK)
|
||||
@@ -109,4 +107,42 @@ void espNow(){ // Set device as a Wi-Fi Station
|
||||
{
|
||||
Serial.println("Failed to add peer");
|
||||
return;
|
||||
}}
|
||||
}
|
||||
}
|
||||
|
||||
void readAllMultiPlexer()
|
||||
{
|
||||
// we counting in binary
|
||||
Serial.print("0,0,0,0: ");
|
||||
Serial.println(analogReadMultiPlexer(0, 0, 0, 0, A0));
|
||||
Serial.print("1,0,0,0: ");
|
||||
Serial.println(analogReadMultiPlexer(1, 0, 0, 0, A0));
|
||||
Serial.print("0,1,0,0: ");
|
||||
Serial.println(analogReadMultiPlexer(0, 1, 0, 0, A0));
|
||||
Serial.print("1,1,0,0: ");
|
||||
Serial.println(analogReadMultiPlexer(1, 1, 0, 0, A0));
|
||||
Serial.print("0,0,1,0: ");
|
||||
Serial.println(analogReadMultiPlexer(0, 0, 1, 0, A0));
|
||||
Serial.print("1,0,1,0: ");
|
||||
Serial.println(analogReadMultiPlexer(1, 0, 1, 0, A0));
|
||||
Serial.print("0,1,1,0: ");
|
||||
Serial.println(analogReadMultiPlexer(0, 1, 1, 0, A0));
|
||||
Serial.print("1,1,1,0: ");
|
||||
Serial.println(analogReadMultiPlexer(1, 1, 1, 0, A0));
|
||||
Serial.print("0,0,0,1: ");
|
||||
Serial.println(analogReadMultiPlexer(0, 0, 0, 1, A0));
|
||||
Serial.print("1,0,0,1: ");
|
||||
Serial.println(analogReadMultiPlexer(1, 0, 0, 1, A0));
|
||||
Serial.print("0,1,0,1: ");
|
||||
Serial.println(analogReadMultiPlexer(0, 1, 0, 1, A0));
|
||||
Serial.print("1,1,0,1: ");
|
||||
Serial.println(analogReadMultiPlexer(1, 1, 0, 1, A0));
|
||||
Serial.print("0,0,1,1: ");
|
||||
Serial.println(analogReadMultiPlexer(0, 0, 1, 1, A0));
|
||||
Serial.print("1,0,1,1: ");
|
||||
Serial.println(analogReadMultiPlexer(1, 0, 1, 1, A0));
|
||||
Serial.print("0,1,1,1: ");
|
||||
Serial.println(analogReadMultiPlexer(0, 1, 1, 1, A0));
|
||||
Serial.print("1,1,1,1: ");
|
||||
Serial.println(analogReadMultiPlexer(1, 1, 1, 1, A0));
|
||||
}
|