diff --git a/firmware/Makefile b/firmware/Makefile index fb82ebd..e47cfcd 100644 --- a/firmware/Makefile +++ b/firmware/Makefile @@ -1,6 +1,6 @@ PROJECT=pentabug -APPS = buggy mariotheme geiger ducklings wuerfel blinker +APPS = buggy jumpy mariotheme geiger ducklings wuerfel blinker OPTIMIZATION = -Os MCU = atmega88pa diff --git a/firmware/apps/jumpy.c b/firmware/apps/jumpy.c new file mode 100644 index 0000000..2b14084 --- /dev/null +++ b/firmware/apps/jumpy.c @@ -0,0 +1,61 @@ +#include +#include +#include +#include +#include +#include + +#define SENSITIVITY_FACT 4 + +static uint16_t max_sound; +static uint8_t first; + +static void init(void) { + pentatonic_direction(ALL_OUT); + listen_init(); + + max_sound = 5; + first = 0; +} + +static void run(void) { + uint16_t sound = listen_measure(); + + pentatonic_all_led_set(max_sound >> 5); + + if(!first && sound > max_sound / SENSITIVITY_FACT) { + int8_t intensity = SENSITIVITY_FACT + 1 - max_sound / sound; + + intensity = MIN(intensity, SENSITIVITY_FACT + 1); + + motor_on(); + + set_note(NOTE_C, (rand() & 3) + 3); + + for(size_t i = 0; i < intensity; ++i) { + led_set(RIGHT, rand() & 1); + led_set(LEFT, rand() & 1); + + wait_ms(100); + } + + // turn everything off + + stop_note(); + + motor_off(); + + led_off(RIGHT); + led_off(LEFT); + + wait_ms(100); + } else { + first = 0; + } + + if(sound > max_sound) { + max_sound = sound; + } +} + +REGISTER(run, init, NULL); diff --git a/firmware/include/pentabug/listen.h b/firmware/include/pentabug/listen.h new file mode 100644 index 0000000..f75b572 --- /dev/null +++ b/firmware/include/pentabug/listen.h @@ -0,0 +1,12 @@ +#ifndef LISTEN_H +#define LISTEN_H + +#include + +void listen_init(void); + +void listen_stop(void); + +uint16_t listen_measure(void); + +#endif /* LISTEN_H */ diff --git a/firmware/lib/listen.c b/firmware/lib/listen.c new file mode 100644 index 0000000..8fb3254 --- /dev/null +++ b/firmware/lib/listen.c @@ -0,0 +1,66 @@ +#include + +#include + +#include +#include + +void listen_init(void) { + ADCSRA |= (1 << ADEN); +} + +void listen_stop(void) { + ADCSRA &= ~(1 << ADEN); +} + +uint16_t listen_measure(void) { + // save previous state + + uint8_t prev_state = PINC & (1 << 0); + + // set to ground for discharge + + DDRC |= 1 << 0; + PORTC &= ~(1 << 0); + + // wait for discharge + + wait_ms(1); + + // set direction to input for measurement + + DDRC &= ~(1 << 0); + + // collect some sound waves + + wait_ms(1); + + // start measurement + + // TODO: why can't i move this to the initialization? + ADMUX = (1 << REFS0) | (1 << ADLAR); + ADCSRA |= (1 << ADPS2) | (1 << ADPS1); + + ADMUX = (ADMUX & ~(0x1F)) | 0; + + ADCSRA |= (1 << ADSC); + + // wait for measurement to finish + + while (ADCSRA & (1 << ADSC)) test_stop_app(); + + uint16_t res = ADCL; + res |= ADCH << 8; + + // restore state + + if(prev_state) { + PORTC |= 1 << 0; + } + + DDRC |= 1 << 0; + + // done + + return res; +}