Hello, this is my first time using this forum so if there is any issue, just let me know.
My Arduino is connected to a potentiometer that is going to read 25 inputs and convert them using the ADC/Interrupts. The code works outside of the first conversion. It appears to not do it at all after a board reset. If I execute the code more than once before the board resets, it prints the first iteration, but it prints the digital value as "000" with a time of "0us". I'm not sure what would be causing this to happen.
//Screenshot of the output
// Below is the "main" code that I am trying to execute
#include <avr/wdt.h>
unsigned long stopTime = 0;
unsigned long startTime = 0;
unsigned long totalTime = 0;
unsigned long averageTime = 0;
const byte adc_pin = A0; // = 14 (pins_arduino.h)
volatile int adc_value;
volatile bool adc_done;
volatile bool adc_busy;
void setup() {
Serial.begin(9600);
pinMode(A0,INPUT);
ADCSRA = bit(ADEN) // Turn ADC on
| bit(ADIE) // Enable interrupt
| bit(ADPS0) | bit(ADPS1) | bit(ADPS2); // Prescaler of 128
ADMUX = bit(REFS0) // AVCC
| ((adc_pin - 14) & 0x07); // Arduino Uno to ADC pin
Serial.println("Board was reset"); // prints the sentence on the serial monitor
}
// ADC complete ISR
ISR(ADC_vect) {
adc_value = ADC;
totalTime = micros() - startTime;
adc_done = true;
adc_busy = false;
}
void loop() {
mainfunction(); // loop runs main function, allows me to control code easier
}
void mainfunction() { //acts as main
static String userInput;
static int AR_analogIN = 0;
static int P_analogIn = 0;
Serial.println("Select a type of conversion to perform (‘a’ for lab #4; ‘b’ for lab #5; 'c' for lab #6) > ");
wdt_enable(WDTO_4S); //set watchdog to have 4S timer
while(!Serial.available()) {}
userInput = Serial.readString();
if (userInput == "a") {
wdt_disable(); //disables WDT
Serial.println("Starting a set of conversions using AnalogRead: ");
for(int i = 1; i<=25 ; i++) { //Loops through for 25 conversions
String readdump = Serial.readString(); // reads each value sent to serial
startTime = micros();
AR_analogIN = analogRead(A0);
totalTime = micros() - startTime;
Serial.print("#");
Serial.print(i);
Serial.print(": digital value = ");
String HexString = String(AR_analogIN,HEX);
while (HexString.length() != 3) {
HexString = String("0" + HexString);
}
Serial.print(HexString); //prints the analogIN in hex
Serial.print(" Time = ");
Serial.print(totalTime);
Serial.print(" usecs");
averageTime = averageTime + totalTime;
Serial.println();
}
Serial.print("avg conversion time = ");
Serial.print(averageTime / 25); //formula for average time of conversion
Serial.println(" usecs");
averageTime = 0;
totalTime = 0;
startTime = 0;
}
else if (userInput == "b") {
ACD_init();
wdt_disable();
Serial.println("Starting a set of conversions using polling and port manipulation: ");
for(int i = 1; i<=25 ; i++) { //Loops through for 25 conversions
int readdump = Serial.parseInt(); // reads each value sent to serial
P_analogIn = adc_read(A0);
Serial.print("#");
Serial.print(i);
Serial.print(": digital value = ");
String HexString = String(P_analogIn,HEX);
while (HexString.length() != 3) {
HexString = String("0" + HexString);
}
Serial.print(HexString); //prints the analogIN in hex
Serial.print(" Time = ");
Serial.print(totalTime);
Serial.print(" usecs");
averageTime = averageTime + totalTime;
Serial.println();
}
Serial.print("avg conversion time = ");
Serial.print(averageTime / 25); //formula for average time of conversion
Serial.println(" usecs");
averageTime = 0;
startTime = 0;
totalTime = 0;
}
else if (userInput == "c") {
wdt_disable(); //disables WDT
Serial.println("Starting a set of conversions using interrupts: ");
for(int i = 1; i<=25 ; i++) { //Loops through for 25 conversions
int readdump = Serial.parseInt();
if (adc_done) {
Serial.print("#");
Serial.print(i);
Serial.print(": digital value = ");
String HexString = String(adc_value,HEX);
while (HexString.length() != 3) {
HexString = String("0" + HexString);
}
Serial.print(HexString);
Serial.print(" Time = ");
Serial.print(totalTime);
Serial.println(" usecs");
averageTime = averageTime + totalTime;
adc_done = false;
}
// Start new conversion
if (!adc_busy) {
adc_busy = true;
// start the conversion
startTime = micros();
bitSet(ADCSRA, ADSC);
}
}
Serial.print("avg conversion time = ");
Serial.print(averageTime / 25); //formula for average time of conversion
Serial.println(" usecs");
averageTime = 0;
startTime = 0;
totalTime = 0;
}
else { //if the user input is not a or b or c
Serial.println("Error: invalid input - the only valid input is 'a' or 'b' or 'c'"); //error
wdt_reset(); // resets the WDT
mainfunction(); // resets and calls main function from scratch again
}
}
void ACD_init() { // function to initialize the ADC
ADMUX = (1 << REFS0); //default Ch-0; Vref = 5V
ADCSRA |= (1 << ADEN) | (0 << ADSC) | (0 << ADATE); //auto-trigger OFF
ADCSRB = 0x00;
}
uint16_t adc_read(uint8_t ch) { // Function to read value of ADC
ADCSRA |= (1 << ADSC); //starts single conversion and writes a '1' to ADSC
startTime = micros();
while (ADCSRA & (1 << ADSC)); //waits for the conversion to complete, poll until ADSC becomes '0' again
ADC = (ADCL | (ADCH << 8));
totalTime = micros() - startTime;
return (ADC); //return conversion value
}
//check why timings are inconsistent
//INTERRUPT for loop starts at 2... 1st doesn't work for some reason
//tidy up code
// This is the ISR
ISR(ADC_vect) {
adc_value = ADC;
totalTime = micros() - startTime;
adc_done = true;
adc_busy = false;
}
//This is the Setup for the ADC/Interrupt
ADCSRA = bit(ADEN) // Turn ADC on
| bit(ADIE) // Enable interrupt
| bit(ADPS0) | bit(ADPS1) | bit(ADPS2); // Prescaler of 128
ADMUX = bit(REFS0) // AVCC
| ((adc_pin - 14) & 0x07); // Arduino Uno to ADC pin