- commit
- 4068174
- parent
- e58a19a
- author
- Neale Pickett
- date
- 2016-10-02 11:59:11 -0600 MDT
Added wand and 7seg displays
5 files changed,
+201,
-29
+65,
-26
1@@ -10,26 +10,44 @@
2 #include "Synchrotron.h"
3
4 // Music Player
5-#define MUSIC_CS 7
6-#define MUSIC_DATA 6
7-#define MUSIC_CARDCS 4
8-#define MUSIC_REQ 3
9+#define MUSIC_MCS 7
10+#define MUSIC_DCS 6
11+#define MUSIC_CCS 4
12+#define MUSIC_DRQ 0 // Cut trace on board and wire to 0, so you can use 3 for SPI
13 MusicPlayer *music;
14
15+// LED output scaling
16+#define brightness 255
17+
18 // Synchrotron
19 #define SYNC1_NPIXELS 24
20 #define SYNC1_DATA 5
21 Synchrotron *sync1;
22
23+// Neutrona Wand
24+#define WAND1_NPIXELS 14
25+#define WAND1_DATA 9
26+Synchrotron *wand1;
27+
28+// Displays
29+Adafruit_7segment disp1;
30+Adafruit_7segment disp2;
31+
32 // Debug LED
33 #define DEBUG 13
34
35 // Inputs
36 #define TRIGGER 8
37+#define POT1 A0
38
39 // global time counter
40 unsigned long jiffies = 0;
41
42+// 6 seems to be about what my overly-critical brain needs to buffer out
43+// any delays caused by NMI sections of music player code so that they're unnoticeable
44+#define MILLIS_PER_JIFFY 6
45+
46+
47 void setup() {
48 randomSeed(analogRead(12));
49
50@@ -40,10 +58,20 @@ void setup() {
51 pinMode(DEBUG, OUTPUT);
52
53 // music player, this sets up SPI for us
54- music = new MusicPlayer(MUSIC_CS, MUSIC_DATA, MUSIC_REQ, MUSIC_CARDCS);
55+ music = new MusicPlayer(MUSIC_MCS, MUSIC_DCS, MUSIC_DRQ, MUSIC_CCS);
56
57 // synchrotron
58 sync1 = new Synchrotron(SYNC1_NPIXELS, SYNC1_DATA);
59+
60+ // nuetrona wand
61+ wand1 = new Synchrotron(WAND1_NPIXELS, WAND1_DATA);
62+
63+ // 7segment displays
64+ disp1 = Adafruit_7segment();
65+ disp1.begin(0x70);
66+
67+ disp2 = Adafruit_7segment();
68+ disp2.begin(0x71);
69 }
70
71
72@@ -56,39 +84,39 @@ void flashDebug() {
73
74 void loop() {
75 static int state = 0;
76- // 6 seems to be about what my overly-critical brain needs to buffer out
77- // any music player delays so that they're unnoticeable
78- unsigned long new_jiffies = millis() / 6;
79+ static float disp2val = 40.83;
80+ unsigned long new_jiffies = millis() / MILLIS_PER_JIFFY;
81 boolean trigger = ! digitalRead(TRIGGER);
82
83 music->poll(jiffies);
84
85 switch (state) {
86- case 0:
87- if (trigger && music->startPlayingFile("track001.mp3")) {
88- state = 1;
89- sync1->charge();
90- }
91+ case 0: // move to steady state
92+ sync1->transition(400, 12, brightness, 0, 0);
93+ wand1->transition(400, 24, brightness, 0, 0);
94+ state = 10;
95 break;
96- case 1:
97- if (! music->isPlaying()) {
98- state = 3;
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 3:
107- if (trigger && music->startPlayingFile("track003.mp3")) {
108- state = 4;
109- sync1->fire();
110+ case 20: // charge button pressed
111+ if (sync1->transitioned()) {
112+ state = 30;
113 }
114 break;
115- case 4:
116- if (! trigger && music->startPlayingFile("track002.mp3")) {
117- state = 5;
118- sync1->discharge();
119+ case 30: // waiting for fire button
120+ if (trigger && music->startPlayingFile("nutrona.mp3")) {
121+ state = 40;
122+ sync1->transition(40, 1, brightness/8, brightness/4, brightness/2);
123+ wand1->transition(40, 5, brightness/6, brightness/2, brightness/6);
124 }
125 break;
126- case 5:
127- if (! music->isPlaying()) {
128+ case 40: // fire button pressed
129+ if (! trigger && music->startPlayingFile("track002.mp3")) {
130 state = 0;
131 }
132 break;
133@@ -97,6 +125,17 @@ void loop() {
134 if (new_jiffies > jiffies) {
135 jiffies = new_jiffies;
136 sync1->tick(jiffies);
137+ wand1->tick(jiffies);
138+
139+ if (jiffies % 10 == 0) {
140+ // This is expensive
141+ disp1.printFloat(5198 * sync1->speed());
142+ disp1.writeDisplay();
143+
144+ disp2val = analogRead(POT1) / 10.0;
145+ disp2.printFloat(disp2val, 1);
146+ disp2.writeDisplay();
147+ }
148 flashDebug();
149 }
150 }
+14,
-3
1@@ -39,12 +39,22 @@ Synchrotron::transition(int duration, int final_tickrate, byte final_r, byte fin
2 initial_b = b;
3 }
4
5+bool
6+Synchrotron::transitioned() {
7+ return (transition_elapsed >= transition_length);
8+}
9+
10+float
11+Synchrotron::speed() {
12+ return 1 / ftickrate;
13+}
14+
15 Synchrotron::standby() {
16 transition(400, 12, brightness, 0, 0);
17 }
18
19 Synchrotron::charge() {
20- transition(400, 2, brightness, brightness/8, 0);
21+ transition(700, 2, brightness, brightness/8, 0);
22 }
23
24 Synchrotron::fire() {
25@@ -75,10 +85,11 @@ Synchrotron::tick(unsigned long jiffies) {
26 }
27
28 if (transition_length > transition_elapsed) {
29- tickrate = initial_tickrate + (dtickrate * transition_elapsed);
30+ transition_elapsed += 1;
31+ ftickrate = initial_tickrate + (dtickrate * transition_elapsed);
32+ tickrate = ftickrate;
33 r = initial_r + (dr * transition_elapsed);
34 g = initial_g + (dg * transition_elapsed);
35 b = initial_b + (db * transition_elapsed);
36- transition_elapsed += 1;
37 }
38 }
+3,
-0
1@@ -14,9 +14,12 @@ class Synchrotron {
2 int transition_length, transition_elapsed;
3 int initial_tickrate, initial_r, initial_g, initial_b;
4 float dtickrate, dr, dg, db;
5+ float ftickrate;
6 public:
7 Synchrotron(uint16_t n, uint8_t p=6, neoPixelType t=NEO_GRB + NEO_KHZ800);
8 transition(int duration, int final_tickrate, byte final_r, byte final_g, byte final_b);
9+ bool transitioned();
10+ float speed();
11 standby();
12 charge();
13 fire();
+0,
-0
+119,
-0
1@@ -0,0 +1,119 @@
2+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
3+<!-- Created with Inkscape (http://www.inkscape.org/) -->
4+
5+<svg
6+ xmlns:dc="http://purl.org/dc/elements/1.1/"
7+ xmlns:cc="http://creativecommons.org/ns#"
8+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
9+ xmlns:svg="http://www.w3.org/2000/svg"
10+ xmlns="http://www.w3.org/2000/svg"
11+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
12+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
13+ width="141.89731mm"
14+ height="141.89731mm"
15+ viewBox="0 0 502.78573 502.78572"
16+ id="svg2"
17+ version="1.1"
18+ inkscape:version="0.91 r13725"
19+ sodipodi:docname="radlove.svg">
20+ <defs
21+ id="defs4" />
22+ <sodipodi:namedview
23+ id="base"
24+ pagecolor="#ffffff"
25+ bordercolor="#666666"
26+ borderopacity="1.0"
27+ inkscape:pageopacity="0.0"
28+ inkscape:pageshadow="2"
29+ inkscape:zoom="1.4"
30+ inkscape:cx="240.22136"
31+ inkscape:cy="248.73745"
32+ inkscape:document-units="px"
33+ inkscape:current-layer="g4238"
34+ showgrid="false"
35+ fit-margin-top="0"
36+ fit-margin-left="0"
37+ fit-margin-right="0"
38+ fit-margin-bottom="0"
39+ inkscape:window-width="1920"
40+ inkscape:window-height="1016"
41+ inkscape:window-x="0"
42+ inkscape:window-y="27"
43+ inkscape:window-maximized="1" />
44+ <metadata
45+ id="metadata7">
46+ <rdf:RDF>
47+ <cc:Work
48+ rdf:about="">
49+ <dc:format>image/svg+xml</dc:format>
50+ <dc:type
51+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
52+ <dc:title></dc:title>
53+ </cc:Work>
54+ </rdf:RDF>
55+ </metadata>
56+ <g
57+ inkscape:label="Layer 1"
58+ inkscape:groupmode="layer"
59+ id="layer1"
60+ transform="translate(-120.0357,-286.68361)">
61+ <g
62+ id="g4238">
63+ <circle
64+ r="242.39842"
65+ cy="538.07648"
66+ cx="371.42856"
67+ id="path4136"
68+ style="opacity:1;fill:#ffff00;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:17.98888016;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" />
69+ <path
70+ d="m 479.19755,351.41513 a 215.53796,215.53796 0 0 1 107.76897,186.66135 l -215.53796,0 z"
71+ sodipodi:end="0"
72+ sodipodi:start="5.2359878"
73+ sodipodi:ry="215.53796"
74+ sodipodi:rx="215.53796"
75+ sodipodi:cy="538.07648"
76+ sodipodi:cx="371.42856"
77+ sodipodi:type="arc"
78+ style="opacity:1;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:15.9955101;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none"
79+ id="circle4161" />
80+ <path
81+ d="M 155.89059,538.07647 A 215.53796,215.53796 0 0 1 263.65958,351.41513 l 107.76898,186.66135 z"
82+ sodipodi:end="4.1887902"
83+ sodipodi:start="3.1415927"
84+ sodipodi:ry="215.53796"
85+ sodipodi:rx="215.53796"
86+ sodipodi:cy="538.07648"
87+ sodipodi:cx="371.42856"
88+ sodipodi:type="arc"
89+ id="path4163"
90+ style="opacity:1;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:15.9955101;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" />
91+ <path
92+ style="opacity:1;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:15.9955101;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none"
93+ id="path4165"
94+ sodipodi:type="arc"
95+ sodipodi:cx="371.42856"
96+ sodipodi:cy="538.07648"
97+ sodipodi:rx="215.53796"
98+ sodipodi:ry="215.53796"
99+ sodipodi:start="1.0471976"
100+ sodipodi:end="2.0943951"
101+ d="m 479.19753,724.73783 a 215.53796,215.53796 0 0 1 -215.53795,0 L 371.42856,538.07648 Z" />
102+ </g>
103+ <g
104+ transform="matrix(0.79020839,0,0,0.79020839,-76.502899,240.96985)"
105+ inkscape:label="Layer 1"
106+ id="layer1-7">
107+ <g
108+ transform="matrix(0.97556,0,0,0.97556,-18.264,24.845)"
109+ style="stroke:#af024c;stroke-width:2.87529993"
110+ id="g17152">
111+ <path
112+ d="m 540.37525,265.35878 c -29.691,0.61893 -55.518,19.25 -64.878,50.794 -15.808,81.974 75.349,116.47 125.55,165.46 43.586,-56.698 128.92,-71.353 124.66,-155.21 -3.7056,-18.7 -14.155,-33.925 -28.166,-44.632 -18.775,-14.365 -44.927,-19.303 -67.275,-10.718 -11.956,4.22 -22.844,11.552 -30.981,21.271 -14.141,-17.43 -36.494,-27.452 -58.909,-26.962 z"
113+ style="fill:#d40055;stroke:#000000;stroke-width:15.06948352;stroke-miterlimit:4;stroke-dasharray:none"
114+ sodipodi:nodetypes="cccccccc"
115+ id="path8148"
116+ inkscape:connector-curvature="0" />
117+ </g>
118+ </g>
119+ </g>
120+</svg>