Added mpu6050 and analog read for joysticks. Added magnetic switch read. Sample rate now controlled by mpu6050 (41HZ). Need some improvements on analog read (need continues mode instead of freerunning. Fifo overflow issues because 2 readings take up to 16ms).
This commit is contained in:
+167
-62
@@ -1,26 +1,22 @@
|
|||||||
#include <helper_3dmath.h>
|
#include "I2Cdev.h"
|
||||||
#include <MPU6050_6Axis_MotionApps20.h>
|
#include "MPU6050_6Axis_MotionApps20.h"
|
||||||
#include <MPU6050.h>
|
|
||||||
|
|
||||||
|
|
||||||
#include <Wire.h>
|
#include <Wire.h>
|
||||||
#include <WiFiUdp.h>
|
#include <WiFiUdp.h>
|
||||||
#include <ESP8266WiFi.h>
|
#include <ESP8266WiFi.h>
|
||||||
#include <EEPROM.h>
|
#include <EEPROM.h>
|
||||||
|
#include <Adafruit_ADS1015.h>
|
||||||
|
|
||||||
String WifiSSIDPrefix = "CrystalPoint";
|
String WifiSSIDPrefix = "CrystalPoint";
|
||||||
uint16_t BasestationPort = 2730;
|
uint16_t BasestationPort = 2730;
|
||||||
IPAddress BasestationIp = IPAddress(192, 168, 4, 1);
|
IPAddress BasestationIp = IPAddress(192, 168, 4, 1);
|
||||||
|
|
||||||
|
Adafruit_ADS1115 ads;
|
||||||
|
|
||||||
struct MPU6050Data{
|
struct MPU6050Data{
|
||||||
int gx;
|
int yaw;
|
||||||
int gy;
|
int pitch;
|
||||||
int gz;
|
int roll;
|
||||||
int ax;
|
|
||||||
int ay;
|
|
||||||
int az;
|
|
||||||
int fx;
|
|
||||||
int fy;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct JoystickData{
|
struct JoystickData{
|
||||||
@@ -34,6 +30,29 @@ struct SwitchData{
|
|||||||
char magnetSwitch;
|
char magnetSwitch;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//mpu6050
|
||||||
|
MPU6050 mpu;
|
||||||
|
bool dmpReady = false; // set true if DMP init was successful
|
||||||
|
uint8_t mpuIntStatus; // holds actual interrupt status byte from MPU
|
||||||
|
uint8_t devStatus; // return status after each device operation (0 = success, !0 = error)
|
||||||
|
uint16_t packetSize; // expected DMP packet size (default is 42 bytes)
|
||||||
|
uint16_t fifoCount; // count of all bytes currently in FIFO
|
||||||
|
uint8_t fifoBuffer[64]; // FIFO storage buffer
|
||||||
|
|
||||||
|
// orientation/motion vars
|
||||||
|
Quaternion q; // [w, x, y, z] quaternion container
|
||||||
|
VectorInt16 aa; // [x, y, z] accel sensor measurements
|
||||||
|
VectorInt16 aaReal; // [x, y, z] gravity-free accel sensor measurements
|
||||||
|
VectorInt16 aaWorld; // [x, y, z] world-frame accel sensor measurements
|
||||||
|
VectorFloat gravity; // [x, y, z] gravity vector
|
||||||
|
float euler[3]; // [psi, theta, phi] Euler angle container
|
||||||
|
float ypr[3]; // [yaw, pitch, roll] yaw/pitch/roll container and gravity vector
|
||||||
|
|
||||||
|
volatile bool mpuInterrupt = false; // indicates whether MPU interrupt pin has gone high
|
||||||
|
void dmpDataReady() {
|
||||||
|
mpuInterrupt = true;
|
||||||
|
}
|
||||||
|
|
||||||
//Data buffer for sensors
|
//Data buffer for sensors
|
||||||
struct MPU6050Data mpu6050data = {0};
|
struct MPU6050Data mpu6050data = {0};
|
||||||
struct JoystickData joystickdata = {0};
|
struct JoystickData joystickdata = {0};
|
||||||
@@ -42,6 +61,7 @@ struct SwitchData switchdata = {0};
|
|||||||
//UDP server (receiving) setup
|
//UDP server (receiving) setup
|
||||||
unsigned int udpPort = 2730;
|
unsigned int udpPort = 2730;
|
||||||
byte packetBuffer[512]; //udp package buffer
|
byte packetBuffer[512]; //udp package buffer
|
||||||
|
char sendBuffer[45];
|
||||||
WiFiUDP Udp;
|
WiFiUDP Udp;
|
||||||
|
|
||||||
void setup(void){
|
void setup(void){
|
||||||
@@ -50,58 +70,136 @@ void setup(void){
|
|||||||
WiFi.mode(WIFI_STA);
|
WiFi.mode(WIFI_STA);
|
||||||
WiFi.disconnect();
|
WiFi.disconnect();
|
||||||
EEPROM.begin(512);
|
EEPROM.begin(512);
|
||||||
Udp.begin(udpPort);
|
|
||||||
|
|
||||||
|
delay(10);
|
||||||
|
Udp.begin(udpPort);
|
||||||
|
Wire.begin();
|
||||||
|
|
||||||
|
//Magnetic sensor
|
||||||
|
pinMode(13,INPUT);
|
||||||
|
|
||||||
//clearEeprom();
|
//clearEeprom();
|
||||||
//connectLastBasestation();
|
connectLastBasestation();
|
||||||
searchBasestation();
|
//searchBasestation();
|
||||||
|
|
||||||
|
delay(1000);
|
||||||
|
ads.begin();
|
||||||
|
|
||||||
|
mpu6050setup();
|
||||||
|
}
|
||||||
|
|
||||||
|
void mpu6050setup(){
|
||||||
|
mpu.initialize();
|
||||||
|
Serial.println(mpu.testConnection() ? F("MPU6050 connection successful") : F("MPU6050 connection failed"));
|
||||||
|
devStatus = mpu.dmpInitialize();
|
||||||
|
|
||||||
|
mpu.setXGyroOffset(62);
|
||||||
|
mpu.setYGyroOffset(25);
|
||||||
|
mpu.setZGyroOffset(-11);
|
||||||
|
mpu.setXAccelOffset(-2030);
|
||||||
|
mpu.setYAccelOffset(11);
|
||||||
|
mpu.setZAccelOffset(2119); // 1688 factory default for my test chip
|
||||||
|
|
||||||
|
if (devStatus == 0) {
|
||||||
|
mpu.setDMPEnabled(true);
|
||||||
|
|
||||||
|
attachInterrupt(15, dmpDataReady, RISING); //intrupt pin on pin 15
|
||||||
|
mpuIntStatus = mpu.getIntStatus();
|
||||||
|
|
||||||
|
dmpReady = true;
|
||||||
|
|
||||||
|
packetSize = mpu.dmpGetFIFOPacketSize();
|
||||||
|
} else {
|
||||||
|
Serial.print(F("DMP Initialization failed (code "));
|
||||||
|
Serial.print(devStatus);
|
||||||
|
Serial.println(F(")"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void loop(void){
|
void loop(void){
|
||||||
//receiving rumble or shock data from basestation
|
//wait for interupt from mpu6050, in the mean time pol udp server for new data
|
||||||
int noBytes = Udp.parsePacket();
|
while (!mpuInterrupt && fifoCount < packetSize) {
|
||||||
if ( noBytes ) {
|
//receiving rumble or shock data from basestation
|
||||||
Serial.print(millis() / 1000);
|
int noBytes = Udp.parsePacket();
|
||||||
Serial.print(":Packet of ");
|
if ( noBytes ) {
|
||||||
Serial.print(noBytes);
|
Serial.print(millis() / 1000);
|
||||||
Serial.print(" received from ");
|
Serial.print(":Packet of ");
|
||||||
Serial.print(Udp.remoteIP());
|
Serial.print(noBytes);
|
||||||
Serial.print(":");
|
Serial.print(" received from ");
|
||||||
Serial.println(Udp.remotePort());
|
Serial.print(Udp.remoteIP());
|
||||||
// We've received a packet, read the data from it
|
Serial.print(":");
|
||||||
Udp.read(packetBuffer,noBytes); // read the packet into the buffer
|
Serial.println(Udp.remotePort());
|
||||||
|
// We've received a packet, read the data from it
|
||||||
// display the packet contents in HEX
|
Udp.read(packetBuffer,noBytes); // read the packet into the buffer
|
||||||
for (int i=1;i<=noBytes;i++){
|
|
||||||
Serial.print(packetBuffer[i-1],HEX);
|
// display the packet contents in HEX
|
||||||
if (i % 32 == 0){
|
for (int i=1;i<=noBytes;i++){
|
||||||
|
Serial.print(packetBuffer[i-1],HEX);
|
||||||
|
if (i % 32 == 0){
|
||||||
|
Serial.println();
|
||||||
|
}
|
||||||
|
else Serial.print(' ');
|
||||||
|
}
|
||||||
Serial.println();
|
Serial.println();
|
||||||
}
|
|
||||||
else Serial.print(' ');
|
|
||||||
}
|
}
|
||||||
Serial.println();
|
delay(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Send new data
|
|
||||||
joystickdata.x = 1;
|
|
||||||
joystickdata.y = 2;
|
|
||||||
joystickdata.button = 0;
|
|
||||||
mpu6050data.gx = 1;
|
|
||||||
mpu6050data.gy = 2;
|
|
||||||
mpu6050data.gz = 3;
|
|
||||||
mpu6050data.ax = 4;
|
|
||||||
mpu6050data.ay = 5;
|
|
||||||
mpu6050data.az = 6;
|
|
||||||
mpu6050data.fx = 7;
|
|
||||||
mpu6050data.fy = 8;
|
|
||||||
switchdata.backSwitch = 9;
|
|
||||||
switchdata.magnetSwitch = 10;
|
|
||||||
|
|
||||||
|
|
||||||
sendUdpMessage(&joystickdata, &mpu6050data, &switchdata);
|
|
||||||
|
|
||||||
//30 times per second new data
|
//We are out of the while loop, so mpu interupt fired;
|
||||||
delay(33);
|
readFifoMpu6050(&mpu6050data);
|
||||||
|
|
||||||
|
readSwitches(&switchdata);
|
||||||
|
|
||||||
|
readJoystick(&joystickdata);
|
||||||
|
|
||||||
|
//Send new data
|
||||||
|
joystickdata.button = 0;
|
||||||
|
|
||||||
|
sendUdpMessage(&joystickdata, &mpu6050data, &switchdata);
|
||||||
|
}
|
||||||
|
|
||||||
|
void readJoystick(struct JoystickData *joystickdata){
|
||||||
|
joystickdata->x = ads.readADC_SingleEnded(0);
|
||||||
|
joystickdata->y = ads.readADC_SingleEnded(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void readFifoMpu6050(struct MPU6050Data *mpu6050data){
|
||||||
|
// reset interrupt flag and get INT_STATUS byte
|
||||||
|
mpuInterrupt = false;
|
||||||
|
mpuIntStatus = mpu.getIntStatus();
|
||||||
|
|
||||||
|
// get current FIFO count
|
||||||
|
fifoCount = mpu.getFIFOCount();
|
||||||
|
|
||||||
|
// check for overflow (this should never happen unless our code is too inefficient)
|
||||||
|
if ((mpuIntStatus & 0x10) || fifoCount == 1024) {
|
||||||
|
// reset so we can continue cleanly
|
||||||
|
mpu.resetFIFO();
|
||||||
|
Serial.println(F("FIFO overflow!"));
|
||||||
|
} else if (mpuIntStatus & 0x02){
|
||||||
|
// wait for correct available data length, should be a VERY short wait
|
||||||
|
while (fifoCount < packetSize) fifoCount = mpu.getFIFOCount();
|
||||||
|
|
||||||
|
// read a packet from FIFO
|
||||||
|
mpu.getFIFOBytes(fifoBuffer, packetSize);
|
||||||
|
|
||||||
|
// track FIFO count here in case there is > 1 packet available
|
||||||
|
// (this lets us immediately read more without waiting for an interrupt)
|
||||||
|
fifoCount -= packetSize;
|
||||||
|
|
||||||
|
// get Euler angles in degrees
|
||||||
|
mpu.dmpGetQuaternion(&q, fifoBuffer);
|
||||||
|
mpu.dmpGetGravity(&gravity, &q);
|
||||||
|
mpu.dmpGetYawPitchRoll(ypr, &q, &gravity);
|
||||||
|
|
||||||
|
mpu6050data->yaw = ypr[0] * 18000/M_PI;
|
||||||
|
mpu6050data->pitch = ypr[1] * 18000/M_PI;
|
||||||
|
mpu6050data->roll = ypr[2] * 18000/M_PI;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void readSwitches(struct SwitchData *switchdata){
|
||||||
|
switchdata->magnetSwitch = !digitalRead(13);
|
||||||
}
|
}
|
||||||
|
|
||||||
void searchBasestation(void){
|
void searchBasestation(void){
|
||||||
@@ -121,6 +219,10 @@ void searchBasestation(void){
|
|||||||
|
|
||||||
//Connect to the basestation
|
//Connect to the basestation
|
||||||
WiFi.begin(WifiSSID, WifiPassword);
|
WiFi.begin(WifiSSID, WifiPassword);
|
||||||
|
while (WiFi.status() != WL_CONNECTED) {
|
||||||
|
delay(500);
|
||||||
|
Serial.print(".");
|
||||||
|
}
|
||||||
|
|
||||||
///Writing data to eeprom
|
///Writing data to eeprom
|
||||||
writeEeprom(WifiSSID, WifiPassword);
|
writeEeprom(WifiSSID, WifiPassword);
|
||||||
@@ -158,6 +260,10 @@ void connectLastBasestation(void){
|
|||||||
|
|
||||||
//Connect to the basestation
|
//Connect to the basestation
|
||||||
WiFi.begin(eepromWifiSSID, eepromWifiPassword);
|
WiFi.begin(eepromWifiSSID, eepromWifiPassword);
|
||||||
|
while (WiFi.status() != WL_CONNECTED) {
|
||||||
|
delay(500);
|
||||||
|
Serial.print(".");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -174,13 +280,12 @@ void calculateWiFiPassword(String WifiSSID, char *WifiPassword)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void sendUdpMessage(struct JoystickData *joystick, struct MPU6050Data *mpu6050data, struct SwitchData *switchdata){
|
void sendUdpMessage(struct JoystickData *joystick, struct MPU6050Data *mpu6050data, struct SwitchData *switchdata){
|
||||||
char sendBuffer[512];
|
|
||||||
Udp.beginPacket(BasestationIp, BasestationPort);
|
Udp.beginPacket(BasestationIp, BasestationPort);
|
||||||
sprintf(sendBuffer, "%06d%06d%01d", joystick->x, joystick->y, joystick->button);
|
sprintf(sendBuffer, "%06d|%06d|%01d|", joystick->x, joystick->y, joystick->button);
|
||||||
sprintf(sendBuffer, "%s%06d%06d%06d%06d%06d%06d%06d%06d", sendBuffer, mpu6050data->gx, mpu6050data->gy, mpu6050data->gz, mpu6050data->ax, mpu6050data->ay, mpu6050data->az, mpu6050data->fx, mpu6050data->fy);
|
sprintf(sendBuffer, "%s%06d|%06d|%06d", sendBuffer, mpu6050data->yaw, mpu6050data->pitch, mpu6050data->roll);
|
||||||
sprintf(sendBuffer, "%s%01d%01d", sendBuffer, switchdata->backSwitch, switchdata->magnetSwitch);
|
sprintf(sendBuffer, "%s%01d|%01d", sendBuffer, switchdata->backSwitch, switchdata->magnetSwitch);
|
||||||
Serial.printf("%s", sendBuffer);
|
// Serial.printf("%s", sendBuffer);
|
||||||
Serial.println();
|
// Serial.println();
|
||||||
Udp.write(sendBuffer);
|
Udp.write(sendBuffer);
|
||||||
Udp.endPacket();
|
Udp.endPacket();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user