MCP3008 Version

Dependencies:   mbed-rtos mbed mcp3008

Fork of KIK01_Proto01 by Ryo Od

Committer:
ryood
Date:
Wed Jun 21 00:14:49 2017 +0000
Revision:
13:43a43da257e3
Parent:
12:5b498285d121
MCP3008

Who changed what in which revision?

UserRevisionLine numberNew contents of line
ryood 3:f89b400cfe57 1 /*
ryood 3:f89b400cfe57 2 * KIK01
ryood 3:f89b400cfe57 3 * Kick Machine
ryood 3:f89b400cfe57 4 *
ryood 13:43a43da257e3 5 * 2017.06.19 Proto02
ryood 3:f89b400cfe57 6 * 2017.06.04 created.
ryood 3:f89b400cfe57 7 *
ryood 3:f89b400cfe57 8 */
ryood 3:f89b400cfe57 9
ryood 0:2dcec10e9199 10 #include "mbed.h"
ryood 0:2dcec10e9199 11 #include "rtos.h"
ryood 13:43a43da257e3 12 #include "mcp3008.h"
ryood 0:2dcec10e9199 13
ryood 10:79134dbb339d 14 #define UART_TRACE (1)
ryood 12:5b498285d121 15 #define PIN_CHECK (1)
ryood 0:2dcec10e9199 16 #define TITLE_STR1 ("KIK01 Kick Machine")
ryood 13:43a43da257e3 17 #define TITLE_STR2 ("20170621")
ryood 0:2dcec10e9199 18
ryood 0:2dcec10e9199 19 #define PI_F (3.1415926f)
ryood 13:43a43da257e3 20 #define SAMPLING_RATE (48000)
ryood 0:2dcec10e9199 21 #define SAMPLING_PERIOD (1.0f/SAMPLING_RATE)
ryood 13:43a43da257e3 22 #define ENVELOPE_UPDATE_RATE (48000)
ryood 3:f89b400cfe57 23
ryood 13:43a43da257e3 24 AnalogOut Dac1(PA_4);
ryood 0:2dcec10e9199 25
ryood 13:43a43da257e3 26 SPI spiM(SPI_MOSI, SPI_MISO, SPI_SCK);
ryood 13:43a43da257e3 27 MCP3008 Adc0(spiM, D9);
ryood 13:43a43da257e3 28 MCP3008 Adc1(spiM, D10);
ryood 8:bb34a4894337 29
ryood 12:5b498285d121 30 DigitalOut Dout0(PA_10);
ryood 12:5b498285d121 31 DigitalOut Dout1(PB_3);
ryood 13:43a43da257e3 32 DigitalOut Dout2(PB_5);
ryood 12:5b498285d121 33
ryood 11:7e11404adca0 34 class EnvelopeAR
ryood 11:7e11404adca0 35 {
ryood 0:2dcec10e9199 36 public:
ryood 0:2dcec10e9199 37 EnvelopeAR(int _attack, int _release, float _v0, float _v1, float _v2, float _attackTauRatio=0.36f, float _releaseTauRatio=0.36f) :
ryood 0:2dcec10e9199 38 amplitude(_v0),
ryood 0:2dcec10e9199 39 v0(_v0),
ryood 0:2dcec10e9199 40 v1(_v1),
ryood 0:2dcec10e9199 41 v2(_v2),
ryood 0:2dcec10e9199 42 vLast(_v0),
ryood 0:2dcec10e9199 43 attackTauRatio(_attackTauRatio),
ryood 11:7e11404adca0 44 releaseTauRatio(_releaseTauRatio) {
ryood 0:2dcec10e9199 45 setAttack(_attack);
ryood 0:2dcec10e9199 46 setRelease(_release);
ryood 0:2dcec10e9199 47 }
ryood 0:2dcec10e9199 48
ryood 0:2dcec10e9199 49 ~EnvelopeAR() {}
ryood 0:2dcec10e9199 50
ryood 0:2dcec10e9199 51 void setAttack(int _attack) {
ryood 0:2dcec10e9199 52 attack = _attack;
ryood 0:2dcec10e9199 53 tau0 = attack * attackTauRatio;
ryood 0:2dcec10e9199 54 }
ryood 11:7e11404adca0 55 int getAttack() {
ryood 11:7e11404adca0 56 return attack;
ryood 11:7e11404adca0 57 }
ryood 0:2dcec10e9199 58
ryood 0:2dcec10e9199 59 void setRelease(int _release) {
ryood 0:2dcec10e9199 60 release = _release;
ryood 0:2dcec10e9199 61 tau1 = release * releaseTauRatio;
ryood 0:2dcec10e9199 62 }
ryood 11:7e11404adca0 63 int getRelease() {
ryood 11:7e11404adca0 64 return release;
ryood 11:7e11404adca0 65 }
ryood 0:2dcec10e9199 66
ryood 5:846772a77d33 67 void setAttackTauRatio(float _attackTauRatio) {
ryood 5:846772a77d33 68 attackTauRatio = _attackTauRatio;
ryood 5:846772a77d33 69 tau0 = attack * attackTauRatio;
ryood 5:846772a77d33 70 }
ryood 11:7e11404adca0 71 float getAttackTauRatio() {
ryood 11:7e11404adca0 72 return attackTauRatio;
ryood 11:7e11404adca0 73 }
ryood 0:2dcec10e9199 74
ryood 11:7e11404adca0 75 void setReleaseTauRatio(float _releaseTauRatio) {
ryood 5:846772a77d33 76 releaseTauRatio = _releaseTauRatio;
ryood 5:846772a77d33 77 tau1 = release * releaseTauRatio;
ryood 5:846772a77d33 78 }
ryood 11:7e11404adca0 79 float getReleaseTauRatio() {
ryood 11:7e11404adca0 80 return releaseTauRatio;
ryood 11:7e11404adca0 81 }
ryood 11:7e11404adca0 82
ryood 11:7e11404adca0 83 float getTau0() {
ryood 11:7e11404adca0 84 return tau0;
ryood 11:7e11404adca0 85 }
ryood 11:7e11404adca0 86 float getTau1() {
ryood 11:7e11404adca0 87 return tau1;
ryood 11:7e11404adca0 88 }
ryood 0:2dcec10e9199 89
ryood 11:7e11404adca0 90 void setV0(float _v0) {
ryood 11:7e11404adca0 91 v0 = _v0;
ryood 11:7e11404adca0 92 }
ryood 11:7e11404adca0 93 float getV0() {
ryood 11:7e11404adca0 94 return v0;
ryood 11:7e11404adca0 95 }
ryood 11:7e11404adca0 96 void setV1(float _v1) {
ryood 11:7e11404adca0 97 v1 = _v1;
ryood 11:7e11404adca0 98 }
ryood 11:7e11404adca0 99 float getV1() {
ryood 11:7e11404adca0 100 return v1;
ryood 11:7e11404adca0 101 }
ryood 11:7e11404adca0 102 void setV2(float _v2) {
ryood 11:7e11404adca0 103 v2 = _v2;
ryood 11:7e11404adca0 104 }
ryood 11:7e11404adca0 105 float getV2() {
ryood 11:7e11404adca0 106 return v2;
ryood 11:7e11404adca0 107 }
ryood 0:2dcec10e9199 108
ryood 11:7e11404adca0 109 float getAmplitude() {
ryood 11:7e11404adca0 110 return amplitude;
ryood 11:7e11404adca0 111 }
ryood 0:2dcec10e9199 112 float getAmplitude(int tick) {
ryood 0:2dcec10e9199 113 if (tick < attack) {
ryood 0:2dcec10e9199 114 // attackの処理
ryood 0:2dcec10e9199 115 amplitude = v0 + (v1 - v0) * (1 - expf(-(float)tick / tau0));
ryood 0:2dcec10e9199 116 vLast = amplitude;
ryood 11:7e11404adca0 117 } else {
ryood 0:2dcec10e9199 118 // releaseの処理
ryood 0:2dcec10e9199 119 amplitude = (vLast - v2) * (expf(-(float)(tick - attack) / tau1)) + v2;
ryood 0:2dcec10e9199 120 }
ryood 0:2dcec10e9199 121 return amplitude;
ryood 0:2dcec10e9199 122 }
ryood 0:2dcec10e9199 123
ryood 0:2dcec10e9199 124 private:
ryood 0:2dcec10e9199 125 int attack;
ryood 0:2dcec10e9199 126 int release;
ryood 0:2dcec10e9199 127 float amplitude;
ryood 0:2dcec10e9199 128 float v0;
ryood 0:2dcec10e9199 129 float v1;
ryood 0:2dcec10e9199 130 float v2;
ryood 0:2dcec10e9199 131 float vLast;
ryood 0:2dcec10e9199 132 float tau0;
ryood 0:2dcec10e9199 133 float tau1;
ryood 0:2dcec10e9199 134 float attackTauRatio;
ryood 0:2dcec10e9199 135 float releaseTauRatio;
ryood 0:2dcec10e9199 136 };
ryood 0:2dcec10e9199 137
ryood 11:7e11404adca0 138 class EnvelopeParam
ryood 11:7e11404adca0 139 {
ryood 5:846772a77d33 140 public:
ryood 5:846772a77d33 141 int attack;
ryood 5:846772a77d33 142 int release;
ryood 5:846772a77d33 143 float v0;
ryood 5:846772a77d33 144 float v1;
ryood 5:846772a77d33 145 float v2;
ryood 5:846772a77d33 146 float attackTauRatio;
ryood 5:846772a77d33 147 float releaseTauRatio;
ryood 5:846772a77d33 148 };
ryood 11:7e11404adca0 149
ryood 9:d1e6eae9722b 150 EnvelopeAR envelopeFrequency(5, 300, 880.0f, 120.0f, 40.0f, 0.36f, 0.1f);
ryood 5:846772a77d33 151 EnvelopeAR envelopeAmplitude(50, 200, 0.99f, 1.0f, 0.0f);
ryood 5:846772a77d33 152
ryood 5:846772a77d33 153 volatile EnvelopeParam frequencyParam;
ryood 5:846772a77d33 154 volatile EnvelopeParam amplitudeParam;
ryood 0:2dcec10e9199 155
ryood 3:f89b400cfe57 156 volatile int ticks;
ryood 3:f89b400cfe57 157 volatile int envelopeTicks;
ryood 3:f89b400cfe57 158 volatile float frequency;
ryood 3:f89b400cfe57 159 volatile float phi;
ryood 3:f89b400cfe57 160 volatile float phiDelta;
ryood 3:f89b400cfe57 161 volatile float amplitude;
ryood 3:f89b400cfe57 162
ryood 5:846772a77d33 163 volatile float bpm;
ryood 5:846772a77d33 164 volatile int envelopeLength;
ryood 0:2dcec10e9199 165
ryood 0:2dcec10e9199 166 void generateWave()
ryood 0:2dcec10e9199 167 {
ryood 0:2dcec10e9199 168 phi += phiDelta;
ryood 0:2dcec10e9199 169 if (phi >= 1.0f) {
ryood 0:2dcec10e9199 170 phi -= 2.0f;
ryood 0:2dcec10e9199 171 }
ryood 10:79134dbb339d 172 float level = cosf(PI_F * phi) * amplitude;
ryood 1:f9b967ae26e4 173
ryood 3:f89b400cfe57 174 Dac1.write((level * 0.7f + 1.0f) / 2.0f);
ryood 0:2dcec10e9199 175 }
ryood 0:2dcec10e9199 176
ryood 0:2dcec10e9199 177 void generateEnvelope()
ryood 0:2dcec10e9199 178 {
ryood 0:2dcec10e9199 179 // Frequency Envelope
ryood 0:2dcec10e9199 180 frequency = envelopeFrequency.getAmplitude(envelopeTicks);
ryood 0:2dcec10e9199 181 phiDelta = 2.0f * frequency / SAMPLING_RATE;
ryood 0:2dcec10e9199 182
ryood 0:2dcec10e9199 183 // Amplitude Envelope
ryood 0:2dcec10e9199 184 amplitude = envelopeAmplitude.getAmplitude(envelopeTicks);
ryood 0:2dcec10e9199 185
ryood 0:2dcec10e9199 186 envelopeTicks++;
ryood 7:6735a343780e 187 if (envelopeTicks >= envelopeLength) {
ryood 0:2dcec10e9199 188 envelopeTicks = 0;
ryood 12:5b498285d121 189 phi = PI_F / 2.0f;
ryood 0:2dcec10e9199 190 }
ryood 0:2dcec10e9199 191 }
ryood 0:2dcec10e9199 192
ryood 2:8dff77a1ee4d 193 void update()
ryood 2:8dff77a1ee4d 194 {
ryood 12:5b498285d121 195 #if (PIN_CHECK)
ryood 12:5b498285d121 196 Dout0 = 1;
ryood 12:5b498285d121 197 #endif
ryood 3:f89b400cfe57 198 ticks++;
ryood 12:5b498285d121 199 if (ticks >= SAMPLING_RATE / ENVELOPE_UPDATE_RATE) {
ryood 12:5b498285d121 200 #if (PIN_CHECK)
ryood 12:5b498285d121 201 Dout1 = 1;
ryood 12:5b498285d121 202 #endif
ryood 3:f89b400cfe57 203 ticks = 0;
ryood 11:7e11404adca0 204
ryood 5:846772a77d33 205 // set envelope parameters
ryood 5:846772a77d33 206 envelopeAmplitude.setAttack(amplitudeParam.attack);
ryood 5:846772a77d33 207 envelopeAmplitude.setRelease(amplitudeParam.release);
ryood 5:846772a77d33 208 envelopeAmplitude.setV0(amplitudeParam.v0);
ryood 5:846772a77d33 209 envelopeAmplitude.setV1(amplitudeParam.v1);
ryood 5:846772a77d33 210 envelopeAmplitude.setV2(amplitudeParam.v2);
ryood 5:846772a77d33 211 envelopeAmplitude.setAttackTauRatio(amplitudeParam.attackTauRatio);
ryood 5:846772a77d33 212 envelopeAmplitude.setReleaseTauRatio(amplitudeParam.releaseTauRatio);
ryood 11:7e11404adca0 213
ryood 6:897d6392b408 214 envelopeFrequency.setAttack(frequencyParam.attack);
ryood 6:897d6392b408 215 envelopeFrequency.setRelease(frequencyParam.release);
ryood 5:846772a77d33 216 envelopeFrequency.setV0(frequencyParam.v0);
ryood 6:897d6392b408 217 envelopeFrequency.setV1(frequencyParam.v1);
ryood 6:897d6392b408 218 envelopeFrequency.setV2(frequencyParam.v2);
ryood 6:897d6392b408 219 envelopeFrequency.setAttackTauRatio(frequencyParam.attackTauRatio);
ryood 6:897d6392b408 220 envelopeFrequency.setReleaseTauRatio(frequencyParam.releaseTauRatio);
ryood 11:7e11404adca0 221
ryood 2:8dff77a1ee4d 222 generateEnvelope();
ryood 12:5b498285d121 223 #if (PIN_CHECK)
ryood 12:5b498285d121 224 Dout1 = 0;
ryood 12:5b498285d121 225 #endif
ryood 2:8dff77a1ee4d 226 }
ryood 2:8dff77a1ee4d 227 generateWave();
ryood 12:5b498285d121 228 #if (PIN_CHECK)
ryood 12:5b498285d121 229 Dout0 = 0;
ryood 12:5b498285d121 230 #endif
ryood 2:8dff77a1ee4d 231 }
ryood 2:8dff77a1ee4d 232
ryood 5:846772a77d33 233 void setParams()
ryood 5:846772a77d33 234 {
ryood 13:43a43da257e3 235 bpm = Adc0.read_input(7) * 180.0f + 60.0f;
ryood 12:5b498285d121 236 envelopeLength = 60 * ENVELOPE_UPDATE_RATE / bpm;
ryood 11:7e11404adca0 237
ryood 13:43a43da257e3 238 amplitudeParam.attack = Adc0.read_input(0) * envelopeLength;
ryood 13:43a43da257e3 239 amplitudeParam.release = Adc0.read_input(1) * envelopeLength;
ryood 13:43a43da257e3 240 amplitudeParam.v0 = Adc0.read_input(4);
ryood 5:846772a77d33 241 amplitudeParam.v1 = 1.0f;
ryood 5:846772a77d33 242 amplitudeParam.v2 = 0.0f;
ryood 5:846772a77d33 243 amplitudeParam.attackTauRatio = 0.36f;
ryood 13:43a43da257e3 244 amplitudeParam.releaseTauRatio = Adc0.read_input(3) + 0.01f;
ryood 11:7e11404adca0 245
ryood 13:43a43da257e3 246 frequencyParam.attack = Adc1.read_input(0) * envelopeLength * 0.1f;
ryood 13:43a43da257e3 247 frequencyParam.release = Adc1.read_input(1) * envelopeLength + 1;
ryood 13:43a43da257e3 248 frequencyParam.v0 = Adc1.read_input(4) * 4000.0f;
ryood 13:43a43da257e3 249 frequencyParam.v1 = Adc1.read_input(5) * 400.0f;
ryood 13:43a43da257e3 250 frequencyParam.v2 = Adc1.read_input(6) * 400.0f;
ryood 13:43a43da257e3 251 frequencyParam.attackTauRatio = Adc1.read_input(2) + 0.01f;
ryood 13:43a43da257e3 252 frequencyParam.releaseTauRatio = Adc1.read_input(3) + 0.01f;
ryood 5:846772a77d33 253 }
ryood 5:846772a77d33 254
ryood 0:2dcec10e9199 255 int main()
ryood 0:2dcec10e9199 256 {
ryood 0:2dcec10e9199 257 printf("%s %s\r\n", TITLE_STR1, TITLE_STR2);
ryood 13:43a43da257e3 258
ryood 0:2dcec10e9199 259 frequency = 1000.0f;
ryood 0:2dcec10e9199 260 phiDelta = 2.0f * frequency / SAMPLING_RATE;
ryood 0:2dcec10e9199 261 amplitude = 1.0f;
ryood 11:7e11404adca0 262
ryood 3:f89b400cfe57 263 ticks = 0;
ryood 2:8dff77a1ee4d 264 envelopeTicks = 0;
ryood 11:7e11404adca0 265
ryood 5:846772a77d33 266 bpm = 120.0f;
ryood 5:846772a77d33 267 setParams();
ryood 5:846772a77d33 268
ryood 2:8dff77a1ee4d 269 Ticker samplingTicker;
ryood 2:8dff77a1ee4d 270 samplingTicker.attach(&update, SAMPLING_PERIOD);
ryood 11:7e11404adca0 271
ryood 3:f89b400cfe57 272 for (;;) {
ryood 13:43a43da257e3 273 #if (PIN_CHECK)
ryood 13:43a43da257e3 274 Dout2 = 1;
ryood 13:43a43da257e3 275 #endif
ryood 5:846772a77d33 276 setParams();
ryood 13:43a43da257e3 277 #if (PIN_CHECK)
ryood 13:43a43da257e3 278 Dout2 = 0;
ryood 13:43a43da257e3 279 #endif
ryood 11:7e11404adca0 280
ryood 11:7e11404adca0 281 #if UART_TRACE
ryood 6:897d6392b408 282 printf("%.1f\t%d\t", bpm, envelopeLength);
ryood 11:7e11404adca0 283
ryood 6:897d6392b408 284 printf("%d\t%d\t", amplitudeParam.attack, amplitudeParam.release);
ryood 6:897d6392b408 285 printf("%.2f\t%.2f\t%.2f\t", amplitudeParam.v0, amplitudeParam.v1, amplitudeParam.v2);
ryood 6:897d6392b408 286 printf("%.2f\t%.2f\t", amplitudeParam.attackTauRatio, amplitudeParam.releaseTauRatio);
ryood 6:897d6392b408 287
ryood 6:897d6392b408 288 printf("%d\t%d\t", frequencyParam.attack, frequencyParam.release);
ryood 6:897d6392b408 289 printf("%.2f\t%.2f\t%.2f\t", frequencyParam.v0, frequencyParam.v1, frequencyParam.v2);
ryood 6:897d6392b408 290 printf("%.2f\t%.2f\r\n", frequencyParam.attackTauRatio, frequencyParam.releaseTauRatio);
ryood 11:7e11404adca0 291 #endif
ryood 11:7e11404adca0 292
ryood 13:43a43da257e3 293 Thread::wait(1);
ryood 3:f89b400cfe57 294 }
ryood 0:2dcec10e9199 295 }