Проблема с питанием - неадекватные символы на экране при питании от батарейки

Экран
Offline
Зарегистрирован: 20.12.2017

Добрый день! Недавно вспомнил о своём старом проекте (его суть изложена в теме по ссылке: 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");




}

 

 

Экран
Offline
Зарегистрирован: 20.12.2017

P. P. S. - цифры 9,16 и 2,041 в комментариях - здесь ни к чему, эти цифры я писал в комментарии во время проверки, и забыл удалить

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

Я думаю, не надо быть семи пядей во лбу, чтобы сообразить, что проблема в питании.

Крона - очень маломощный источник. Максимум, на что ее может хватить - на кратковременное (максимум - десятки секунд) включение самой Ардуины и экономичного экрана. Подсветка экрана способна сразу убить крону. Измерьте напряжение на кроне при работе Ардуино. Лучше - осциллографом. Если есть провалы ниже 7 В, питания явно не хватает.

4 батарейки - это около 6 Вольт. На прямую на 5В такое напряжение подавать страшновато, а для стабилизатора все, что ниже 7 В - мало. Добавьте пятую батарейку.

Более или менее вменяемое питание - от двух элементов 18650.