KIK01 Release
Dependencies: mcp3008 mbed mbed-rtos AverageMCP3008 VoltageMonitor
main.cpp
- Committer:
- ryood
- Date:
- 2019-02-23
- Revision:
- 40:2e252971aa08
- Parent:
- 39:3c73531d13a2
- Child:
- 41:ac576c48eace
File content as of revision 40:2e252971aa08:
/* * KIK01 * Kick Machine * * 2019.02.23 Ver.1.01 Dual SyncIns / SyncOuts * 2018.01.17 Release * 2017.12.15 Proto08: LEDs * 2017.12.03 Proto07: SyncIn * 2017.11.29 Proto06: Add Power Monitor * 2017.10.19 Proto05: Add NOS01 Controller * 2017.09.16 Proto04: SPI1 for AD8402 Wein Bridge DCO & Internal DAC for Dual-OTA-VCA * 2017.07.04 Proto03: MCP4922 DCA * 2017.06.19 Proto02 * 2017.06.04 created. * */ #include "mbed.h" #include "rtos.h" #include "mcp3008.h" #include "AverageMCP3008.h" #include "EnvelopeAR.h" #define UART_TRACE (0) #include "VoltageMonitor.h" #define PIN_CHECK (0) #define LED_SYNCOUT_BLINK (1) #define TITLE_STR1 ("KIK01 Kick Machine Ver.1.0.1") #define TITLE_STR2 ("20190223") #define TITLE_STR3 (__TIME__) #define PI_F (3.1415926f) #define MCP3008_SPI_SPEED (1406250) #define AD8402_SPI_SPEED (10000000) #define ENVELOPE_UPDATE_RATE (32000) // Hz #define AD8402_RMAX (10000.0f) #define AD8402_RMIN (50.0f) #define AVERAGE_BUFFER_SIZE (4) #define PM_VDD (3.32f) #define PM_LoThreshold (2.3f) #define PM_HiThreshold (2.7f) #define LED_BEAT_KIK_BLINK_CYCLE (0.15f) #define LED_BEAT_NOS_BLINK_CYCLE (0.15f) #define LED_SYNCIN_KIK_BLINK_CYCLE (0.04f) #define LED_SYNCIN_NOS_BLINK_CYCLE (0.04f) #define LED_SYNCOUT_KIK_BLINK_CYCLE (0.04f) #define LED_SYNCOUT_NOS_BLINK_CYCLE (0.04f) // LEDs DigitalOut LedPower(PB_2); DigitalOut LedBeatKik(PA_12); DigitalOut LedSyncInKik(PA_11); DigitalOut LedSyncOutKik(PB_12); DigitalOut LedBeatNos(PC_8); DigitalOut LedSyncInNos(PC_6); DigitalOut LedSyncOutNos(PC_5); // Envelope Output AnalogOut Dac1(PA_4); // Kik AnalogOut Dac2(PA_5); // Nos // AD8402 SPI (SPI2) // SPI (PinName mosi, PinName miso, PinName sclk, PinName ssel=NC) SPI SpiMAD8402(PB_15, PB_14, PB_13); DigitalOut AD8402Cs(PC_4, 1); // Initaially Inactive // MCP3008 SPI // SPI (PinName mosi, PinName miso, PinName sclk, PinName ssel=NC) SPI SpiMAdc(PB_5, PB_4, PB_3); MCP3008 Adc1(&SpiMAdc, PA_9); MCP3008 Adc2(&SpiMAdc, PA_8); MCP3008 Adc3(&SpiMAdc, PB_10); AverageMCP3008 AvgAdc1(&Adc1, AVERAGE_BUFFER_SIZE); AverageMCP3008 AvgAdc2(&Adc2, AVERAGE_BUFFER_SIZE); AverageMCP3008 AvgAdc3(&Adc3, AVERAGE_BUFFER_SIZE); // Power Monitor AnalogIn PowerMonitorIn(PA_0); VoltageMonitor PWMon(&PowerMonitorIn, PM_VDD, PM_LoThreshold, PM_HiThreshold, &LedPower); // Sync DigitalOut SyncOutKik(PC_12); DigitalOut SyncOutNos(PD_2); InterruptIn SyncInKik(PC_10); InterruptIn SyncInNos(PC_11); DigitalIn AutoRunSw(PB_1); // Check pins DigitalOut Dout1(D14); DigitalOut Dout2(D15); DigitalOut Dout3(D2); EnvelopeAR envelopeFrequencyKik(5, 300, 880.0f, 120.0f, 40.0f, 0.36f, 0.1f); EnvelopeAR envelopeAmplitudeKik(50, 200, 0.99f, 1.0f, 0.0f); EnvelopeAR envelopeAmplitudeNos(50, 200, 0.99f, 1.0f, 0.0f); EnvelopeParam frequencyParamKik; EnvelopeParam amplitudeParamKik; EnvelopeParam amplitudeParamNos; Timeout timeoutLedBeatKik; Timeout timeoutLedBeatNos; Timeout timeoutLedSyncInKik; Timeout timeoutLedSyncInNos; #if (LED_SYNCOUT_BLINK) Timeout timeoutLedSyncOutKik; Timeout timeoutLedSyncOutNos; #endif volatile int ticksKik; volatile int ticksNos; volatile float frequencyKik; volatile float amplitudeKik; volatile float amplitudeNos; volatile int envelopeLength; volatile int stepLength; float bpm; //----------------------------------------------------------------------------- // Interrupt Service Routine //----------------------------------------------------------------------------- void ledBeatAtTimeoutKik() { LedBeatKik = 0; } void ledBeatAtTimeoutNos() { LedBeatNos = 0; } void ledSyncInAtTimeoutKik() { LedSyncInKik = 0; } void ledSyncInAtTimeoutNos() { LedSyncInNos = 0; } #if (LED_SYNCOUT_BLINK) void ledSyncOutAtTimeoutKik() { LedSyncOutKik = 0; } void ledSyncOutAtTimeoutNos() { LedSyncOutNos = 0; } #endif void syncInFunctionKik() { ticksKik = 0; LedSyncInKik = 1; timeoutLedSyncInKik.attach(&ledSyncInAtTimeoutKik, LED_SYNCIN_KIK_BLINK_CYCLE); } void syncInFunctionNos() { ticksNos = 0; LedSyncInNos = 1; timeoutLedSyncInNos.attach(&ledSyncInAtTimeoutNos, LED_SYNCIN_NOS_BLINK_CYCLE); } void AD8402Write(uint8_t address, uint8_t value) { #if (PIN_CHECK) Dout2 = 1; #endif AD8402Cs = 0; SpiMAD8402.write(address); SpiMAD8402.write(value); AD8402Cs = 1; //wait_us(1); #if (PIN_CHECK) Dout2 = 0; #endif } void DcoSetFrequency(float freq) { const float c = 0.00000047; float r = 1.0f / (2.0f * PI_F * frequencyKik * c); if (r < AD8402_RMIN) r = AD8402_RMIN; if (r > AD8402_RMAX) r = AD8402_RMAX; uint8_t v = 256.0f * (r - AD8402_RMIN) / AD8402_RMAX; AD8402Write(0, v); AD8402Write(1, v); } void DcaSetAmplitude(int channel, float amp) { switch (channel) { case 1: Dac1.write(amp); break; case 2: //Dac2.write(amp); Dac2.write(amp * 0.8f); // Avoid LED,s Non-Linearity break; default: error("DcaSetAmplitude(): invalid channel"); } } void update() { #if (PIN_CHECK) Dout1 = 1; #endif // Output Sync Signal per steps if (ticksKik % stepLength == 0) { SyncOutKik = 1; #if (LED_SYNCOUT_BLINK) LedSyncOutKik = 1; timeoutLedSyncOutKik.attach(&ledSyncOutAtTimeoutKik, LED_SYNCOUT_KIK_BLINK_CYCLE); #endif } if (ticksNos % stepLength == 0) { SyncOutNos = 1; #if (LED_SYNCOUT_BLINK) LedSyncOutNos = 1; timeoutLedSyncOutNos.attach(&ledSyncOutAtTimeoutNos, LED_SYNCOUT_NOS_BLINK_CYCLE); #endif } // set envelope parameters envelopeAmplitudeKik.setParam(amplitudeParamKik); envelopeFrequencyKik.setParam(frequencyParamKik); envelopeAmplitudeNos.setParam(amplitudeParamNos); frequencyKik = envelopeFrequencyKik.getAmplitude(ticksKik); amplitudeKik = envelopeAmplitudeKik.getAmplitude(ticksKik); amplitudeNos = envelopeAmplitudeNos.getAmplitude(ticksNos); DcoSetFrequency(frequencyKik); DcaSetAmplitude(1, amplitudeKik); DcaSetAmplitude(2, amplitudeNos); ticksKik++; ticksNos++; if (AutoRunSw && ticksKik >= envelopeLength) { ticksKik = 0; LedBeatKik = 1; timeoutLedBeatKik.attach(&ledBeatAtTimeoutKik, LED_BEAT_KIK_BLINK_CYCLE); } if (AutoRunSw && ticksNos >= envelopeLength) { ticksNos = 0; LedBeatNos = 1; timeoutLedBeatNos.attach(&ledBeatAtTimeoutNos, LED_BEAT_NOS_BLINK_CYCLE); } // Output SyncSignal SyncOutKik = 0; SyncOutNos = 0; #if (PIN_CHECK) Dout1 = 0; #endif } //----------------------------------------------------------------------------- // Functions //----------------------------------------------------------------------------- void readParams() { bpm = AvgAdc1.read_input(7) * 180.0f + 60.0f; envelopeLength = 60 * ENVELOPE_UPDATE_RATE / bpm; stepLength = envelopeLength / 4; amplitudeParamKik.attack = AvgAdc1.read_input(0) * envelopeLength + 1; amplitudeParamKik.release = AvgAdc1.read_input(1) * envelopeLength; amplitudeParamKik.v0 = AvgAdc1.read_input(4); amplitudeParamKik.v1 = AvgAdc1.read_input(5); amplitudeParamKik.v2 = AvgAdc1.read_input(6); amplitudeParamKik.attackTauRatio = AvgAdc1.read_input(2) + 0.01f; amplitudeParamKik.releaseTauRatio = AvgAdc1.read_input(3) + 0.01f; frequencyParamKik.attack = AvgAdc2.read_input(0) * envelopeLength * 0.1f; frequencyParamKik.release = AvgAdc2.read_input(1) * envelopeLength + 1; frequencyParamKik.v0 = AvgAdc2.read_input(4) * 4000.0f; frequencyParamKik.v1 = AvgAdc2.read_input(5) * 400.0f; frequencyParamKik.v2 = AvgAdc2.read_input(6) * 400.0f; frequencyParamKik.attackTauRatio = AvgAdc2.read_input(2) + 0.01f; frequencyParamKik.releaseTauRatio = AvgAdc2.read_input(3) + 0.01f; amplitudeParamNos.attack = AvgAdc3.read_input(0) * envelopeLength + 1; amplitudeParamNos.release = AvgAdc3.read_input(1) * envelopeLength; amplitudeParamNos.v0 = AvgAdc3.read_input(4); amplitudeParamNos.v1 = AvgAdc3.read_input(5); amplitudeParamNos.v2 = AvgAdc3.read_input(6); amplitudeParamNos.attackTauRatio = AvgAdc3.read_input(2) + 0.01f; amplitudeParamNos.releaseTauRatio = AvgAdc3.read_input(3) + 0.01f; } void LedsCheck(int n, int wait) { for (int i = 0; i < n; i++) { LedBeatKik = 1; Thread::wait(wait); LedBeatKik = 0; LedSyncInKik = 1; Thread::wait(wait); LedSyncInKik = 0; LedSyncOutKik = 1; Thread::wait(wait); LedSyncOutKik = 0; } } int main() { printf("\r\n\n%s %s %s\r\n", TITLE_STR1, TITLE_STR2, TITLE_STR3); // LEDs Check LedsCheck(4, 100); // 4 counts, 100ms cycle SpiMAD8402.format(8, 0); SpiMAD8402.frequency(AD8402_SPI_SPEED); SpiMAdc.format(8, 0); SpiMAdc.frequency(MCP3008_SPI_SPEED); SyncInKik.mode(PullDown); SyncInNos.mode(PullDown); AutoRunSw.mode(PullUp); frequencyKik = 100.0f; amplitudeKik = 1.0f; amplitudeNos = 1.0f; bpm = 120.0f; readParams(); ticksKik = 0; ticksNos = 0; Ticker samplingTicker; samplingTicker.attach(&update, (1.0f/ENVELOPE_UPDATE_RATE)); // Sync Interrupt SyncInKik.rise(&syncInFunctionKik); SyncInNos.rise(&syncInFunctionNos); for (;;) { #if (PIN_CHECK) Dout3 = 1; #endif readParams(); #if (PIN_CHECK) Dout3 = 0; #endif #if UART_TRACE printf("%.1f\t%d\t", bpm, envelopeLength); printf("| %d\t%d\t", amplitudeParamKik.attack, amplitudeParamKik.release); printf("%.2f\t%.2f\t%.2f\t", amplitudeParamKik.v0, amplitudeParamKik.v1, amplitudeParamKik.v2); printf("%.2f\t%.2f\t", amplitudeParamKik.attackTauRatio, amplitudeParamKik.releaseTauRatio); printf("| %d\t%d\t", frequencyParamKik.attack, frequencyParamKik.release); printf("%.2f\t%.2f\t%.2f\t", frequencyParamKik.v0, frequencyParamKik.v1, frequencyParamKik.v2); printf("%.2f\t%.2f\t", frequencyParamKik.attackTauRatio, frequencyParamKik.releaseTauRatio); printf("| %d\t%d\t", amplitudeParamNos.attack, amplitudeParamNos.release); printf("%.2f\t%.2f\t%.2f\t", amplitudeParamNos.v0, amplitudeParamNos.v1, amplitudeParamNos.v2); printf("%.2f\t%.2f\t", amplitudeParamNos.attackTauRatio, amplitudeParamNos.releaseTauRatio); printf("| AutoRun:%d\t", int(AutoRunSw)); #endif PWMon.check(); //Thread::wait(1); } }