-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathPlaytune_poll.h
211 lines (167 loc) · 6.02 KB
/
Playtune_poll.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
// Playtune_poll.h
// Here is where you define the pin configuration for playing music. Because we use direct register
// manipulation for speed, it's a little complicated, so bear with me.
// First, define the number of channels (output pins), which is the maximum number of notes that
// you want to play simultaneously. This can be up to 16, but it's best for efficiency to not make
// it much bigger than what you will actually be using for the most complicated song.
#define MAX_CHANS 8 // maximum number of simultaneous notes
// Next, choose which set of pins in this file you want to use. This should match the processor
// chosen in the tools/board menu of the Arduino IDE (Integrated Development Environment).
#define ARDUINO_NANO // which set of pin definitions below to use
// Now define the output pin that is wired to the speaker for each channel in the section you chose.
// The pin numbers are the "virtual" numbers that typically are printed on the board and are used in
// digitalWrite() functions. Our channels are numbered in sequence starting with 0. Again, it's best
// not to assign too many more channels than you really intend to use.
// For Teensy 3.x and Teensy LC microcontrollers, which use an ARM processor, defining pins is not so bad.
// Just define one macro for each channel, as in the following example.
#ifdef TEENSY_LC // define 8 channels on a Teensy LC
#define CHAN_0_PIN 5
#define CHAN_1_PIN 6
#define CHAN_2_PIN 7
#define CHAN_3_PIN 8
#define CHAN_4_PIN 9
#define CHAN_5_PIN 10
#define CHAN_6_PIN 11
#define CHAN_7_PIN 12
#endif
#ifdef TEENSY_3x // define 8 channels on a Teensy 3.x
#define CHAN_0_PIN 5
#define CHAN_1_PIN 6
#define CHAN_2_PIN 7
#define CHAN_3_PIN 8
#define CHAN_4_PIN 9
#define CHAN_5_PIN 10
#define CHAN_6_PIN 11
#define CHAN_7_PIN 12
#endif
// For Arduino microcontrollers using an AVX processor, it's a little more complicated.
// For each channel, you need to give the pin number, the data register that it is wired
// to, and the number of the bit in that register that corresponds to the specific pin.
// You can get that information by looking at the schematic for the board, or from one
// of the detailed pinout diagrams like https://docs.arduino.cc/hardware/nano.
// I've included several examples below.
#ifdef ARDUNIO_MICRO // define 8 channels on an Arduino Micro
#define CHAN_0_PIN 5 // channel 0 outputs on pin 5,
#define CHAN_0_REG C // pin 5 is wired to register C,
#define CHAN_0_BIT 6 // and is bit 6 in that register
#define CHAN_1_PIN 6
#define CHAN_1_REG D
#define CHAN_1_BIT 7
#define CHAN_2_PIN 7
#define CHAN_2_REG E
#define CHAN_2_BIT 6
#define CHAN_3_PIN 8
#define CHAN_3_REG B
#define CHAN_3_BIT 4
#define CHAN_4_PIN 9
#define CHAN_4_REG B
#define CHAN_4_BIT 5
#define CHAN_5_PIN 10
#define CHAN_5_REG B
#define CHAN_5_BIT 6
#define CHAN_6_PIN 11
#define CHAN_6_REG B
#define CHAN_6_BIT 7
#define CHAN_7_PIN 12
#define CHAN_7_REG D
#define CHAN_7_BIT 6
#endif // Arduino Micro
#ifdef ARDUINO_NANO // define 8 channels on an Arduino Nano
#define CHAN_0_PIN 5 // channel 0 outputs on pin 5,
#define CHAN_0_REG D // pin 5 is wired to register D,
#define CHAN_0_BIT 5 // and is bit 5 in that register
#define CHAN_1_PIN 6
#define CHAN_1_REG D
#define CHAN_1_BIT 6
#define CHAN_2_PIN 7
#define CHAN_2_REG D
#define CHAN_2_BIT 7
#define CHAN_3_PIN 8
#define CHAN_3_REG B
#define CHAN_3_BIT 0
//#define CHAN_4_PIN 9 // conflicts with SERVO_PIN_A in PWMServo.h
//#define CHAN_4_REG B
//#define CHAN_4_BIT 1
#define CHAN_4_PIN 14 // use A0 instead
#define CHAN_4_REG C
#define CHAN_4_BIT 0
#define CHAN_5_PIN 10 // conflicts with SPI SS
#define CHAN_5_REG B
#define CHAN_5_BIT 2
#define CHAN_6_PIN 11 // conflicts with SPI MOSI
#define CHAN_6_REG B
#define CHAN_6_BIT 3
#define CHAN_7_PIN 12 // conflicts with SPI MISO
#define CHAN_7_REG B
#define CHAN_7_BIT 4
// here are some alternates you could use on the Nano for any of the channels:
//#define CHAN_x_PIN 14
//#define CHAN_x_REG C
//#define CHAN_x_BIT 0
//#define CHAN_x_PIN 15
//#define CHAN_x_REG C
//#define CHAN_x_BIT 1
//#define CHAN_x_PIN 16
//#define CHAN_x_REG C
//#define CHAN_x_BIT 2
//#define CHAN_x_PIN 17
//#define CHAN_x_REG C
//#define CHAN_x_BIT 3
//#define CHAN_x_PIN 18
//#define CHAN_x_REG C
//#define CHAN_x_BIT 4
//#define CHAN_x_PIN 19
//#define CHAN_x_REG C
//#define CHAN_x_BIT 5
#endif // Arduino Nano
#ifdef ARDUINO_MEGA // define 8 channels on an Arduino Mega
#define CHAN_0_PIN 53 // channel zero outputs on pin 53,
#define CHAN_0_REG B // pin 53 is wired to register B,
#define CHAN_0_BIT 0 // and is bit 0 in that register
#define CHAN_1_PIN 51
#define CHAN_1_REG B
#define CHAN_1_BIT 2
#define CHAN_2_PIN 49
#define CHAN_2_REG L
#define CHAN_2_BIT 0
#define CHAN_3_PIN 47
#define CHAN_3_REG L
#define CHAN_3_BIT 2
#define CHAN_4_PIN 45
#define CHAN_4_REG L
#define CHAN_4_BIT 4
#define CHAN_5_PIN 43
#define CHAN_5_REG L
#define CHAN_5_BIT 6
#define CHAN_6_PIN 41
#define CHAN_6_REG G
#define CHAN_6_BIT 0
#define CHAN_7_PIN 39
#define CHAN_7_REG G
#define CHAN_7_BIT 2
#endif // Arduino Mega
// If you want to use an oscilloscope to measure how long our interrupt routine
// takes, you can configure a pin that outputs a high when it is running.
#define SCOPE_TEST false // make scope measurements?
#ifdef CORE_TEENSY
#define SCOPE_PIN 13 // board pin
#endif
#ifdef ARDUINO_NANO
#define SCOPE_PIN 4 // board pin
#define SCOPE_REG D // data register
#define SCOPE_BIT 4 // bit number in that register
#endif
#ifdef ARDUINO_MEGA
#define SCOPE_PIN 4 // board pin
#define SCOPE_REG G // data register
#define SCOPE_BIT 5 // bit number in that register
#endif
// Finally, here are the prototypes of routines you can call
void tune_start_timer(int);
void tune_playscore(const byte *);
void tune_stopscore(void);
void tune_stop_timer(void);
void tune_resumescore(bool init_pins);
extern volatile boolean tune_playing;
void tune_speed(unsigned percent); // adjust playing speed:
// 100 = normal, 50 = slow by 1/2, 200 = doubletime, etc.