From 64501dac6c53ec2b5836896b36e8c698b939c954 Mon Sep 17 00:00:00 2001 From: Alex Wulff Date: Tue, 19 Jul 2022 15:05:16 -0400 Subject: [PATCH] Added lots of comments --- pico-light-voice/source/main.cpp | 49 +++++++++++++++++++++++--------- 1 file changed, 35 insertions(+), 14 deletions(-) diff --git a/pico-light-voice/source/main.cpp b/pico-light-voice/source/main.cpp index f9c2fc0..55bf6c4 100644 --- a/pico-light-voice/source/main.cpp +++ b/pico-light-voice/source/main.cpp @@ -12,7 +12,16 @@ // ############ ADC and Model Stuff ############ +// NSAMP is the number of samples collected between each run of the +// machine learning code. An NSAMP of 1000 at a 4 kHz sample rate +// means the model will run once every quarter second. As each new +// batch of NSAMP samples are collected, the last INSIZE-NSAMP samples +// collected from the previous run are wrapped around to the beginning +// of the sample buffer, and the next NSAMP samples are added on #define NSAMP 1000 +// INSIZE is the input size of the model. In most cases, this should +// be one second's worth of data, so it should be equal to the sample +// rate of the ADC. #define INSIZE 4000 // set this to determine sample rate @@ -21,13 +30,19 @@ // 9600 = 5,000 Hz #define CLOCK_DIV 12000 +// ADC channel #define CAPTURE_CHANNEL 0 + +// Pin for light strip #define LED_PIN 25 + +// cooldown time for activating start #define COOLDOWN_US 1000000 float features[INSIZE]; uint16_t capture_buf[NSAMP]; uint16_t intermediate_buf[INSIZE]; +uint64_t last_on_time = 0; // ############ Functions ############ int raw_feature_get_data(size_t offset, size_t length, float *out_ptr) { @@ -40,18 +55,17 @@ int main() stdio_usb_init(); stdio_init_all(); - // function lives in lights.cpp + // Launch lighting core - function lives in lights.cpp multicore_launch_core1(core1_entry); gpio_init(LED_PIN); gpio_set_dir(LED_PIN, GPIO_OUT); + // configure Edge Impulse things ei_impulse_result_t result = {nullptr}; - signal_t features_signal; features_signal.total_length = INSIZE; features_signal.get_data = &raw_feature_get_data; - if (INSIZE != EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE) { while (1) { printf("Input frame size incorrect!\n"); @@ -60,7 +74,6 @@ int main() } adc_gpio_init(26 + CAPTURE_CHANNEL); - adc_init(); adc_select_input(CAPTURE_CHANNEL); adc_fifo_setup( @@ -86,8 +99,6 @@ int main() // Pace transfers based on availability of ADC samples channel_config_set_dreq(&cfg, DREQ_ADC); - - uint64_t last_on_time = 0; while (true) { adc_fifo_drain(); @@ -132,21 +143,22 @@ int main() const float thresh = 0.6; - uint32_t state = 0; + uint32_t model_result = 0; for (size_t ix = 0; ix < EI_CLASSIFIER_LABEL_COUNT; ix++) { + // activate only if it's above the threshold and cooldown is over if (ix == 2 && result.classification[ix].value > thresh && time_us_64()-last_on_time>COOLDOWN_US) { printf("START\n"); last_on_time = time_us_64(); - // Set the state to 1 for the keyword you use to turn the lights - // on and change the lighting state - state = 1; + // Set the result to 1 for the keyword you use to turn the + // lights on and or change the lighting state + model_result = 1; } if (ix == 3 && result.classification[ix].value > thresh) { printf("STOP\n"); - // Set the state to 2 for the keyword that turns off the lights - state = 2; + // Set the result to 2 for the keyword that turns off the lights + model_result = 2; } printf("%0.2f, ",result.classification[ix].value); @@ -156,14 +168,23 @@ int main() // If the lighting core wants a state update, and there's a state // update to give, then we'll send it over. - if (multicore_fifo_rvalid() && state != 0) { + if (multicore_fifo_rvalid() && model_result != 0) { multicore_fifo_pop_blocking(); - multicore_fifo_push_blocking(state); + multicore_fifo_push_blocking(model_result); } + // Signal processing done. Now wait for audio sampling to finish... + // You should see the LED flashing during the sampling period. If + // it is not flashing, the inferencing is taking too long and there + // is data loss between inferencing windows. See the tutorial for + // this project for more information. gpio_put(LED_PIN, 0); dma_channel_wait_for_finish_blocking(dma_chan); + // We want to be really quick here, otherwise we'll lose lots of + // audio between when we stopped sampling and when we start the next + // sampling window. Just doing some very fast moves (no conversions) + // wrap newest samples to beginning for (uint32_t i=0; i