Hey Guys,
Would Just like to know if anyone can spot any errors in my code:
I am first using timer1 to count up to 9000ticks with a clock of 16Mhz and prescalar of 1024.
during this time I am integrating an unknown voltage.
After 9000 ticks. I thereafter switch off the unknown voltage and switch on a negative reference voltage and de-integrate it
this is the dual slope integration method for ADC.
I run the output of the comparator of the dual slope ADC to the ICP pin 8 on arduino board and monitor for falling edge upon which i save time from ICR1.
I am getting incorrect results.
code:
/*
* ----------------------------------------------------------------------------
* ALPHATRONICS POWER METER
* DUAL SLOPE INTEGRATING ANALOG-DIGITAL CONVERTER
* REFERENCE VOLTAGE DE-INTEGRATION
* ----------------------------------------------------------------------------
*/
//INCLUDES
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include <math.h>
/***********/
/* DEFINITIONS */
/***********/
//Reference S-R variables
#define ICP_Pin 8
#define Vref_Control_1 9
#define Vref_Control_2 12
//Input S-R Variables : Allocation of Control Pins for Each ADC
#define Vin_Control_1 10
//Discharge S-R
#define Discharge_Pin 11
/********************/
/* Global variables */
/********************/
//Reference S-R Variables
double period_high = 0.00;
double period_low = 0.00;
double period = 0.00;
/*************************/
/* SYSTEM INITIALIZATION */
/*************************/
void setup()
{
Serial.begin(9600);
/**********************/
/* I/O INITIALIZATION */
/**********************/
// OUTPUTS
pinMode(ICP_Pin,INPUT);//ICP1 as INPUT
pinMode(Vref_Control_1,OUTPUT);
pinMode(Vref_Control_2,OUTPUT);
pinMode(Vin_Control_1, OUTPUT); //Defining control pin 1 as an output
pinMode(Discharge_Pin, OUTPUT);// initialize the digital pin as an output.
digitalWrite(Discharge_Pin, HIGH); // turn the LED off by making the voltage LOW
digitalWrite(Vref_Control_1, HIGH); // turn the LED off by making the voltage LOW
digitalWrite(Vin_Control_1, HIGH); // turn the LED off by making the voltage LOW
/******************************/
/* Initialization of the code */
/******************************/
// Global enable interrupts
sei();
}
/******************/
/* MAIN CODE LOOP */
/******************/
void loop()
{
Discharge();
Timer1_Input_SR();
Timer1_Reference();
Serial.print(period);
Serial.print(" ");
Serial.print(ICR1);
Serial.print(" ");
Serial.print(ICR1L);
Serial.print(" ");
Serial.print(ICR1H);
Serial.print(" ");
Serial.println(" ");
delay(1000);
}
/***********************/
/* INTERRUPT FUNCTIONS */
/***********************/
//Timer1 Ouput COmpare Match Interrupt Subroutine
//Responsible for switching of Inpput Voltage control pins of each ADC
ISR(TIMER1_COMPB_vect)
{
digitalWrite(Vin_Control_1, HIGH);//Output a low to Control Pin 1 To switch OFF the Input Voltage for the 1st and 2nd ADC
Serial.println(TCNT1);
}
// Timer 1 input capture interrupt service routine
ISR(TIMER1_CAPT_vect)
{
/*period_high = ICR1H;
period_low = ICR1L;*/
digitalWrite(Vref_Control_1, HIGH); //Output a Low to Control Pin 1 to switch OFF the reference Voltage for the 1st ADC
digitalWrite(Vref_Control_2, HIGH); //Output a Low to Control Pin 2 to switch OFF the reference Voltage for the 2nd ADC
period = ICR1;
}
/***********************/
/* OTHER FUNCTIONS */
/***********************/
//Discharge Capacitor
void Discharge()
{
digitalWrite(Discharge_Pin, LOW); // turn the LED on (HIGH is the voltage level)
delay(3000); // wait for a second
digitalWrite(Discharge_Pin, HIGH); // turn the LED off by making the voltage LOW
}
// Initialize Timer1
void Timer1_Input_SR(){
cli(); // disable global interrupts
TCCR1A = 0; // set entire TCCR1A register to 0
TCCR1B = 0; // set entire TCCR1A register to 0
TCNT1 = 0;
/*Serial.print("INIT ");
Serial.print(TCNT1);
Serial.println(" ");*/
digitalWrite(Vin_Control_1, LOW); //Output a High to Control Pin 1 to switch ON the Input Voltage for the 1st and 2nd ADC
// set compare match register to desired timer count: to account for 0.036s of Integration Time
OCR1B = 9000;
// Timer1 Starts counting in CTC mode:
TCCR1B |= (1 << WGM12);
// Set CS10 and CS12 bits in TCCR1B for 1024 prescaler:
TCCR1B |= (1 << CS10);
TCCR1B |= (1 << CS12);
// enable timer compare interrupt:
TIMSK1 |= (1 << OCIE1B);
// enable global interrupts:
sei();
}
void Timer1_Reference()
{
cli();
digitalWrite(Vref_Control_1, LOW); //Output a High to Control Pin 1 to switch ON the reference Voltage for the 1st ADC
digitalWrite(Vref_Control_2, LOW); //Output a High to Control Pin 2 to switch ON the reference Voltage for the 2nd ADC
// Timer/Counter 1 initialization
// Clock source: System Clock
// Prescalar 1024
// Mode: Normal
// OC1A output: Discon.
// OC1B output: Discon.
// OC1C output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer 1 Overflow Interrupt: Off
// Input Capture Interrupt: Onn
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
// Compare C Match Interrupt: Off
TCCR1A = 0x00;
TCCR1B = 0x05;
TCNT1H = 0x00;
TCNT1L = 0x00;
ICR1H = 0x00;
ICR1L = 0x00;
// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK1 |= 0x20;
TIFR1 |= 0x20;
sei();
}