Захотел измерить напряжение с помощью встроенного в ESP8266 ADC. Скачал
схему с официального сайта. Глянул номиналы резисторов R1 и R2 в voltage divider (udp: в версии с USB Type-C ребята из Wemos изменили нумерацию компонентов - теперь это R12 и R13). Набросал код. Подключаю - ADC выдает 3.20000000V, а мультиметр 3.279V. Красивые нули намекают на
(
Read more... )
абсолютно верно. молодец.
"в теории лучше добавить больше, что бы не было сильно заметно погрешности в измерении"
да лучше R1 чуть-чуть больше, но причина другая. дело в том что в мире нет ничего идеального и батареек в том числе - одна выдает 4.2в, а другая 3.7в. поэтому всегда берут с запасом. например: вам надо измерить напряжение li-ion. у него сразу после заряда напряжение 4.2в, а потом в процессе разряда довольно длительное время остается в районе 3.7в. я бы заменил R1 так, чтоб делитель спокойно приваривал чуть больше 4.2в. думаю 4.5в будет ок, а лучше 5в. итого по формуле 5v*100к/(400k+100k)=1v нам нужен резистор 400к.
вы спросите а почему сразу не на 6в или 10в? и вот тут мы подходим к погрешности измерении. чем выше мы задираем входное напряжение делителя, тем меньше у нас точность. весь секрет в разрядности АЦП. У esp8266 10-бит или 1024 отсчета. теоретический, минимальное напряжение которое мы можем измерить 1в/1024=0.001в (это без делителя). а если с делителем R1=400k/R2=100k, то меньше 0.005в вы уже не измерите. тут только вы как разработчик решаете что вам важнее, точнось, надежность или цена.
"У меня сразу пара вопросов. Зачем вы в калькуляторе считали для 1.025v?"
показать, что у платы из коробки странный делитель - на него нельзя подавать 3.3в.
"Резистор в 270кОм вы добавили просто для универсальности измерений до 5.7v?"
да. только не добавил, а заменил 220КОм на 470КОм
Reply
Reply
Reply
Запутался опять. По схеме в старой версии вемоса есть R1 220kOm и R2 100kOm,что бы измерять до 5в нужно добавить 200 кОм R1 , это правильно? Если да, то как их подключить ? R2 100kOm ведь уже не нужно подключить т.к. он на плате впаян, правильно ?
Еще не совсем понятно как правильно вычесть аналоговые показания в вольты.
raw = analogRead(A0);
volt=raw/1023.0;
volt=volt*4.2;
На какое значения нужно умножать ?
Reply
Подробнее тут.
Reply
Если нужно именно заменить, то придется искать и выпаивать на плате те 220кOm и ставить вместо него 400кOm, я вас правильно понял?
Я читал еще вот эту статью.
Reply
так точно.
Reply
Я ставил дополнительно простой voltage sensor shield:
https://microcontrollerslab.com/voltage-sensor-module-pinout-interfacing-arduino-features-working/
В нем стоят сопротивления на 30 и 7.5 кОм, позволяет измерять 0-24в в ардуине и 0-16 соответсвенно в wemos.
Вот простой скетч для калибровки esp8266 / Wemos d1 mini
Выводит каждую секунду в serial значения на пине, и вольтаж в трех точках, на esp8266, на пине A0 платы wemos, и на входе voltage sensor shield.
При несовпадении - подкручиваем значения резисторов в коде.
// Wemos d1 mini voltage calibration
// number of analog samples to take per reading
#define NUM_SAMPLES 10
int sum_voltage = 0; // sum of samples taken
unsigned char sample_count = 0; // current sample number
float adc_voltage = 0.0; // Floats for ADC voltage & Input voltage
float in_voltage = 0.0;
float R1 = 202000.0; // Floats for resistor values in divider (in ohms)
float R2 = 100000.0;
float R1_ext = 30000.0; // Floats for external resistor values in divider (in ohms)
float R2_ext = 7500.0;
//**********************************************************************************
void setup ()
{
// Serial port
Serial.begin(9600);
delay(1000); // wait for pc can connect to serail after upload;
Serial.print("Compiled: ");
Serial.print(__DATE__);
Serial.println(__TIME__);
// Voltage start
pinMode(A0, INPUT);
Serial.print (" Digital ");
Serial.print ("0-1024");
Serial.print (" / esp8266 ");
Serial.print ("0-1.025");
Serial.print (" V / Wemos ");
Serial.print ("0-3.200");
Serial.print (" V / Sensor shield ");
Serial.print ("0-16");
Serial.println (" V");
}
//**********************************************************************************
void loop ()
{
if (millis() - timerLED >= 1000) { // таймер 1 second)
timerLED = millis(); // сброс таймера
// voltage
sample_count = 0;
sum_voltage = 0;
while (sample_count < NUM_SAMPLES) {
sum_voltage += analogRead(A0);
sample_count++;
delay(10);
}
adc_voltage = ((float)sum_voltage / (float)NUM_SAMPLES ) / 1024.0;
in_voltage = adc_voltage / (R2/(R1+R2)) / (R2_ext/(R1_ext+R2_ext)) ;
Serial.print (" Digital ");
Serial.print ((float)sum_voltage / (float)NUM_SAMPLES);
Serial.print (" / esp8266 ");
Serial.print (adc_voltage);
Serial.print (" V / Wemos ");
Serial.print (adc_voltage / (R2/(R1+R2)) );
Serial.print (" V / Sensor shield ");
Serial.print (in_voltage);
Serial.println (" V");
}
}
Reply
Leave a comment