<LcdBarGraph.h> что это?

maxvalin
Offline
Зарегистрирован: 22.02.2016

Поиск по форуму ничего не дал, а наткнулся случайно на эту библиотеку.

Хотя бы в кратце что это за библиотека? и если не трудно маленький пример , главное на русском чтоб понятно было)))

 (в смысле коментарии)

Lictor
Offline
Зарегистрирован: 01.10.2015

Она помогает выводить аналоговые значения. Работает на базе LiquedCrystal

#include <LiquidCrystal.h>
#include <LcdBarGraph.h>

byte lcdNumCols = 16; // -- number of columns in the LCD
byte sensorPin = 0; // -- value for this example

LiquidCrystal lcd(12, 11, 5, 4, 3, 2); // -- creating LCD instance
LcdBarGraph lbg(&lcd, lcdNumCols);  // -- creating

void setup(){
  // -- initializing the LCD
  lcd.begin(2, lcdNumCols);
  lcd.clear();
  // -- do some delay: some time I've got broken visualization
  delay(100);
}

void loop()
{
  // -- draw bar graph from the analog value readed
  lbg.drawValue( analogRead(sensorPin), 1024);
  // -- do some delay: frequent draw may cause broken visualization
  delay(100);
}

А этот код отображает шкалу относительно поворота переменного резистора.

Jeka_M
Jeka_M аватар
Offline
Зарегистрирован: 06.07.2014

maxvalin пишет:

Поиск по форуму ничего не дал

Зато поиск по интернету даёт: LcdBarGraphBarGraph

http://playground.arduino.cc/Code/LcdBarGraph

https://www.youtube.com/watch?v=noXtsvPRwQk

https://www.youtube.com/watch?v=4zbBaQPvBC0

Клапауций 234
Offline
Зарегистрирован: 24.10.2016

Jeka_M пишет:

Зато поиск по интернету даёт:

я запретил интернет.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Клапауций 234 пишет:

я запретил интернет.

Блин, так оказывает под ником "Клапауций" скрывается депутат госдумы Ирина Анатольевна Яровая!!!

Мужики, я его (её) раскусил!!!

Клапауций 234
Offline
Зарегистрирован: 24.10.2016

ЕвгенийП пишет:

Блин, так оказывает под ником "Клапауций" скрывается...

бери выше, блин... Трамп скоро скроется, но пока Обама вам ссыт по подъездам и гусей давит бульдозерами.

maxvalin
Offline
Зарегистрирован: 22.02.2016

ничерта поиск не дал. Вы дали ссылки на два видео с ютуба ниочем (создать свои символы и загнать их в шкалу - это уже сделал), на картинки с графиками - тоже ни очем, единственная ссылка на англосайт о библиотеке 

LcdBarGraph.h

 . На русском встречается только эта тема в гугле . Посмотреть как он работает на видео? я и без этого понял.

   Как применить его в деле, имея переменные? Есть 0-100Вольт. вот пример как обяснен вариант с делителем

//////ПРИМЕР формулы АЦП
    /*(analogRead(A5) * 1.1) / 10.23;
     float переменная = (читаем нужный аналоговый вход, умножаем на опорное напряжение)
     делим на коефициент делителя*/
 
эту библиотеку тяжело вот так объяснить?
maxvalin
Offline
Зарегистрирован: 22.02.2016

или к примеру как рисуется вот этот же граф бар только врукопашку:

/////создаю левый первый символ, начало шкалы (создается к примеру https://robom.ru/page/generaciya-matricy-displeya.html)
byte perv[8] = {
    0b11111,
    0b10000,
    0b10000,
    0b10000,
    0b10000,
    0b10000,
    0b10000,
    0b11111
};
///здесь остальные символы например
void setup()
 lcd.begin(16, 2); //инициализация дисплея например 16 на2 
//здесь после инициализации дисплея
lcd.createChar(1, perv); // записываю в память экрана символ "первый"
 
lcd.print(1, BYTE);              // ну и вытягиваю уже этот символ где понадобится
Клапауций 234
Offline
Зарегистрирован: 24.10.2016

maxvalin пишет:

ничерта поиск не дал.

 

 

 . На русском встречается...

на китайском ищи.

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

maxvalin пишет:
вот пример как обяснен вариант с делителем

//////ПРИМЕР формулы АЦП
    /*(analogRead(A5) * 1.1) / 10.23;
     float переменная = (читаем нужный аналоговый вход, умножаем на опорное напряжение)
     делим на коефициент делителя*/
 
эту библиотеку тяжело вот так объяснить?

Вообще-то это неправильный комментарий. Правильный должен выглядеть примерно так:

int voltage = analogRead(A5) * 1.1 / 10.23; // int результат в сотых долях вольта для внутреннего источника опорного напряжения

maxvalin
Offline
Зарегистрирован: 22.02.2016

вопрос посложнее: как инвертировать шкалу? Тоисть есть значение от 20 до 80, но мне надо чтоб шкала заполнялась когда 80-это минимум а 20 это максимум.

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

newValue = 100 - oldValue;

Это наиболее простой и быстрый вариант. Если хотите перестраховаться, используйте map().

maxvalin
Offline
Зарегистрирован: 22.02.2016

andriano пишет:

 int результат в сотых долях вольта для внутреннего источника опорного напряжения

ну-ну, и чей коментарий быстрее поймут простые смертные? Понятное дело что ваш правильный, но если человек вообще первый раз это делает? )

maxvalin
Offline
Зарегистрирован: 22.02.2016

andriano пишет:

newValue = 100 - oldValue;

Это наиболее простой и быстрый вариант. Если хотите перестраховаться, используйте map().

использовать арифметичесский остаток... попробую!

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

maxvalin пишет:

andriano пишет:

 int результат в сотых долях вольта для внутреннего источника опорного напряжения

ну-ну, и чей коментарий быстрее поймут простые смертные? Понятное дело что ваш правильный, но если человек вообще первый раз это делает? )

Простые смертные быстрее поймут правильный комментарий, притом, намного быстрее. Потому как неправильный комментарий они не поймут никогда.

Для кого писался тот код, что Вы привели в качестве образца, не знаю, но точно знаю, кем он писался - вероятнее всего как раз новичком. Ну или по крайней мере, человеком, не слишком хорошо разбирающимся в программировании.

Мне кажется, для новичков гораздо полезнее разбирать код, написанный грамотным программистом, чем код, который написан новичком и содержит ошибки самого разного плана.

maxvalin
Offline
Зарегистрирован: 22.02.2016
    lcd.print(UinSmooth,1); // вывожу усредненные показания для тока
    lcd.print("     ");
    lcd.setCursor(14, 0);
    lcd.print("N");
    lcd.setCursor(0, 0);
    lcd.print("V=");  
    lcd.print(VinSmooth,0); // вывожу усредненные показания для напряжения.
    lcd.print("   ");
    UinShkal = 100 - UinSmooth;
    lbg.drawValue( UinShkal, 60); 

работает, пока что без мапа, ну и без точных данных. На данном этапе подготовки, то что  нужно!

п.с Конечно мой пример написан делитантом)))

maxvalin
Offline
Зарегистрирован: 22.02.2016
[code]
#include <LiquidCrystal.h>
#include <LcdBarGraph.h>
#include <LineDriver.h>


/*
/////создаю левый первый символ
byte perv[8] = {
    0b11111,
    0b10000,
    0b10000,
    0b10000,
    0b10000,
    0b10000,
    0b10000,
    0b11111
};
// второй символ с двумя заполненми полосками
byte vtor[8] = {
    0b11111,
    0b11000,
    0b11000,
    0b11000,
    0b11000,
    0b11000,
    0b11000,
    0b11111
};
//третий символ с тремя заполненными полосками
byte tretiy[8] = {
    0b11111,
    0b11100,
    0b11100,
    0b11100,
    0b11100,
    0b11100,
    0b11100,
    0b11111
};
// четвертый с 4 полосками
byte zhetv[8] = {
    0b11111,
    0b11110,
    0b11110,
    0b11110,
    0b11110,
    0b11110,
    0b11110,
    0b11111
};
//заполненная клеточка
byte polnaya[8] = {
    0b11111,
    0b11111,
    0b11111,
    0b11111,
    0b11111,
    0b11111,
    0b11111,
    0b11111
};
// пустая клетка
byte pustaya[8] = {
    0b11111,
    0b00000,
    0b00000,
    0b00000,
    0b00000,
    0b00000,
    0b00000,
    0b11111
};
//правая пустая
byte pravaya[8] = {
    0b11111,
    0b00001,
    0b00001,
    0b00001,
    0b00001,
    0b00001,
    0b00001,
    0b11111
};




//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// класс титановый велосипед для тактовой кнопки.
// фильтр дребезга, отслеживание событий: нажатие, отпускание, двойное нажатие(doubleclick),
нажато и удерживается в течении определённого времени, отпущено и неактивно в течении определённого времени.
///~~~~~~~~~~~~~~~~~~~~
// здесь код приведённого выше класса class BUTTON {}; 
//~~~~~~~~~~~~~~~~~~~~

BUTTON BUTTON_01(3); // объявляем объект класса BUTTON кнопку с именем BUTTON_01, подключенную к пину 3.
BUTTON BUTTON_02(4); // объявляем объект класса BUTTON кнопку с именем BUTTON_02, подключенную к пину 4.

void setup () {}

void loop() {

BUTTON_01.read(); // обновляем состояние переменных кнопки BUTTON_01.
BUTTON_02.read(); // обновляем состояние переменных кнопки BUTTON_02.

// работаем с переменными кнопки BUTTON_01.
if (BUTTON_01.click_down) {что-то делаем при нажатии}
if (BUTTON_01.click_up) {что-то делаем при отпускании}
if (BUTTON_01.doubleclick) {что-то делаем при двойном нажатии(doubleclick)}
if (BUTTON_01.timer) {что-то делаем, если кнопка отпущена и неактивна в течении определённого времени}
if (BUTTON_01.retention) {что-то делаем при нажатии и удержании в течении определённого времени}

// работаем с переменными кнопки BUTTON_02.
if (BUTTON_02.click_down) {}
if (BUTTON_02.click_up) {}
if (BUTTON_02.doubleclick) {}
if (BUTTON_02.timer) {}
if (BUTTON_02.retention) {}

}*/
class BUTTON {
public:
//================================================================
static const byte bounce_              =   50; // длительность отслеживания дребезга.
static const byte doubleclick_         =  200; // длительность отслеживания двойного клика.
static const unsigned long timer_      = 5000; // длительность отслеживания неактивности.
static const unsigned int retention_   = 2000; // длительность отслеживания нажатия и удержания.
//================================================================
boolean click_down;
boolean click_up;
boolean doubleclick;
boolean timer;
boolean retention;
//=================================
unsigned long m;
boolean  p;
boolean  b;
boolean dc;
byte     c;
boolean  t;
boolean  r;
//=================================
byte _pb;
//=================================
BUTTON(byte pb) {
_pb = pb;
pinMode(_pb, INPUT);
digitalWrite(_pb, 1);
//====
click_down      = 0;
click_up        = 0;
doubleclick     = 0;
timer           = 0;
retention       = 0;
//====
m  =      millis();
p  = digitalRead(_pb);
b  =                0;
dc =                0;
c  =                0;
t  =                0;
r  =                0;
//====
}

void read() {
//=======================================================
unsigned long nm =      millis();
boolean       np = digitalRead(_pb);
//=================
boolean nb  = 0;
boolean ndc = 0;
boolean nt  = 0;
boolean nr  = 0;
//================
click_down  = 0;
click_up    = 0;
doubleclick = 0;
timer       = 0;
retention   = 0;
//=================
if (np != p) {p = np; m = nm; }
//=======================================================
if (nm - m > bounce_) {nb = 1;}
if (nm - m > doubleclick_) {ndc = 1;}
if (ndc != dc) {dc = ndc; if (dc == 1) {c = 0;}}
if (nb != b) {b = nb;
if (p == 0 && b == 0) {click_down = 1;
++c;      if (c == 2) {c = 0; doubleclick = 1;}
}
if (p == 1 && b == 1) {click_up = 1;}
}
//=======================================================
if (nm - m > timer_) {nt = 1;}
if (nt != t) {t = nt;
if (p == 1 && t == 1) {timer = 1;}
}
//=======================================================
if (nm - m > retention_) {nr = 1;}
if (nr != r) {r = nr;
if (p == 0 && r == 1) {retention = 1;}
}
//=======================================================
}
};
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

#include <SimpleTimer.h>
SimpleTimer timer;

LiquidCrystal lcd(12, 11, 5, 4, 3, 2); // для экрана  RS, E, DB4, DB5, DB6, DB7
long zamerV = 500;  // интервал для змеров покзаний
long startlog = 5000; // интервал для логирования показний
long previousMillis = 0; // время последнего задействования
float Vin = 0; // переменная для напржения(для замера) 
float Uin = 0; // переменная для тока(для замера)
#include <SD.h> // библиотека для карты пмяти  
         /// пины для карты памяти
/*uint8_t const SS_PIN = 53;
uint8_t const MOSI_PIN = 51;
uint8_t const MISO_PIN = 50;
uint8_t const SCK_PIN = 52;*/
File myFile; // создаю мой файл для карты памяти 
float VinOld,VinSmooth;  // переменные для усреднения напряжения
float UinOld,UinSmooth;  // переменные для усреднения тока
float UinShkal; // переменная для шкалы
float Uinzaryad = 40;    // переменная для контроля зарядки, отключение пускателя
BUTTON Akkum1(32);     // кнопка запуска заряда акумулятора 1 на пине 1
BUTTON Akkum2(34);     // кнопка запуска заряда акумулятора 2 на пине 2
BUTTON Akkum3(36);     // кнопка запуска заряда акумулятора 3 на пине 3
volatile uint8_t minut=0;
volatile uint8_t chas=0;
volatile uint8_t sec=0;
byte relay1 = 46; //реле на 46 пине 
byte nomerP = 0; //флаг , определяет номер програмы, какой аккумулятор нужно заряжать.
LcdBarGraph lbg(&lcd, 16, 0, 1);  // -- создаю графбар: перая цифра-количество полных кубиков в шкале, вторая:от куда начинается, третья: по высоте номер строки  (column 1)




void setup()
{ 
  pinMode (46, OUTPUT); //выход на реле№1 основное включает зарядку
  pinMode(A5, INPUT); // вход для 
  TCCR1A=(1<<WGM11); //режим14 FAST PWM  это для часов
  TCCR1B=(1<<CS12)|(1<<WGM13)|(1<<WGM12); //делить частоту CPU на 256 это для часов
  ICR1=62499;  // (16000000MHz /div256) -1 = 1 раз в секунду это для часов
  TIMSK1=(1<<TOIE1); //разрешить прерывание это для часов
  lcd.begin(16, 2);
  /*
  lcd.createChar(1, perv); // создаю в память экрана символ "первый"
  lcd.createChar(2, vtor); // создаю в память экрана символ второй
  lcd.createChar(3, tretiy); // создаю в память экрана символ третий
  lcd.createChar(4, zhetv); // создаю в память экрана символ четвертый
  lcd.createChar(5, polnaya); // создаю в память экрана символ закрашенная клетка
  lcd.createChar(6, pustaya); // создаю в память экрана символ пустая клетка
  lcd.createChar(7, pravaya); // создаю в память экрана символ правая клетка
  */
  
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print(" PROVER UROVEN ");
  lcd.setCursor(1, 1);
  lcd.print("  DISTILATA! ");
  //delay (100);
  lcd.clear();
  analogReference(INTERNAL1V1); // переключаю на внутренее опорное 1.1в
  pinMode(53, OUTPUT); // специально иначе логировать не будет
  Serial.begin(9600); 
  while (!Serial) // если открывается порт на пк
  {
    ; //Ждём инициализации серийного порта. Нужно для Leonardo
  }

  Serial.print("Initializing SD card...");
  if (!SD.begin(4)) {
    Serial.println("initialization failed!");
    return;
  }
  Serial.println("initialization done.");
  
}
ISR (TIMER1_OVF_vect) { 
sec++ ; //инкремент переменной каждую секунду
if (sec>59){sec=0; minut++; }
if (minut>59){minut=0; chas++; }
if (chas>23){chas=0;}
}

void loop()
{ 
    timer.run();
    Akkum1.read(); // обновляем состояние переменных кнопки первого акума
    Akkum2.read(); // обновляем состояние переменных кнопки второго
    Akkum3.read(); // обновляем состояние переменных кнопки третьего
    
        //////ПРИМЕР формулы АЦП
    /*(analogRead(A5) * 1.1) / 10.23;
     float переменная = (читаем нужный аналоговый вход, умножаем на опорное напряжение)
     делим на коефициент делителя*/
     
    unsigned long currentMillis = millis();
    if(currentMillis - previousMillis >= zamerV)
    {
    previousMillis = currentMillis;    
    float Vin = (analogRead(A5) * 1.1) / 10.23; // вычисление ацп напряжение на А5
    VinOld=VinSmooth;   // приравнивание переменных друг другу
    VinSmooth=(3.0*VinOld+Vin)/4.0; // формула для усреднения показания  
    float Uin = (analogRead(A10) *1.1/1023)/0.00075;  //// вычисление тока на А10
    UinOld=UinSmooth;
    UinSmooth=(6.0*UinOld+Uin)/7.0;
    }
    lcd.setCursor(14, 0);
    lcd.print("N");
    lcd.print(nomerP);
    lcd.setCursor(6, 0);
    lcd.print("A=");
    lcd.print(UinSmooth,1); // вывожу усредненные показания для тока
    lcd.print("     ");
    lcd.setCursor(14, 0);
    lcd.print("N");
    lcd.setCursor(0, 0);
    lcd.print("V=");  
    lcd.print(VinSmooth,0); // вывожу усредненные показания для напряжения.
    lcd.print("   ");
    UinShkal = 100 - UinSmooth;
    lbg.drawValue( UinShkal, 60); // -- рисую график из данных по току, после формул усреднения
    
   

    
    
    if(currentMillis - previousMillis >= startlog)
     {
      previousMillis = currentMillis;
      myFile = SD.open("LOG1.csv", FILE_WRITE);
      if (myFile)       // Если файл открылся, пишем в него:
    { 
     myFile.print(VinSmooth);
     myFile.write(";");
     myFile.print(UinSmooth);
     myFile.write(";");
     myFile.print(nomerP);
     myFile.write(";");
     myFile.print(chas);  
     myFile.write(".");
     myFile.print(minut);
     myFile.println("");
     // Закрываем файл:
     myFile.close();
     Serial.println("done.");
     } 
   else 
     {
     // если файл не открылся, сообщает об ошибке:
     Serial.println("error opening LOG1.csv");
     }

      // открываем файл только для чтения
      myFile = SD.open("LOG1.csv");
  if (myFile) 
     {
      Serial.println("LOG1.csv:");
      // читаем файл посимвольно до конца:
  while (myFile.available()) 
     {
      Serial.write(myFile.read());
     }
     // закрываем файл:
     myFile.close();
     } 
  else 
     {
     // если файл не открылся, сообщает об ошибке:
     Serial.println("error opening LOG1.csv");
     }
     }
/////// обработка кнопок
 if (Akkum1.click_down)     // если нажата кнопка первого аккумулятора то включаю пускатель и включаю флаг первой программы               
   {
   digitalWrite(relay1, HIGH);
   nomerP = 1; //определяем что включен первый аккумулятор на зарядку
   }

 if (Akkum2.click_down)     // если нажата кнопка второго аккумулятора то включаю пускатель и включаю флаг второй программы               
   {
   digitalWrite(relay1, HIGH);
   nomerP = 2; //определяем что включен второй аккумулятор на зарядку
   }

 if (Akkum3.click_down)     // если нажата кнопка третьего аккумулятора то включаю пускатель и включаю флаг третьей программы               
   {
   digitalWrite(relay1, HIGH);
   nomerP = 3; //определяем что включен третий аккумулятор на зарядку
    
    }
  /////////// запуск и обработка первого аккумултора
  if (nomerP == 1 && relay1 == HIGH && UinSmooth >= 80)// если ток заряда больше 80 ампер пишем пустую шкалу
   {
  
        

    
    
    }






     
                  
}



[/code]

Уж если не трудно, делитанский вопрос: Почему мигает на экране именно 

 lcd.setCursor(14, 0);
    lcd.print("N");
    lcd.print(nomerP);

куда бы я его не тыкал((( те два показателя без мерцания а этот мерцает