KIK01 Release

Dependencies:   mcp3008 mbed mbed-rtos AverageMCP3008 VoltageMonitor

Committer:
ryood
Date:
Wed Dec 20 19:53:57 2017 +0000
Revision:
35:05798de92fb5
Parent:
34:0ef840ff8f74
Child:
36:3543a352b9d4
Initialize CS as Hi. Change SPI Clock.

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 35:05798de92fb5 5 * 2017.12.15 Proto08: LEDs
ryood 33:eac518ea0f34 6 * 2017.12.03 Proto07: SyncIn
ryood 32:41cda5ad45e4 7 * 2017.11.29 Proto06: Add Power Monitor
ryood 27:b07a55935230 8 * 2017.10.19 Proto05: Add NOS01 Controller
ryood 17:a5d9908bd456 9 * 2017.09.16 Proto04: SPI1 for AD8402 Wein Bridge DCO & Internal DAC for Dual-OTA-VCA
ryood 15:8f674acdac03 10 * 2017.07.04 Proto03: MCP4922 DCA
ryood 13:43a43da257e3 11 * 2017.06.19 Proto02
ryood 3:f89b400cfe57 12 * 2017.06.04 created.
ryood 3:f89b400cfe57 13 *
ryood 3:f89b400cfe57 14 */
ryood 3:f89b400cfe57 15
ryood 0:2dcec10e9199 16 #include "mbed.h"
ryood 0:2dcec10e9199 17 #include "rtos.h"
ryood 13:43a43da257e3 18 #include "mcp3008.h"
ryood 28:387c5a6d5206 19 #include "AverageMCP3008.h"
ryood 22:a3bb7594f9bb 20 #include "EnvelopeAR.h"
ryood 0:2dcec10e9199 21
ryood 17:a5d9908bd456 22 #define UART_TRACE (1)
ryood 32:41cda5ad45e4 23 #include "VoltageMonitor.h"
ryood 32:41cda5ad45e4 24
ryood 12:5b498285d121 25 #define PIN_CHECK (1)
ryood 35:05798de92fb5 26 #define TITLE_STR1 ("KIK01 Kick Machine Proto08")
ryood 35:05798de92fb5 27 #define TITLE_STR2 ("20171221")
ryood 0:2dcec10e9199 28
ryood 0:2dcec10e9199 29 #define PI_F (3.1415926f)
ryood 15:8f674acdac03 30
ryood 35:05798de92fb5 31 #define MCP3008_SPI_SPEED (1406250)
ryood 21:a527f51381d6 32 #define AD8402_SPI_SPEED (10000000)
ryood 31:3c7e1cd0d947 33 #define ENVELOPE_UPDATE_RATE (32000) // Hz
ryood 17:a5d9908bd456 34
ryood 20:70a05941db8c 35 #define AD8402_RMAX (10000.0f)
ryood 20:70a05941db8c 36 #define AD8402_RMIN (50.0f)
ryood 20:70a05941db8c 37
ryood 31:3c7e1cd0d947 38 #define AVERAGE_BUFFER_SIZE (4)
ryood 31:3c7e1cd0d947 39
ryood 32:41cda5ad45e4 40 #define PM_VDD (3.32f)
ryood 35:05798de92fb5 41 #define PM_LoThreshold (2.3f)
ryood 35:05798de92fb5 42 #define PM_HiThreshold (2.7f)
ryood 32:41cda5ad45e4 43
ryood 35:05798de92fb5 44 // LEDs
ryood 35:05798de92fb5 45 DigitalOut LedPower(PC_5);
ryood 35:05798de92fb5 46 DigitalOut LedBeat(PA_12);
ryood 35:05798de92fb5 47 DigitalOut LedSyncIn(PA_11);
ryood 35:05798de92fb5 48 DigitalOut LedSyncOut(PB_12);
ryood 35:05798de92fb5 49
ryood 35:05798de92fb5 50
ryood 35:05798de92fb5 51 // Envelope Output
ryood 26:866d672ba446 52 AnalogOut Dac1(PA_4);
ryood 27:b07a55935230 53 AnalogOut Dac2(PA_5);
ryood 3:f89b400cfe57 54
ryood 26:866d672ba446 55 // AD8402 SPI (SPI2)
ryood 26:866d672ba446 56 // SPI (PinName mosi, PinName miso, PinName sclk, PinName ssel=NC)
ryood 26:866d672ba446 57 SPI SpiMAD8402(PB_15, PB_14, PB_13);
ryood 35:05798de92fb5 58 DigitalOut AD8402Cs(PC_4, 1); // Initaially Inactive
ryood 15:8f674acdac03 59
ryood 18:1bf4abf6895b 60 // MCP3008 SPI
ryood 26:866d672ba446 61 // SPI (PinName mosi, PinName miso, PinName sclk, PinName ssel=NC)
ryood 26:866d672ba446 62 SPI SpiMAdc(PB_5, PB_4, PB_3);
ryood 32:41cda5ad45e4 63 MCP3008 Adc1(&SpiMAdc, PA_9);
ryood 26:866d672ba446 64 MCP3008 Adc2(&SpiMAdc, PA_8);
ryood 32:41cda5ad45e4 65 MCP3008 Adc3(&SpiMAdc, PB_10);
ryood 31:3c7e1cd0d947 66 AverageMCP3008 AvgAdc1(&Adc1, AVERAGE_BUFFER_SIZE);
ryood 31:3c7e1cd0d947 67 AverageMCP3008 AvgAdc2(&Adc2, AVERAGE_BUFFER_SIZE);
ryood 32:41cda5ad45e4 68 AverageMCP3008 AvgAdc3(&Adc3, AVERAGE_BUFFER_SIZE);
ryood 32:41cda5ad45e4 69
ryood 32:41cda5ad45e4 70 // Power Monitor
ryood 32:41cda5ad45e4 71 AnalogIn PowerMonitorIn(PA_0);
ryood 35:05798de92fb5 72 VoltageMonitor PWMon(&PowerMonitorIn, PM_VDD, PM_LoThreshold, PM_HiThreshold, &LedPower);
ryood 8:bb34a4894337 73
ryood 18:1bf4abf6895b 74 // Sync
ryood 33:eac518ea0f34 75 DigitalOut SyncOut(PC_10);
ryood 33:eac518ea0f34 76 InterruptIn SyncIn(PC_11);
ryood 18:1bf4abf6895b 77
ryood 14:8e96f97e261b 78 // Check pins
ryood 26:866d672ba446 79 DigitalOut Dout1(PB_9);
ryood 26:866d672ba446 80 DigitalOut Dout2(PB_8);
ryood 27:b07a55935230 81 DigitalOut Dout3(PB_6);
ryood 14:8e96f97e261b 82
ryood 9:d1e6eae9722b 83 EnvelopeAR envelopeFrequency(5, 300, 880.0f, 120.0f, 40.0f, 0.36f, 0.1f);
ryood 5:846772a77d33 84 EnvelopeAR envelopeAmplitude(50, 200, 0.99f, 1.0f, 0.0f);
ryood 29:947992b9904f 85 EnvelopeAR envelopeNoiseAmplitude(50, 200, 0.99f, 1.0f, 0.0f);
ryood 5:846772a77d33 86
ryood 25:b4977c7e0db7 87 EnvelopeParam frequencyParam;
ryood 25:b4977c7e0db7 88 EnvelopeParam amplitudeParam;
ryood 29:947992b9904f 89 EnvelopeParam noiseAmplitudeParam;
ryood 0:2dcec10e9199 90
ryood 3:f89b400cfe57 91 volatile int ticks;
ryood 3:f89b400cfe57 92 volatile float frequency;
ryood 3:f89b400cfe57 93 volatile float amplitude;
ryood 29:947992b9904f 94 volatile float noiseAmplitude;
ryood 3:f89b400cfe57 95
ryood 5:846772a77d33 96 volatile float bpm;
ryood 5:846772a77d33 97 volatile int envelopeLength;
ryood 14:8e96f97e261b 98 volatile int stepLength;
ryood 0:2dcec10e9199 99
ryood 17:a5d9908bd456 100 void AD8402Write(uint8_t address, uint8_t value)
ryood 17:a5d9908bd456 101 {
ryood 21:a527f51381d6 102 #if (PIN_CHECK)
ryood 26:866d672ba446 103 Dout2 = 1;
ryood 21:a527f51381d6 104 #endif
ryood 21:a527f51381d6 105
ryood 18:1bf4abf6895b 106 AD8402Cs = 0;
ryood 21:a527f51381d6 107 SpiMAD8402.write(address);
ryood 21:a527f51381d6 108 SpiMAD8402.write(value);
ryood 18:1bf4abf6895b 109 AD8402Cs = 1;
ryood 17:a5d9908bd456 110 wait_us(1);
ryood 21:a527f51381d6 111
ryood 21:a527f51381d6 112 #if (PIN_CHECK)
ryood 26:866d672ba446 113 Dout2 = 0;
ryood 21:a527f51381d6 114 #endif
ryood 17:a5d9908bd456 115 }
ryood 17:a5d9908bd456 116
ryood 23:da7c5f7feff1 117 void DcoSetFrequency(float freq)
ryood 17:a5d9908bd456 118 {
ryood 17:a5d9908bd456 119 const float c = 0.00000047;
ryood 17:a5d9908bd456 120 float r = 1.0f / (2.0f * PI_F * frequency * c);
ryood 20:70a05941db8c 121 if (r < AD8402_RMIN) r = AD8402_RMIN;
ryood 20:70a05941db8c 122 if (r > AD8402_RMAX) r = AD8402_RMAX;
ryood 20:70a05941db8c 123
ryood 20:70a05941db8c 124 uint8_t v = 256.0f * (r - AD8402_RMIN) / AD8402_RMAX;
ryood 21:a527f51381d6 125
ryood 17:a5d9908bd456 126 AD8402Write(0, v);
ryood 17:a5d9908bd456 127 AD8402Write(1, v);
ryood 23:da7c5f7feff1 128 }
ryood 17:a5d9908bd456 129
ryood 27:b07a55935230 130 void DcaSetAmplitude(int channel, float amp)
ryood 23:da7c5f7feff1 131 {
ryood 27:b07a55935230 132 switch (channel) {
ryood 27:b07a55935230 133 case 1:
ryood 27:b07a55935230 134 Dac1.write(amp);
ryood 27:b07a55935230 135 break;
ryood 27:b07a55935230 136 case 2:
ryood 33:eac518ea0f34 137 //Dac2.write(amp);
ryood 27:b07a55935230 138 Dac2.write(amp * 0.8f); // Avoid LED,s Non-Linearity
ryood 27:b07a55935230 139 break;
ryood 27:b07a55935230 140 default:
ryood 27:b07a55935230 141 error("DcaSetAmplitude(): invalid channel");
ryood 27:b07a55935230 142 }
ryood 17:a5d9908bd456 143 }
ryood 15:8f674acdac03 144
ryood 2:8dff77a1ee4d 145 void update()
ryood 2:8dff77a1ee4d 146 {
ryood 12:5b498285d121 147 #if (PIN_CHECK)
ryood 26:866d672ba446 148 Dout1 = 1;
ryood 12:5b498285d121 149 #endif
ryood 15:8f674acdac03 150
ryood 14:8e96f97e261b 151 // Output Sync Signal per steps
ryood 17:a5d9908bd456 152 if (ticks % stepLength == 0) {
ryood 33:eac518ea0f34 153 SyncOut = 1;
ryood 35:05798de92fb5 154 LedSyncOut = !LedSyncOut;
ryood 14:8e96f97e261b 155 }
ryood 15:8f674acdac03 156
ryood 17:a5d9908bd456 157 // set envelope parameters
ryood 25:b4977c7e0db7 158 envelopeAmplitude.setParam(amplitudeParam);
ryood 25:b4977c7e0db7 159 envelopeFrequency.setParam(frequencyParam);
ryood 30:1291e20b1c53 160 envelopeNoiseAmplitude.setParam(noiseAmplitudeParam);
ryood 11:7e11404adca0 161
ryood 23:da7c5f7feff1 162 frequency = envelopeFrequency.getAmplitude(ticks);
ryood 30:1291e20b1c53 163 amplitude = envelopeAmplitude.getAmplitude(ticks);
ryood 30:1291e20b1c53 164 noiseAmplitude = envelopeNoiseAmplitude.getAmplitude(ticks);
ryood 23:da7c5f7feff1 165
ryood 23:da7c5f7feff1 166 DcoSetFrequency(frequency);
ryood 27:b07a55935230 167 DcaSetAmplitude(1, amplitude); // DCO
ryood 30:1291e20b1c53 168 DcaSetAmplitude(2, noiseAmplitude); // NOS01
ryood 11:7e11404adca0 169
ryood 17:a5d9908bd456 170 ticks++;
ryood 17:a5d9908bd456 171 if (ticks >= envelopeLength) {
ryood 17:a5d9908bd456 172 ticks = 0;
ryood 35:05798de92fb5 173 LedBeat = !LedBeat;
ryood 2:8dff77a1ee4d 174 }
ryood 15:8f674acdac03 175
ryood 14:8e96f97e261b 176 // Output SyncSignal
ryood 33:eac518ea0f34 177 SyncOut = 0;
ryood 15:8f674acdac03 178
ryood 12:5b498285d121 179 #if (PIN_CHECK)
ryood 26:866d672ba446 180 Dout1 = 0;
ryood 12:5b498285d121 181 #endif
ryood 2:8dff77a1ee4d 182 }
ryood 2:8dff77a1ee4d 183
ryood 25:b4977c7e0db7 184 void readParams()
ryood 5:846772a77d33 185 {
ryood 28:387c5a6d5206 186 bpm = AvgAdc1.read_input(7) * 180.0f + 60.0f;
ryood 12:5b498285d121 187 envelopeLength = 60 * ENVELOPE_UPDATE_RATE / bpm;
ryood 14:8e96f97e261b 188 stepLength = envelopeLength / 4;
ryood 11:7e11404adca0 189
ryood 28:387c5a6d5206 190 amplitudeParam.attack = AvgAdc1.read_input(0) * envelopeLength;
ryood 28:387c5a6d5206 191 amplitudeParam.release = AvgAdc1.read_input(1) * envelopeLength;
ryood 28:387c5a6d5206 192 amplitudeParam.v0 = AvgAdc1.read_input(4);
ryood 28:387c5a6d5206 193 amplitudeParam.v1 = AvgAdc1.read_input(5);
ryood 28:387c5a6d5206 194 amplitudeParam.v2 = AvgAdc1.read_input(6);
ryood 28:387c5a6d5206 195 amplitudeParam.attackTauRatio = AvgAdc1.read_input(2) + 0.01f;
ryood 28:387c5a6d5206 196 amplitudeParam.releaseTauRatio = AvgAdc1.read_input(3) + 0.01f;
ryood 11:7e11404adca0 197
ryood 28:387c5a6d5206 198 frequencyParam.attack = AvgAdc2.read_input(0) * envelopeLength * 0.1f;
ryood 28:387c5a6d5206 199 frequencyParam.release = AvgAdc2.read_input(1) * envelopeLength + 1;
ryood 28:387c5a6d5206 200 frequencyParam.v0 = AvgAdc2.read_input(4) * 4000.0f;
ryood 28:387c5a6d5206 201 frequencyParam.v1 = AvgAdc2.read_input(5) * 400.0f;
ryood 28:387c5a6d5206 202 frequencyParam.v2 = AvgAdc2.read_input(6) * 400.0f;
ryood 28:387c5a6d5206 203 frequencyParam.attackTauRatio = AvgAdc2.read_input(2) + 0.01f;
ryood 28:387c5a6d5206 204 frequencyParam.releaseTauRatio = AvgAdc2.read_input(3) + 0.01f;
ryood 29:947992b9904f 205
ryood 29:947992b9904f 206 noiseAmplitudeParam.attack = AvgAdc3.read_input(0) * envelopeLength;
ryood 29:947992b9904f 207 noiseAmplitudeParam.release = AvgAdc3.read_input(1) * envelopeLength;
ryood 29:947992b9904f 208 noiseAmplitudeParam.v0 = AvgAdc3.read_input(4);
ryood 29:947992b9904f 209 noiseAmplitudeParam.v1 = AvgAdc3.read_input(5);
ryood 29:947992b9904f 210 noiseAmplitudeParam.v2 = AvgAdc3.read_input(6);
ryood 29:947992b9904f 211 noiseAmplitudeParam.attackTauRatio = AvgAdc3.read_input(2) + 0.01f;
ryood 29:947992b9904f 212 noiseAmplitudeParam.releaseTauRatio = AvgAdc3.read_input(3) + 0.01f;
ryood 5:846772a77d33 213 }
ryood 5:846772a77d33 214
ryood 35:05798de92fb5 215 void syncInFunction()
ryood 33:eac518ea0f34 216 {
ryood 33:eac518ea0f34 217 ticks = 0;
ryood 35:05798de92fb5 218 LedSyncIn = !LedSyncIn;
ryood 35:05798de92fb5 219 }
ryood 35:05798de92fb5 220
ryood 35:05798de92fb5 221 void LedsCheck(int n, int wait)
ryood 35:05798de92fb5 222 {
ryood 35:05798de92fb5 223 for (int i = 0; i < n; i++) {
ryood 35:05798de92fb5 224 //LedPower = 1;
ryood 35:05798de92fb5 225 LedBeat = 1;
ryood 35:05798de92fb5 226 LedSyncIn = 1;
ryood 35:05798de92fb5 227 LedSyncOut = 1;
ryood 35:05798de92fb5 228 Thread::wait(wait);
ryood 35:05798de92fb5 229 //LedPower = 0;
ryood 35:05798de92fb5 230 LedBeat = 0;
ryood 35:05798de92fb5 231 LedSyncIn = 0;
ryood 35:05798de92fb5 232 LedSyncOut = 0;
ryood 35:05798de92fb5 233 Thread::wait(wait);
ryood 35:05798de92fb5 234 }
ryood 33:eac518ea0f34 235 }
ryood 33:eac518ea0f34 236
ryood 0:2dcec10e9199 237 int main()
ryood 0:2dcec10e9199 238 {
ryood 27:b07a55935230 239 #if UART_TRACE
ryood 27:b07a55935230 240 printf("\r\n\n%s %s\r\n", TITLE_STR1, TITLE_STR2);
ryood 27:b07a55935230 241 #endif
ryood 15:8f674acdac03 242
ryood 35:05798de92fb5 243 // LEDs Check
ryood 35:05798de92fb5 244 LedsCheck(4, 100); // 4 counts, 100ms cycle
ryood 35:05798de92fb5 245
ryood 21:a527f51381d6 246 SpiMAD8402.format(8, 0);
ryood 21:a527f51381d6 247 SpiMAD8402.frequency(AD8402_SPI_SPEED);
ryood 17:a5d9908bd456 248
ryood 26:866d672ba446 249 SpiMAdc.format(8, 0);
ryood 26:866d672ba446 250 SpiMAdc.frequency(MCP3008_SPI_SPEED);
ryood 15:8f674acdac03 251
ryood 17:a5d9908bd456 252 frequency = 100.0f;
ryood 0:2dcec10e9199 253 amplitude = 1.0f;
ryood 29:947992b9904f 254 noiseAmplitude = 1.0f;
ryood 17:a5d9908bd456 255 bpm = 120.0f;
ryood 17:a5d9908bd456 256
ryood 25:b4977c7e0db7 257 readParams();
ryood 11:7e11404adca0 258
ryood 3:f89b400cfe57 259 ticks = 0;
ryood 2:8dff77a1ee4d 260 Ticker samplingTicker;
ryood 17:a5d9908bd456 261 samplingTicker.attach(&update, (1.0f/ENVELOPE_UPDATE_RATE));
ryood 33:eac518ea0f34 262
ryood 33:eac518ea0f34 263 // Sync Interrupt
ryood 35:05798de92fb5 264 SyncIn.rise(&syncInFunction);
ryood 35:05798de92fb5 265 SyncIn.mode(PullDown);
ryood 11:7e11404adca0 266
ryood 3:f89b400cfe57 267 for (;;) {
ryood 13:43a43da257e3 268 #if (PIN_CHECK)
ryood 26:866d672ba446 269 Dout3 = 1;
ryood 15:8f674acdac03 270 #endif
ryood 25:b4977c7e0db7 271
ryood 25:b4977c7e0db7 272 readParams();
ryood 25:b4977c7e0db7 273
ryood 13:43a43da257e3 274 #if (PIN_CHECK)
ryood 26:866d672ba446 275 Dout3 = 0;
ryood 15:8f674acdac03 276 #endif
ryood 11:7e11404adca0 277
ryood 32:41cda5ad45e4 278
ryood 11:7e11404adca0 279 #if UART_TRACE
ryood 6:897d6392b408 280 printf("%.1f\t%d\t", bpm, envelopeLength);
ryood 11:7e11404adca0 281
ryood 31:3c7e1cd0d947 282 printf("| %d\t%d\t", amplitudeParam.attack, amplitudeParam.release);
ryood 6:897d6392b408 283 printf("%.2f\t%.2f\t%.2f\t", amplitudeParam.v0, amplitudeParam.v1, amplitudeParam.v2);
ryood 6:897d6392b408 284 printf("%.2f\t%.2f\t", amplitudeParam.attackTauRatio, amplitudeParam.releaseTauRatio);
ryood 6:897d6392b408 285
ryood 31:3c7e1cd0d947 286 printf("| %d\t%d\t", frequencyParam.attack, frequencyParam.release);
ryood 6:897d6392b408 287 printf("%.2f\t%.2f\t%.2f\t", frequencyParam.v0, frequencyParam.v1, frequencyParam.v2);
ryood 29:947992b9904f 288 printf("%.2f\t%.2f\t", frequencyParam.attackTauRatio, frequencyParam.releaseTauRatio);
ryood 29:947992b9904f 289
ryood 31:3c7e1cd0d947 290 printf("| %d\t%d\t", noiseAmplitudeParam.attack, noiseAmplitudeParam.release);
ryood 29:947992b9904f 291 printf("%.2f\t%.2f\t%.2f\t", noiseAmplitudeParam.v0, noiseAmplitudeParam.v1, noiseAmplitudeParam.v2);
ryood 32:41cda5ad45e4 292 printf("%.2f\t%.2f\t", noiseAmplitudeParam.attackTauRatio, noiseAmplitudeParam.releaseTauRatio);
ryood 11:7e11404adca0 293 #endif
ryood 11:7e11404adca0 294
ryood 32:41cda5ad45e4 295 PWMon.check();
ryood 32:41cda5ad45e4 296
ryood 13:43a43da257e3 297 Thread::wait(1);
ryood 3:f89b400cfe57 298 }
ryood 0:2dcec10e9199 299 }