Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: AverageMCP3008 mbed-rtos mbed mcp3008
Fork of KIK01_Proto03 by
main.cpp
- Committer:
- ryood
- Date:
- 2017-10-21
- Revision:
- 31:3c7e1cd0d947
- Parent:
- 30:1291e20b1c53
File content as of revision 31:3c7e1cd0d947:
/*
* KIK01
* Kick Machine
*
* 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 (1)
#define PIN_CHECK (1)
#define TITLE_STR1 ("KIK01 Kick Machine")
#define TITLE_STR2 ("20171020")
#define PI_F (3.1415926f)
#define MCP3008_SPI_SPEED (1312500)
#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)
AnalogOut Dac1(PA_4);
AnalogOut Dac2(PA_5);
// 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);
// MCP3008 SPI
// SPI (PinName mosi, PinName miso, PinName sclk, PinName ssel=NC)
SPI SpiMAdc(PB_5, PB_4, PB_3);
MCP3008 Adc1(&SpiMAdc, PB_10);
MCP3008 Adc2(&SpiMAdc, PA_8);
MCP3008 Adc3(&SpiMAdc, PA_9);
AverageMCP3008 AvgAdc1(&Adc1, AVERAGE_BUFFER_SIZE);
AverageMCP3008 AvgAdc2(&Adc2, AVERAGE_BUFFER_SIZE);
AverageMCP3008 AvgAdc3(&Adc3, AVERAGE_BUFFER_SIZE);
// Sync
DigitalOut SyncPin(PA_10);
// Check pins
DigitalOut Dout1(PB_9);
DigitalOut Dout2(PB_8);
DigitalOut Dout3(PB_6);
EnvelopeAR envelopeFrequency(5, 300, 880.0f, 120.0f, 40.0f, 0.36f, 0.1f);
EnvelopeAR envelopeAmplitude(50, 200, 0.99f, 1.0f, 0.0f);
EnvelopeAR envelopeNoiseAmplitude(50, 200, 0.99f, 1.0f, 0.0f);
EnvelopeParam frequencyParam;
EnvelopeParam amplitudeParam;
EnvelopeParam noiseAmplitudeParam;
volatile int ticks;
volatile float frequency;
volatile float amplitude;
volatile float noiseAmplitude;
volatile float bpm;
volatile int envelopeLength;
volatile int stepLength;
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 * frequency * 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 * 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 (ticks % stepLength == 0) {
SyncPin = 1;
}
// set envelope parameters
envelopeAmplitude.setParam(amplitudeParam);
envelopeFrequency.setParam(frequencyParam);
envelopeNoiseAmplitude.setParam(noiseAmplitudeParam);
frequency = envelopeFrequency.getAmplitude(ticks);
amplitude = envelopeAmplitude.getAmplitude(ticks);
noiseAmplitude = envelopeNoiseAmplitude.getAmplitude(ticks);
DcoSetFrequency(frequency);
DcaSetAmplitude(1, amplitude); // DCO
DcaSetAmplitude(2, noiseAmplitude); // NOS01
ticks++;
if (ticks >= envelopeLength) {
ticks = 0;
}
// Output SyncSignal
SyncPin = 0;
#if (PIN_CHECK)
Dout1 = 0;
#endif
}
void readParams()
{
bpm = AvgAdc1.read_input(7) * 180.0f + 60.0f;
envelopeLength = 60 * ENVELOPE_UPDATE_RATE / bpm;
stepLength = envelopeLength / 4;
amplitudeParam.attack = AvgAdc1.read_input(0) * envelopeLength;
amplitudeParam.release = AvgAdc1.read_input(1) * envelopeLength;
amplitudeParam.v0 = AvgAdc1.read_input(4);
amplitudeParam.v1 = AvgAdc1.read_input(5);
amplitudeParam.v2 = AvgAdc1.read_input(6);
amplitudeParam.attackTauRatio = AvgAdc1.read_input(2) + 0.01f;
amplitudeParam.releaseTauRatio = AvgAdc1.read_input(3) + 0.01f;
frequencyParam.attack = AvgAdc2.read_input(0) * envelopeLength * 0.1f;
frequencyParam.release = AvgAdc2.read_input(1) * envelopeLength + 1;
frequencyParam.v0 = AvgAdc2.read_input(4) * 4000.0f;
frequencyParam.v1 = AvgAdc2.read_input(5) * 400.0f;
frequencyParam.v2 = AvgAdc2.read_input(6) * 400.0f;
frequencyParam.attackTauRatio = AvgAdc2.read_input(2) + 0.01f;
frequencyParam.releaseTauRatio = AvgAdc2.read_input(3) + 0.01f;
noiseAmplitudeParam.attack = AvgAdc3.read_input(0) * envelopeLength;
noiseAmplitudeParam.release = AvgAdc3.read_input(1) * envelopeLength;
noiseAmplitudeParam.v0 = AvgAdc3.read_input(4);
noiseAmplitudeParam.v1 = AvgAdc3.read_input(5);
noiseAmplitudeParam.v2 = AvgAdc3.read_input(6);
noiseAmplitudeParam.attackTauRatio = AvgAdc3.read_input(2) + 0.01f;
noiseAmplitudeParam.releaseTauRatio = AvgAdc3.read_input(3) + 0.01f;
}
int main()
{
#if UART_TRACE
printf("\r\n\n%s %s\r\n", TITLE_STR1, TITLE_STR2);
#endif
SpiMAD8402.format(8, 0);
SpiMAD8402.frequency(AD8402_SPI_SPEED);
SpiMAdc.format(8, 0);
SpiMAdc.frequency(MCP3008_SPI_SPEED);
frequency = 100.0f;
amplitude = 1.0f;
noiseAmplitude = 1.0f;
bpm = 120.0f;
readParams();
ticks = 0;
Ticker samplingTicker;
samplingTicker.attach(&update, (1.0f/ENVELOPE_UPDATE_RATE));
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", amplitudeParam.attack, amplitudeParam.release);
printf("%.2f\t%.2f\t%.2f\t", amplitudeParam.v0, amplitudeParam.v1, amplitudeParam.v2);
printf("%.2f\t%.2f\t", amplitudeParam.attackTauRatio, amplitudeParam.releaseTauRatio);
printf("| %d\t%d\t", frequencyParam.attack, frequencyParam.release);
printf("%.2f\t%.2f\t%.2f\t", frequencyParam.v0, frequencyParam.v1, frequencyParam.v2);
printf("%.2f\t%.2f\t", frequencyParam.attackTauRatio, frequencyParam.releaseTauRatio);
printf("| %d\t%d\t", noiseAmplitudeParam.attack, noiseAmplitudeParam.release);
printf("%.2f\t%.2f\t%.2f\t", noiseAmplitudeParam.v0, noiseAmplitudeParam.v1, noiseAmplitudeParam.v2);
printf("%.2f\t%.2f\r\n", noiseAmplitudeParam.attackTauRatio, noiseAmplitudeParam.releaseTauRatio);
#endif
Thread::wait(1);
}
}
