Go Down

Topic: ADC triggered by Timer0 atmega328 (Read 1 time) previous topic - next topic

DrAzzy

1) See datasheet, that's how you clear it.

I didn't realize you had to do that if using it as a trigger source, though...
ATTinyCore for x4/x5/x61/x7/x8/x41/1634/828/x313 megaTinyCore for the megaavr ATtinies - Board Manager:
http://drazzy.com/package_drazzy.com_index.json
ATtiny breakouts, mosfets, awesome prototyping board in my store http://tindie.com/stores/DrAzzy

FantomT

Try this:
Code: [Select]
ISR(TIMER1_COMPB_vect)
{
static int16_t counter = 0;
static int32_t accumul = 0;

    int32_t temp  = ADCL; 
            temp += (ADCH << 8); 
            temp -= adc_Offst;

  temp = temp * temp;
  accumul += temp;

  if(++counter > 1000) { // 20 Hz, 20 frame/sec.
    ppm_Level = accumul;
    counter = 0;
    accumul = 0;
    flag    = 1;
    }
}

void adc_init()
{
  ADMUX    = 0xC5;        // PIN 5 Analog. REF Internal. Bias = 0.55V
  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)|
      (0<<ADPS1)|         // ADC Prescaler : 1 MHz.
      (0<<ADPS0)); 
  ADCSRB = ((1<<ADTS2)|   // Sets Auto Trigger source - Timer/Counter1 Compare Match B
      (0<<ADTS1)|
      (1<<ADTS0));
  /* 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<<CS10);                      // clk/1 prescaling.
  OCR1A  = SMP_TMR1;
  OCR1B  = SMP_TMR1;

  TCNT1  = 0;
  TIFR1   |= (1<<OCF1B);
  TIMSK1  |= (1<<OCIE1B);
}


Code: [Select]

#include <Adafruit_GFX.h>    // Core graphics library
#include <Adafruit_TFTLCD.h> // Hardware-specific library

#define LCD_CS A3
#define LCD_CD A2
#define LCD_WR A1
#define LCD_RD A0
#define LCD_RESET A4

#define BLACK   0x0000
//#define BLUE    0x001F
#define RED     0xF800
#define GREEN   0x07E0
//#define CYAN    0x07FF
#define MAGENTA 0xF81F
#define YELLOW  0xFFE0
#define WHITE   0xFFFF
#define LIGHTGREY   0xC618
#define ORANGE  0xFD20

Adafruit_TFTLCD tft(LCD_CS, LCD_CD, LCD_WR, LCD_RD, LCD_RESET);

#define  SMP_RATE                   20       // Sampling Rate, in kHz
#define  SMP_TMR1 ((16000/SMP_RATE) -1)      // Sampling Period of Timer1

             int16_t     adc_Offst =   512;
volatile     int32_t     ppm_Level =     0;
             float       rms_Level =   0.0;

volatile     int8_t      flag      =     0;

void setup(void) {
  Serial.begin(115200);
 
           tft.reset();
  uint16_t identifier = tft.readID();
           tft.begin(identifier);
           tft.setRotation( 1);
           tft.fillScreen(BLACK);

  adc_init();
  analogMeter(); // Draw analogue meter
}

void loop()
{
  char    incomingByte;
  int32_t temp1, temp2;

  if( flag ) {
    temp1 = ppm_Level;     
    temp1 = sqrt(temp1);   
    rms_Level = 20.0 * log10(temp1 +1);

    rms_Level -= 48.175;
    temp2 = rms_Level * 3.333;
    refresh(temp2);   
    flag = 0;
    }

  if (Serial.available() > 0) {   
    incomingByte = Serial.read();
    // "x" command - DEBUG
    if( incomingByte == 'x' ) {
      Serial.println("\n\t");
      Serial.println(ppm_Level, DEC);
      Serial.println(rms_Level, 2);
      }
   }
}


You don't need TFT LCD to run a code, read data over serial.

6v6gt

Hi thanks for your help.
1) in the ISR why do u set TIFR1 OCF1B bit to 1 instead of clear it?
2) Thinking about what I really need to do, it's impossible to trigger the adc by the timer at high speed, because the adc must be clocked at 125 or 250 khz, it takes at least 13 clock cycles so the timer can run at a maximum frequency of 10 or 20khz.
maybe 6v6gt was right, I should have thought about the frequency of the timer before
For higher speeds than are possible with the AVR inbuilt ADCs, start looking at external SPI ADCs like MCP3002 (or better) which can handle sample rates of up to 200K SPS. I have used this is in a ESP8266 project where the inbuilt ADC is too weak for my purpose.

Go Up