lcd1602 Тахометр с большими цифрами.

Sanho
Offline
Зарегистрирован: 24.02.2016

Ребята, попался тут как-то пример тахометра с большими цифрами. на 1602.  https://gist.github.com/ronivaldo/5587355/download#

 http://www.youtube.com/watch?v=MeCZi3DPNtw

Даже не тахометр, а так, демонстрация. Но сами цифры не плохие, решил поэкспериментировать, ввел в скетч датчик холла, и прерывание. Но как тахометр работать не хочет. При запуске, сначала чистый экран, затем при подаче импульсов, появляются цифры, и беспорядочно сто-то считают, но не частоту, при остановке импульсов, счет тоже останавливается. Умные головы, подскажите в чем причина, где копать, может кто-то уже сталкивался с этим скетчем?

Вот, что я сделал.

#include <LiquidCrystal.h>
#define RPMpin 2 // датчик Холла
// initialize the interface pins
LiquidCrystal lcd(12, 11, 6, 5, 4, 3);
long microsold = 0;
int rpm = 0;
// the 8 arrays that form each segment of the custom numbers
byte bar1[8] = 
{
        B11100,
        B11110,
        B11110,
        B11110,
        B11110,
        B11110,
        B11110,
        B11100
};
byte bar2[8] =
{
        B00111,
        B01111,
        B01111,
        B01111,
        B01111,
        B01111,
        B01111,
        B00111
};
byte bar3[8] =
{
        B11111,
        B11111,
        B00000,
        B00000,
        B00000,
        B00000,
        B11111,
        B11111
};
byte bar4[8] =
{
        B11110,
        B11100,
        B00000,
        B00000,
        B00000,
        B00000,
        B11000,
        B11100
};
byte bar5[8] =
{
        B01111,
        B00111,
        B00000,
        B00000,
        B00000,
        B00000,
        B00011,
        B00111
};
byte bar6[8] =
{
        B00000,
        B00000,
        B00000,
        B00000,
        B00000,
        B00000,
        B11111,
        B11111
};
byte bar7[8] =
{
        B00000,
        B00000,
        B00000,
        B00000,
        B00000,
        B00000,
        B00111,
        B01111
};
byte bar8[8] =
{
        B11111,
        B11111,
        B00000,
        B00000,
        B00000,
        B00000,
        B00000,
        B00000
};



void setup()
{
   attachInterrupt(0, RPM, FALLING);
  // assignes each segment a write number
  lcd.createChar(1,bar1);
  lcd.createChar(2,bar2);
  lcd.createChar(3,bar3);
  lcd.createChar(4,bar4);
  lcd.createChar(5,bar5);
  lcd.createChar(6,bar6);
  lcd.createChar(7,bar7);
  lcd.createChar(8,bar8);
  
  // sets the LCD's rows and colums:
  lcd.begin(16, 2);

}

void custom0(int col)
{ // uses segments to build the number 0
  lcd.setCursor(col, 0); 
  lcd.write(2);  
  lcd.write(8); 
  lcd.write(1);
  lcd.setCursor(col, 1); 
  lcd.write(2);  
  lcd.write(6);  
  lcd.write(1);
}

void custom1(int col)
{
  lcd.setCursor(col,0);
  lcd.write(32);
  lcd.write(32);
  lcd.write(1);
  lcd.setCursor(col,1);
  lcd.write(32);
  lcd.write(32);
  lcd.write(1);
}

void custom2(int col)
{
  lcd.setCursor(col,0);
  lcd.write(5);
  lcd.write(3);
  lcd.write(1);
  lcd.setCursor(col, 1);
  lcd.write(2);
  lcd.write(6);
  lcd.write(6);
}

void custom3(int col)
{
  lcd.setCursor(col,0);
  lcd.write(5);
  lcd.write(3);
  lcd.write(1);
  lcd.setCursor(col, 1);
  lcd.write(7);
  lcd.write(6);
  lcd.write(1); 
}

void custom4(int col)
{
  lcd.setCursor(col,0);
  lcd.write(2);
  lcd.write(6);
  lcd.write(1);
  lcd.setCursor(col, 1);
  lcd.write(32);
  lcd.write(32);
  lcd.write(1);
}

void custom5(int col)
{
  lcd.setCursor(col,0);
  lcd.write(2);
  lcd.write(3);
  lcd.write(4);
  lcd.setCursor(col, 1);
  lcd.write(7);
  lcd.write(6);
  lcd.write(1);
}

void custom6(int col)
{
  lcd.setCursor(col,0);
  lcd.write(2);
  lcd.write(3);
  lcd.write(4);
  lcd.setCursor(col, 1);
  lcd.write(2);
  lcd.write(6);
  lcd.write(1);
}

void custom7(int col)
{
  lcd.setCursor(col,0);
  lcd.write(2);
  lcd.write(8);
  lcd.write(1);
  lcd.setCursor(col, 1);
  lcd.write(32);
  lcd.write(32);
  lcd.write(1);
}

void custom8(int col)
{
  lcd.setCursor(col, 0); 
  lcd.write(2);  
  lcd.write(3); 
  lcd.write(1);
  lcd.setCursor(col, 1); 
  lcd.write(2);  
  lcd.write(6);  
  lcd.write(1);
}

void custom9(int col)
{
  lcd.setCursor(col, 0); 
  lcd.write(2);  
  lcd.write(3); 
  lcd.write(1);
  lcd.setCursor(col, 1); 
  lcd.write(7);  
  lcd.write(6);  
  lcd.write(1);
}

void printNumber(int value, int col) {
  if (value == 0) {
    custom0(col);
  } if (value == 1) {
    custom1(col);
  } if (value == 2) {
    custom2(col);
  } if (value == 3) {
    custom3(col);
  } if (value == 4) {
    custom4(col);
  } if (value == 5) {
    custom5(col);
  } if (value == 6) {
    custom6(col);
  } if (value == 7) {
    custom7(col);
  } if (value == 8) {
    custom8(col);
  } if (value == 9) {
    custom9(col);
  }      
}  

void printRPM(int rpm) {
  int m , c, d, u, number;
  number = rpm;
  if (number > 999) {
    m = (number - (number % 1000)) / 1000;
    number = number % 1000;
  } else {
    m = 0;
  }  
  
  if (number > 99) {
    c = (number - (number % 100)) / 100;
    number = number % 100;
  } else {
    c = 0;
  }  

  if (number > 9) {
    d = (number - (number % 10)) / 10;
    number = number % 10;
  } else {
    d = 0;
  }  
  
  u = number;
  
  lcd.setCursor(0, 0);
  lcd.print("RPM:");
  printNumber(m, 4);
  printNumber(c, 7);
  printNumber(d, 10);
  printNumber(u, 13);
    
}  

void loop(){
}
void RPM ()
{ 
printRPM(millis() % 1000000);
rpm = (1000000.0/(micros() - microsold))*60;
microsold = micros();

  delay(200);
  }

 

Araris
Offline
Зарегистрирован: 09.11.2012

1. Переменные rpm и microsold должны быть объявлены volatile (http://arduino.ru/Reference/Volatile), microsold сделайте unsigned long, а не long.

2. В строке 300 в функцию вывода на экран должно посылаться значение переменной rpm. 

3. Функция delay() внутри обработчика прерывания не работает.

Обработчик прерывания должен быть максимально простым и коротким, поэтому Вам лучше оставить в нём только подсчёт rpm, а периодический вывод её значения на экран перенести в loop().

Sanho
Offline
Зарегистрирован: 24.02.2016

Спасибо за ответ!

Да, понял, что с этой строкой 300 что-то не понятно, если ее убираешь, вообще ничего не появляется.

Сам скетч тахометра, простой, и отдельно хорошо работает, а вот вставить его, не получается. И почему-то произвольный счет цифр всегда идет на увеличение.

Будем разбираться.

#define RPMpin 2 // датчик Холла
#include <LiquidCrystal.h>
LiquidCrystal lcd(12,11,6,5,4,3);
long microsold = 0;
int rpm = 0;

void setup() {
attachInterrupt(0, RPM, FALLING);
}
void loop() {
delay(100);
lcd.clear();
lcd.print("RPM =");
lcd.setCursor(6, 0);
lcd.print(rpm,DEC);

delay (1000);
}
void RPM ()
{
rpm = (1000000.0/(micros() - microsold))*60;
microsold = micros();
}

 

Araris
Offline
Зарегистрирован: 09.11.2012

Переменные rpm и microsold должны быть объявлены volatile (http://arduino.ru/Reference/Volatile), microsold сделайте unsigned long, а не long.

И ещё не вижу в скетче http://arduino.ru/Reference/PinMode

Sanho
Offline
Зарегистрирован: 24.02.2016

Спасибо, буду пробовать. Я не силен в программировании, но сдается мне, что проблема не в подсчете импульсов, а выводе цифр. Пин указан в начале скетча. Отдельно тахометр считает нормально. Будем копать.

define RPMpin 2 // датчик Холла

 

Sanho
Offline
Зарегистрирован: 24.02.2016

Araris 

Спасибо за подсказки, теперь вроде начал считать. Вот только при остановке импульсов, тахометр не обнуляется, замирает на последних цифрах. Пока не пойму в чем дело. Тахометр отдельно, тоже не сбрасывает.

Araris
Offline
Зарегистрирован: 09.11.2012

Sanho пишет:

Araris 

Вот только при остановке импульсов, тахометр не обнуляется, замирает на последних цифрах.

Внутри loop() пропишите что-то вроде if ( micros() - microsold) > 6000000) { rpm = 0; } // 6000000 - это 6 секунд, например.

[Последнюю фразу я не понял.]

Sanho
Offline
Зарегистрирован: 24.02.2016

Спасибо большое!

Все заработало.

viktorflam
Offline
Зарегистрирован: 09.09.2016

Сталкнулся с подобной проблеммой... 

Скинь пожалуйста рабочий скеч - поразбираюсь...

James
Offline
Зарегистрирован: 26.02.2016

плюсую

James
Offline
Зарегистрирован: 26.02.2016

плюсую