#include #define PIN 2 #define NUMPIXELS 264 Adafruit_NeoPixel pixels(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800); #define ACT_COUNT 10 #define ACT_DELAY 100 #define ROUND_SIZE 3 #define ANA_PIN A1 size_t rtt_adc_convs = 0; #define ADC_VAL_CNT 700 int8_t adc_storage[ADC_VAL_CNT]; void setup() { cli(); /* For debug purposes */ Serial.begin(230400); pinMode(ANA_PIN, INPUT); pixels.setBrightness(255); pixels.begin(); pixels.fill(pixels.Color(0xFF,0xFF,0xFF)); pixels.show(); delay(1000); /* Init ADC and timer registers */ ADCSRA |= (1<= 1;i--){ adc_storage[i] = adc_storage[i-1]; } return; } uint8_t get_max_adc_val(size_t beginning, size_t end){ uint8_t val = 0x00; for(size_t i = beginning; i < end;i++){ if( adc_storage[i] > 0 && (adc_storage[i] > val)){ val = adc_storage[i]; }else if( adc_storage[i] < 0 && (-adc_storage[i]) > val){ val = -adc_storage[i]; } } return val; } uint8_t get_avg_adc_val(size_t beginning, size_t end){ uint16_t val = 0x0000; for(size_t i = beginning; i < end;i++){ if( adc_storage[i] > 0){ val += adc_storage[i]; }else { val += -adc_storage[i]; } } return (val/(end-beginning))*1.41421356; } int8_t get_adc(){ ADCSRA |= (1<> ADSC) & 0x1){ /* Conversion in progress*/} uint8_t val = ADCH; return val; } uint32_t Wheel(byte WheelPos) { if(WheelPos < 85) { return pixels.Color(WheelPos * 3, 255 - WheelPos * 3, 0); } else if(WheelPos < 170) { WheelPos -= 85; return pixels.Color(255 - WheelPos * 3, 0, WheelPos * 3); } else { WheelPos -= 170; return pixels.Color(0, WheelPos * 3, 255 - WheelPos * 3); } } void loop() { #if 0 static size_t ii = 0; if(ii >= ROUND_SIZE){ pixels.fill(pixels.Color(0x00,0x00,0x00)); ii = 0; } for(size_t i = ii; i < NUMPIXELS; i+=ROUND_SIZE){ pixels.setPixelColor(i, pixels.Color(0x00, 0x00, (0xFF/ROUND_SIZE)*ii)); } pixels.show(); delay(100); ii++; #endif PORTC ^= 1<<5; /* Reference Point for the 100% Mark and the AGC */ uint8_t max_val = get_max_adc_val(0, ADC_VAL_CNT); if(max_val < 20){ /* If the signal is very low, the AGC should not kick in */ max_val = 20; } /* We took to long to complete one Round Trip. Take all we have! */ if(rtt_adc_convs >= ADC_VAL_CNT){ rtt_adc_convs = ADC_VAL_CNT; } uint8_t avg_last_rtt = get_avg_adc_val(0,rtt_adc_convs); rtt_adc_convs = 0; #ifdef MAX_BAR uint8_t reg_max = get_max_adc_val(0, rtt_adc_convs); #endif /* Calculate the average loudness of the signal since the last RTT and * derive the height of the signal on the tower from it. */ float perc = (avg_last_rtt*1.0)/(max_val*1.0); size_t height = NUMPIXELS * perc; Serial.println(avg_last_rtt); #ifdef MAX_BAR float regperc = (avg_last64*1.0)/(reg_max*1.0); size_t regheight = NUMPIXELS * regperc; #else size_t regheight = height; #endif /* One circle on the top which falls down */ static size_t reg_height = 0; if(regheight > reg_height){ reg_height = regheight; }else if(regheight < reg_height){ if(reg_height >= 2){ reg_height-=2; }else{ reg_height = 0; } } pixels.fill(pixels.Color(0x00,0x00,0x00)); /* Fill the tower */ for(size_t i = 0; i < height && i < NUMPIXELS; i++){ float mul = 1.0; pixels.setPixelColor(i, pixels.Color(((i*mul)/NUMPIXELS)*0xFF, (NUMPIXELS-(i*mul)/NUMPIXELS)*0xFF, 0x00)); } static uint8_t stat = 0; /* Fill the dropdown max value */ for(size_t i = reg_height; i < reg_height+ROUND_SIZE && i < NUMPIXELS; i++){ pixels.setPixelColor(i, Wheel(((i-reg_height)+stat) & 255)); } stat++; PORTC ^= 1<<5; pixels.show(); return; } // Interrupt subroutine for ADC conversion complete interrupt ISR(ADC_vect) { /* Adjust the value in the ADC register to fit into an int8_t which is * centered around the 2.5V value ~. The maximum Amplitude is less than * 1V Vpp usually */ uint16_t val = ADC; int16_t symm = (val-(1024/2)); if(symm >=0){ symm >>= 1; symm &=0xFF; }else{ int16_t inv = -symm; inv >>= 1; inv &= 0xFF; symm = - inv; } int8_t res = symm; /* Insert the gotten value into the array */ lshift_adc_vals(); adc_storage[0] = res; rtt_adc_convs++; }