Hello!
I am trying to have a code that will light a led and will calculate the time an LDR is taking to detect it.
I am struggling a little bit with the timers. I am using Timer1 at 100kHz without prescaler to detect the signal from the LDR (read the analog input)
As I am not able to use millis()... I do not know why, to be honest... I am using the interruptions on the Timer1 to update a counter, that should be happening every 10 us. However it looks to be slower than that.
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
//Register variables
unsigned char OCR1AL_reg = 0x88; //output compare low 8 bits for Counter 1
unsigned char OCR1AH_reg = 0x89; //output compare high 8 bits for Counter 1
unsigned char TCCR1B_reg = 0x81; //Timer/Counter0 Control Register B
unsigned char TCCR1A_reg = 0x80; //Timer/Counter0 Control Register A
unsigned char TIMSK1_reg = 0x6F; //Timer/Counter0 Interrupt Mask Register
unsigned char TIFR1_reg = 0x36; //Timer/Counter0 Interrupt Flag Register
unsigned char TCNT1H_reg = 0x85; //Timer/Counter0 Interrupt Flag Register
unsigned char TCNT1L_reg = 0x84; //Timer/Counter0 Interrupt Flag Register
boolean ledState=false;
int ledPin = 6; // LED connected to digital pin 6
int ledPin2= 7;
unsigned char SREG_reg = 0x5F; //Status register used for disabling and enabling global interrupts
int analogIn = A0;
int Aval =0;
unsigned long timeDetection;
unsigned long timeLED =0;
unsigned long diffTime=0;
unsigned long counterTime=0 ;
bool flagInput = false;
bool flagPrint = false;
bool checkAnalog = false;
void setup()
{
Serial.begin(115200);
//resetting the Timer/Counter1
(*(volatile unsigned char*)(TCNT1H_reg)) = 0;
(*(volatile unsigned char*)(TCNT1L_reg)) = 0;
//disabling all global interrupts
(*(volatile unsigned char *)(SREG_reg)) = 0b00000000;
//defining prescalar
(*(volatile unsigned char *)(TCCR1B_reg)) = 0b01001001; //the last 3 bits set to 001 will make the clock scalar 1 ;
//setting up CTC mode
(*(volatile unsigned char *)(TCCR1A_reg)) = 0b10000000;
//defining the output compare value which is calculated to be assuming 16MHz clock speed: OCRNA = (fClk_I/O)/(N*fOCRNA) where N is the prescalar fOCRNA is the compare value and fClk_I/O is the clock speed
//the value calculated for fOCRNA to be 1 MHz is 16 --> 0b10000
(*(volatile unsigned char *)(OCR1AH_reg)) = 0b00000000; //writing to high first which will write to a temp register first
(*(volatile unsigned char *)(OCR1AL_reg)) = 0b10100000; //writing to low will write both high and low in the same clock cycle
(*(volatile unsigned char *)(TIMSK1_reg)) = 0b00100010; //writing so that output compare A is set up
//enable global interrupts
(*(volatile unsigned char*)(SREG_reg)) = 0b10000000;
// initialize digital pin LED_BUILTIN as an output.
pinMode(ledPin, OUTPUT);
pinMode(ledPin2, OUTPUT);
}
ISR(TIMER1_COMPA_vect) // timer compare interrupt service routine
{
counterTime++;
CheckAnalogInput()
}
void CheckAnalogInput(){
//Read Analog and write in serial.
Aval = analogRead(analogIn); // read the input pin
if (Aval<300 && flagInput)
{
timeDetection= counterTime;
flagInput=false;
flagPrint= true;
digitalWrite(ledPin, 0);
}
}
void loop()
{
//Serial.println(counterTime);
if (flagPrint)
{
flagPrint=false;
Serial.print("timeLED (ms)");
Serial.println(timeLED* 0.01);
Serial.print("timeDetection (ms) ");
Serial.println(timeDetection* 0.01);
Serial.print("diffTime (ms) ");
diffTime= timeDetection - timeLED;
Serial.println(diffTime* 0.01);
counterTime=0;
}
if (Serial.available()) {
// get the new byte:
char inChar = (char)Serial.read();
// if the incoming character is a newline, set a flag so the main loop can
// do something about it:
if (inChar == '\n') {
digitalWrite(ledPin, 1);
timeLED= counterTime;
flagInput = true;
}
}
}
First of all, Do you know why I cannot use millis()? everytime I try to use it instead of the counter I get 0. If I use micros() it will overflow... For that reason I decided to use the counter.
When I check with the counter, the values I get make no sense...
Hope you can help me here!