Строку 3 убери. Можно ее в сетап() перенести. Переменную х объяви глобально.
И с целыми числами так не работает. Вот пример скользящее среднее с целочисленным вычислением.
word prevMillis, intervalMs = 50;
int avgAdc, errorVal, averageFactor = 8;
void setup() {
Serial.begin(115200);
avgAdc = analogRead(A0);
}
void loop() {
if((word)millis() - prevMillis >= intervalMs){
prevMillis += intervalMs;
int valAdc = analogRead(A0);
int delta = valAdc - avgAdc;
int sum = errorVal + delta;
avgAdc += sum / averageFactor;
errorVal = sum % averageFactor;//накапливаем погрешность
Serial.print(valAdc); Serial.print('\t');
Serial.print(errorVal); Serial.print('\t');
Serial.println(avgAdc);
}
}
Гм.. Со static вообще какая-то чертовщина стала..
С напряжением всё нормуль - вяло шевелится в пределах десятых. То есть нормально.
А вот с измерением тока наблюдаются чудеса.
Через некоторое время (довольно приличное) он уходит в небеса.
Например, вместо 40mA выдаётся 2621.40 (смотрю в serial), или просто “0”..
При этом на контрольном приборе никаких скачков не наблюдается.
Через некоторое время всё восстанавливается.
Что бы это может быть? Переполнение?
Не здесь ли - uint16_t sensorValue2 = a-11;// уберем погрешность ??
Походу, насчёт измерения тока что-то аппаратное.
При токе = 0 на пине А7 около 0.7 V. То ли что-то отвалилось, то ли операционник сдох.
Может я где-то накосячил.. С софтом пока стоп. Буду проверять железо.
Если амперметр показывает ноль при нулевом токе, то все нормально. Просто вычитай из АЦП число, соответствующее нулевому току. В схеме на ОУ есть смещение на неинвертирующем входе, так что она работает как задумано.
Упустил, ты же меняешь родной мк на атмегу. Тогда убери резистор R5.
Удалил R5 - всё пропало, Шеф! Всё пропало!
Почти постоянно “0” на выходе.. Раскумариваться начинает только при токе > 0.4A..
Минус 11 отсюда - uint16_t sensorValue2 = a-11; убрал.
Плюс ко всему, оказалось что резисторы в обратной связи (с 6-й ноги на 7-ю) в моей “коробочке” другие - 47к и 2.2к подстроечный..
И 2.2к с 6-й ноги на “землю”.
Так это и “напряжометр” придётся переделывать.
Может запитать LM358 от 5В ?
P.S. Вот такая схема сейчас. Измерение напряжения не рисовал.
Не переживай)
Почему так происходит. У LM358 на входах стоят рнр транзисторы, поэтому есть вытекающие токи порядка 5 нА.
На резисторе 300 Ом падает 1.5 мВ при токе 5 нА, а на резисторе 2.2 кОма падает 11 мВ. И пока на входе+ напряжение не превысит напряжение на входе- (11 мВ), на выходе будет ноль.
Как исправить.
Вместо 270 кОм поставить подстроечник 1 МОм и им выставлять ноль.
Вместо 300 Ом поставить 2.2 кОм постоянный, а лучше 4.7 кОм подстроечник и им выставить ноль.
Поставить на место 270 кОм, а в скетче прописать автокалибровку. При первом включении замерить выходное напряжение на ОУ при нулевом токе и записать в ЕЕПРОМ.Дальше вычитать это значение. Возможно так и сделано в оригинале.
Да, в оригинале есть перемычка для калибровки.
А в “ардуиновом” варианте (как сейчас у меня) - вот это - “float sensorValue2 = a-12;// уберем погрешность” .
Но сейчас очень смущает непонятно откуда появившаяся “тупизна” измерения тока. Сейчас напряжение на выходе операционника начинает изменяться только при токе > 400 mA.
А мне надо измерения от 30 до 500 mA.
Попробую вернуть R5 на место и добавить “пин калибровки”.
Ну я же выше написал почему так происходит и варианты решения. Если что непонятно из написанного, задавай конкретней вопрос.
Шунт сопротивлением каким?
Вечером верну на место R5 и питание от родного стабилизатора.
Ну и ещё раз проверю, не накосячил ли где с соединениями.
Сейчас на работе, паяльник недоступен.
По-возможности, пока поизобретаю (или где-нить выкраду ) код калибровки.
P.S. Но я был бы ещё более восхищён, если бы Вы подмогнули в написании корректировки нуля амперметра в скетче.
С этим у меня - как “неожиданно” выяснилось - проблемы.. И плагиат чёт никак не гуглится..
Видимо, из-за погоды. Со вчерашнего вечера льёт без перекуров и +13 (днём)..
Для чего нужна первая строка, если в ней x всегда будет равно 0 ?
И в итоге всегда получим x = analogRead(A0) / 4.
Может всё-таки uint16_t x = analogRead(A0); ? Без static.
Нет, это начальная инициализация переменной. Возможно она будет равна нулю, возможно нет. Но она будет примерно соответствовать последующим измерениям. Если просто присвоить ей нуль, то выход на действующее значение будет (может быть) довольно долгим
static позволяет переменной сохранять свое значение при выходе из ее блока. Т.е. на следующей итерации loop() она будет иметь то же самое значение, которое получила на прежнем проходе. Т.е. аналог глобальной переменной, но с ограниченной областью видимости
Гм.. Ну во-первых, подтверждено экспериментально.
А во-вторых -
Ключевое слово static используется для создания переменной, которая видна только одной функции. Однако в отличие от локальных переменных, которые создаются и уничтожаются при каждом вызове функции, статические переменные остаются после вызова функции, сохраняя свои значения между её вызовами.
равное “0”, т.к. “первый проход” будет при отсутствии напряжения/тока.
В итоге у меня получилось именно x = analogRead(A0) / 4.