Accelerometers, Interrupts, timing oh my.
Weakness: MPU-6050 GY-521 (a.k.a. “The Devil”)
I knew this was my weakness, and it still is. It’s broken me. After many frustrating hours moving this thing around, several tutorial (links below), and ultimately having it sit on the table and increment while no movement or rotation. I gave up. While I could get the tutorials to work, everything thing hooked up and the processing sketches to run, I still didn’t know what it was actually doing. Reading through the code only kind of helped, but when things started get dicey is how exactly they were using the raw data.
Gyroscopes and Accelerometers on a Chip
Arduino 5 Minute Tutorials: Lesson 7 – Accelerometers, Gyros, IMUs
Tutorial: How to use the GY-521 module (MPU-6050 breakout board) with the Arduino Uno
https://create.arduino.cc/projecthub/Aritro/getting-started-with-imu-6-dof-motion-sensor-96e066
http://www-robotics.cs.umass.edu/~grupen/503/Projects/ArduinoMPU6050-Tutorial.pdf
The list could go on. I’ve racked up an extensive search history of accelerometers & arduino as well as MPU6050 tutorials.
Interrupts
After picking myself back up, I decided to tackle another weakness. Interrupts. I’ve been avoiding them for some time, and am still working at fulling understanding their capabilities. The trouble I always run into is how to exit a light sequence. I also ran into some issues while using music. I decided to make a few simple interactions with button, sounds, and light to tackle my interrupt fears head on.
This project simple starts a song, pauses the song mid-way, lights a NeoPixel sequence (also the devil), and exits the sequence. A second button will stop the song or light sequence and restart the song from the beginning.
Arduino Code
/***************************************************
DFPlayer - A Mini MP3 Player For Arduino
<https://www.dfrobot.com/index.php?route=product/product&product_id=1121>
***************************************************
This example shows the basic function of library for DFPlayer.
Created 2016-12-07
By [Angelo qiao](Angelo.qiao@dfrobot.com)
GNU Lesser General Public License.
See <http://www.gnu.org/licenses/> for details.
All above must be included in any redistribution
****************************************************/
/***********Notice and Trouble shooting***************
1.Connection and Diagram can be found here
<https://www.dfrobot.com/wiki/index.php/DFPlayer_Mini_SKU:DFR0299#Connection_Diagram>
2.This code is tested on Arduino Uno, Leonardo, Mega boards.
****************************************************/
#include <SoftwareSerial.h>
#include <DFRobotDFPlayerMini.h>
SoftwareSerial mySoftwareSerial(10, 11); // RX, TX
DFRobotDFPlayerMini myDFPlayer;
void printDetail(uint8_t type, int value);
//--------NEOPIXEL SETUP --------
#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
#include <avr/power.h>
#endif
static const int PIN = 5;
static const int NUMPIXELS = 2;
Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);
//------------------------------
//------- TIMING --------
unsigned long lastSampleTime = 0;
unsigned long sampleInterval = 500; // in ms
//------------------------------
static const int bPinOne = 2;
static const int bPinTwo = 3;
int bCountOne = 0;
int bCountTwo = 0;
bool bStateOne = false;
bool bStateTwo = false;
int currentState = 0;
void setup() {
mySoftwareSerial.begin(9600);
Serial.begin(115200);
Serial.println();
Serial.println(F("DFRobot DFPlayer Mini Demo"));
Serial.println(F("Initializing DFPlayer ... (May take 3~5 seconds)"));
if (!myDFPlayer.begin(mySoftwareSerial)) { //Use softwareSerial to communicate with mp3.
Serial.println(F("Unable to begin:"));
Serial.println(F("1.Please recheck the connection!"));
Serial.println(F("2.Please insert the SD card!"));
while (true);
}
Serial.println(F("DFPlayer Mini online."));
myDFPlayer.volume(30); //Set volume value. From 0 to 30
myDFPlayer.play(1); //Play the first mp3
pinMode(bPinOne, INPUT_PULLUP);
pinMode(bPinTwo, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(bPinOne), bSwitchOne, CHANGE);
attachInterrupt(digitalPinToInterrupt(bPinTwo), bSwitchTwo, CHANGE);
pixels.begin();
pixels.show();
}
void loop(){
if(currentState == 3){
myDFPlayer.play(1);
}
if (currentState == 1){
myDFPlayer.pause();
rainbow(20);
} else if (currentState == 2){
pixelOff();
myDFPlayer.start();
}
if (myDFPlayer.available()) {
printDetail(myDFPlayer.readType(), myDFPlayer.read()); //Print the detail message from DFPlayer to handle different errors and states.
}
}
void bSwitchOne() {
unsigned long now = millis();
if (lastSampleTime + sampleInterval < now) {
lastSampleTime = now;
bCountOne++;
bStateOne = true;
Serial.print("button one: ");
Serial.println(bCountOne);
if (bCountOne % 2 == 1){
currentState = 1;
} else if (bCountOne % 2 == 0){
currentState = 2;
}
}
}
void bSwitchTwo() {
unsigned long now = millis();
if (lastSampleTime + sampleInterval < now) {
lastSampleTime = now;
bCountTwo++;
bStateTwo = true;
Serial.print("button two: ");
Serial.println(bCountTwo);
if (bCountTwo % 2 == 1){
currentState = 3;
} else if (bCountTwo % 2 == 0){
currentState = 4;
}
}
}
void rainbow(uint8_t wait) {
uint16_t i, j;
for (j = 0; j < 256; j++) {
for (i = 0; i < pixels.numPixels(); i++) {
pixels.setPixelColor(i, Wheel((i + j) & 255));
}
pixels.show();
delay(wait);
}
}
void pixelOff() {
for (int i = 0; i < pixels.numPixels(); i++) {
pixels.setPixelColor(i, (0, 0, 0));
}
pixels.show();
}
uint32_t Wheel(byte WheelPos) {
WheelPos = 255 - WheelPos;
if (WheelPos < 85) {
return pixels.Color(255 - WheelPos * 3, 0, WheelPos * 3);
}
if (WheelPos < 170) {
WheelPos -= 85;
return pixels.Color(0, WheelPos * 3, 255 - WheelPos * 3);
}
WheelPos -= 170;
return pixels.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
}
void printDetail(uint8_t type, int value) {
switch (type) {
case TimeOut:
Serial.println(F("Time Out!"));
break;
case WrongStack:
Serial.println(F("Stack Wrong!"));
break;
case DFPlayerCardInserted:
Serial.println(F("Card Inserted!"));
break;
case DFPlayerCardRemoved:
Serial.println(F("Card Removed!"));
break;
case DFPlayerCardOnline:
Serial.println(F("Card Online!"));
break;
case DFPlayerPlayFinished:
Serial.print(F("Number:"));
Serial.print(value);
Serial.println(F(" Play Finished!"));
break;
case DFPlayerError:
Serial.print(F("DFPlayerError:"));
switch (value) {
case Busy:
Serial.println(F("Card not found"));
break;
case Sleeping:
Serial.println(F("Sleeping"));
break;
case SerialWrongStack:
Serial.println(F("Get Wrong Stack"));
break;
case CheckSumNotMatch:
Serial.println(F("Check Sum Not Match"));
break;
case FileIndexOut:
Serial.println(F("File Index Out of Bound"));
break;
case FileMismatch:
Serial.println(F("Cannot Find File"));
break;
case Advertise:
Serial.println(F("In Advertise"));
break;
default:
break;
}
break;
default:
break;
}
}