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:
jancoow
2016-05-23 00:42:24 +02:00
parent 8f06664f43
commit c9bb6b525e
+167 -62
View File
@@ -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();
} }