Как измерять напряжение автономного питания на Arduino Nano.

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

ЕвгенийП пишет:

В общем, мне это надоело.

что-то вы быстро сдались )))
 

bool m;
void setup() {
  Serial.begin(115200);
}

void loop() {
  ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
  ADCSRA |= _BV(ADSC); // Начало преобразований
  while (bit_is_set(ADCSRA, ADSC)); // измерение
  uint8_t low  = ADCL; // сначала нужно прочесть ADCL - это запирает ADCH
  uint8_t high = ADCH; // Разлочить оба
  uint16_t result1 = (high << 8) | low;
  float result = result1;

  if(Serial.available()){Serial.flush(); m = !m;}
  if(!m){
  result = (1.087 * 1023 * 1000) / result; //Результат Vcc в милливольтах
  }else{
  result = (((10870 * 1024L + result1 / 2) / result1) + 500) / 1000;
  }
  Serial.print("Vcc = ");
  Serial.println(result, 2);
  delay(1000);
}

и вывод:
 

Vcc = 4942.23
Vcc = 4920.36
Vcc = 4920.36
Vcc = 4942.23
Vcc = 49.00
Vcc = 4920.36
Vcc = 49.00
Vcc = 4942.23
Vcc = 49.00
Vcc = 4920.36
Vcc = 49.00
Vcc = 4920.36
Vcc = 49.00
Vcc = 4942.23
Vcc = 49.00

Если выводить в милливольтах ваша формула плюсит на 50 милливольт относительно истинного 4920

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

ua6em, Вы уже выпили?

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

ЕвгенийП пишет:

ua6em, Вы уже выпили?

только чай...тестер показывает 4920, ваша формула если выводить в милливольтах 4997, формула через float 4923

xDriver
xDriver аватар
Offline
Зарегистрирован: 14.08.2015

такие ошибки (19 строка)  даже я по пьяне уже не допускаю.

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

xDriver пишет:

такие ошибки (19 строка)  даже я по пьяне уже не допускаю.

у меня все ходы записаны ))) пост #11 строка -    return (((internalRefference * 1024L + adc / 2) / adc) + 500) / 1000;

xDriver
xDriver аватар
Offline
Зарегистрирован: 14.08.2015

понял, ждемс...

кстати, у меня вот такая хрень

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

xDriver пишет:

понял, ждемс...

кстати, у меня вот такая хрень

а ты в монитор порта что-нить отправь и, таки да, я свои данные ИОН подставил...если в милливольтах то
 

Vcc = 4942.23
Vcc = 4997.00
Vcc = 4942.23
Vcc = 4997.00
Vcc = 4942.23
Vcc = 4997.00
Vcc = 4942.23
Vcc = 4997.00
Vcc = 4942.23
Vcc = 4997.00
Vcc = 4942.23
Vcc = 4997.00

 

xDriver
xDriver аватар
Offline
Зарегистрирован: 14.08.2015

блин, вроде не пил еще, все я понял ))

 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

ua6em пишет:
ваша формула если выводить в милливольтах
Моя формула предназначена для десятых долей вольта. А там, можете хоть в нановольтах выводить :-)

Если Вы хотите приспособить её для float, так делайте это правильно. А то, что у Вас написано в строке №19 - это что угодно, только не моя формула :-)

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

ЕвгенийП пишет:

А то, что у Вас написано в строке №19 - это что угодно, только не моя формула :-)

поясните -  result = (((10870 * 1024L + result1 / 2) / result1) + 500) / 1000;

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

ua6em, а что, собственно, Вас не устраивает?

При напряжении питания 5.0 В и опорном 1.087 В ADC должен выдавать 222. Подставляем в формулу, получаем 50, т.е. напряжение в десятых долях вольта.

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

andriano пишет:

ua6em, а что, собственно, Вас не устраивает?

При напряжении питания 5.0 В и опорном 1.087 В ADC должен выдавать 222. Подставляем в формулу, получаем 50, т.е. напряжение в десятых долях вольта.

понятно, что программист как бог может придумать любую удобную ему новую единицу измерения, речь о другом, что формула считает неправильно, завышая показания, ЕвгенийП говорит, что это не его формула, вот и спросил, что в ней не так? (ЧТО Я НЕ ТАК ПОНЯЛ)

v258
v258 аватар
Offline
Зарегистрирован: 25.05.2020

ua6em пишет:

понятно, что программист как бог может придумать любую удобную ему новую единицу измерения

Она удобна тем, что не нужно использовать float, при этом обеспечивая нужную точность. Можно и в миливольтах: 5В == 5000мВ

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

v258 пишет:

ua6em пишет:

понятно, что программист как бог может придумать любую удобную ему новую единицу измерения

Она удобна тем, что не нужно использовать float, при этом обеспечивая нужную точность. Можно и в миливольтах: 5В == 5000мВ

так ++ жеж, что не есть карасо )))

Komandir
Komandir аватар
Offline
Зарегистрирован: 18.08.2018

ua6em у вас формула без округления - вот и чуть точнее

но float деление цепляет хз сколько лишнего кода !

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

Komandir пишет:
но float деление цепляет хз сколько лишнего кода !

минимум 1.5к сразу

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

ua6em пишет:

ЕвгенийП пишет:

А то, что у Вас написано в строке №19 - это что угодно, только не моя формула :-)

поясните -  result = (((10870 * 1024L + result1 / 2) / result1) + 500) / 1000;

А чего тут пояснять. У меня только целочисленные операции, Вы же решили перевести на flaot, но

1. деления остались целочисленными
2. на кой-то хрен оставили на месте мои "+ result1 / 2" и " + 500", которые нужны для более аккуратно целочисленного округления, а при флоате только мешают.

Т.е. Вы уж определитесь, Вы используете мою формулу для целых, или делаете во флоат, тогда переходите на все операции во float и выбрасывайте мои прибавление половин. То, что написано у меня никаким образом не предназначено для милливольтов, поэтому все Ваши замечания про "завышает на 50 милливольт" - мимо.

Да, кстати, строки №№10-12 полностью эквивалентны

uint16_t result1 = ADC;

это прямо в даташите написано. Зачем плодить три строки вместо одной?

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

ЕвгенийП пишет:

Да, кстати, строки №№10-12 полностью эквивалентны

uint16_t result1 = ADC;

это прямо в даташите написано. Зачем плодить три строки вместо одной?

так глубоко не копал, но к примеру на важгаде брать значения регистров в 3-м таймере можно только половинками, видимо уши оттуда растут, код был нагло спионэрен )))

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

ua6em пишет:

так глубоко не копал, но к примеру на важгаде брать значения регистров в 3-м таймере можно только половинками, видимо уши оттуда растут, код был нагло спионэрен )))

Так он половинками и берётся. Просто, компилятор берёт половинки в правильном порядке, так что можно не париться.

В даташите так прямо и написано: "Note that when using “C”, the compiler handles the 16-bit access"

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

ua6em пишет:

andriano пишет:

ua6em, а что, собственно, Вас не устраивает?

При напряжении питания 5.0 В и опорном 1.087 В ADC должен выдавать 222. Подставляем в формулу, получаем 50, т.е. напряжение в десятых долях вольта.

понятно, что программист как бог может придумать любую удобную ему новую единицу измерения, речь о другом, что формула считает неправильно, завышая показания

Ну так приведите пример, на котором его формула считает неправильно. На моем примере в сообщении №61 ошибок нет.

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

andriano пишет:

Ну так приведите пример, на котором его формула считает неправильно. На моем примере в сообщении №61 ошибок нет.

дело не в неправильной формуле, а в методе определения напряжения ИОН, действуем от обратного, измеряем напряжение на батарее точным прибором и напряжение ИОН определяем расчётом это напряжение в формулу заносим и, всё встанет по своим местам )))

b707
Offline
Зарегистрирован: 26.05.2017

Ua6en - если ты неверно померил свой ИОН - причем тут формула? Формула верная, а вот ты похоже просто так и не понял методику измерения

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

b707 пишет:
Ua6en - если ты неверно померил свой ИОН - причем тут формула? Формула верная, а вот ты похоже просто так и не понял методику измерения

чего там понимать то?
ЗЫ как наладчик КИП 8-го разряда может что-то неправильно измерить?

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

ua6em пишет:

дело не в неправильной формуле, а в методе определения напряжения ИОН, действуем от обратного, измеряем напряжение на батарее точным прибором и напряжение ИОН определяем расчётом это напряжение в формулу заносим и, всё встанет по своим местам )))

Здесь вообще ничего измерять не надо. От слова "совсем"!

Я же привел пример расчета:

1. Задаем любое напряжение (сами - от фонаря, вот какое число нам понравится, такое и задаем).

2. Вычисляем, чему будет равно наше опорное напряжение в "попугаях" от этого опорного.

3. Подставляем вычисленное число в формулу и считаем, что получилось.

4. А теперь сравниваем, что было (1), и что получилось в результате (3).

 

Все исключительно расчетным путем. Я, например, считал на калькуляторе, но по правилам Си.

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

andriano пишет:

Все исключительно расчетным путем. Я, например, считал на калькуляторе, но по правилам Си.

можно и так, мне просто другое непонятно ну не может разработчик заложить в ИОН разброс в 10%, он жеж не идиот, лазерная калибровка этого напряжения должна быть, наверно эти атмеги какой-то определённый индекс имеют, ИМНО

arduinec
Offline
Зарегистрирован: 01.09.2015

http://arduino.ru/forum/programmirovanie/sysinfo-arduino

Там показано как в Ардуине измерять напряжение, температуру и прочее.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

ua6em пишет:
ну не может разработчик заложить в ИОН разброс в 10%, он жеж не идиот

Почему? Вот из таблицы 29-11 даташита:

Не просто 10%, а даже ±9%, т.е. "от края до края" - все 18%

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

ЕвгенийП пишет:

ua6em пишет:
ну не может разработчик заложить в ИОН разброс в 10%, он жеж не идиот

Почему? Вот из таблицы 29-11 даташита:

Не просто 10%, а даже ±9%, т.е. "от края до края" - все 18%

это нас обывателей, для себя, вот у меня уверенность 100500, 0,1% точности заложено, в крайнем случае 0,5%...технологически это совсем несложно как бы

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

ua6em пишет:
вот у меня уверенность
Это как Вам будет угодно :-)

Я вот тут сейчас на практике столкнулся с уходом воч-дог таймера у тиньки от температуры. Прилично так убегает - создало реальные проблемы.

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

ЕвгенийП пишет:

ua6em пишет:
вот у меня уверенность
Это как Вам будет угодно :-)

Я вот тут сейчас на практике столкнулся с уходом воч-дог таймера у тиньки от температуры. Прилично так убегает - создало реальные проблемы.

это да! от температуры и напряжения питания с ним полный трэш, что есть, то есть

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

ua6em пишет:

можно и так, мне просто другое непонятно ну не может разработчик заложить в ИОН разброс в 10%, он жеж не идиот, лазерная калибровка этого напряжения должна быть, наверно эти атмеги какой-то определённый индекс имеют, ИМНО

Лично мне непонятно, что именно Вам непонятно.))))

Вот мне пока ни в одной из моих конструкций не пришлось использовать встроенный ИОН. Как Вы думаете, готов ли я платить больше за кристалл, который дополнительно был подвергнут лазерной калибровке того, чем я не пользуюсь? Не забывайте, речь идет о самом дешевом сегменте простейших МК.

 

b707
Offline
Зарегистрирован: 26.05.2017

ua6em пишет:

ЗЫ как наладчик КИП 8-го разряда может что-то неправильно измерить?

ой да сколько угодно, вспомни задачу про бочку :)

По-моему тут ровно та же ситуация - ты упираешься в незначительные мелочи, не понимая главного :)

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

andriano пишет:

Вот мне пока ни в одной из моих конструкций не пришлось использовать встроенный ИОН. Как Вы думаете, готов ли я платить больше за кристалл, который дополнительно был подвергнут лазерной калибровке того, чем я не пользуюсь? Не забывайте, речь идет о самом дешевом сегменте простейших МК.

оказывается ИОН можно откалибровать и по его калибровке есть целый мануал #18 )))

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

b707 пишет:

ой да сколько угодно, вспомни задачу про бочку :)

это которую никто из физиков-математиков-программистов не решил, а в направлении решения которой продвинулся всего один из пользователей этого сайта? Помню )))
Ну не у всех же Пифагорийское движение мысли, куда бы мы столько Пифагоров дели...

lilik
Offline
Зарегистрирован: 19.10.2017

:-)

Интересный способ измерения питающего напряжения.  Только так и не понял какой конкретно функцией считывается значение опорного напряжения  по отношению к питающему? Чем 1,1 В превращаются в 210-230 усл. единиц? По ссылке 

https://blog.unlimite.net/?p=25

только команда (а как ?)...

2. Снять показания АЦП для внутреннего источника 1.1 В.

... и код мутный ниже.

long readVcc() {
  // Read 1.1V reference against AVcc
  // set the reference to Vcc and the measurement to the internal 1.1V reference
  #if defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
    ADMUX = _BV(REFS0) | _BV(MUX4) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
  #elif defined (__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__)
    ADMUX = _BV(MUX5) | _BV(MUX0);
  #elif defined (__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)
    ADMUX = _BV(MUX3) | _BV(MUX2);
  #else
    ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
  #endif  

  delay(75); // Wait for Vref to settle
  ADCSRA |= _BV(ADSC); // Start conversion
  while (bit_is_set(ADCSRA,ADSC)); // measuring

  uint8_t low  = ADCL; // must read ADCL first - it then locks ADCH  
  uint8_t high = ADCH; // unlocks both

  long result = (high<<8) | low;

  result = 1125300L / result; // Calculate Vcc (in mV); 1125300 = 1.1*1023*1000
  return result; // Vcc in millivolts
}

 

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

строка 11 - конфигурирование мультиплексера

строка 15 разрешаем измерение, пока бит окончания измерения (строка 15) не установлен, в регистре ADC - значение

 

lilik
Offline
Зарегистрирован: 19.10.2017

Спасибо, стало гораздо ярче :-)

Попробовал, чуть изменив исходник:

void setup() {
Serial.begin(9600); //  
}
void loop() {
Serial.println(readVcc());  
delay(2000);
}
float readVcc() {
  // Read 1.1V reference against AVcc
 ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
 delay(75); // Wait for Vref to settle
  ADCSRA |= _BV(ADSC); // Start conversion
  while (bit_is_set(ADCSRA,ADSC)); // measuring

  uint8_t low  = ADCL; // must read ADCL first - it then locks ADCH  
  uint8_t high = ADCH; // unlocks both

  long result = (high<<8) | low;

 float res = 1125300L /(1000*result); // Calculate Vcc (in mV); 1125300 = 1.1*1023*1000
  return res; // Vcc in millivolts
}

В мониторе ровно 5.00, а на вольтметре 4.79, тоже ровно.

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

lilik пишет:

В мониторе ровно 5.00, а на вольтметре 4.79, тоже ровно.

float res = 1078037L /(1000*result)

 

lilik
Offline
Зарегистрирован: 19.10.2017

Теперь чего то 4.00 ровно, на вольтметре те же 4.79 :-)

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Он хотел написать 1174635.

lilik
Offline
Зарегистрирован: 19.10.2017

Наверное с флоатом я неправильно переделал что-то, в исходнике.

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

andriano пишет:

Он хотел написать 1174635.

скосячил, каюсь )))

и таки да, если нет чем замерить AREF лучше рассчитать

lilik
Offline
Зарегистрирован: 19.10.2017

andriano пишет:

Он хотел написать 1174635.

Нет, тоже 5.00. Явно с числами я не так сделал, 00 при любых извратах остаются, меняется только первая цифра.

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

lilik пишет:

Наверное с флоатом я неправильно переделал что-то, в исходнике.

Наверное.

Для начала вместо 1000 напишите 1000.0 и посмотрите, что получится.

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

lilik пишет:

andriano пишет:

Он хотел написать 1174635.

Нет, тоже 5.00. Явно с числами я не так сделал, 00 при любых извратах остаются, меняется только первая цифра.

Так чего же Вы хотите, если все вычисления делаете в целых?

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

вот тут код от DIMAX, там с float

lilik
Offline
Зарегистрирован: 19.10.2017

Никак не привыкну к этой математике, надо так:

 float res = 1078.037/result; //

Тогда в монитор идут 4.81, редко 4.83, а на вольтметре ровно 4.80, в принципе здорово с учётом необходимости расчёта коэффициента пропорции под экземпляр платы на калькуляторе.

 

 

b707
Offline
Зарегистрирован: 26.05.2017

lilik пишет:

Интересный способ измерения питающего напряжения.  Только так и не понял какой конкретно функцией считывается значение опорного напряжения  по отношению к питающему? Чем 1,1 В превращаются в 210-230 усл. единиц?

не понимаете вероятно потому, что плохо представляете себе работу ADC в контроллере.

Для начала  - вы в курсе, что в 328й атмеге только один ADC? - вы спросите, как же ему удается читать сигнал аж с 8ми входов А0-А7? - а очень просто, через переключатель, типа галетного :)

Положение переключателя определяется регистром ADMUX, меняя его, мы подключаем ADC к разным источникам сигнала. Среди этих источников не только 8 внешних аналоговых входов, но так же и внутренний аналоговый референс 1.1в и внутренний термометр атмеги.

Дальше, я думаю, все понятно...

lilik
Offline
Зарегистрирован: 19.10.2017

b707 пишет:

lilik пишет:

Интересный способ измерения питающего напряжения.  Только так и не понял какой конкретно функцией считывается значение опорного напряжения  по отношению к питающему? Чем 1,1 В превращаются в 210-230 усл. единиц?

не понимаете вероятно потому, что плохо представляете себе работу ADC в контроллере.

Для начала  - вы в курсе, что в 328й атмеге только один ADC? - вы спросите, как же ему удается читать сигнал аж с 8ми входов А0-А7? - а очень просто, через переключатель, типа галетного :)

Положение переключателя определяется регистром ADMUX, меняя его, мы подключаем ADC к разным источникам сигнала. Среди этих источников не только 8 внешних аналоговых входов, но так же и внутренний аналоговый референс 1.1в и внутренний термометр атмеги.

Дальше, я думаю, все понятно...

Вот, именно часть этих данных я и не знал, просто интуитивно думал, что analogRead(1.1V) должна быть тогда в доступных функциях :-)

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

b707 пишет:

 но так же и внутренний аналоговый референс 1.1в и внутренний термометр атмеги.

точно? а не с вывода AREF?