Официальный сайт компании Arduino по адресу arduino.cc
Проблема с питанием - неадекватные символы на экране при питании от батарейки
- Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии
Добрый день! Недавно вспомнил о своём старом проекте (его суть изложена в теме по ссылке: http://arduino.ru/forum/programmirovanie/spidometr-rabotayushchii-s-pomo...). Довёл, кстати говоря, до ума, и вопросов по вычислению скорости больше нет (использовал округление числа, функция ceil, надеюсь, здесь всё правильно, но если нет, прошу поправить). И всё работает прекрасно, но только тогда, когда arduino uno подключена к компьютеру через провод USB. Как только я пытаюсь её подключить от батарейки через VIN-вход, она вроде бы работает, но при этом на экран, во-первых, вместо чисел и фразы "km/h" (кстати, дисплей почему-то отказался поддерживать любые знаки, даже пробел, и мне пришлось функцией char самостоятельно рисовать все знаки - это очень странно, поскольку такой же дисплей в прошлых проектах хорошо работал с любыми знаками, но это не самое главное в моём вопросе), выводятся бессмысленные хаотичные символы.
А во-вторых, они выводятся не в том месте, где должна была выводиться скорость (с помощью предварительной настройки курсора функцией setCursor()), а в любом месте, иногда эти символы заполняют весь экран.
---
Предоставляю изменённый код скетча, если нужно (хотя вряд ли проблема кроется в нём):
P. S. Пробовал включить, используя 9 V-крону, 4 батарейки AA а также через понижающий преобразователь lm2596 и круглый вход вместо входа vin. Все разы arduino запускалась и работала, но выводила на экране неадекватные символы.
#include <Wire.h> #include <LiquidCrystal_I2C.h> //библиотека для экрана int gerkontime1 = 0; //эти две переменные нужны для того, чтобы оберечься от дребезга геркона int gerkontime2 = 0; int sekundi = 0; //эта переменная впоследствии будет являться количеством секунд с последнего сброса переменной gerkon при подсчёте скорости (знаю, не так назвал, но лень было менять название во всём коде, поэтому оставил) int gerkon = 0; // собственно, количество полных оборотов колеса int time24 = 0; //переменная для подсчёта миллисекунд с последнего сброса количества оборотов int dlina = (3, 14) * 65; //радиус = 1/2 диаметра 26 дюймов (1 дюйм=2,5 см) int mvsekundu = 0; //в этой переменной будет скорость в м/с int realskorost = 0; // в этой переменной будет новая скорость, а в следующей - старая int starayaskorost = 0; LiquidCrystal_I2C lcd(0x3F,16,2); byte simvol[8] = { 0b00001, 0b00010, 0b00010, 0b00100, 0b00100, 0b01000, 0b01000, 0b10000 }; void setup() { Serial.begin(9600); //использовалось для проверок переменных, для отладки pinMode(2, INPUT); //контакт геркона pinMode(13, OUTPUT); //второй контакт геркона digitalWrite(13, HIGH); lcd.init(); lcd.backlight(); lcd.createChar(1, simvol); lcd.setCursor(7,1); lcd.print("km"); lcd.setCursor(9,1); lcd.print(char(1)); lcd.print("h"); delay(500); lcd.clear(); } void contact () { int time1 = millis() - time24; // постоянно мониторим, сколько времени прошло с момента последнего сброса gerkontime2 = millis() - gerkontime1; if (gerkontime2 <= 200) { // если с момента срабатывания геркона прошло менее 500 миллисекунд, значит это дребезг и ничего не надо делать } else { if (time1 < 4000) { ++gerkon; //ещё один полный оборот колеса } if (time1 >= 4000) { //если прошло более 4 секунд, делаем вычисления starayaskorost = realskorost; // бывшая realskorost теперь уже starayaskorost)) sekundi = ceil(time1) / 1000; // поскольку здесь более 4 секунд, не факт, что велосипедист едет очень медленно и после срабатывания геркона на 3 секунде, не может следующее срабатывание быть не на 4, а на 5 или 6. int dlina4 = (dlina / 100)*gerkon; //2,041*gerkon //длина окружности была указана в сантиметрах, переводим в метры и умножаем на количество оборотов mvsekundu = dlina4 / sekundi; //9,16 //теперь находим скорость в метрах в секунду realskorost = mvsekundu * 3, 6; //переводим в км/ч lcd.setCursor(3,1); lcd.print(ceil(realskorost)); lcd.createChar(1, simvol); lcd.setCursor(7,1); lcd.print("km"); lcd.setCursor(9,1); lcd.print(char(1)); lcd.print("h"); time24 = millis(); gerkon = 0; //обнуляем переменную gerkon и обновляем переменную time24 } gerkontime1 = millis(); //это всё для той же защиты от дребезга, при первом срабатывании геркона записывается текущее время } } void loop() { int time1 = millis() - time24; //на всякий случай, постоянно обновляем переменную time1 if (digitalRead(2)==LOW) { contact(); } Serial.println(realskorost); //использовалось для проверки, закомментировано) // Serial.println(realskorost); // Serial.println(" km/h"); }
P. P. S. - цифры 9,16 и 2,041 в комментариях - здесь ни к чему, эти цифры я писал в комментарии во время проверки, и забыл удалить
Я думаю, не надо быть семи пядей во лбу, чтобы сообразить, что проблема в питании.
Крона - очень маломощный источник. Максимум, на что ее может хватить - на кратковременное (максимум - десятки секунд) включение самой Ардуины и экономичного экрана. Подсветка экрана способна сразу убить крону. Измерьте напряжение на кроне при работе Ардуино. Лучше - осциллографом. Если есть провалы ниже 7 В, питания явно не хватает.
4 батарейки - это около 6 Вольт. На прямую на 5В такое напряжение подавать страшновато, а для стабилизатора все, что ниже 7 В - мало. Добавьте пятую батарейку.
Более или менее вменяемое питание - от двух элементов 18650.