Измеритель ёмкости аккумуляторов (18650) от AlexGyver
- Войдите на сайт для отправки комментариев
Исходник http://alexgyver.ru/capacity_tester/
собрал, запустил, работает ... всё вроде бы просто и понятно. Поменял там некоторые пины, еще что-то по мелочи. Никаких проблем ...
Начал тестить аккумы - оказалось, что долго. А в порт время шлётся в секундах и быстро осознать сколько это 27352с :) не получается - ну думаю "делов то", переведу в часы ... делю время ещё на 3600. Жму загрузка .... и облом:
D:\Мои документы\Arduino\capacity_tester\capacity_tester.ino: In function 'void loop()':
capacity_tester:78: error: 'readVcc' was not declared in this scope
capacity_tester:79: error: 'readAnalog' was not declared in this scope
capacity_tester:84: error: 'sendData' was not declared in this scope
capacity_tester:92: error: 'disp_print' was not declared in this scope
capacity_tester:100: error: 'disp_print' was not declared in this scope
D:\Мои документы\Arduino\capacity_tester\capacity_tester.ino: In function 'void sendData()':
capacity_tester:121: error: 'disp_print' was not declared in this scope
exit status 1
'readVcc' was not declared in this scope
попробовал исходник - тоже самое, переустановил - эффекта ноль :(
Поэтому прошу помощи ... помогите разобратся, что произошло. Ведь еще вчера всё спокойно компелилось :(
зы: тему создал в проектах т.к. есть еще вопрос по доработке, а как тут дорабатывать если "всё умерло" :)
Код в студию. Именно ваш, правленый.
#define NUM_READS 100 #include "TM1637.h" //библиотека дисплея byte load_pin=0; //пин нагрузки (аналоговый!!!!) byte buzz_gnd=2; //динамик земля byte buzz_pin=5; //динамик сигнал byte disp_gnd=6; //земля дисплея byte CLK = 7; //пин дисплея byte DIO = 8; //пин дисплея byte disp_vcc=10; //питание дисплея TM1637 disp(CLK,DIO); //обозвать дисплей disp byte butt_pin=11; //состояние кнопки byte butt_gnd=12; //земля кнопки byte relay_pin=3; //пин реле было 13 const float typVbg = 1.095; // 1.0 -- 1.2 float Voff = 2.5; // напряжение отсечки (для Li-ion=2.5 В, для LiPo=3.0 В) float R = 8.455; //сопротивление нагрузки float I; float cap = 0; //начальная ёмкость float V; float Vcc; float Wh = 0; unsigned long prevMillis; unsigned long testStart; String cap_string; void setup() { pinMode(relay_pin, OUTPUT); //пин реле как выход digitalWrite(relay_pin, HIGH); //выключить реле (оно обратное у меня) pinMode(buzz_pin, OUTPUT); //пищалка pinMode(buzz_gnd, OUTPUT); //пищалка digitalWrite(buzz_gnd, 0); pinMode(butt_pin, INPUT_PULLUP); //кнопка подтянута pinMode(butt_gnd, OUTPUT); //земля кнопки digitalWrite(butt_gnd, 0); pinMode(disp_vcc, OUTPUT); //питание дисплея pinMode(disp_gnd, OUTPUT); //земля дисплея digitalWrite(disp_vcc, 1); digitalWrite(disp_gnd, 0); disp.init(); //инициализация дисплея disp.set(5); //яркость (0-7) Serial.begin(9600); //открыть порт для связи с компом Serial.println("Press any key to start the test..."); //Отправьте любой символ для начала теста while (Serial.available() == 0) { disp.display(3,0); if (digitalRead(butt_pin)==0) {break;} //или нажмите кнопку, чтобы начать тест! } tone(buzz_pin,1000,500); Serial.println("Test is launched..."); Serial.print("s"); Serial.print(" "); Serial.print("V"); Serial.print(" "); Serial.print("A"); Serial.print(" "); Serial.print("mAh"); Serial.print(" "); Serial.print("Wh"); Serial.print(" "); Serial.println("Vcc"); digitalWrite(relay_pin, LOW); //Переключить реле (замкнуть акум на нагрузку) testStart = millis(); //время начала теста в системе отсчёта ардуины prevMillis = millis(); //время первого шага } void loop() { Vcc = readVcc(); //хитрое считывание опорного напряжения (функция readVcc() находится ниже) V = (readAnalog(load_pin) * Vcc) / 1023.000; //считывание напряжения АКБ I = V/R; //расчет тока по закону Ома, в Амперах cap += I*(millis()-prevMillis)/3600000*1000; //расчет емкости АКБ в мАч Wh += I*V *(millis() - prevMillis)/3600000; //расчет емкости АКБ в ВтЧ prevMillis = millis(); sendData(); // отправка данных if (V < Voff) { //выключение нагрузки при достижении минимального напряжения digitalWrite(relay_pin, HIGH); //разорвать цепь (отключить акб от нагрузки) Serial.println("Test is done"); //тест закончен for (int i=0; i<5; i++) { //выполнить 5 раз tone(buzz_pin,1000,500); //пищать на 3 пин частотой 100 герц 500 миллисекунд disp_print(cap_string); delay(1000); disp.clearDisplay(); delay(500); } while (2 > 1) { //бесконечный цикл, чтобы loop() не перезапустился + моргаем результатом! tone(buzz_pin,1000,500); //пищать на 3 пин частотой 100 герц 500 миллисекунд disp_print(cap_string); delay(1000); disp.clearDisplay(); delay(10000); } } } void sendData() { //функция, которая посылает данные в порт Serial.print((millis() - testStart) / 3600000); Serial.print(" "); Serial.print(V, 3); Serial.print(" "); Serial.print(I, 1); Serial.print(" "); Serial.print(cap, 0); Serial.print(" "); Serial.print(Wh, 2); Serial.print(" "); Serial.println(Vcc, 3); cap_string=String(round(cap)); disp_print(cap_string); } //----------Функция точного определения опорного напряжения для измерения напряжения на акуме------- float readAnalog(int pin) { // read multiple values and sort them to take the mode int sortedValues[NUM_READS]; for (int i = 0; i < NUM_READS; i++) { delay(25); int value = analogRead(pin); int j; if (value < sortedValues[0] || i == 0) { j = 0; //insert at first position } else { for (j = 1; j < i; j++) { if (sortedValues[j - 1] <= value && sortedValues[j] >= value) { // j is insert position break; } } } for (int k = i; k > j; k--) { // move all values higher than current reading up one position sortedValues[k] = sortedValues[k - 1]; } sortedValues[j] = value; //insert current reading } //return scaled mode of 10 values float returnval = 0; for (int i = NUM_READS / 2 - 5; i < (NUM_READS / 2 + 5); i++) { returnval += sortedValues[i]; } return returnval / 10; } //----------Функция точного определения опорного напряжения для измерения напряжения на акуме КОНЕЦ------- //----------фильтр данных (для уменьшения шумов и разброса данных)------- float readVcc() { // read multiple values and sort them to take the mode float sortedValues[NUM_READS]; for (int i = 0; i < NUM_READS; i++) { float tmp = 0.0; ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1); ADCSRA |= _BV(ADSC); // Start conversion delay(25); 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 tmp = (high << 8) | low; float value = (typVbg * 1023.0) / tmp; int j; if (value < sortedValues[0] || i == 0) { j = 0; //insert at first position } else { for (j = 1; j < i; j++) { if (sortedValues[j - 1] <= value && sortedValues[j] >= value) { // j is insert position break; } } } for (int k = i; k > j; k--) { // move all values higher than current reading up one position sortedValues[k] = sortedValues[k - 1]; } sortedValues[j] = value; //insert current reading } //return scaled mode of 10 values float returnval = 0; for (int i = NUM_READS / 2 - 5; i < (NUM_READS / 2 + 5); i++) { returnval += sortedValues[i]; } return returnval / 10; } //----------фильтр данных (для уменьшения шумов и разброса данных) КОНЕЦ------- void disp_print(String x) { disp.point(POINT_OFF); switch (x.length()) { //кароч тут измеряется длина строки и соотвествено выводится всё на дисплей case 1: disp.display(0,18); disp.display(1,18); disp.display(2,18); disp.display(3,x[0]- '0'); break; case 2: disp.display(0,18); disp.display(1,18); disp.display(2,x[0]- '0'); disp.display(3,x[1]- '0'); break; case 3: disp.display(0,18); disp.display(1,x[0]- '0'); disp.display(2,x[1]- '0'); disp.display(3,x[2]- '0'); break; } }Где и что вы изменили?
Переставьте все функции типа readVCC, ReadAnalog и т.п. ВЫШЕ их первого использования и всё будет нормально.
хм .. перенес их между void setup() и void loop() ... и вправду заработало. Интересно, но ведь так не было :)
Большое спасибо
В последний раз попытался поменять
а изначально, это .. но при этих изменениях все работало
вроде бы всё
Поменялась версия IDE. Или Вы обновили, или сама обновилась.
Правильно именно так (объявление выше использования), но старые версии IDE эту ошибку типа исправляли за Вас. А новые не исправляют.
Поменялась версия IDE. Или Вы обновили, или сама обновилась.
я её обновил с 1.6.8 до 1.6.12 .. но уже после появления ошибки
прохоже проблема в руских буквах в пути до файла .ino
D:\Мои документы\Arduino\capacity_tester\capacity_tester.ino
Перекинул из "D:\мои документы\Arduino\" в чисто англоязычный путь и всё заработало в старом варианте ... когда функции readVCC и другие располагаются в конце.
Хочу добавить что бы после завершения теста аккум автоматом вставал на зарядку. Скажите можно такой зарядничек запитать от самой ардуины? или на платку зарядника нужно ставить свой БП, второе реле и коммутировать оба провода?
зы: извиняюсь за дикий "фотошоп" ... лень рисовать :)
От Ардуины запитывать никак нельзя! У нее выходной ток по цифровым пинам максимум 30-40 миллиАмпер. А плата для зарядки лития, изображенная на фото, заряжает током 1 Ампер. Так что для зарядки однозначно нужен внешний блок питания. Для этой цели отлично подойдет зарядное устройство для смартфона, которое дает на выходе 5В/1А. Тем более на плате зарядки имеется разъем microUSB. Только при подключении к общей схеме с Ардуино, необходимо будет соединить "земли" (общий провод, GND). То есть Ваш синий провод остается, а вот красный провод, идущий к Ардуино, убираем.
Посмотрел цикл видео у AlexGyver по литиевым аккумуляторам и собрал точно такое же устройство для проверки. Настроил под свои "железки" и протестировал один АКБ с Алика. Заявлено продавцом 4800 мАч, а по факту вышло всего 656 мАч. Ну да грех жаловаться, так как за 89 рублей другого и не ожидал. )) Даже спор открывать не стал.
Но дело не в этом. Подскажите, пожалуйста, как оставить функционал схемы, но выводить все на ЖК-дисплей 1602? В программировании я практически не разбираюсь. То есть общее представление имею, но программу написать или код оптимизировать, для меня "слабо". Есть желание собрать все как автономное устройство. Что-то типа iMax B6, только проще и более узкой специализации.
Подскажите, пожалуйста, как оставить функционал схемы, но выводить все на ЖК-дисплей 1602?
Здесь на форуме есть замечательный проект от bodriy2014, ( http://srukami.inf.ua/testbat3.htm ) где весь подобный функционал давно реализован. Проект под экран 5110, но есть моды и под 1602:
Этот (1602 с I2C модулем) я брал у пользователя arthemy .
Этот делал сам на базе двух вышеуказанных (схемка здесь посложнее).
Спасибо большое! Буду изучать!
От Ардуины запитывать никак нельзя! У нее выходной ток по цифровым пинам максимум 30-40 миллиАмпер.
вот и меня сомнения глодали :) вдруг не потянет ... я тогда припаяюсь наверно к УСБ разъёму ардуинки, чтоб два питания не городить, и поставлю сдвоенное реле и буду перекидывать оба питающих провода
я тогда припаяюсь наверно к УСБ разъёму ардуинки, чтоб два питания не городить, и поставлю сдвоенное реле и буду перекидывать оба питающих провода
Вот только к компьютеру я ардуинку после таких модификаций не подключал бы...
Вот только к компьютеру я ардуинку после таких модификаций не подключал бы...
сначала хотел написать всеобъемлющее слово "блин" :)
... а потом подумалось а что такого случится? в момент программирования (скажем что-то поправить в скетче) измеряемого аккума стоять не будет .. и что? ну запитана платка зарядки можно подумать много она в простое съест. А при измерениях питать сию девайсину от компа у меня даже мысль не возникала :) всяко разно внешний БП, или пауэрбанк в мобильном варианте
Релюшки тоже желательно отключать, пятивольтовые на обмотку немалый ток берут. При заряде/измерении на такой девайс БП ампера на 2 надо. Если делать отдельным устройством - можно пару съёмных джамперов поставить, или дип-переключателей.
Релюшки тоже желательно отключать, пятивольтовые на обмотку немалый ток берут
надо тогда подумать .. что б реле под ток без нужды не вставало. А джампер штука такая ... можно и забыть выключить :)