Advanced IoT ESP32

Jesse Duran
Fall 2020
CE 351

Introduction:

The goal of this lab was to become familiarized with the ESP32 microcontroller. The intruduction to other MCUs than Arduino leads to a larger expanse of tools in our toolbox. Our skills in developing a product were also improved upon as we created a PCB using the MCU without the additional compoants.

Tasks:



Task1: ESP32 on board blink


Task2: MPU6050 Data plotted using serial monitor


Task3: Accelerometer data converted to G's


Task 5. Accerometer data plotted in Python

Task 6: storeing data in temp variables
 AccX_temp=Wire.read()<<8 | Wire.read();
  AccX=AccX_temp/8192.0;
  AccY_temp=Wire.read()<<8 | Wire.read();
  AccY=AccY_temp/8192.0;
  AccZ_temp=Wire.read()<<8 | Wire.read();
  AccZ=AccZ_temp/8192.0;



Task 7 ESP32 WIFI communication plotted to Serial Monitor

Task 8:
Slave Code writing to SD card
#include "FS.h"
#include "SD.h"
#include "SPI.h"
#include<esp_now.h>
#include<WiFi.h>
float incomingAccX, incomingAccY, incomingAccZ;
void accSD(int16_t,int16_t,int16_t);

typedef struct struct_message{
float AccX;
float AccY;
float AccZ;
} struct_message;

struct_message incomingReadings;

// Callback when data is received
void OnDataRecv(const uint8_t * mac, const uint8_t *incomingData, int len) {
memcpy(&incomingReadings, incomingData, sizeof(incomingReadings));
incomingAccX=incomingReadings.AccX;
incomingAccY=incomingReadings.AccY;
incomingAccZ=incomingReadings.AccZ;
}
void accSD(const float x , const float y,const float z){
appendFile(SD, "/AccX_Wifi.txt",x);
appendFile_char(SD, "/AccX_Wifi.txt", ",");

appendFile(SD, "/AccY_Wifi.txt", y);
appendFile_char(SD, "/AccY_Wifi.txt", ",");

appendFile(SD, "/AccZ_Wifi.txt", x);
appendFile_char(SD, "/AccZ_Wifi.txt", ",");

}
//void accSD(int16_t x,int16_t y,int16_t z){
// appendFile(SD, "/AccX_Wifi.txt",x);
// appendFile_char(SD, "/AccX_Wifi.txt", ",");
//
// appendFile(SD, "/AccY_Wifi.txt", y);
// appendFile_char(SD, "/AccY_Wifi.txt", ",");
//
// appendFile(SD, "/AccZ_Wifi.txt", x);
// appendFile_char(SD, "/AccZ_Wifi.txt", ",");
//
//}

void setup(){
Serial.begin(115200);
WiFi.mode(WIFI_STA);
// Init ESP-NOW
if (esp_now_init() != ESP_OK) {
Serial.println("Error initializing ESP-NOW");
return;
}
// Register for a callback function that will be called when data is received
esp_now_register_recv_cb(OnDataRecv);
if(!SD.begin()){
Serial.println("Card Mount Failed");
return;
}
}
void loop(){
uint8_t cardType = SD.cardType();
if(cardType == CARD_NONE){
Serial.println("No SD card attached");
return;
}
appendFile(SD, "/AccX_Wifi.txt",incomingAccX);
appendFile_char(SD, "/AccX_Wifi.txt", ",");

appendFile(SD, "/AccY_Wifi.txt", incomingAccY);
appendFile_char(SD, "/AccY_Wifi.txt", ",");

appendFile(SD, "/AccZ_Wifi.txt", incomingAccZ);
appendFile_char(SD, "/AccZ_Wifi.txt", ",");
}


void appendFile(fs::FS &fs, const char * path, float message){ // changed the argument type to int16_t

File file = fs.open(path, FILE_APPEND);
if(!file){
Serial.println("Failed to open file for appending");
return;
}
if(file.print(message)){
Serial.println("Message appended");
} else {
Serial.println("Append failed");
}
file.close();
}
void appendFile_char(fs::FS &fs, const char * path, const char * message){ // added an 'appendFile_char' function to append ',' as data separators
Serial.printf("Appending to file: %s\n", path);

File file = fs.open(path, FILE_APPEND);
if(!file){
Serial.println("Failed to open file for appending");
return;
}
if(file.print(message)){
Serial.println("Message appended");
} else {
Serial.println("Append failed");
}
file.close();
}

------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Master Code sending accelermeter data
#include "FS.h"
#include "SD.h"
#include "SPI.h"
#include<esp_now.h>
#include<WiFi.h>
#include<Wire.h>
const int MPU=0x68;//Device address
float AccX, AccY, AccZ;
int16_t AccX_temp, AccY_temp, AccZ_temp;
String success;
uint8_t broadcastAddress[] = {0xFC, 0xF5, 0xC4, 0x26, 0xF7, 0x7C}; // Receiver's mac address

typedef struct struct_message{
float AccX;
float AccY;
float AccZ;
} struct_message;

struct_message MPU6050Readings;

void setup(){
Wire.begin(); //To redefine the I2C pins: Wire.begin(SDA,SCL) or Wire.begin(SDA, SCL, Bus_Speed).
// Wake up the sensor (reset)
Wire.beginTransmission(MPU);
Wire.write(0x6B);//Wake up the MPU chip
Wire.write(0x00);
Wire.endTransmission(true);
Wire.beginTransmission(MPU);
Wire.write(0x1C);//Talk to the ACCEL_CONFIG register (1C hex)
Wire.write(0x08);//Set the register bits as 00001000 (+/- 4g full scale range)
Wire.endTransmission(true);
Serial.begin(115200); // It's fine to use a higher speed other than 9600 but remember to change the rate in your serial monitor
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 Send CB to get the status of Trasnmitted packet
// esp_now_register_send_cb(OnDataSent);
// Register peer
esp_now_peer_info_t peerInfo;
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;
}
}
void loop(){
accRead();
MPU6050Readings.AccX=AccX;
MPU6050Readings.AccY=AccY;
MPU6050Readings.AccZ=AccZ;
esp_err_t result = esp_now_send(broadcastAddress, (uint8_t *) &MPU6050Readings, sizeof(MPU6050Readings)); //Send the data. &MPU6050Readings is just a 8-bit character pointer to store the data
if (result == ESP_OK) { // For debug purpose
Serial.println("Sent with success");
}
else {
Serial.println("Error sending the data");
}
Serial.print(MPU6050Readings.AccX);
Serial.print(" ");
Serial.print(MPU6050Readings.AccY);
Serial.print(" ");
Serial.print(MPU6050Readings.AccY);
Serial.println(" ");
}
void accRead(){ // read the MPU data to ESP32
Wire.beginTransmission(MPU);
Wire.write(0x3B);//Start with register 0x3B
Wire.endTransmission(false);
Wire.requestFrom(MPU,6,true);// Read 6 registers total
AccX_temp=Wire.read()<<8 | Wire.read();
AccX=AccX_temp;
AccY_temp=Wire.read()<<8 | Wire.read();
AccY=AccY_temp;
AccZ_temp=Wire.read()<<8 | Wire.read();
AccZ=AccZ_temp;
Wire.endTransmission(true);
}
// Callback when data is sent, for debug purpose
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");
if (status ==0){
success = "Delivery Success :)";
}
else{
success = "Delivery Fail :(";
}
}

----------------------------------------------------------------------------------------------------------------------------------------------------

Task 9 Clean code for master and slave:

Clean Slave Code
//Clean code fore ESP32 SD card slave
#include "FS.h"
#include "SD.h"
#include "SPI.h"
#include<esp_now.h>
#include<WiFi.h>
float incomingAccX, incomingAccY, incomingAccZ;
void accSD(int16_t,int16_t,int16_t);

typedef struct struct_message{
float AccX;
float AccY;
float AccZ;
} struct_message;

struct_message incomingReadings;

// Callback when data is received
void OnDataRecv(const uint8_t * mac, const uint8_t *incomingData, int len) {
memcpy(&incomingReadings, incomingData, sizeof(incomingReadings));
incomingAccX=incomingReadings.AccX;
incomingAccY=incomingReadings.AccY;
incomingAccZ=incomingReadings.AccZ;
}
void accSD(const float x , const float y,const float z){
appendFile(SD, "/AccX_Wifi.txt",x);
appendFile_char(SD, "/AccX_Wifi.txt", ",");

appendFile(SD, "/AccY_Wifi.txt", y);
appendFile_char(SD, "/AccY_Wifi.txt", ",");

appendFile(SD, "/AccZ_Wifi.txt", x);
appendFile_char(SD, "/AccZ_Wifi.txt", ",");

}

void setup(){
WiFi.mode(WIFI_STA);
// Init ESP-NOW
if (esp_now_init() != ESP_OK) {
return;
}
// Register for a callback function that will be called when data is received
esp_now_register_recv_cb(OnDataRecv);

}
void loop(){
uint8_t cardType = SD.cardType();

appendFile(SD, "/AccX_Wifi.txt",incomingAccX);
appendFile_char(SD, "/AccX_Wifi.txt", ",");

appendFile(SD, "/AccY_Wifi.txt", incomingAccY);
appendFile_char(SD, "/AccY_Wifi.txt", ",");

appendFile(SD, "/AccZ_Wifi.txt", incomingAccZ);
appendFile_char(SD, "/AccZ_Wifi.txt", ",");
}


void appendFile(fs::FS &fs, const char * path, float message){ // changed the argument type to int16_t

File file = fs.open(path, FILE_APPEND);

file.print(message);

file.close();
}
void appendFile_char(fs::FS &fs, const char * path, const char * message){ // added an 'appendFile_char' function to append ',' as data separators

File file = fs.open(path, FILE_APPEND);

file.print(message);

file.close();
}

-----------------------------------------------------------------------------------------------------------------------------------------------------------
Clean Master Code

//Clean code fore ESP32 SD card slave
#include "FS.h"
#include "SD.h"
#include "SPI.h"
#include<esp_now.h>
#include<WiFi.h>
float incomingAccX, incomingAccY, incomingAccZ;
void accSD(int16_t,int16_t,int16_t);

typedef struct struct_message{
float AccX;
float AccY;
float AccZ;
} struct_message;

struct_message incomingReadings;

// Callback when data is received
void OnDataRecv(const uint8_t * mac, const uint8_t *incomingData, int len) {
memcpy(&incomingReadings, incomingData, sizeof(incomingReadings));
incomingAccX=incomingReadings.AccX;
incomingAccY=incomingReadings.AccY;
incomingAccZ=incomingReadings.AccZ;
}
void accSD(const float x , const float y,const float z){
appendFile(SD, "/AccX_Wifi.txt",x);
appendFile_char(SD, "/AccX_Wifi.txt", ",");

appendFile(SD, "/AccY_Wifi.txt", y);
appendFile_char(SD, "/AccY_Wifi.txt", ",");

appendFile(SD, "/AccZ_Wifi.txt", x);
appendFile_char(SD, "/AccZ_Wifi.txt", ",");

}

void setup(){
WiFi.mode(WIFI_STA);
// Init ESP-NOW
if (esp_now_init() != ESP_OK) {
return;
}
// Register for a callback function that will be called when data is received
esp_now_register_recv_cb(OnDataRecv);

}
void loop(){
uint8_t cardType = SD.cardType();

appendFile(SD, "/AccX_Wifi.txt",incomingAccX);
appendFile_char(SD, "/AccX_Wifi.txt", ",");

appendFile(SD, "/AccY_Wifi.txt", incomingAccY);
appendFile_char(SD, "/AccY_Wifi.txt", ",");

appendFile(SD, "/AccZ_Wifi.txt", incomingAccZ);
appendFile_char(SD, "/AccZ_Wifi.txt", ",");
}


void appendFile(fs::FS &fs, const char * path, float message){ // changed the argument type to int16_t

File file = fs.open(path, FILE_APPEND);

file.print(message);

file.close();
}
void appendFile_char(fs::FS &fs, const char * path, const char * message){ // added an 'appendFile_char' function to append ',' as data separators

File file = fs.open(path, FILE_APPEND);

file.print(message);

file.close();
}



Master PCB




Figure 1. ESP32 Master Schematic



Figure 2. Ratnest and wired board



Figure 3. Gerber file verification


PCB Soldering

Once we had the PCB in hand we began soldering. Solder paste was used for soldering each of the componants, using the hot air blower. This is a valuable skill for soldering small smd parts and IC chips. Unfortnately, in my PCB design my voltage regulator was not connected to VIN and OUT1 was shorted to IN1.  This made the PCB un usable. Fortunalty, Tyrone  Bracker-Yazzie gave me one of his PCBs.


Figure 4. Soldered PCB (TBY's design)
Once soldered the votage coming out of the regulator was 2.8V. Too low to power the ESP32. After much debugging, we were unable to solve the problem.

Redesigned PCB

After noticing the faults in my PCB I went back and fixed them. The following is the correct schematic.

Figure 5. Corrected PCB schematic. The circle in red is what changed. IN1 was connected to VIN and OUT1 was disconnected from IN1.

Discussion


This project introduced working with different MCUs than Arduinos. This opens the door to a wider variety of applications. The PCB design wrapped in the power considerations for a low power and wearable design. Further practice with barebones microcontrollers makes our skills of creating products is stregthened. There is much to learn from the failures in the project. For one, double checking PCB layouts is critical before sending them to be manufactured. Regardless of the outcome, there was learning to be had. I feel much more confident in soldering small PCBs and SMD IC's.