Hi
I have a 328P on my own PCB, with its Vcc connected to a boost converter (3.3v out) and ADC1 connected to the middle of a voltage divider between Ground and the solar voltage input to the boost converter.
The PCB layout and schematic are attached.
Using a multimeter I can see 1.1v at AREF, and I can see ~0.4v at ADC1 if I power the PCB from 1 x AA and ~0.9v if I power the PCB from 2 x 1.5v batteries
However, both analogRead and my manual reading of ADCW seem to be giving spurious results. The first reading is very high, but I can live with that, and then subsequently the readings seem to show no relation to the voltage being measured.
I have two copies of the same PCB and both are showing the same problem.
PCB1, 1.5v, output: 545, 539, 521
Setup()
544
545
1023
1023
1023
1023
1023
1023
, Volt: 26, rawVolt: 3433
554
539
1023
1023
1023
1023
1023
1023
, Volt: 24, rawVolt: 3169
536
521
1023
1023
1023
1023
1023
1023
, Volt: 24, rawVolt: 3171
PCB1, 3v, output:1002, 569, 529
Setup()
785
1002
1023
1023
1023
1023
1023
1023
, Volt: 33, rawVolt: 4362
582
569
1023
1023
1023
1023
1023
1023
, Volt: 24, rawVolt: 3170
544
529
1023
1023
1023
1023
1023
1023
PCB2, 1.5v, output:963, 468, 453
Setup()
979
963
1012
1023
1023
1023
1023
1023
, Volt: 26, rawVolt: 3433
514
468
515
1023
1023
1023
1023
1023
, Volt: 24, rawVolt: 3178
501
453
505
1023
1023
1023
1023
1023
PCB2, 3v, output: 1023, 513, 490
Setup()
927
1023
1023
1023
1023
1023
1023
1023
, Volt: 33, rawVolt: 4424
557
513
562
1023
1023
1023
1023
1023
, Volt: 24, rawVolt: 3228
541
490
541
1023
1023
1023
1023
1023
Code:
#include <SoftwareSerial.h>
SoftwareSerial Serial1(7, 6); // RX, TX
void setup() {
Serial1.begin(19200);
Serial1.println("");
Serial1.println("Setup() "); Serial1.flush();
}
#define TEMP_OFFSET 32900L // 329.00
#define TEMP_DIV 122L // 1.22
void loop() {
analogReference(INTERNAL);
delay(20);
Serial1.println(analogRead(A0));
Serial1.println(analogRead(A1)); // SolarV
Serial1.println(analogRead(A2));
Serial1.println(analogRead(A3)); // connected to Vcc
Serial1.println(analogRead(A4));
Serial1.println(analogRead(A5));
Serial1.println(analogRead(A6));
Serial1.println(analogRead(A7));
delay(10000);
// Usefull info: https://garretlab.web.fc2.com/en/arduino/inside/hardware/arduino/avr/cores/arduino/wiring_analog.c/analogRead.html
// * Read Temperature
// Temp is coded in the range 0..89, representing -50C to +39C with a resolution of 1C
//int16_t rawTemp, temp = 0; // use 16bit as ADCW is 16 bit
// The ADMUX(ADC Multiplexer Selection Register) controls the reference voltage,
// the presentation of the ADC conversion(left adjust or right adjust) and analog channel selection.
//ADMUX = (_BV(REFS1) | _BV(REFS0) | _BV(MUX3)); // REFS1 + REFS0 = internal ref (1.1v), MUX3 = A8 = temp
// The ADCSRA (ADC Control and Status Register A) is a register to control AD conversion.
//ADCSRA |= _BV(ADEN); // ADEN = enable
//delay(20); // wait for voltages to become stable
//ADCSRA |= _BV(ADSC); // Start the A2D conversion
//while (bit_is_set(ADCSRA, ADSC)); // ADSC within ADCSRA is cleared when the conversion finishes
//rawTemp = ADCW;
//temp = ((rawTemp * 100l) - TEMP_OFFSET) / TEMP_DIV; // ADCW 16 bit reg to degrees Celsius. 100l included to allow integer maths
//if (temp < -50) temp = -50; // protect the encoding code
//if (temp > 39) temp = 39;
//temp = temp + 50; // scale -50 to 39, to 0 to 89, representing -50C to 39C
// * Read Solar Voltage
// Solar volt is coded in the range 0..39, representing 0.0v to 3.9v with a resolution of 0.1v
uint16_t rawVolt, volt; // use 16bit as ADCW is 16 bit
rawVolt = 0;
// The ADMUX(ADC Multiplexer Selection Register) controls the reference voltage,
// the presentation of the ADC conversion(left adjust or right adjust) and analog channel selection.
ADMUX = (_BV(REFS1) | _BV(REFS0) | _BV(MUX1)); // REFS1 + REFS0 = internal ref (1.1v), MUX1 = A1
for(int i = 0; i <= 5; i++) {
// The ADCSRA (ADC Control and Status Register A) is a register to control AD conversion.
ADCSRA |= _BV(ADEN); // ADEN = enable
delay(20); // wait for voltages to become stable
ADCSRA |= _BV(ADSC); // Start the A2D conversion
while (bit_is_set(ADCSRA, ADSC)); // ADSC within ADCSRA is cleared when the conversion finishes
rawVolt += ADCW;
}
volt = rawVolt / 5; // average across 5 readings
volt = volt * 0.0381; // scale 0 to 1023 to 0 to 39, representing 0 to 3.9v
if (volt > 39) volt = 39; // protect the encoding code
//Serial1.print("Temp: ");
//Serial1.print(temp);
//Serial1.print(", rawTemp: ");
//Serial1.print(rawTemp);
Serial1.print(", Volt: ");
Serial1.print(volt);
Serial1.print(", rawVolt: ");
Serial1.println(rawVolt);
delay(1000);
}
Any thoughts or help appreciated.
Thanks very much
Kevin