#include <fix_fft.h>
//#include <TinyWireM.h>
#include "DigiKeyboard.h"
int i = 0;
int8_t data[128];
int8_t im[128];
byte sent = 0;
void setup() {
ADCSRA |= (1 << ADEN); // Turn ADC on
ADCSRA |= (1 << ADSC); // Start Conversion
ADCSRA |= (1 << ADATE); // ADC Auto Trigger Enable
ADMUX = 00000001; // use adc1
DIDR0 = 00000100; // turn off the digital input for adc1
// TinyWireM.begin();
}
void loop() {
for(i=0; i<128; i++) {
while(!(ADCSRA & _BV(ADIF))); // wait for adc to be ready (ADIF)
ADCSRA |= (1 << ADIF); // restart adc
byte m = ADCL; // fetch adc data
byte j = ADCH;
int k = ((int)j << 8) | m; // form into an int
data[i] = (int8_t)k;
}
fix_fft(data,im,7,0);
for (i=0; i< 64;i++) //real val is for the amplitude
data[i] = sqrt(data[i] * data[i] + im[i] * im[i]);
sent = data[16];
DigiKeyboard.println(data[15]);
// TinyWireM.beginTransmission(1); // Begin transmission mode to slave 1
//TinyWireM.send(sent); // Send 1 byte to the mega
//TinyWireM.endTransmission(); // End transmission
}
I have been copying code snippets from other online examples who claim it works but I'm not getting anything. I don't seem to be enabling the right bits in the right order or something. Can't seem to figure it out. Can anyone identify the problem, or perhaps simply suggest an easier way to do it?
All I want to do is have channel 1 (PB2) set to free running mode and then to store each conversion in the data array. That's it. Thank you.
Good catch. However the ADC doesn't appear to be running at full speed (free-running). A quick modification of the code to display micros shows that I'm only running the loop at 32 Hz, which is the same as it was when I used single-ended mode.
You can drive the ADC from a timer and should get a much higher throughput than you have quoted. You can also lower the resolution to say 8bits to make it faster. But you may have other problems too.
However, the ADC in the ATtiny85 is not as good as say that of the ATtiny84 or the ATmega328p.
I have an abandoned project where I tried to push the ATtiny85 ADC to its limits ( a demodulator which needed sampling at 9600 Hz with 8 bit resolution) . I gave up and used a ATmega328p. I can try to find some relics if it would help.
So the ADC is not of the same quality? I didn't know that.
BTW, I tinkered a bit more and determined that I was calling micros in the wrong place. I am indeed getting very close to 9600 Hz now (95 something). I have a signal generator that I fed into the PB2 pin at 6624 Hz and bucket 43 did display a magnitude of 5 on average (ranging from 1 to 9), whereas before it was stable at 0.
I intend to use a band-pass filter in hardware to remove any noise that might contaminate the input, which should help make the output cleaner. Perhaps this may help your project.
int i = 0, j=0;
int8_t data[128];
int8_t im[128];
byte sent = 0;
void setup() {
// ADCSRA = 0xe0+7;
ADCSRA |= (1 << ADEN); // Turn ADC on
ADCSRA |= (1 << ADSC); // Start Conversion
ADCSRA |= (1 << ADATE); // ADC Auto Trigger Enable
// ADCSRA |= (1 << ADPS2) | (1 << ADPS1); // approx 10kHz sample rate
// ADCSRA |= (1 << ADPS0);
ADMUX = 00000001; // use adc1
DIDR0 = 00000100; // turn off the digital input for adc1
// TinyWireM.begin();
}
void loop() {
/*
for (i=0; i < 128; i++){
data[i] = analogRead(PB1)*0.25-128;
im[i] = 0;
}
*/
for(i=0; i<128; i++) {
while(!(ADCSRA & _BV(ADIF))); // wait for adc to be ready (ADIF)
ADCSRA |= (1 << ADIF); // restart adc
byte m = ADCL; // fetch adc data
byte j = ADCH;
int k = ((int)j << 8) | m; // form into an int
data[i] = (int8_t)k*.25-128;
}
fix_fft(data,im,7,0);
for (i=0; i< 64;i++) //real val is for the amplitude
data[i] = sqrt(data[i] * data[i] + im[i] * im[i]);
sent = data[43];
DigiKeyboard.println(data[43]);
// TinyWireM.beginTransmission(1); // Begin transmission mode to slave 1
//TinyWireM.send(sent); // Send 1 byte to the mega
//TinyWireM.endTransmission(); // End transmission
}