Add files formerly without version control

Signed-off-by: Tyrolyean <tyrolyean@tyrolyean.net>
This commit is contained in:
Tyrolyean 2020-09-29 20:54:22 +02:00
parent d0db5f0cd8
commit 96236cc600
No known key found for this signature in database
GPG Key ID: 81EC9BAC5E9667C6
1 changed files with 209 additions and 0 deletions

209
test_spectr/test_spectr.ino Normal file
View File

@ -0,0 +1,209 @@
#include <Adafruit_NeoPixel.h>
#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<<ADEN) | (1<<ADIE) | (1<<ADATE);
ADMUX |= (0<<ADLAR) | (1<<REFS0)| (1<<MUX0);
ADCSRB |= (1<<ADTS2) | (0<<ADTS0);
TCCR0B &= ~((1<<2) | (1<<1) | (1<<0));
TCCR0B |= (1<<1) | (1<<0);
DDRC |= 1<<5;
PORTC = 0x00;
sei();
ADCSRA |= (1<<ADSC);
return;
}
void lshift_adc_vals(){
for(size_t i = ADC_VAL_CNT-1; i >= 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);
while((ADCSRA >> 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++;
}