Skip to content

Instantly share code, notes, and snippets.

@ItsMichal
Created December 14, 2021 20:37
Show Gist options
  • Save ItsMichal/a0e3c76776388fc8ad6c5e681297bef3 to your computer and use it in GitHub Desktop.
Save ItsMichal/a0e3c76776388fc8ad6c5e681297bef3 to your computer and use it in GitHub Desktop.
Pressure Puncher Code!
/*
* PressurePuncher Code v1
* by Michal Bodzianowski - 2021
*/
//Library Imports
#include <Arduino_LSM6DS3.h>
#include <Adafruit_NeoPixel.h>
#include <map>
#include <MadgwickAHRS.h>
#include <SamdAudio.h>
#include <SdFat.h>
#include <SPI.h>
//Our pins-
// LED 9
// SCK 13
// MISO 12
// MOSI 11
// CS 10
const uint8_t SD_CS_PIN = 10; //CS pin on the SD card reader
const unsigned int sampleRate = 41000; //Sample rate. All clips are 41khz mono
#define AUDIO_BUFFER_SIZE 1024 //Audio buffer size
#define NUM_AUDIOCHAN 4 //Audio channels. Default is 4. 0 is reserved for BG music.
#define SAMPLE_RATE 10 //Sample Rate for IMU
#define LED_PIN 9 //Pin for the LED strip
#define NUM_PIXELS 30 //Number of LED pixel
#define ALPHA 0.95 // Smoothing factor for input - 0-1, 0 more smooth, 1 less smooth
float ax,ay,az; //Raw accelerometer values
float gx,gy,gz; //Raw gyrometer values
// int degreesX = 0; //DEPREC
// int degreesY = 0; //DEPREC
//Tracks whether on cooldown so audio doesn't spam
bool cooldown = false;
//Current audio channel- we alternate
//so audios don't overwrite each other
int curChannel = 1;
//Global timer
int timer = 0;
//Smoothed Pitch, Yaw, and Roll values
float ppitch = 0, pyaw = 0, proll = 0;
float pitch = 0, yaw = 0, roll = 0;
int lastHit =0;
SamdAudio AudioPlayer; //The AudioPlayer object.
SdFat memory; //the sd card object to use for all our file access
Madgwick filter; // Madgwick Algorithm filter to interpret IMU values
Adafruit_NeoPixel ledStrip(NUM_PIXELS, LED_PIN, NEO_GRB + NEO_KHZ800); //LEDstrip object
//Using code reference from https://github.com/hydronics2/SamdAudio/blob/master/examples/play_wav_from_SD_card/play_wav_from_SD_card.ino
//First time setup
void setup() {
//Set SD card to output
pinMode(SD_CS_PIN, OUTPUT);
//Begin serial monitoring
Serial.begin(115200);
// while(!Serial); //DEBUG - comment for production
//Begin the madgwick filtering
filter.begin(SAMPLE_RATE);
// Initialize SD card
Serial.print("Initializing SD card...");
//Look for SD card
bool sdGood = memory.begin(SD_CS_PIN, SD_SCK_MHZ(12));
while ( !sdGood ) //this command blocks if there is no sd card inserted
{
Serial.println(F("Unable To read SD card"));
delay(1000);
sdGood = memory.begin(SD_CS_PIN, SD_SCK_MHZ(12));
}
Serial.println(F("SD Ready"));
// Set up AudioPlayer
Serial.print("Initializing SD card...");
if (AudioPlayer.begin(sampleRate, NUM_AUDIOCHAN, AUDIO_BUFFER_SIZE) == -1)
{
Serial.println(" failed!");
return;
}
Serial.println(" done.");
//Play initial BGM
playInitialAudio();
//Make IMU
if (!IMU.begin()) {
Serial.println("Failed to initialize IMU!");
while (1);
}
//Begin LED Strip
ledStrip.begin();
}
void loop() {
determineCooldown();
readAngle();
basicModeLoop();
// lightLoop();
timer++;
}
void playInitialAudio(){
AudioPlayer.play("wiibox.wav", 0);
AudioPlayer.play("intro.wav", 3);
}
void determineCooldown(){
//Cooldown checker
if(cooldown){
cooldown = !offCooldown();
}else{
cooldown = detectHit();
}
}
//Code from woolseyworkshop.com/2020/02/12/using-the-arduino_lsm6ds3-library-to-access-the-arduino-uno-wifi-rev2-imu/
void readAngle(){
static unsigned long previousTime = millis();
unsigned long currentTime = millis();
if (currentTime - previousTime >= 1000/SAMPLE_RATE) {
// printValues(); //DEBUG
printRotationAngles();
previousTime = millis();
}
}
//Audio Helper function
void playAudio(const char* audioName){
AudioPlayer.play(audioName, curChannel);
curChannel++;
if(curChannel > NUM_AUDIOCHAN - 1){
curChannel = 1;
}
}
//Print the rotation angles for debugging
void printRotationAngles() {
char buffer[5];
float ax, ay, az;
float gx, gy, gz;
if (IMU.accelerationAvailable() && IMU.gyroscopeAvailable()
&& IMU.readAcceleration(ax, ay, az) && IMU.readGyroscope(gx, gy, gz)) {
filter.updateIMU(gx, gy, gz, ax, ay, az);
proll = roll;
ppitch = pitch;
pyaw = yaw;
//Weighted
roll = filter.getRoll() * ALPHA + (1-ALPHA) * roll;
pitch = filter.getPitch() * ALPHA + (1-ALPHA) * pitch;
yaw = filter.getYaw() * ALPHA + (1-ALPHA) * yaw;
// Serial.print("Roll = ");
// Serial.print(abs(proll-roll));
// Serial.print(" °, ");
// Serial.print("Pitch = ");
// Serial.print(abs(ppitch-pitch));
// Serial.print(" °, ");
// Serial.print("Yaw = ");
// Serial.print(abs(pyaw-yaw));
// Serial.println(" °");
}
}
bool offCooldown(){
if(abs(pyaw-yaw) < 15 && abs(proll-roll) < 15){
return true;
}else{
return false;
}
}
bool detectHit(){
if((abs(pyaw-yaw) > 25 && abs(pyaw-yaw) < 200) || (abs(proll-roll) > 25 && abs(proll-roll) < 200)){
return true;
}else{
return false;
}
}
void lightAllLEDs(int r, int g, int b){
for(int i = 0; i < NUM_PIXELS; i++){
ledStrip.setPixelColor(i,r,g,b);
}
ledStrip.show();
}
void lightLEDRange(int r, int g, int b, int start, int end){
for(int i = start; i < end; i++){
ledStrip.setPixelColor(i,r,g,b);
}
ledStrip.show();
}
int curLed = 0;
int curHue = 0;
void lightLoop(){
// if(timer % 500 == 0){
int H=curHue;
int S=100;
int V=100;
float s = S/100;
float v = V/100;
float C = s*v;
float X = C*(1-abs(fmod(H/60.0, 2)-1));
float m = v-C;
float r,g,b;
if(H >= 0 && H < 60){
r = C,g = X,b = 0;
}
else if(H >= 60 && H < 120){
r = X,g = C,b = 0;
}
else if(H >= 120 && H < 180){
r = 0,g = C,b = X;
}
else if(H >= 180 && H < 240){
r = 0,g = X,b = C;
}
else if(H >= 240 && H < 300){
r = X,g = 0,b = C;
}
else{
r = C,g = 0,b = X;
}
int R = (r+m)*255;
int G = (g+m)*255;
int B = (b+m)*255;
// Serial.println("DEBUG");
// Serial.println(R);
// Serial.println(G);
// Serial.println(B);
lightLEDRange(R, G, B, 0, 30);
curHue+=20;
curLed++;
if(curHue > 360){
curHue =0;
}
if(curLed > NUM_PIXELS-1){
curLed =0;
}
// }
}
void playRandomAudio(){
const char* audioNames[] = {"calm-down.wav", "classic_hurt.wav", "gnome.wav", "mario.wav", "scout.wav", "wow.wav"};
playAudio(audioNames[random(6)]);
}
void basicModeLoop(){
int back = map(roll, -10, 50, 0, 255);
int forward = map(roll, -10, -100, 0, 255);
int left = map(yaw, 60, 10, 0,255);
int right = map(yaw, 60, 200, 0,255);
// int negpitchr = map(roll, 0, -100, 0, 255);
// Serial.print("Roll - ");
// Serial.println(roll);
// Serial.print("Yaw -");
// Serial.println(yaw);
ledStrip.clear();
if(detectHit() && !cooldown){
lightLoop();
playRandomAudio();
}
}
//https://www.codespeedy.com/hsv-to-rgb-in-cpp/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment