To make the wand from scratch, open up Autodesk Fusion to design the wand. The wand has four main parts:
Name | Value (mm) |
---|---|
main_wand_diameter | 40 |
main_wand_length | 130 |
handle_diameter | 40 |
handle_length | 33 |
tip_length | 150 |
#include WiFi.h
#include esp_wifi.h
void readMacAddress(){
uint8_t baseMac[6];
esp_err_t ret = esp_wifi_get_mac(WIFI_IF_STA, baseMac);
if (ret == ESP_OK) {
Serial.printf("%02x:%02x:%02x:%02x:%02x:%02x\n",
baseMac[0], baseMac[1], baseMac[2],
baseMac[3], baseMac[4], baseMac[5]);
} else {
Serial.println("Failed to read MAC address");
}
}
void setup(){
Serial.begin(115200);
WiFi.mode(WIFI_STA);
WiFi.STA.begin();
Serial.print("[DEFAULT] ESP32 Board MAC Address: ");
readMacAddress();
}
void loop(){
}
// PHYS 70 Receiver Microcontroller
// NOTE: on USB power, Serial.println works; comment all Serial if you want to run on Li-ion battery //
// Imports and Installs
#include esp_now.h
#include WiFi.h
// Variables
int ledPin = D0;
typedef struct struct_message {
float a;
float b;
float c;
} struct_message;
struct_message myData;
float lastDataA = NAN;
float lastDataB = NAN;
float lastDataC = NAN;
unsigned long lastTime = 0;
const unsigned long waitInterval = 1000; // how much to wait before next swoosh
// Callbacks
void OnDataRecv(const uint8_t * mac, const uint8_t *incomingData, int len) {
memcpy(&myData, incomingData, sizeof(myData));
//Serial.print("Received: ");
//Serial.println(myData.a);
// If booting up for first time
if (isnan(lastDataA)) {
lastDataA = myData.a;
}
if (isnan(lastDataB)) {
lastDataB = myData.b;
}
if (isnan(lastDataC)) {
lastDataC = myData.c;
}
//Serial.println(myData.a);
//Serial.println(myData.b);
//Serial.println(myData.c);
// If we swish the wand hard enough and a bit after a previous swish, it'll trigger an event
if ((abs(myData.a - lastDataA) > 4 ||
abs(myData.b - lastDataB) > 4 ||
abs(myData.c - lastDataC) > 4)
&& (millis() - lastTime >= waitInterval)) {
//Serial.println("We've swooshed!");
int state = digitalRead(ledPin);
if (state == HIGH) {
//Serial.println("Nox!");
digitalWrite(ledPin, LOW);
} else {
//Serial.println("Lumos!");
digitalWrite(ledPin, HIGH);
}
lastTime = millis();
}
lastDataA = myData.a;
lastDataB = myData.b;
lastDataC = myData.c;
}
// Function: Setup
void setup() {
// Initialize Serial and Time
lastTime = millis();
//Serial.begin(115200);
//Serial.println("Starting...");
// Initialize ledPin, WiFi
pinMode(ledPin, OUTPUT);
digitalWrite(ledPin, HIGH);
WiFi.mode(WIFI_STA);
// Initialize ESP-NOW
if (esp_now_init() != ESP_OK) {
//Serial.println("Error initializing ESP-NOW");
return;
}
// Initialize Callback
//Serial.println("ESP-NOW ready to receive");
esp_now_register_recv_cb(esp_now_recv_cb_t(OnDataRecv));
}
// Function: Loop
void loop() {
}
// PHYS 70 Sender Microcontroller
// NOTE: on USB power, Serial.println works; comment all Serial if you want to run on Li-ion battery //
// Imports and Installs
#include esp_now.h
#include WiFi.h
#include Adafruit_MPU6050.h
#include Adafruit_Sensor.h
// Variables
unsigned long lastTime = 0;
const unsigned long interval = 100;
// esp32: 0XC0, 0X5D, 0X89, 0XAF, 0XE8, 0X6C
// xiao esp32: 24:ec:4a:ca:6d:b4
uint8_t broadcastAddress[] = {0X21, 0XEC, 0X4A, 0XCA, 0X6D, 0XB4};
typedef struct struct_message {
float a;
float b;
float c;
} struct_message;
struct_message myData;
esp_now_peer_info_t peerInfo;
// Callbacks
void OnDataSent(const uint8_t *mac_addr, esp_now_send_status_t status) {}
// Classes
class MPU {
public:
Adafruit_MPU6050 mpu;
unsigned long mpuLastTime = 0;
const unsigned long mpuInterval = 100;
sensors_event_t a, g, temp;
MPU() {
}
void GetMPUData() {
mpu.getEvent(&a, &g, &temp);
/*
Serial.print("Acceleration X: ");
Serial.print(a.acceleration.x);
Serial.print(", Y: ");
Serial.print(a.acceleration.y);
Serial.print(", Z: ");
Serial.print(a.acceleration.z);
Serial.println(" m/s^2");
*/
}
};
// Objects
MPU myMPU;
// Function: Setup
void setup() {
Serial.begin(115200);
// Initialize WiFi
WiFi.mode(WIFI_STA);
// Initialize ESP-Now and Peer Info
if (esp_now_init() != ESP_OK) {
//Serial.println("Error initializing ESP-NOW");
return;
}
esp_now_register_send_cb(OnDataSent);
memcpy(peerInfo.peer_addr, broadcastAddress, 6);
peerInfo.channel = 0;
peerInfo.encrypt = false;
if (esp_now_add_peer(&peerInfo) != ESP_OK) {
//Serial.println("Failed to add peer");
return;
}
// Initialize MPU
while (!myMPU.mpu.begin()) {
if (millis() - myMPU.mpuLastTime > myMPU.mpuInterval) {
myMPU.mpuLastTime = millis();
//Serial.println("Failed to find MPU6050 chip");
}
}
myMPU.mpu.setAccelerometerRange(MPU6050_RANGE_8_G);
myMPU.mpu.setGyroRange(MPU6050_RANGE_500_DEG);
myMPU.mpu.setFilterBandwidth(MPU6050_BAND_5_HZ);
//Serial.println("Successfully found MPU6050 chip");
}
// Function: Loop
void loop() {
if (millis() - lastTime > interval) {
lastTime = millis();
// get MPU Data
myMPU.GetMPUData();
// format MPU data into message
myData.a = myMPU.a.acceleration.x;
myData.b = myMPU.a.acceleration.y;
myData.c = myMPU.a.acceleration.z;
// send message
esp_err_t result = esp_now_send(broadcastAddress, (uint8_t *) &myData, sizeof(myData));
//if (result == ESP_OK) {
// Serial.println("Success sending the data");
//}
}
}