KIK01 Proto 08

Dependencies:   AverageMCP3008 VoltageMonitor mbed-rtos mbed mcp3008

Fork of KIK01_Proto07 by Ryo Od

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 /*
00002  * KIK01
00003  * Kick Machine
00004  *
00005  * 2018.01.17 Release
00006  * 2017.12.15 Proto08: LEDs
00007  * 2017.12.03 Proto07: SyncIn
00008  * 2017.11.29 Proto06: Add Power Monitor
00009  * 2017.10.19 Proto05: Add NOS01 Controller
00010  * 2017.09.16 Proto04: SPI1 for AD8402 Wein Bridge DCO & Internal DAC for Dual-OTA-VCA
00011  * 2017.07.04 Proto03: MCP4922 DCA
00012  * 2017.06.19 Proto02
00013  * 2017.06.04 created.
00014  *
00015  */
00016 
00017 #include "mbed.h"
00018 #include "rtos.h"
00019 #include "mcp3008.h"
00020 #include "AverageMCP3008.h"
00021 #include "EnvelopeAR.h"
00022 
00023 #define UART_TRACE      (0)
00024 #include "VoltageMonitor.h"
00025 
00026 #define PIN_CHECK       (0)
00027 #define LED_SYNCOUT_BLINK   (1)
00028 
00029 #define TITLE_STR1      ("KIK01 Kick Machine Proto08")
00030 #define TITLE_STR2      ("20180117")
00031 
00032 #define PI_F            (3.1415926f)
00033 
00034 #define MCP3008_SPI_SPEED       (1406250)
00035 #define AD8402_SPI_SPEED        (10000000)
00036 #define ENVELOPE_UPDATE_RATE    (32000)  //  Hz
00037 
00038 #define AD8402_RMAX (10000.0f)
00039 #define AD8402_RMIN (50.0f)
00040 
00041 #define AVERAGE_BUFFER_SIZE (4)
00042 
00043 #define PM_VDD           (3.32f)
00044 #define PM_LoThreshold   (2.3f)
00045 #define PM_HiThreshold   (2.7f)
00046 
00047 #define LED_BEAT_BLINK_CYCLE        (0.15f)
00048 #define LED_SYNCIN_BLINK_CYCLE      (0.04f)
00049 #define LED_SYNCOUT_BLINK_CYCLE     (0.04f)
00050 
00051 // LEDs
00052 DigitalOut LedPower(PB_2);
00053 DigitalOut LedBeat(PA_12);
00054 DigitalOut LedSyncIn(PA_11);
00055 DigitalOut LedSyncOut(PB_12);
00056 
00057 // Envelope Output
00058 AnalogOut Dac1(PA_4);
00059 AnalogOut Dac2(PA_5);
00060 
00061 // AD8402 SPI (SPI2)
00062 // SPI (PinName mosi, PinName miso, PinName sclk, PinName ssel=NC)
00063 SPI SpiMAD8402(PB_15, PB_14, PB_13);
00064 DigitalOut AD8402Cs(PC_4, 1);   // Initaially Inactive
00065 
00066 // MCP3008 SPI
00067 // SPI (PinName mosi, PinName miso, PinName sclk, PinName ssel=NC)
00068 SPI SpiMAdc(PB_5, PB_4, PB_3);
00069 MCP3008 Adc1(&SpiMAdc, PA_9);
00070 MCP3008 Adc2(&SpiMAdc, PA_8);
00071 MCP3008 Adc3(&SpiMAdc, PB_10);
00072 AverageMCP3008 AvgAdc1(&Adc1, AVERAGE_BUFFER_SIZE); 
00073 AverageMCP3008 AvgAdc2(&Adc2, AVERAGE_BUFFER_SIZE); 
00074 AverageMCP3008 AvgAdc3(&Adc3, AVERAGE_BUFFER_SIZE);
00075 
00076 // Power Monitor
00077 AnalogIn PowerMonitorIn(PA_0);
00078 VoltageMonitor PWMon(&PowerMonitorIn, PM_VDD, PM_LoThreshold, PM_HiThreshold, &LedPower);
00079 
00080 // Sync
00081 DigitalOut SyncOut(PC_10);
00082 InterruptIn SyncIn(PC_11);
00083 DigitalIn AutoRunSw(PB_1);
00084 
00085 // Check pins
00086 DigitalOut Dout1(D14);
00087 DigitalOut Dout2(D15);
00088 DigitalOut Dout3(D2);
00089 
00090 EnvelopeAR envelopeFrequency(5, 300, 880.0f, 120.0f, 40.0f, 0.36f, 0.1f);
00091 EnvelopeAR envelopeAmplitude(50, 200, 0.99f, 1.0f, 0.0f);
00092 EnvelopeAR envelopeNoiseAmplitude(50, 200, 0.99f, 1.0f, 0.0f);
00093 
00094 EnvelopeParam frequencyParam;
00095 EnvelopeParam amplitudeParam;
00096 EnvelopeParam noiseAmplitudeParam;
00097 
00098 Timeout timeoutLedBeat;
00099 Timeout timeoutLedSyncIn;
00100 #if (LED_SYNCOUT_BLINK)
00101 Timeout timeoutLedSyncOut;
00102 #endif
00103 
00104 volatile int ticks;
00105 volatile float frequency;
00106 volatile float amplitude;
00107 volatile float noiseAmplitude;
00108 
00109 volatile int envelopeLength;
00110 volatile int stepLength;
00111 
00112 float bpm;
00113 
00114 //-----------------------------------------------------------------------------
00115 // Interrupt Service Routine
00116 //-----------------------------------------------------------------------------
00117 
00118 void ledBeatAtTimeout()
00119 {
00120     LedBeat = 0;
00121 }
00122 
00123 void ledSyncInAtTimeout()
00124 {
00125     LedSyncIn = 0;
00126 }
00127 
00128 #if (LED_SYNCOUT_BLINK)
00129 void ledSyncOutAtTimeout()
00130 {
00131     LedSyncOut = 0;
00132 }
00133 #endif
00134 
00135 void syncInFunction()
00136 {
00137     ticks = 0;
00138     LedSyncIn = 1;
00139     timeoutLedSyncIn.attach(&ledSyncInAtTimeout, LED_SYNCIN_BLINK_CYCLE);
00140 }
00141 
00142 void AD8402Write(uint8_t address, uint8_t value)
00143 {
00144 #if (PIN_CHECK)
00145     Dout2 = 1;
00146 #endif    
00147 
00148     AD8402Cs = 0;
00149     SpiMAD8402.write(address);
00150     SpiMAD8402.write(value);
00151     AD8402Cs = 1;
00152     //wait_us(1);
00153 
00154 #if (PIN_CHECK)
00155     Dout2 = 0;
00156 #endif
00157 }
00158 
00159 void DcoSetFrequency(float freq)
00160 {
00161     const float c = 0.00000047;
00162     float r = 1.0f / (2.0f * PI_F * frequency * c);
00163     if (r < AD8402_RMIN) r = AD8402_RMIN;
00164     if (r > AD8402_RMAX) r = AD8402_RMAX;
00165     
00166     uint8_t v = 256.0f * (r - AD8402_RMIN) / AD8402_RMAX;
00167 
00168     AD8402Write(0, v);
00169     AD8402Write(1, v);
00170 }
00171 
00172 void DcaSetAmplitude(int channel, float amp)
00173 {
00174     switch (channel) {
00175     case 1:
00176         Dac1.write(amp);
00177         break;
00178     case 2:
00179         //Dac2.write(amp);
00180         Dac2.write(amp * 0.8f); // Avoid LED,s Non-Linearity
00181         break;
00182     default:
00183         error("DcaSetAmplitude(): invalid channel");
00184     }
00185 }
00186 
00187 void update()
00188 {
00189 #if (PIN_CHECK)
00190     Dout1 = 1;
00191 #endif
00192 
00193     // Output Sync Signal per steps
00194     if (ticks % stepLength == 0) {
00195         SyncOut = 1;
00196 #if (LED_SYNCOUT_BLINK)
00197         LedSyncOut = 1;
00198         timeoutLedSyncOut.attach(&ledSyncOutAtTimeout, LED_SYNCOUT_BLINK_CYCLE);        
00199 #endif
00200     }
00201 
00202     // set envelope parameters
00203     envelopeAmplitude.setParam(amplitudeParam);
00204     envelopeFrequency.setParam(frequencyParam);
00205     envelopeNoiseAmplitude.setParam(noiseAmplitudeParam);
00206 
00207     frequency = envelopeFrequency.getAmplitude(ticks);
00208     amplitude = envelopeAmplitude.getAmplitude(ticks);
00209     noiseAmplitude = envelopeNoiseAmplitude.getAmplitude(ticks); 
00210     
00211     DcoSetFrequency(frequency);
00212     DcaSetAmplitude(1, amplitude);  // DCO
00213     DcaSetAmplitude(2, noiseAmplitude);  // NOS01
00214 
00215     ticks++;
00216     if (AutoRunSw && ticks >= envelopeLength) {
00217         ticks = 0;
00218         LedBeat = 1;
00219         timeoutLedBeat.attach(&ledBeatAtTimeout, LED_BEAT_BLINK_CYCLE);
00220     }
00221 
00222     // Output SyncSignal
00223     SyncOut = 0;
00224 
00225 #if (PIN_CHECK)
00226     Dout1 = 0;
00227 #endif
00228 }
00229 
00230 //-----------------------------------------------------------------------------
00231 // Functions
00232 //-----------------------------------------------------------------------------
00233 
00234 void readParams()
00235 {
00236     bpm = AvgAdc1.read_input(7) * 180.0f + 60.0f;
00237     envelopeLength = 60 * ENVELOPE_UPDATE_RATE / bpm;
00238     stepLength = envelopeLength / 4;
00239 
00240     amplitudeParam.attack = AvgAdc1.read_input(0) * envelopeLength;
00241     amplitudeParam.release = AvgAdc1.read_input(1) * envelopeLength;
00242     amplitudeParam.v0 = AvgAdc1.read_input(4);
00243     amplitudeParam.v1 = AvgAdc1.read_input(5);
00244     amplitudeParam.v2 = AvgAdc1.read_input(6);
00245     amplitudeParam.attackTauRatio = AvgAdc1.read_input(2) + 0.01f;
00246     amplitudeParam.releaseTauRatio = AvgAdc1.read_input(3) + 0.01f;
00247 
00248     frequencyParam.attack = AvgAdc2.read_input(0) * envelopeLength * 0.1f;
00249     frequencyParam.release = AvgAdc2.read_input(1) * envelopeLength + 1;
00250     frequencyParam.v0 = AvgAdc2.read_input(4) * 4000.0f;
00251     frequencyParam.v1 = AvgAdc2.read_input(5) * 400.0f;
00252     frequencyParam.v2 = AvgAdc2.read_input(6) * 400.0f;
00253     frequencyParam.attackTauRatio = AvgAdc2.read_input(2) + 0.01f;
00254     frequencyParam.releaseTauRatio = AvgAdc2.read_input(3) + 0.01f;
00255     
00256     noiseAmplitudeParam.attack = AvgAdc3.read_input(0) * envelopeLength;
00257     noiseAmplitudeParam.release = AvgAdc3.read_input(1) * envelopeLength;
00258     noiseAmplitudeParam.v0 = AvgAdc3.read_input(4);
00259     noiseAmplitudeParam.v1 = AvgAdc3.read_input(5);
00260     noiseAmplitudeParam.v2 = AvgAdc3.read_input(6);
00261     noiseAmplitudeParam.attackTauRatio = AvgAdc3.read_input(2) + 0.01f;
00262     noiseAmplitudeParam.releaseTauRatio = AvgAdc3.read_input(3) + 0.01f;
00263 }
00264 
00265 void LedsCheck(int n, int wait)
00266 {
00267     for (int i = 0; i < n; i++) {
00268         LedBeat = 1;
00269         Thread::wait(wait);
00270         LedBeat = 0;
00271 
00272         LedSyncIn = 1;
00273         Thread::wait(wait);
00274         LedSyncIn = 0;
00275 
00276         LedSyncOut = 1;
00277         LedSyncOut = 0;
00278         Thread::wait(wait);
00279     }
00280 }
00281 
00282 int main()
00283 {
00284 #if UART_TRACE
00285     printf("\r\n\n%s %s\r\n", TITLE_STR1, TITLE_STR2);
00286 #endif
00287 
00288     // LEDs Check
00289     LedsCheck(4, 100);  // 4 counts, 100ms cycle
00290 
00291     SpiMAD8402.format(8, 0);
00292     SpiMAD8402.frequency(AD8402_SPI_SPEED);
00293 
00294     SpiMAdc.format(8, 0);
00295     SpiMAdc.frequency(MCP3008_SPI_SPEED);
00296     
00297     SyncIn.mode(PullDown);
00298     AutoRunSw.mode(PullUp);
00299 
00300     frequency = 100.0f;
00301     amplitude = 1.0f;
00302     noiseAmplitude = 1.0f;
00303     bpm = 120.0f;
00304     
00305     readParams();
00306 
00307     ticks = 0;
00308     Ticker samplingTicker;
00309     samplingTicker.attach(&update, (1.0f/ENVELOPE_UPDATE_RATE));
00310     
00311     // Sync Interrupt
00312     SyncIn.rise(&syncInFunction);
00313     SyncIn.mode(PullDown);
00314 
00315     for (;;) {
00316 #if (PIN_CHECK)
00317         Dout3 = 1;
00318 #endif
00319 
00320         readParams();
00321 
00322 #if (PIN_CHECK)
00323         Dout3 = 0;
00324 #endif
00325 
00326 
00327 #if UART_TRACE
00328         printf("%.1f\t%d\t", bpm, envelopeLength);
00329 
00330         printf("| %d\t%d\t", amplitudeParam.attack, amplitudeParam.release);
00331         printf("%.2f\t%.2f\t%.2f\t", amplitudeParam.v0, amplitudeParam.v1, amplitudeParam.v2);
00332         printf("%.2f\t%.2f\t", amplitudeParam.attackTauRatio, amplitudeParam.releaseTauRatio);
00333 
00334         printf("| %d\t%d\t", frequencyParam.attack, frequencyParam.release);
00335         printf("%.2f\t%.2f\t%.2f\t", frequencyParam.v0, frequencyParam.v1, frequencyParam.v2);
00336         printf("%.2f\t%.2f\t", frequencyParam.attackTauRatio, frequencyParam.releaseTauRatio);
00337         
00338         printf("| %d\t%d\t", noiseAmplitudeParam.attack, noiseAmplitudeParam.release);
00339         printf("%.2f\t%.2f\t%.2f\t", noiseAmplitudeParam.v0, noiseAmplitudeParam.v1, noiseAmplitudeParam.v2);
00340         printf("%.2f\t%.2f\t", noiseAmplitudeParam.attackTauRatio, noiseAmplitudeParam.releaseTauRatio);
00341         
00342         printf("| AutoRun:%d\t", int(AutoRunSw));
00343 #endif
00344 
00345         PWMon.check();
00346 
00347         Thread::wait(1);
00348     }
00349 }