Created
September 1, 2019 03:21
-
-
Save dragonlock2/43a271a353125fc9af5b1cd2af89acf9 to your computer and use it in GitHub Desktop.
Code for my 4th gen Arduino based lightsaber.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <TMRpcm.h> | |
#include <SdFat.h> | |
//#include <CapacitiveSensor.h> | |
File file; | |
SdFat SD; | |
TMRpcm audio; | |
//CapacitiveSensor top = CapacitiveSensor(A0, A1); //20M resistor between, antenna on A1 | |
//CapacitiveSensor bot = CapacitiveSensor(A3, A2); //20M resistor between, antenna on A2 | |
const byte clashSens = 7; //medium sensor | |
const byte swingSens = 2; //fast sensor | |
const byte blade = 3; | |
const byte acc1 = 5; | |
const byte acc2 = 6; | |
//constants | |
int ON_TIME; //delay when turning on | |
int OFF_TIME; // delay when turning off | |
int BLASTER_DELAY; //min time to play lockup | |
const int ACCENT_DELAY = 7; | |
int TOP; //for capacitive switches | |
int BOT; | |
//local variables | |
boolean state = false; | |
long pulseTime; //used to keep track of time while fading | |
boolean goinDown; //check if fade up or down | |
byte curBrightBlade; | |
long blasterTime; //check to see if pressed long enough to play lockup | |
byte curBrightAcc1 = 255; | |
//byte curBrightAcc2 = 255; | |
long accTime = 0; | |
boolean accDown = true; | |
//int diff; //for cap switch | |
//long total1; | |
//long total2; | |
//attribute stuff | |
byte font; | |
byte numBoot; | |
byte numClash; | |
byte numOff; | |
byte numOn; | |
byte numSwing; | |
byte curVolume; | |
byte numBlast; | |
byte PULSE_DELAY; //length of pulse change from bright to dim of blade | |
byte MIN_BRIGHT_BLADE; //from 0-255 | |
const int MAX_BRIGHT_BLADE = 255; | |
const int MIN_BRIGHT_ACC1 = 128; | |
//const int MIN_BRIGHT_ACC2 = 128; | |
//used to get config stuff | |
const char configFile[11] = "config.txt"; | |
const char setFont[8] = "set.txt"; | |
char blast[11] = "blast0.wav"; | |
char zero = '0'; | |
char newLine = '\n'; | |
char boot[16]; | |
char clash[17]; | |
char hum[14]; | |
char lockup[17]; | |
char off[15]; | |
char on[14]; | |
char swing[17]; | |
const int factor = 4; //factor to change delay bc pwm | |
void setup() { | |
//Serial.begin(9600); | |
TCCR2B = TCCR2B & B11111000 | B00000010; //set pwm to inaudible | |
TCCR0B = TCCR0B & B11111000 | B00000010; //why all delays are xfactor | |
pinMode(A0, OUTPUT); | |
pinMode(A3, OUTPUT); | |
digitalWrite(A0, HIGH); | |
digitalWrite(A3, HIGH); | |
pinMode(acc1, OUTPUT); | |
pinMode(acc2, OUTPUT); | |
//analogWrite(acc1, curBrightAcc1); | |
//analogWrite(acc2, curBrightAcc1); | |
//top.set_CS_AutocaL_Millis(0xFFFFFFFF); | |
//bot.set_CS_AutocaL_Millis(0xFFFFFFFF); | |
SD.begin(8, SPI_FULL_SPEED); | |
pinMode(clashSens, INPUT_PULLUP); | |
pinMode(swingSens, INPUT_PULLUP); | |
audio.speakerPin = 9; | |
pinMode(10, OUTPUT); | |
audio.setVolume(3); | |
//audio.quality(1); //not sure if affects ram usage or speed | |
delay(50*factor); | |
getSwitchAttributes(); | |
//BOT = -1000; //testing purposes | |
//TOP = 1000; | |
//getDiff(); getDiff(); //do twice | |
if(topSW()) { | |
audio.play("choose.wav", 0); | |
while(audio.isPlaying(0)); | |
chooseFont(); | |
} | |
delay(50*factor); | |
getAttributes(); | |
audio.setVolume(curVolume); | |
randomSeed(analogRead(A5)); | |
boot[10] = zero + random(0, numBoot); | |
audio.play(boot, 0); | |
while(audio.isPlaying(0)); | |
audio.loop(1, 1); | |
//BOT = -200; //testing purposes | |
//TOP = 200; | |
} | |
void loop() { | |
if(topSW()) { //check activation | |
state = !state; | |
if(state) | |
onAnim(); | |
else | |
offAnim(); | |
} | |
if(state) { //if on do this stuff //when on accents and blade have same brightness | |
if(botSW()) { | |
blasterTime = millis(); | |
while(botSW()) { | |
delay(10); //debounce | |
if(millis() - blasterTime >= BLASTER_DELAY * factor) { //lockup time | |
analogWrite(blade, MAX_BRIGHT_BLADE); | |
analogWrite(acc1, MAX_BRIGHT_BLADE); | |
analogWrite(acc2, MAX_BRIGHT_BLADE); | |
audio.play(lockup, 0); | |
audio.loop(1, 0); | |
while(botSW()); | |
audio.loop(0, 0); | |
} | |
} | |
if(millis() - blasterTime < BLASTER_DELAY * factor) { | |
analogWrite(blade, MAX_BRIGHT_BLADE); | |
analogWrite(acc1, MAX_BRIGHT_BLADE); | |
analogWrite(acc2, MAX_BRIGHT_BLADE); | |
blast[5] = zero + random(0, numBlast); //need to make settable | |
audio.play(blast, 0); | |
while(audio.isPlaying(0)); | |
analogWrite(blade, curBrightBlade); | |
analogWrite(acc1, curBrightBlade); | |
analogWrite(acc2, curBrightBlade); | |
} | |
audio.stopPlayback(0); | |
} | |
if(!digitalRead(swingSens) && digitalRead(clashSens)) { //make sure its only a swing | |
swing[11] = zero + random(0, numSwing); | |
audio.play(swing, 0); | |
Serial.println("swing"); | |
while(audio.isPlaying(0)) | |
updateBlade(); | |
} | |
if(!digitalRead(clashSens)) { | |
Serial.println("clash"); | |
analogWrite(blade, MAX_BRIGHT_BLADE); | |
analogWrite(acc1, MAX_BRIGHT_BLADE); | |
analogWrite(acc2, MAX_BRIGHT_BLADE); | |
clash[11] = zero + random(0, numClash); | |
audio.play(clash, 0); | |
while(audio.isPlaying(0)); | |
analogWrite(blade, curBrightBlade); | |
analogWrite(acc1, curBrightBlade); | |
analogWrite(acc2, curBrightBlade); | |
} | |
updateBlade(); | |
} | |
//Serial.println(diff); | |
if(!state) updateAccents(); | |
} | |
void onAnim() { | |
on[8] = zero + random(0, numOn); | |
audio.play(on, 0); | |
for(int i = 0; i <= MAX_BRIGHT_BLADE; i++) { | |
analogWrite(blade, i); | |
if(i > curBrightAcc1) { | |
analogWrite(acc1, i); | |
analogWrite(acc2, i); | |
} | |
delay(ON_TIME/(MAX_BRIGHT_BLADE + 1)*factor); | |
} | |
audio.play(hum, 1); | |
goinDown = true; | |
curBrightBlade = MAX_BRIGHT_BLADE; | |
while(audio.isPlaying(0)) | |
updateBlade(); | |
} | |
void offAnim() { | |
off[9] = zero + random(0, numOff); | |
audio.play(off, 0); | |
audio.stopPlayback(1); | |
for(int i = curBrightBlade; i >= 0; i--) { | |
analogWrite(blade, i); | |
analogWrite(acc1, i); | |
analogWrite(acc2, i); | |
delay(OFF_TIME/(curBrightBlade + 1)*factor); | |
} | |
while(audio.isPlaying()); | |
for(int i = 0; i <= curBrightAcc1; i++) { | |
analogWrite(acc1, i); | |
analogWrite(acc2, i); | |
delay(ACCENT_DELAY*factor); | |
} | |
} | |
/* | |
void getDiff() { | |
total1 = top.capacitiveSensorRaw(15); | |
total2 = bot.capacitiveSensorRaw(15); | |
diff = total1 - total2; | |
} | |
*/ | |
bool topSW() { | |
return analogRead(A2) < TOP; | |
} | |
bool botSW() { | |
return analogRead(A1) < BOT; | |
} | |
void updateBlade() { | |
if(millis() - pulseTime >= PULSE_DELAY*factor) { | |
pulseTime = millis(); | |
if(goinDown) { | |
curBrightBlade--; | |
if(curBrightBlade <= MIN_BRIGHT_BLADE) { | |
goinDown = false; | |
curBrightBlade = MIN_BRIGHT_BLADE; | |
} | |
} else { | |
curBrightBlade++; | |
if(curBrightBlade >= MAX_BRIGHT_BLADE) { | |
goinDown = true; | |
curBrightBlade = MAX_BRIGHT_BLADE; | |
} | |
} | |
analogWrite(blade, curBrightBlade); | |
analogWrite(acc1, curBrightBlade); | |
analogWrite(acc2, curBrightBlade); | |
} | |
} | |
void updateAccents() { //currently making both same | |
/* | |
if(millis() - accTime >= ACCENT_DELAY*factor) { | |
accTime = millis(); | |
if(accDown) { | |
curBrightAcc1--; | |
if(curBrightAcc1 <= MIN_BRIGHT_ACC1) { | |
accDown = false; | |
curBrightAcc1 = MIN_BRIGHT_ACC1; | |
} | |
} else { | |
curBrightAcc1++; | |
if(curBrightAcc1 >= 255) { | |
accDown = true; | |
curBrightAcc1 = 255; | |
} | |
} | |
analogWrite(acc1, curBrightAcc1); | |
analogWrite(acc2, curBrightAcc1); | |
} | |
*/ | |
analogWrite(acc1, 255); | |
analogWrite(acc2, 255); | |
} | |
void chooseFont() { | |
file = SD.open(setFont); | |
font = (file.readStringUntil(newLine).charAt(0) - zero); //gets current font | |
file.close(); | |
file = SD.open(configFile); | |
int totalFont = file.readStringUntil(newLine).charAt(0) - zero; | |
file.close(); | |
char bootFile[16]; //files need to be char arrays | |
(String("font" + String(font) + F("/boot0.wav"))).toCharArray(bootFile, 16); | |
//Serial.println(font); | |
audio.play(bootFile); | |
while(!botSW()) { //waits for aux press to confirm font | |
if(topSW()) { //increments through fonts | |
font = (font + 1) % totalFont; | |
bootFile[4] = zero + font; | |
audio.play(bootFile); | |
//Serial.println(bootFile); | |
delay(250*factor); | |
} | |
} | |
saveFont(); | |
} | |
void saveFont() { | |
//Serial.println(font); | |
audio.play("selected.wav", 0); | |
while(audio.isPlaying(0)); | |
file = SD.open(setFont); | |
String selectedFont = file.readStringUntil(newLine); | |
selectedFont.setCharAt(0, zero + font); | |
file.close(); | |
SD.remove(setFont); | |
file = SD.open(setFont, FILE_WRITE); | |
file.println(selectedFont); | |
file.close(); | |
file = SD.open(setFont); //don't know why i have to open and close again | |
//while(file.available()) | |
// Serial.write(file.read()); | |
file.close(); | |
} | |
void getSwitchAttributes() { | |
file = SD.open(configFile); | |
file.readStringUntil(newLine); //skip the total font line; | |
TOP = file.readStringUntil(newLine).substring(0, 3).toInt(); | |
BOT = file.readStringUntil(newLine).substring(0, 3).toInt(); | |
//Serial.println(TOP); | |
//Serial.println(BOT); | |
} | |
void getAttributes() { | |
file = SD.open(setFont); | |
font = file.readStringUntil(newLine).charAt(0) - zero; | |
file.close(); | |
file = SD.open(configFile); | |
file.readStringUntil(newLine); //skip the total font line; | |
file.readStringUntil(newLine); //and switch lines | |
file.readStringUntil(newLine); | |
BLASTER_DELAY = file.readStringUntil(newLine).substring(0, 3).toInt(); | |
numBlast = file.readStringUntil(newLine).substring(0, 1).toInt(); | |
//TOP_ON = file.readStringUntil(newLine).substring(0, 3).toInt(); | |
file.close(); | |
String base; | |
base.reserve(7); | |
base = "font" + String(font) + F("/"); | |
char configFont[18]; //attribute file | |
(String(base + F("numbers.txt"))).toCharArray(configFont, 18); | |
file = SD.open(configFont); | |
numBoot = file.readStringUntil(newLine).charAt(0) - zero; | |
numClash = file.readStringUntil(newLine).charAt(0) - zero; | |
numOff = file.readStringUntil(newLine).charAt(0) - zero; | |
numOn = file.readStringUntil(newLine).charAt(0) - zero; | |
numSwing = file.readStringUntil(newLine).charAt(0) - zero; | |
curVolume = file.readStringUntil(newLine).charAt(0) - zero; | |
ON_TIME = file.readStringUntil(newLine).substring(0, 4).toInt(); | |
OFF_TIME = file.readStringUntil(newLine).substring(0, 4).toInt(); | |
PULSE_DELAY = file.readStringUntil(newLine).substring(0, 2).toInt(); | |
MIN_BRIGHT_BLADE = file.readStringUntil(newLine).substring(0, 3).toInt(); | |
MIN_BRIGHT_BLADE = MAX_BRIGHT_BLADE * MIN_BRIGHT_BLADE / 100; //calculate now so not later | |
file.close(); | |
String manip; | |
manip.reserve(18); | |
manip = base + F("boot0.wav"); | |
manip.toCharArray(boot, 16); | |
manip = base + F("clash0.wav"); | |
manip.toCharArray(clash, 17); | |
manip = base + F("hum.wav"); | |
manip.toCharArray(hum, 14); | |
manip = base + F("lockup.wav"); | |
manip.toCharArray(lockup, 17); | |
manip = base + F("off0.wav"); | |
manip.toCharArray(off, 15); | |
manip = base + F("on0.wav"); | |
manip.toCharArray(on, 14); | |
manip = base + F("swing0.wav"); | |
manip.toCharArray(swing, 17); | |
/* | |
Serial.println(boot); | |
Serial.println(clash); | |
Serial.println(hum); | |
Serial.println(lockup); | |
Serial.println(off); | |
Serial.println(on); | |
Serial.println(swing); */ | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment