#1 Re: Програмування Arduino » Последовательный вывод данных на LCD » 2016-11-02 09:02:23

Хочу поделится рабочей версией. Спасибо доброму человеку выручил. Я его совместил со своим кодом и всё прекрасно работает.

/*
#1 светодиоды led1-led8
#2 I2C LCD1602          GND -> GND
                      +5V -> +5V
                      SDA -> A4(SDA)
                      SCL -> A5(SCL)
  подсветка ->13 (backlight_pin)
#3 кнопка ->2 (BUTTON_PIN)
#4 пищалка ->9 (BUTTON_PIN)
#5 RХ->0
   TХ->1
*/
//#1 флаги
const int MSG_End = 8 ; // количество исслед каналов
uint8_t msgFlag[MSG_End] =      {0, 0, 0, 0, 0, 0, 0, 0}; // флаги текущих состояний UPS (1 - это авария)
void ledControl() { // моргание нужными LED
}
//#2  дисплей
const char * message[MSG_End] = {  // сообщения об авариях
  "1:UPS1 Inver OFF",
  "2:UPS1 On Batter",
  "3:UPS1 Gen Alarm",
  "4:UPS1 Inver OFF",
  "5:UPS2 Inver OFF",
  "6:UPS2 ON Batter",
  "7:UPS2 Gen Alarm",
  "8:UPS2 Inver OFF",
};
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
const int backlight_pin = 13;
LiquidCrystal_I2C lcd(0x27, 16, 2); // Устанавливаем дисплей

void displayData() {// отображение информации
  static uint8_t number_step = 0; // номер шага вывода
  lcd.setCursor(0, 0);
  // вывод верхней строки
  for (int i = 0; i < MSG_End; i++) {
    if (!msgFlag[i]) {
      lcd.print(i + 1);
      lcd.print(" ");
    }
    else {
      if (number_step & 1) lcd.print("X");
      else lcd.print(i + 1);
      lcd.print(" ");
    }
  }
  // вывод нижней строки
  lcd.setCursor(0, 1);
  if (msgFlag[number_step] )lcd.print(message[number_step]);
  number_step++;
  if (number_step >= MSG_End) number_step = 0;
}
//#3 кнопка
const int BUTTON_PIN = 2;
void readButtons(byte pin) {// сканируем кнопку
}
//#4 пищалка
const int BUZZER_PIN = 9;
void buzzer(byte pin) { // звуковые уведомления
}
//#5 сериал
const int RX_PIN = 0;
const int TX_PIN = 1;
void readSerial(byte rxPin) {// слушаем Serial
}
void dataManager() {  // обработка данных
    msgFlag[0] = true;  // авария на 2-м UPS
    msgFlag[5] = true;  // авария на 7-м UPS
    //msgFlag[7] = true;  // авария на 8-м UPS
}
void sendData(byte txPin) {// отправка данных
}
// mail
void setup() {
  //#1   флаги
  //#2   дисплей
  lcd.init()             ; // инициализация LCD
  pinMode ( backlight_pin, OUTPUT );
  digitalWrite ( backlight_pin, 1 );
  lcd.backlight(); // Включаем подсветку дисплея
  //#3 кнопка
  //#4 пищалка
  //#5 сериал
}
void loop() {
  static uint32_t MILLIS ;
  MILLIS = millis() ;
  //#1 флаги
  ledControl();                 // моргание нужными LED
  //#2 1000 милисек дисплей
  static uint32_t future2 = 0 ;
  if (MILLIS >= future2) {
    future2 = MILLIS + 1000 ;
    displayData();       // отображение информации
  }
  //#3 кнопка
  readButtons(BUTTON_PIN);      // сканируем кнопку
  //#4 пищалка
  buzzer(BUZZER_PIN);           // звуковые уведомления
  //#5 сериал
  static uint32_t future5 = 10000 ;
  if (MILLIS >= future5) {
    future5 = MILLIS + 1000 ;
    readSerial(RX_PIN);           // слушаем Serial
    dataManager();                // обработка данных
    sendData(TX_PIN);             // отправка данных
  }
}
 

#2 Re: Програмування Arduino » Последовательный вывод данных на LCD » 2016-10-29 11:38:36

NoName пише:

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

Здравствуйте
Я проверил не получилось.
Вот Видео там цикличность даже останавливается
https://youtu.be/qk4XUJQPYVI

#3 Re: Програмування Arduino » Последовательный вывод данных на LCD » 2016-10-28 22:59:15

У меня всё собранное на работе. Утром поеду проверять. А пока попытаюсь в Протеусе проверить.
Вам ещё раз гигантское спасибо. Я обязательно отпишусь о результате.
Извините что побеспокоил Вас.

#4 Re: Програмування Arduino » Последовательный вывод данных на LCD » 2016-10-28 22:51:15

for ( ; c < 8; c++ )
if ( !msgFlag[c] ) break;

А что даёт пробел перед ; в первой строке?

#5 Re: Програмування Arduino » Последовательный вывод данных на LCD » 2016-10-28 22:48:57

Мне нужно только исправить правильный вывод сообщений на дисплей.

#7 Re: Програмування Arduino » Последовательный вывод данных на LCD » 2016-10-28 22:29:46

Чтобы тем кто хочет помочь другая часть кода не мешала я выложил только проблемную часть.

#8 Re: Програмування Arduino » Последовательный вывод данных на LCD » 2016-10-28 22:28:10

Вот мой скетч. Это второе устройство первое передаёт ему информацию о состоянии 8 входов. С передачей проблем нет и лампочки загарают правильно. Единственное проблема в отображении на дисплее.
https://dl.dropboxusercontent.com/u/406 … chiy22.rar

#9 Re: Програмування Arduino » Последовательный вывод данных на LCD » 2016-10-28 22:10:36

Rauf_AF пише:
NoName пише:

дайте  URL на библиотеку LCD а то
https://github.com/fdebrabander/Arduino … 2C-library
не такая как у Вас
действительно, ошибок синтактических немеренно в том тексте что скинул (

Всё уроки с дочкой сделал, сыночек тоже уснул теперь сел за комп.
Я эту библиотеку прямо в Arduino IDE скачал там нужно выбрать (Скетч> Подключить библиотеку> Управлять библиотеками) там в пол поиска написал LiquidCrystal_I2C в скриншоте видно.
Большое спасибо что уделяете моей проблеме своё время.

Это ссылка на библиотеку которую я взял из папки Ардуино софта.
https://dl.dropboxusercontent.com/u/406 … al_I2C.rar

https://dl.dropboxusercontent.com/u/406 … .51.38.png

#10 Re: Програмування Arduino » Последовательный вывод данных на LCD » 2016-10-28 22:02:33

NoName пише:

дайте  URL на библиотеку LCD а то
https://github.com/fdebrabander/Arduino … 2C-library
не такая как у Вас
действительно, ошибок синтактических немеренно в том тексте что скинул (

Всё уроки с дочкой сделал, сыночек тоже уснул теперь сел за комп.
Я эту библиотеку прямо в Arduino IDE скачал там нужно выбрать (Скетч> Подключить библиотеку> Управлять библиотеками) там в пол поиска написал LiquidCrystal_I2C в скриншоте видно.
Большое спасибо что уделяете моей проблеме своё время.

%D0%A1%D0%BA%D1%80%D0%B8%D0%BD%D1%88%D0%BE%D1%82%202016-10-28%2022.51.38.png

#11 Re: Програмування Arduino » Последовательный вывод данных на LCD » 2016-10-28 16:55:58

Вот новое видео первых 3 сработок. Там всё отлично. И ниже код в котором для удобства прописал все эмуляции и укоротил сообщения для 16 символьной строки.


https://youtu.be/QMeUeBFLM74

#include <LiquidCrystal_I2C.h>

#include <Wire.h> 

LiquidCrystal_I2C lcd(0x27,16,2);  // устанавливаем адрес 0x27, и дисплей 16 символов в 2 строки (16х2)

#define BUTTON_PIN                 2
#define RX_PIN                     0
#define TX_PIN                     1
#define BUZZER_PIN                 9
#define BACKLIGHT_PIN              13
#define LCD_HEIGHT                 2
#define LCD_WIDTH                  16
#define MSG_COUNT                  8

boolean needUpdateLCD =            true;                    // флаг-признак необходимости одновить данные на дисплее
String lcdBuffer[LCD_HEIGHT];
const unsigned int updateTime =    2000;                    // интервал смены надписей в нижней строке
const unsigned int flashTime =     250;                     // интервал мигания цифр (при аварии)
boolean msgFlag[MSG_COUNT] =      {0, 0, 0, 0, 0, 0, 0, 0 }; // флаги текущих состояний UPS (1 - это авария)
const String message[MSG_COUNT] = {                         // сообщения об авариях
  "U1 Inverter Off ",
  "U1 On Battery   ",
  "U1 General Alarm",
  "U1 Inverter Off ",
  "U2 Inverter Off ",
  "U2 On Battery   ",
  "U2 General Alarm",
  "U2 Inverter Off ",
};

#define TIMEOUT(tm, lastTm) (millis() - lastTm > tm)         // принять как аксиому :)

/*-----( Import needed libraries )-----*/




// Set the pins on the I2C chip used for LCD connections:
//                    addr, en,rw,rs,d4,d5,d6,d7,bl,blpol
//LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);  // Set the LCD I2C address

//LiquidCrystal_I2C lcd(0x27, BACKLIGHT_PIN, POSITIVE);  // Set the LCD I2C address

// Прототипы функций (чтобы компилятор не ругался)
void displayData();
void dataManager();
void buzzer(byte pin);
void readButtons(byte pin);
void readSerial(byte rxPin);
void sendData(byte txPin);


void loop()
{
  readButtons(BUTTON_PIN);      // сканируем кнопку
  readSerial(RX_PIN);           // слушаем Serial
  dataManager();                // обработка данных
  sendData(TX_PIN);             // отправка данных
  displayData();                // отображение информации
  buzzer(BUZZER_PIN);           // звуковые уведомления
  ledControl();                 // моргание нужными LED
}


void dataManager()
{
  // тут обработка каких-то данных
  // ...

  // эмуляция неисправности трех UPS через 1 мин после включения питания
  if (millis() > 5000)
  {
    msgFlag[0] = true;  // авария на 1-м UPS
    msgFlag[1] = true;  // авария на 2-м UPS
    msgFlag[2] = true;  // авария на 3-м UPS
    //msgFlag[3] = true;  // авария на 4-м UPS
    //msgFlag[4] = true;  // авария на 5-м UPS
    //msgFlag[5] = true;  // авария на 6-м UPS
    //msgFlag[6] = true;  // авария на 7-м UPS
    //msgFlag[7] = true;  // авария на 8-м UPS
  }

}



void displayData()
{
  // формирование первой строки для вывода на дисплей
  static unsigned long lastFlashTime;
  lcdBuffer[0] = "1 2 3 4 5 6 7 8";          // шаблон для первой строки
  if (TIMEOUT(flashTime, lastFlashTime))     // каждые 0,25 сек формируем первую строку
  {
    static boolean flashFlag = true;
    if (flashFlag)
    {                                        // проверяем флаги на наличие ошибок
      for (byte ups = 1; ups <= MSG_COUNT; ups++)
        if (msgFlag[ups - 1]) lcdBuffer[0].replace(String(ups), "x"); // где ошибка - ставим хер
    }
    flashFlag = !flashFlag;
    lastFlashTime = millis();
    needUpdateLCD = true;
  }

  // формирование второй строки для вывода на дисплей
  static unsigned long lastUpdateTime;
  if (TIMEOUT(updateTime, lastUpdateTime))   // каждые 2 сек формируем вторую строку
  {
    lcdBuffer[1] = "                ";   // 20 пробелов (у меня 20 знаков на дисплее)
    lastUpdateTime = millis();
    //needUpdateLCD = true;                  // не нужно, т.к. первая строка все равно чаще обновляет ЖК
    byte ups = 0;
    while (!msgFlag[ups])                    // проверяем флаги на наличие ошибок
    {
      ups++;
      if (ups >= MSG_COUNT)                  // если нет ни одной ошибки, то выходим
      {
        ups = 0;
        return;
      }
    }
    // сюда попадаем, если есть хоть одна ошибка
    static byte c = 0;
    while (!msgFlag[c]) c++;                 // пропускаем сообщения, к которым ошибка не относится
    lcdBuffer[1] = message[c];               // буферизуем сообщение
    c++;                                     // чередуем все сообщения об ошибках
    if (c >= MSG_COUNT - 1) c = 0;

  }

  // обновление данных на дисплее
  if (needUpdateLCD)
  {
    lcd.setCursor(0, 0);
    lcd.print(lcdBuffer[0]);

    lcd.setCursor(0, 1);
    lcd.print(lcdBuffer[1]);

    needUpdateLCD = false;
  } // if
} // displayData



void ledControl()
{
}



void buzzer(byte pin)
{
}



void readButtons(byte pin)
{
}



void readSerial(byte rxPin)
{
}



void sendData(byte txPin)
{
}


void setup()
{
  lcd.init();                     // инициализация LCD 
  lcd.backlight();                // включаем подсветку
  pinMode ( BACKLIGHT_PIN, OUTPUT );
  digitalWrite ( BACKLIGHT_PIN, HIGH );
  lcd.begin(LCD_WIDTH, LCD_HEIGHT);
  lcd.backlight(); // finish with backlight on
  lcd.clear();
}

#12 Re: Програмування Arduino » Последовательный вывод данных на LCD » 2016-10-28 16:43:00

Он не скомпилировался.
exit status 1
'view_error' does not name a type

огрызается.

Если у вас будет время посмотрите пожалуйста я уже давно не могу решить эту проблему. И начальство из-за этого напрягает. Собрал два устройства на ATMEGA328 связал их RS485 связь есть данные идут единственная проблема осталась в последовательном выводе данных на вторую строку. Она 16 символов. Тот код то что я выставил отображает другие комбинации нормально например

void dataManager()
{
  // тут обработка каких-то данных
  // ...

  // эмуляция неисправности трех UPS через 1 мин после включения питания
  if (millis() > 5000)
  {
    msgFlag[0] = true;  // авария на 1-м UPS
    msgFlag[1] = true;  // авария на 2-м UPS
    msgFlag[2] = true;  // авария на 3-м UPS
    //msgFlag[3] = true;  // авария на 4-м UPS
    //msgFlag[4] = true;  // авария на 5-м UPS
    //msgFlag[5] = true;  // авария на 6-м UPS
    //msgFlag[6] = true;  // авария на 7-м UPS
    //msgFlag[7] = true;  // авария на 8-м UPS
  }

}

именно проблемы если эмулировать 1 с 6 или 2 с 6
На нескольких форумах писал на данную проблему ответов пока нет.

#13 Re: Програмування Arduino » Последовательный вывод данных на LCD » 2016-10-28 15:13:02

Спасибо!
Прочитав ваш коммент я призадумался, с х.. понятно. Шоколад??? И понял куда ведёт ссылка )). Да это я увлекаюсь мехатроникой и собрал 3D принтер но печатает он шоколадом )).
Касательно Вашей помощи конечно я благодарен. Но ваше написание это для меня очень сложно я в нём мягко говоря многого не понял.

#14 Програмування Arduino » Последовательный вывод данных на LCD » 2016-10-28 13:42:06

Rauf_AF
відповідей: 27

Здравствуйте.
Прошу Вас оказать помощь в нахождении ошибки в коде. Ниже приведён код цель которого выдавать соответствующие события на дисплей. Но при комбинации 1 го и 6 сообщения на экран циклично выходит абракадабра. Также прилагаю ссылку на видео демонстрирующую данную проблему. За ранее благодарю.

https://youtu.be/lFPrrpiXIzY

#include <LiquidCrystal_I2C.h>

#include <Wire.h> 

LiquidCrystal_I2C lcd(0x27,16,2);  // устанавливаем адрес 0x27, и дисплей 16 символов в 2 строки (16х2)

#define BUTTON_PIN                 2
#define RX_PIN                     0
#define TX_PIN                     1
#define BUZZER_PIN                 9
#define BACKLIGHT_PIN              13
#define LCD_HEIGHT                 2
#define LCD_WIDTH                  16
#define MSG_COUNT                  8

boolean needUpdateLCD =            true;                    // флаг-признак необходимости одновить данные на дисплее
String lcdBuffer[LCD_HEIGHT];
const unsigned int updateTime =    2000;                    // интервал смены надписей в нижней строке
const unsigned int flashTime =     250;                     // интервал мигания цифр (при аварии)
boolean msgFlag[MSG_COUNT] =      {0, 0, 0, 0, 0, 0, 0, 0 }; // флаги текущих состояний UPS (1 - это авария)
const String message[MSG_COUNT] = {                         // сообщения об авариях
  "UPS 1 Inverter Off ",
  "UPS 1 On Battery   ",
  "UPS 1 General Alarm",
  "UPS 1 Inverter Off ",
  "UPS 2 Inverter Off ",
  "UPS 2 On Battery   ",
  "UPS 2 General Alarm",
  "UPS 2 Inverter Off ",
};

#define TIMEOUT(tm, lastTm) (millis() - lastTm > tm)         // принять как аксиому :)

/*-----( Import needed libraries )-----*/




// Set the pins on the I2C chip used for LCD connections:
//                    addr, en,rw,rs,d4,d5,d6,d7,bl,blpol
//LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);  // Set the LCD I2C address

//LiquidCrystal_I2C lcd(0x27, BACKLIGHT_PIN, POSITIVE);  // Set the LCD I2C address

// Прототипы функций (чтобы компилятор не ругался)
void displayData();
void dataManager();
void buzzer(byte pin);
void readButtons(byte pin);
void readSerial(byte rxPin);
void sendData(byte txPin);


void loop()
{
  readButtons(BUTTON_PIN);      // сканируем кнопку
  readSerial(RX_PIN);           // слушаем Serial
  dataManager();                // обработка данных
  sendData(TX_PIN);             // отправка данных
  displayData();                // отображение информации
  buzzer(BUZZER_PIN);           // звуковые уведомления
  ledControl();                 // моргание нужными LED
}


void dataManager()
{
  // тут обработка каких-то данных
  // ...

  // эмуляция неисправности трех UPS через 1 мин после включения питания
  if (millis() > 5000)
  {
    msgFlag[0] = true;  // авария на 2-м UPS
    msgFlag[5] = true;  // авария на 7-м UPS
    //msgFlag[7] = true;  // авария на 8-м UPS
  }

}



void displayData()
{
  // формирование первой строки для вывода на дисплей
  static unsigned long lastFlashTime;
  lcdBuffer[0] = "1 2 3 4 5 6 7 8";          // шаблон для первой строки
  if (TIMEOUT(flashTime, lastFlashTime))     // каждые 0,25 сек формируем первую строку
  {
    static boolean flashFlag = true;
    if (flashFlag)
    {                                        // проверяем флаги на наличие ошибок
      for (byte ups = 1; ups <= MSG_COUNT; ups++)
        if (msgFlag[ups - 1]) lcdBuffer[0].replace(String(ups), "x"); // где ошибка - ставим хер
    }
    flashFlag = !flashFlag;
    lastFlashTime = millis();
    needUpdateLCD = true;
  }

  // формирование второй строки для вывода на дисплей
  static unsigned long lastUpdateTime;
  if (TIMEOUT(updateTime, lastUpdateTime))   // каждые 2 сек формируем вторую строку
  {
    lcdBuffer[1] = "                ";   // 20 пробелов (у меня 20 знаков на дисплее)
    lastUpdateTime = millis();
    //needUpdateLCD = true;                  // не нужно, т.к. первая строка все равно чаще обновляет ЖК
    byte ups = 0;
    while (!msgFlag[ups])                    // проверяем флаги на наличие ошибок
    {
      ups++;
      if (ups >= MSG_COUNT)                  // если нет ни одной ошибки, то выходим
      {
        ups = 0;
        return;
      }
    }
    // сюда попадаем, если есть хоть одна ошибка
    static byte c = 0;
    while (!msgFlag[c]) c++;                 // пропускаем сообщения, к которым ошибка не относится
    lcdBuffer[1] = message[c];               // буферизуем сообщение
    c++;                                     // чередуем все сообщения об ошибках
    if (c >= MSG_COUNT - 1) c = 0;

  }

  // обновление данных на дисплее
  if (needUpdateLCD)
  {
    lcd.setCursor(0, 0);
    lcd.print(lcdBuffer[0]);

    lcd.setCursor(0, 1);
    lcd.print(lcdBuffer[1]);

    needUpdateLCD = false;
  } // if
} // displayData



void ledControl()
{
}



void buzzer(byte pin)
{
}



void readButtons(byte pin)
{
}



void readSerial(byte rxPin)
{
}



void sendData(byte txPin)
{
}


void setup()
{
  lcd.init();                     // инициализация LCD 
  lcd.backlight();                // включаем подсветку
  pinMode ( BACKLIGHT_PIN, OUTPUT );
  digitalWrite ( BACKLIGHT_PIN, HIGH );
  lcd.begin(LCD_WIDTH, LCD_HEIGHT);
  lcd.backlight(); // finish with backlight on
  lcd.clear();
}

Підвал форуму