//Pins
const int led_pin = PB5;//D13-->PB5
//Counter and compare values
const uint16_t t1_load = 0;
const uint16_t t1_comp =31250;// timer clk:16Mhz, 1ms duration (16MHz)(1ms) 16,000
//ADC Variables
volatile bool flgAcqDone = false;
const int bLen =20; //128;
volatile int buffer[bLen + 1];
void setup() {
Serial.begin(9600);
cli();
//----------Counter timer setup
//Set LED Pin to be output
//PORTB=b00000000;
//DDRB=b00000000; //D13-->PB5
DDRB |= (1 << led_pin);
//Serial.print("DDRB: "); Serial.println(DDRB, BIN);
newsetup();
/*
//Reset Timer1 Control Register
//Timer Counter Control Reg 1A TCCR1A
//b7 b6 b5 b4 b3 b2 b1 b0
//COM1A1 COM1A0 COM1B1 COM1B0 - - WGM11 WGM10
TCCR1B = 0;
TCCR1A = 0;
//Reset Timer1 and set compare value
//Timer Counter Control Reg 1B TCCR1B
//b7 b6 b5 b4 b3 b2 b1 b0
//ICNC1 ICES1 - WGM13 WGM12 CS12 CS11 CS10
//Set prescaler to 256: b2 b1 b0= 100 XXX set prescaler X1=16MHz CS12, CS11, CS10=001
TCCR1B |= (1 << CS12);
TCCR1B &= ~(1 << CS11);
TCCR1B &= ~(1 << CS10);
//Set CTC Mode (Clear Timer on Compare Match)
TCCR1B &= ~(1 << WGM13);
TCCR1B |= (1 << WGM12);
Serial.print("TCCR1B: "); Serial.println(TCCR1B, BIN);
//Reset Timer1 and set compare values
//Timer Counter 1: TCNT1H TCNT1L 2 bytes = TCNT1
//Timer Counter 1 Output Compare Register B High & Low byte OCR1B=OCR1BH,OCR1BL
TCNT1 = t1_load;
OCR1B = t1_comp;
OCR1A = t1_comp;//Seems had to int to make work
Serial.print("OCR1B: "); Serial.println(OCR1B, HEX);
Serial.print("TCNT1: "); Serial.println(TCNT1, BIN);
//Enable Timer1 compare interrupt
//Timer/counter1 Interrupt Mask Register
//b7 b6 b5 b4 b3 b2 b1 b0
//- - ICIE1 - - OCIE1B OCIE1A TOIE1
TIMSK1 = (1 << OCIE1B);
Serial.print("TIMSK1: "); Serial.println(TIMSK1, BIN);
//------------ADC Setup--------------------------
//ADSRA ADC Control anb Status Register
//b7 b6 b5 b4 b3 b2 b1 b0
//ADEN ADSC ADATE ADIF ADIE ADPS2 ADPS1 ADPS0
//ADMUX ADC Multplexer Selection Regester
//b7 b6 b5 b4 b3 b2 b1 b0
//REFS1 REFS0 ADLAR - MUX3 MUX2 MUX1 MUX0
ADCSRA |= B00000111;//1<<ADPS2 |= 1<<ADPS1 |= 1<<ADPS0;//Set Prescaler to 128 Fclk,ADC=16MHz/128=125kHz <200kHz
ADMUX &= 0 << ADLAR; //Sets 10 bit result
ADMUX |= 1 << REFS0; //Select adc reference (AVCC with external cap at AREF pin)
//ADCSRB
//b7 b6 b5 b4 b3 b2 b1 b0
//- ACME - - - ADTS2 ADTS1 ADTS0
//Set ADC Trigger Timer/Counter1 compare match B ADTS2, ADTS1, ADTS0= 101
ADCSRB |= (1 << ADTS2);
ADCSRB &= ~(1 << ADTS1);
ADCSRB |= (1 << ADTS0);
Serial.print("ADCSRB: "); Serial.println(ADCSRB);
//ADCSRA
//b7 b6 b5 b4 b3 b2 b1 b0
//ADEN ADSC ADATE ADIF ADIE ADPS2 ADPS1 ADPS0
ADCSRA |= 1 << ADIE; //Enable interrupts
ADCSRA |= 1 << ADEN; //Enable ADC
ADCSRA |= 1 << ADATE; //1: Enables Auto Trigging
ADCSRA &= ~(1 << ADSC); //aLLow Timer1 to trigger start conversion
ADCSRA |= 1 << ADIF; //1: AD Interrupt Flag
sei();//Enable global interrupts
// ADCSRA |= 1 << ADSC; //Start first conversion
Serial.print("ADCSRA: "); Serial.println(ADCSRA);
//Enable Global interrupts
// Serial.print("SREG: "); Serial.println(SREG);
*/
sei();
ADCSRA |= 1 << ADSC; //Start first conversion
//Serial.print("SREG: "); Serial.println(SREG);
}
void newsetup() {
//https://forum.arduino.cc/t/help-with-adc-auto-triggering/215511/4
const uint16_t smpl_Time = 4096;
//ADCSRA
//b7 b6 b5 b4 b3 b2 b1 b0
//ADEN ADSC ADATE ADIF ADIE ADPS2 ADPS1 ADPS0
ADCSRA = (1 << ADEN) | // 1 = ADC Enable
(0 << ADSC) & // ADC Start Conversion
~(1 << ADATE) | // 1 = ADC Auto Trigger Enable
(0 << ADIF) | // ADC Interrupt Flag
(0 << ADIE) | // ADC Interrupt Enable
(1 << ADPS2) |
(1 << ADPS1) | // ADC Prescaler : ADS0=0 Selects 250 kHz. // ADS0=1 Selects 125 kHz.
(1 << ADPS0);
//ADCSRB
//b7 b6 b5 b4 b3 b2 b1 b0
//- ACME - - - ADTS2 ADTS1 ADTS0
// ADCSRB = ((1 << ADTS2) | // Sets Auto Trigger source - Timer/Counter1 Compare Match B
// (0 << ADTS1) |
// (1 << ADTS0));
ADCSRB = ((0 << ADTS2) & (0 << ADTS1) & (0 << ADTS0)); // Sets Freerun mode
/* Set up TIMER 1 - ADC sampler */
TIMSK0 = 0x00;
TIMSK1 = 0x00;
TIMSK2 = 0x00;
TCCR1A = 0;
TCCR1B = 0;
TCCR1C = 0;
TCCR1A = ((1 << WGM11) | (1 << WGM10)); // Mode 15, Fast PWM
TCCR1B = ((1 << WGM13) | (1 << WGM12)); // Mode 15, Fast PWM
TCCR1B |= (1 << CS12) | (1 << CS10); // (1 << CS10); // clk/1 prescaling.
//TCCR1B &= ~((1<<CS12) | (1<<CS10));
OCR1A = smpl_Time;
OCR1B = smpl_Time;
TCNT1 = 0;
TIFR1 |= (1 << OCF1B);
TIMSK1 |= (1 << OCIE1B);
}
void loop() {
delay(500);//Fake do something
//Serial.print("flgAcqDone: "); Serial.println(flgAcqDone);
if (flgAcqDone == true) {
for (int j = 0; j < bLen; j++) {
// Serial.print("Buffer["); Serial.print(j); Serial.print("]= ");
Serial.println(buffer[j]);
}//for
flgAcqDone = false;
}//if
}
ISR(TIMER1_COMPB_vect) {
// Serial.println("ISR(TIMER1_COMPB_vect)");
static int i = 0;
PORTB ^= (1 << led_pin);//Toggle D13 bit located in PORTB
ADCSRA |= 1 << ADSC; //Start conversion
flgAcqDone = false;
while (bitRead(ADCSRA, ADSC) == 1) {
//Serial.println("wait");
}
buffer[i] = ADCL | (ADCH << 8);
//Serial.println(buffer[i]);
i++;
if (i == bLen) {
i = 0;
flgAcqDone = true;
}
//Serial.print("ADCSRA: "); Serial.println(ADCSRA,HEX);
//Serial.print("1<<ADIF: "); Serial.println(1 << ADIF, HEX);
//Serial.print("(1<<ADIF)&ADCSRA=: "); Serial.println((1 << ADIF)&ADCSRA, HEX);
// Serial.print("bitRead(ADCSRA,ADIF)"); Serial.println(bitRead(ADCSRA,ADIF), HEX);
// Serial.print("Buffer["); Serial.print(i); Serial.print("]= ");
// Serial.println(buffer[i]);
}
/*
ISR(ADC_vect)
{
Serial.println("ISR(ADC_vect)");
flgAcqDone = false;
static int i = 0;
buffer[i] = ADCL | (ADCH << 8);
Serial.print("Buffer["); Serial.print(i); Serial.print("]= ");
Serial.println(buffer[i]);
i++;
if (i == bLen - 1) {
i = 0;
flgAcqDone = true;
}
//ADCSRA |= 1 << ADSC; //Start Next conversion
ADCSRA &= 0 << ADSC; //Clear
}
*/
/*
//https://arduino.stackexchange.com/questions/58224/running-adc-triggered-by-timer1-compb
#define SAMPLES_SIZE 205
const int adc_channel = 0;
const uint16_t t1_load = 0;
// 250 corresponds to 8kHz
const uint16_t t1_comp = 25000;
uint16_t samples[SAMPLES_SIZE];
volatile uint8_t samplePos = 0;
static int x = 0;
void initADC() {
// Init ADC free-run mode; f = ( 16MHz/prescaler ) / 13 cycles/conversion
ADMUX = adc_channel; // Channel sel, right-adj, use AREF pin
ADCSRA = _BV(ADEN) | // ADC enable
_BV(ADSC) | // ADC start
_BV(ADATE) | // Auto trigger
_BV(ADIE) | // Interrupt enable
_BV(ADPS2) | _BV(ADPS1) | _BV(ADPS0); // 128:1 / 13 = 9615 Hz
ADCSRB = _BV(ADTS2) | _BV(ADTS0); // Timer/Counter1 Compare Match B
DIDR0 = _BV(adc_channel); // Turn off digital input for ADC pin
}
void initTimer() {
// Reset Timer1 Control Reg A
TCCR1A = 0;
// Set CTC mode
TCCR1B &= ~(1 << WGM13);
TCCR1B |= (1 << WGM12);
// Set prescaler to 8
TCCR1B &= ~(1 << CS12);
TCCR1B |= (1 << CS11);
TCCR1B &= ~(1 << CS10);
// Reset Timer 1 and set compare value
TCNT1 = t1_load;
OCR1B = t1_comp;
// Enable Timer 1 compare interrupt
TIMSK1 = (1 << OCIE1B);
}
void setup() {
cli();
initADC();
initTimer();
sei();
Serial.begin(115200);
}
void loop() {
while(ADCSRA & _BV(ADIE)); // Wait for audio sampling to finish
cli();
// x = x + 2;
// Serial.print(samples[0]);
// Serial.print("\t");
// Serial.println(x);
for (int i = 0; i < SAMPLES_SIZE; i++) {
Serial.println(samples[i]);
}
samplePos = 0;
ADCSRA |= _BV(ADIE); // Resume sampling interrupt
sei();
}
ISR(ADC_vect) {
Serial.println("ISR(ADC_vect)");
int16_t sample = ADC;
samples[samplePos] = sample;
samplePos++;
ADCSRA &= ~_BV(ADIE); // Buffer full, interrupt off
if(samplePos >= SAMPLES_SIZE) {
ADCSRA &= ~_BV(ADIE); // Buffer full, interrupt off
}
}
ISR(TIMER1_COMPB_vect) {
Serial.println("ISR(ADC_vect)");
TCNT1 = 0;
}
*/