Помогите нубу с логгером

iskate
Offline
Зарегистрирован: 25.11.2016

Нужен простенький логгер напряжения в компорт, 10 раз в секунду.

Но гнетут смутные сомнения: если я напишу в цикле

AnalogRead();
Serial.println();
delay(100);   

То как себя поведет общий интервал? Ведь чтение АЦП и запись в компорт тоже сколько-то времени занимают. Или я не прав? И как можно рассчитать сколько именно времени на это требуется, чтоб подкорректировать число в delay()

Мне сверхестественная точность не нужна. Но на сколько "убежит" суммарная ошибка за 10 часов при таком подходе?

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

Делайте через millis(), как в примере "блинк без делэй". Там сначала запоминайте текущий миллис, а уж потом замеряйте и выводите, тогда замер и вывод будут внутри отмеряемого интервала, а между интервалами и ошибка напливаться не будет.

iskate
Offline
Зарегистрирован: 25.11.2016

Спасибо, так и сделаю.

Но похоже я даун. Элементарная вещь вогнола меня в тупик.

Меряю в попугаях стаые батарейки (напрямую, без делителя)

в первом измерении одна, во втором две последовательно:

  value = analogRead(analogInput);
  Serial.println(value);
  delay(100);   

Считаю калькулятором, U замерил мультиметром (одновременно):

U попугаи  

расчет по попугаям

(Uвх=5.04)

1,12 227   1,117266
2,55 425   2,091797

Получилась ерунда...

Переписал так:

  value = (analogRead(analogInput)* 5.04) / 1024.0;
  Serial.println(value);
  delay(100);   

(value тут теперь float)

И чудо - меряет с точность до соток.

Но осадочек остался... В чем проблема? Переполнения нет...

Ps. эксперименты проводил раз по пять, результат одинаковый.

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

Ну, я не знаю, скетч неполный. А вообще, после переключения пина первый замер выбрасывается. Т.е. либо читайте тонкости в даташите (в каких случаях первый замер врёт), либо первый замер просто игнорируйте всегда, как я это делаю..

iskate
Offline
Зарегистрирован: 25.11.2016

Полный не намного больше:

int analogInput = 0;
float value = 0.0;

void setup() {
  // start serial port at 9600 bps:
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }
  pinMode(analogInput, INPUT);
}

void loop() {

  value = (analogRead(analogInput)* 5.04) / 1024.0;
  Serial.println(value);
  delay(100); 
} 

Это второй, работающий, вариант. В первом только value было int, и value = analogRead(analogInput)

Первые отсчеты я и не вижу, пялюсь в консоль на одинаково бегущие цифры (только в единичном разряде иногда прыгают +-1)

Плата - клон на 328P

 

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

Выбросьте 10-ую строку. Врядли поможет, но это неправильно по-любому. Тем более, что Вы в INPUT ставите не аналоговый пин 0, а цифровой - а это совсем другой пин.

Т.е. Вы хотите сказать, что этот скетч выдаёт стабильный результат, а тот с int - скачущий?

Давайте всё-таки оба скетча и результаты, которые они выдают. Будем смотреть.

iskate
Offline
Зарегистрирован: 25.11.2016

Вобщем нефиг было этим в пятницу вечером заниматься...

Вместо 

2,55 425  

должно быть 

2,25 455  

И тогда все сходится

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

Т.е. Вы хотите сказать, что этот скетч выдаёт стабильный результат, а тот с int - скачущий?

Нет, оба скачут - попугаи бывают и 454 и 456, но чаще 455, во втором варианте то 2,25, то 2,24.

Зы. извините за беспокойство

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

очень полезная привычка, если не критично время выполнения, то всегда брать (любимым способом) среднее.

В Вашем случае я бы сделал 4-5 замеров, выкинул минимальное и максимальное значения, а от остальных взял среднее арифметическое.

Сам я обычно беру скользящее от пыры десятков замеров, но Вам нужно 100 мс уложиться. Так что то, что выше написано - самое то.

iskate
Offline
Зарегистрирован: 25.11.2016

Для моей задачи это наверн излишне. Я первый раз чтото делаю на arduino. Несколько некомфортна низкая разрядность, но думаю ее хватит.

Хочу сделать зарядку для автомобильной АКБ, из подручных материалов и максимально просто.

Чтобы заряжала по хитрому алгоритму:

10 сек зарядка, 1 сек пауза для рекомбинации электролита. Если напряжение превысит 14,3  - отдыхаем минут десять, потом опять включаемся, и так пока не надоест. (Пишут что такой алгоритм помогает лучше зарядить / восттановить емкость)

Т.е. делитель я буду делать на макс 30 вольт (силовая часть без нагрузки дает 25 в амплитуде). И получается что разрешение будет 30 / 1024 = 0,029. Если округлить до десяток наверн норм будет. (или даже не округлять, а то что есть сравнивать с 14,3)

А логирование в консоль больше из любопытства, чтоб потом вникать в графики и много думать о теории электрохимии :)

Так как сия затея одноразовая (точнее двухразовая, сейчас подзарядить до весны на хранение, и еще разок весной), думаю что усложнения излишни.