Neale Pickett
·
2016-10-02
ProtonPack.ino
1// Proton Pack with NeoPixels
2// Boy howdy do these make everything easy
3
4#include <SPI.h>
5#include <Wire.h>
6#include <Adafruit_NeoPixel.h>
7#include <Adafruit_LEDBackpack.h>
8#include <Adafruit_GFX.h>
9#include "MusicPlayer.h"
10#include "Synchrotron.h"
11
12// Music Player
13#define MUSIC_MCS 7
14#define MUSIC_DCS 6
15#define MUSIC_CCS 4
16#define MUSIC_DRQ 0 // Cut trace on board and wire to 0, so you can use 3 for SPI
17MusicPlayer *music;
18
19// LED output scaling
20#define brightness 255
21
22// Synchrotron
23#define SYNC1_NPIXELS 24
24#define SYNC1_DATA 5
25Synchrotron *sync1;
26
27// Neutrona Wand
28#define WAND1_NPIXELS 14
29#define WAND1_DATA 9
30Synchrotron *wand1;
31
32// Displays
33Adafruit_7segment disp1;
34Adafruit_7segment disp2;
35
36// Debug LED
37#define DEBUG 13
38
39// Inputs
40#define TRIGGER 8
41#define POT1 A0
42
43// global time counter
44unsigned long jiffies = 0;
45
46// 6 seems to be about what my overly-critical brain needs to buffer out
47// any delays caused by NMI sections of music player code so that they're unnoticeable
48#define MILLIS_PER_JIFFY 6
49
50
51void setup() {
52 randomSeed(analogRead(12));
53
54 // inputs
55 pinMode(TRIGGER, INPUT_PULLUP);
56
57 // outputs
58 pinMode(DEBUG, OUTPUT);
59
60 // music player, this sets up SPI for us
61 music = new MusicPlayer(MUSIC_MCS, MUSIC_DCS, MUSIC_DRQ, MUSIC_CCS);
62
63 // synchrotron
64 sync1 = new Synchrotron(SYNC1_NPIXELS, SYNC1_DATA);
65
66 // nuetrona wand
67 wand1 = new Synchrotron(WAND1_NPIXELS, WAND1_DATA);
68
69 // 7segment displays
70 disp1 = Adafruit_7segment();
71 disp1.begin(0x70);
72
73 disp2 = Adafruit_7segment();
74 disp2.begin(0x71);
75}
76
77
78void flashDebug() {
79 uint8_t val;
80
81 val = (jiffies % 100) < 50;
82 digitalWrite(DEBUG, val);
83}
84
85void loop() {
86 static int state = 0;
87 static float disp2val = 40.83;
88 unsigned long new_jiffies = millis() / MILLIS_PER_JIFFY;
89 boolean trigger = ! digitalRead(TRIGGER);
90
91 music->poll(jiffies);
92
93 switch (state) {
94 case 0: // move to steady state
95 sync1->transition(400, 12, brightness, 0, 0);
96 wand1->transition(400, 24, brightness, 0, 0);
97 state = 10;
98 break;
99 case 10: // waiting for charge button
100 if (trigger && sync1->transitioned() && music->startPlayingFile("track001.mp3")) {
101 state = 20;
102 sync1->transition(700, 2, brightness, brightness/8, 0);
103 wand1->transition(700, 10, brightness, brightness/8, 0);
104 }
105 break;
106 case 20: // charge button pressed
107 if (sync1->transitioned()) {
108 state = 30;
109 }
110 break;
111 case 30: // waiting for fire button
112 if (trigger && music->startPlayingFile("nutrona.mp3")) {
113 state = 40;
114 sync1->transition(40, 1, brightness/8, brightness/4, brightness/2);
115 wand1->transition(40, 5, brightness/6, brightness/2, brightness/6);
116 }
117 break;
118 case 40: // fire button pressed
119 if (! trigger && music->startPlayingFile("track002.mp3")) {
120 state = 0;
121 }
122 break;
123 }
124
125 if (new_jiffies > jiffies) {
126 jiffies = new_jiffies;
127 sync1->tick(jiffies);
128 wand1->tick(jiffies);
129
130 if (jiffies % 10 == 0) {
131 // This is expensive
132 disp1.printFloat(5198 * sync1->speed());
133 disp1.writeDisplay();
134
135 disp2val = analogRead(POT1) / 10.0;
136 disp2.printFloat(disp2val, 1);
137 disp2.writeDisplay();
138 }
139 flashDebug();
140 }
141}
142