diff --git a/docs/Assignments/week_4_programming/IMG_8197(1).mp4 b/docs/Assignments/week_4_programming/IMG_8197(1).mp4 new file mode 100644 index 0000000..cef577b Binary files /dev/null and b/docs/Assignments/week_4_programming/IMG_8197(1).mp4 differ diff --git a/docs/Assignments/week_4_programming/programming.md b/docs/Assignments/week_4_programming/programming.md index 90ee5f4..43ffdc7 100644 --- a/docs/Assignments/week_4_programming/programming.md +++ b/docs/Assignments/week_4_programming/programming.md @@ -449,12 +449,214 @@ Now I wanna map the potmeter values as if it is a PWM signal. The PWM signal for This is my new code. It maps the values from 80 to 4095 to a range of 1400 to 2000. -#### Connection between the controller and the flight controller +### Connection between the controller and the flight controller +#### Controller side Now that I have PWM values the driver can understand I wanna test if the driver works and if I can get readings from the driver. Because it needs some kind of controller script to start. For the wireless communication I wanna use ESPNOW, because the protocol works without internet. The 2 esp's directly connect to each other. The only downside is that you're stuck with esp's because the protocol only works on esp's. I am following [this](https://randomnerdtutorials.com/esp-now-esp32-arduino-ide/) tutorial to create an ESPNOW connection. +What I first need to do according to the tutorial is get the receiver esp their mac adress. Luckily that gets displayed when uploading to the esp. +![alt text](image-26.png) +After `MAC` there is the mac address. I've saved it in my controller code as a compiler flag `#define receiverMAC "d8:3b:da:37:66:00";` So I could use it later on. I don't know if the libraries accepts this compiler flag but I will find out soon enough. + +I first need to create a struct with the data I wanna send. A stuct is a collection of variables named under one big variable. + +```cpp +typedef struct struct_message { + char a[32]; + int b; + float c; + bool d; +} struct_message; +``` +This is a struct in the tutorial but I wanna send my potentiometers their pwm value. So mine will look like this. +```cpp +typedef struct struct_message { + int PWMCH1; + int PWMCH2; + int PWMCH3; + int PWMCH4; +} struct_message; +``` +Now I just realised I was looking at the receiver sketch instead of the sender sketch. But there is no damage done yet because the same struct is needed in both of the scripts. I do need to change the way I declare my mac address. The mac address needs to be stored in an array. like this: +```cpp +// REPLACE WITH YOUR RECEIVER MAC Address +uint8_t broadcastAddress[] = {0xD8, 0x3B, 0xDA, 0x37, 0x66, 0x00}; +``` +Then I added in the rest of the code from the tutorial like this. + +??? code + ```cpp + #include + #include + #include + + // declarations + int normalizePot(int pin, int minValue); + int mapPot(int normalizedValue); + + // constants + const int POTPIN1 = 0; + const int MAXPWMVALUE = 1400; + const int MINPWMVALUE = 2000; + const uint8_t broadcastAddress[] = {0xD8, 0x3B, 0xDA, 0x37, 0x66, 0x00}; + + //Define the struct that will be sent + typedef struct struct_message { + int PWMCH1; + int PWMCH2; + int PWMCH3; + int PWMCH4; + } struct_message; + struct_message myData; //declare the struct as myData + + esp_now_peer_info_t peerInfo; //create a class object of the ESPNow class + + void setup() + { + // Set device as a Wi-Fi Station + WiFi.mode(WIFI_STA); + + // Init ESP-NOW + if (esp_now_init() != ESP_OK) { + Serial.println("Error initializing ESP-NOW"); + return; + } + + + Serial.begin(9600); + pinMode(POTPIN1, INPUT); + } + + void loop() + { + Serial.println(mapPot(normalizePot(POTPIN1, 80))); //call normalizePot and put the output into mapPot then print it + + // Set values to send + myData.PWMCH1 = mapPot(normalizePot(POTPIN1, 80)); + myData.PWMCH2 = 1000; //test values + myData.PWMCH3 = 1000; + myData.PWMCH4 = 1000; + + // Send message via ESP-NOW + esp_err_t result = esp_now_send(broadcastAddress, (uint8_t *) &myData, sizeof(myData)); + + if (result == ESP_OK) { + Serial.println("Sent with success"); + } + else { + Serial.println("Error sending the data"); + } + } + + int mapPot(int normalizedValue){ + return map(normalizedValue, 80, 4095, MINPWMVALUE, MAXPWMVALUE); //map the normalized value to the PWM range + } + + int normalizePot(int pin, int minValue) //normalize the pot value to a range of 80 to 4095 instead of 0 to 4095 because the potmeter is at lower values not accurate + { + int pot = analogRead(pin); + + if (pot <= minValue) + { + return 80; + } + else + { + return pot; + } + } + ``` + +I added that it could connect to the internet and that it attempts to send data. I quickly realised that the mac address I entered was from the controller itself and not the receiving end. So I quickly corrected that mistake. + +Now when I compile it I get errors that the data isn't being send correctly. The issue could be that the second microcontroller isn't turned on with the receiver code. + +![alt text](image-27.png) + +#### Drone side + +For the drone I'm going to start of with a seperate script to see if it works and then start implementing it into the drone driver. I started off with copy pasting the program into my editor and uploading it to my microcontroller. The only thing I needed to do is copy the struct from the controller, because they need to be the same. So this is my code im going to test now. + +??? Code + ```cpp + /* + Rui Santos & Sara Santos - Random Nerd Tutorials + Complete project details at https://RandomNerdTutorials.com/esp-now-esp32-arduino-ide/ + 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 + #include + + // Structure example to receive data + // Must match the sender structure + typedef struct struct_message { + int PWMCH1; + int PWMCH2; + int PWMCH3; + int PWMCH4; + } struct_message; + + // Create a struct_message called myData + struct_message myData; + + // callback function that will be executed when data is received + void OnDataRecv(const uint8_t * mac, const uint8_t *incomingData, int len) { + memcpy(&myData, incomingData, sizeof(myData)); + Serial.print("Bytes received: "); + Serial.println(len); + Serial.print("Char: "); + Serial.println(myData.PWMCH1); + Serial.print("Int: "); + Serial.println(myData.PWMCH2); + Serial.print("Float: "); + Serial.println(myData.PWMCH3); + Serial.print("Bool: "); + Serial.println(myData.PWMCH4); + Serial.println(); + } + + void setup() { + // Initialize Serial Monitor + Serial.begin(9600); + + // Set device as a Wi-Fi Station + WiFi.mode(WIFI_STA); + + // Init ESP-NOW + if (esp_now_init() != ESP_OK) { + Serial.println("Error initializing ESP-NOW"); + 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)); + Serial.println("Waiting for data"); + } + + void loop() { + + } + ``` + + + +A weird thing I found out is that my esp32C3 Supermini doesn't work wirelessly that well. When I uploaded the code it still didn't work untill I held my finger on the antenna. + + + +I've delved a bit deeper into it and then I found online that with the first batches of espC3 supermini's have issues with the antenna. When I was debugging it I noticed that connecting the ground to the antenne fixed it when I tried it with a pin. But when soldered on it didn't work anymore and then only thing that worked was my finger. + +![alt text](IMG_8200.JPEG) +Result of bridging ground and the antenna. Sadly didn't work. After that I grabbed the Xiao espC3 and connected it. It almost worked like a drop in replacement I only needed to change the Potpin. After that it worked flawlessly. + +![alt text](image-28.png) + +Now I can start intergrating the code into the drone driver. ## Sources diff --git a/src/controller/drone controller/src/main.cpp b/src/controller/drone controller/src/main.cpp index 53af349..3f016dc 100644 --- a/src/controller/drone controller/src/main.cpp +++ b/src/controller/drone controller/src/main.cpp @@ -1,23 +1,79 @@ #include +#include +#include + // declarations int normalizePot(int pin, int minValue); +int mapPot(int normalizedValue); // constants -const int potPin1 = 0; +const int POTPIN1 = 2; +const int MAXPWMVALUE = 1400; +const int MINPWMVALUE = 2000; +const uint8_t broadcastAddress[] = {0x8C, 0xBF, 0xEA, 0xCC, 0x8E, 0x5C}; +//Define the struct that will be sent +typedef struct struct_message { + int PWMCH1; + int PWMCH2; + int PWMCH3; + int PWMCH4; +} struct_message; +struct_message myData; //declare the struct as myData + +esp_now_peer_info_t peerInfo; //create a class object of the ESPNow class void setup() { + // Set device as a Wi-Fi Station + WiFi.mode(WIFI_STA); + + // Init ESP-NOW + if (esp_now_init() != ESP_OK) { + Serial.println("Error initializing ESP-NOW"); + return; + } + + // Register peer + memcpy(peerInfo.peer_addr, broadcastAddress, 6); + peerInfo.channel = 0; + peerInfo.encrypt = false; + + // Add peer + if (esp_now_add_peer(&peerInfo) != ESP_OK){ + Serial.println("Failed to add peer"); + return; + } + Serial.begin(9600); - pinMode(potPin1, INPUT); + pinMode(POTPIN1, INPUT); } void loop() { + Serial.println(mapPot(normalizePot(POTPIN1, 80))); //call normalizePot and put the output into mapPot then print it - Serial.println(normalizePot(potPin1, 80)); + // Set values to send + myData.PWMCH1 = mapPot(normalizePot(POTPIN1, 80)); + myData.PWMCH2 = 1000; //test values + myData.PWMCH3 = 1000; + myData.PWMCH4 = 1000; + + // Send message via ESP-NOW + esp_err_t result = esp_now_send(broadcastAddress, (uint8_t *) &myData, sizeof(myData)); + + if (result == ESP_OK) { + Serial.println("Sent with success"); + } + else { + Serial.println("Error sending the data"); + } } -int normalizePot(int pin, int minValue) +int mapPot(int normalizedValue){ + return map(normalizedValue, 80, 4095, MINPWMVALUE, MAXPWMVALUE); //map the normalized value to the PWM range +} + +int normalizePot(int pin, int minValue) //normalize the pot value to a range of 80 to 4095 instead of 0 to 4095 because the potmeter is at lower values not accurate { int pot = analogRead(pin);