#1 2016-10-28 13:42:06

Rauf_AF
Учасник
Зареєстрований: 2016-10-28
Повідомлень: 14

Последовательный вывод данных на LCD

Здравствуйте.
Прошу Вас оказать помощь в нахождении ошибки в коде. Ниже приведён код цель которого выдавать соответствующие события на дисплей. Но при комбинации 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();
}

Неактивний

#2 2016-10-28 14:42:59

NoName
Customer
З Київ
Зареєстрований: 2014-07-08
Повідомлень: 1,446

Re: Последовательный вывод данных на LCD

// где ошибка - ставим х...  ))))
этот комментарий и шоколад просто настоятельно рекомендует с Вами  поработать )

1.  сложный код   у вас получился
ошибки отмечайте битами

#define BIT(x)             (1 << (x))
#define CHECKBIT(x,b)     (x&(b))
#define SETBIT(x,b)     x|=(b)
#define CLEARBIT(x,b)      x&=~(b)

для примера 
enum {
UPS_1_Inverter_Off  = 1,
UPS_1_On_Battery    = 2,
UPS_1_General_Alarm = 3,
UPS_2_Inverter_Off  = 5,
UPS_2_On_Battery    = 6,
UPS_2_General_Alarm = 7,
   
} Error_Event;


int error_status 

SETBIT( error_status, UPS_1_General_Alarm );


//  lcdBuffer[0] = "1 2 3 4 5 6 7 8";   

if ( CHECKBIT(error_status, UPS_1_General_Alarm ) )
{
lcdBuffer[1] = 'x';
}

if ( CHECKBIT(error_status, UPS_2_On_Battery ) )
{
lcdBuffer[4] = 'x';
}

если ошибок нет то error_status == 0
а так идея правильная
успеха


add вывод описания ошибки,
сканируете  в цикле

static  foo = 0

if  ( foo >= 16 ) foo = 0;

for  ( ;foo < 16; foo++ )
{
if ( CHECKBIT ( error_status, BIT ( foo) )
{
  view text  error
  при следующем  вызове функции
  needUpdateLCD = true
  будет показана следующая ошибка
}
}



я скорее всего  не привык  ++ фишкам,
типа копирования строки )
потому мне сложно читать такой  код

    while (!msgFlag[c]) c++;                 // пропускаем сообщения, к которым ошибка не относится
    lcdBuffer[1] = message[c];               // буферизуем сообщение

особенно когда нет контроля  за с  ))
это важно !  ионизирующий поток может погубить память, и тогда на дисплей будет   показа чепуха )
или вообще уйдет в ресет

Остання редакція NoName (2016-10-28 14:58:01)

Неактивний

#3 2016-10-28 15:13:02

Rauf_AF
Учасник
Зареєстрований: 2016-10-28
Повідомлень: 14

Re: Последовательный вывод данных на LCD

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

Неактивний

#4 2016-10-28 15:33:23

NoName
Customer
З Київ
Зареєстрований: 2014-07-08
Повідомлень: 1,446

Re: Последовательный вывод данных на LCD

ок, минут 10,  код выложу, но мне кажется что текст  message
не правильно описан
предположу что строка 0  - описание первой ошибки и т.д.

Неактивний

#5 2016-10-28 15:52:00

NoName
Customer
З Київ
Зареєстрований: 2014-07-08
Повідомлень: 1,446

Re: Последовательный вывод данных на LCD

если не компилируется, вечером посмотрю
и что со второй строкой ?

#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 2 Inverter Off ",
  "UPS 2 On Battery   ",
  "UPS 2 General Alarm",
  "                   ",
  "                   ",
};

#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);



#define BIT(x)             (1 << (x))
#define CHECKBIT(x,b)     (x&(b))
#define SETBIT(x,b)     x|=(b)
#define CLEARBIT(x,b)      x&=~(b)

enum {
UPS_1_Inverter_Off  = 0,
UPS_1_On_Battery    = 1,
UPS_1_General_Alarm = 2,
UPS_2_Inverter_Off  = 3,
UPS_2_On_Battery    = 4,
UPS_2_General_Alarm = 5,

end_Alarm,
} Error_Event;

 // коды ошибок 

int error_status;    // статус с ошибками  


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
  
  SETBIT( error_status, BIT( UPS_1_General_Alarm) ); 
  SETBIT( error_status, BIT( UPS_2_On_Battery) ); 
  
  }

}



void displayData()
{
  int foo; 
  static  view_error = 0

 // формирование первой строки для вывода на дисплей
  static unsigned long lastFlashTime;
  // lcdBuffer[0] = "1 2 3 4 5 6 7 8";          // шаблон для первой строки
  if (TIMEOUT(flashTime, lastFlashTime))     // каждые 0,25 сек формируем первую строку
  {
    lastFlashTime = millis();
 //    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;
 // 
  // я  не помню как работать со стрингами в ардуино, поправите если что 
   lcdBuffer [0] = ""; 
   
   // формируем строку, если нужно blink пропускаете CHECKBIT
   
  for ( foo  = 0; foo < 8 ; foo ++  ) // end_Alarm
  {
	 if ( CHECKBIT ( error_status, BIT (foo) ) 
	 {
		lcdBuffer[0] += 'x';
	 }
	 else 
	 { 
		lcdBuffer[0] += '0'+ foo + 1;
	 }
	  lcdBuffer[0] += " ";
  }

    needUpdateLCD = true;
  }

  // формирование второй строки для вывода на дисплей
  static unsigned long lastUpdateTime2;
  if (TIMEOUT(updateTime, lastUpdateTime2))   // каждые 2 сек формируем вторую строку
  {
    lastUpdateTime2 = millis();
 //   lcdBuffer[1] = "                ";   // 20 пробелов (у меня 20 знаков на дисплее)
 //   //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  ( view_error >= 8 ) view_error = 0;

// проверяем  на установленный бит 
for ( ;view_error < 8; view_error++ )
{
 if ( CHECKBIT ( error_status, BIT ( view_error) )
  {
   lcdBuffer[1] = message[view_error];   
   needUpdateLCD = true;  
  }
  }

  // обновление данных на дисплее
  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();
}

Остання редакція NoName (2016-10-28 15:54:18)

Неактивний

#6 2016-10-28 16:43:00

Rauf_AF
Учасник
Зареєстрований: 2016-10-28
Повідомлень: 14

Re: Последовательный вывод данных на LCD

Он не скомпилировался.
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
На нескольких форумах писал на данную проблему ответов пока нет.

Неактивний

#7 2016-10-28 16:55:58

Rauf_AF
Учасник
Зареєстрований: 2016-10-28
Повідомлень: 14

Re: Последовательный вывод данных на LCD

Вот новое видео первых 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();
}

Неактивний

#8 2016-10-28 19:08:04

NoName
Customer
З Київ
Зареєстрований: 2014-07-08
Повідомлень: 1,446

Re: Последовательный вывод данных на LCD

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

Неактивний

#9 2016-10-28 22:02:33

Rauf_AF
Учасник
Зареєстрований: 2016-10-28
Повідомлень: 14

Re: Последовательный вывод данных на LCD

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

Неактивний

#10 2016-10-28 22:09:57

NoName
Customer
З Київ
Зареєстрований: 2014-07-08
Повідомлень: 1,446

Re: Последовательный вывод данных на LCD

сами допишете вывод
после

if ( CHECKBIT( mem_system.event_flag, lcd2_update ));
{
}
хоть бы варнинг в консоль кинул . 

наброски ,



/*
 * ----------------------------------------------------------------------------
 * "THE BEER-WARE LICENSE" (Revision 00):
 * <devgate.info эт gmail.com> wrote this file.  As long as you retain this notice you
 * can do whatever you want with this stuff. If we meet some day, and you think
 * this stuff is worth it, you can buy me a beer or device ( arduino-ua.com ) in return.   
 * Chingiz   
 * ----------------------------------------------------------------------------
 *  Date create: 2016.10.28  
 *  Date change: 2016.10.28 
 * ----------------------------------------------------------------------------
 */
 
// ARDUINO PIN  CONFIG
// Arduino leonardo
/*
Input and Output

Each of the 20 digital i/o pins on the Leonardo can be used as an input or output, using pinMode(), digitalWrite(), and digitalRead() functions. They operate at 5 volts. Each pin can provide or receive a maximum of 40 mA and has an internal pull-up resistor (disconnected by default) of 20-50 kOhms. In addition, some pins have specialized functions:

Serial: 0 (RX) and 1 (TX). Used to receive (RX) and transmit (TX) TTL serial data using the ATmega32U4 hardware serial capability. Note that on the Leonardo, the Serial class refers to USB (CDC) communication; for TTL serial on pins 0 and 1, use the Serial1 class.
TWI: 2 (SDA) and 3 (SCL). Support TWI communication using the Wire library.
External Interrupts: 3 (interrupt 0), 2 (interrupt 1), 0 (interrupt 2), 1 (interrupt 3) and 7 (interrupt 4). These pins can be configured to trigger an interrupt on a low value, a rising or falling edge, or a change in value. See the attachInterrupt() function for details.
PWM: 3, 5, 6, 9, 10, 11, and 13. Provide 8-bit PWM output with the analogWrite() function.
SPI: on the ICSP header. These pins support SPI communication using the SPI library. Note that the SPI pins are not connected to any of the digital I/O pins as they are on the Uno, They are only available on the ICSP connector. This means that if you have a shield that uses SPI, but does NOT have a 6-pin ICSP connector that connects to the Leonardo's 6-pin ICSP header, the shield will not work.
LED: 13. There is a built-in LED connected to digital pin 13. When the pin is HIGH value, the LED is on, when the pin is LOW, it's off.
Analog Inputs: A0-A5, A6 - A11 (on digital pins 4, 6, 8, 9, 10, and 12). The Leonardo has 12 analog inputs, labeled A0 through A11, all of which can also be used as digital i/o. Pins A0-A5 appear in the same locations as on the Uno; inputs A6-A11 are on digital i/o pins 4, 6, 8, 9, 10, and 12 respectively. Each analog input provide 10 bits of resolution (i.e. 1024 different values). By default the analog inputs measure from ground to 5 volts, though is it possible to change the upper end of their range using the AREF pin and the analogReference() function.
There are a couple of other pins on the board:

AREF. Reference voltage for the analog inputs. Used with analogReference().
Reset. Bring this line LOW to reset the microcontroller. Typically used to add a reset button to shields which block the one on the board.
*/


#define DEBUG
#define DEBOUNCE_TIME 100
#define TASK_PROCESS_TIME 10

#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

/*
 DEBUG          	-    view status exe system  >>  debug uart   
 DEBUG_PWM        	-    view change PWM  >>  debug uart   
 NO_EXT_KEY       	-    no use user keybord,   for check system 
 DEBOUNCE_TIME 		100
 TASK_PROCESS_TIME 	10 -    10 ms programm scheduler  
*/

boolean needUpdateLCD =            true;                    // флаг-признак необходимости одновить данные на дисплее
String  lcdBuffer[LCD_HEIGHT];
const unsigned int updateTime =    2000;                    // интервал смены надписей в нижней строке
const unsigned int flashTime =     250;                     // интервал мигания цифр (при аварии)

typedef enum {
TIMER_EXE       = 0,
TIMER_DISABLED  = 1,
TIMER_RUN       = 2,
}TE_TIMER;


#define BIT(x)        (1 << (x))
#define CHECKBIT(x,b)   (x&(b))
#define SETBIT(x,b)     x|=(b)
#define CLEARBIT(x,b)   x&=~(b)
#define TOGGLEBIT(x,b)  x^=(b)
#define count_element_array(x)  sizeof(x)/sizeof(x[0])

char debug_str[100];



#define KEY1  0x01


#define lcd1_update  0x02
#define lcd2_update  0x04

typedef struct {
 unsigned long    time_start_key_press;
 unsigned long    time_start_key_un_press;
 uint16_t         key_status;
 uint16_t         key_interupt;
 uint16_t         event_flag;

 uint16_t         ERROR_NOW;
 uint16_t         ERROR_OLD;

 uint16_t         TIME_UPDATE_LINE1;
 uint16_t         TIME_UPDATE_LINE2;
 } td_system; 

 
 td_system  mem_system; 
 
TE_TIMER programm_count_down_uint16 ( unsigned short *timer , unsigned char shift );
TE_TIMER programm_count_down_uint32 ( unsigned long *timer , unsigned long shift );
TE_TIMER system_delay_uint32 ( unsigned long *timer , unsigned long shift );
void key_function ( void );

void setup()
{
  pinMode     (BACKLIGHT_PIN, OUTPUT);   // sets the pin as output
  pinMode     (BUTTON_PIN, INPUT);   // sets the pin as input
  Serial.begin(9600);          //  setup serial


 
  SETBIT( mem_system.event_flag, lcd1_update );
  SETBIT( mem_system.event_flag, lcd2_update );


}

TE_TIMER programm_count_down_uint16 ( unsigned short *timer , unsigned char shift )
{
    if (*timer > 0 )
    {
      if (*timer > shift )
      {
        *timer -= shift;
        return TIMER_RUN;
      }
       else
      {
         *timer = 0;
         return TIMER_EXE;
      }
    }
  return TIMER_DISABLED;
}

TE_TIMER programm_count_down_uint32 ( unsigned long *timer , unsigned long shift )
{
    if (*timer > 0 )
    {
      if (*timer > shift )
      {
        *timer -= shift;
        return TIMER_RUN;
      }
       else
      {
         *timer = 0;
         return TIMER_EXE;
      }
    }
  return TIMER_DISABLED;
}


TE_TIMER system_delay_uint32 ( unsigned long *timer , unsigned long shift )
{
    if ( *timer > 0 )
    {
      if (*timer > shift )
      {
        *timer -= shift;
        return TIMER_RUN;
      }
       else
      { // save delta time
         *timer =  ( shift - *timer );
         return TIMER_EXE;
      }
    }
  return TIMER_DISABLED;
}


void key_function ( void )
{

   TE_TIMER  status; 
   
  if ( digitalRead(BUTTON_PIN))  
  {
   status = programm_count_down_uint32 (&mem_system.time_start_key_press, TASK_PROCESS_TIME);
   mem_system.time_start_key_un_press= DEBOUNCE_TIME;
   switch ( status )
   {
    case TIMER_EXE:
    case TIMER_DISABLED:
		SETBIT ( mem_system.key_status,KEY1);
		SETBIT ( mem_system.key_interupt,KEY1);
    break;
   }
  } else {
   
   mem_system.time_start_key_press = DEBOUNCE_TIME;
   status = programm_count_down_uint32 (&mem_system.time_start_key_un_press, TASK_PROCESS_TIME);

   switch ( status )
   {
    case TIMER_EXE:
    case TIMER_DISABLED:
    CLEARBIT ( mem_system.key_status,KEY1);
    SETBIT   ( mem_system.key_interupt,KEY1);
    break;
   }
  }
}


void loop()
{
 static unsigned long  task_time; 
 // static unsigned long  key_time_start_press; 
 // static unsigned long  key_time_start_unpress;  
 TE_TIMER  status; 

 static unsigned long  hw_old_system_timer = 0; 
        unsigned long  hw_current_system_timer = 0; 

 unsigned long  delta_task_timer; 


mem_system.ERROR_NOW = BIT(0) |  BIT(6) ;
 
 hw_current_system_timer  = millis();
 delta_task_timer         = hw_current_system_timer - hw_old_system_timer;
 hw_old_system_timer      = hw_current_system_timer;
 
if ( mem_system.ERROR_NOW != mem_system.ERROR_OLD )
{
	SETBIT( mem_system.event_flag, lcd1_update );
	SETBIT( mem_system.event_flag, lcd2_update );
	mem_system.ERROR_OLD = mem_system.ERROR_NOW;
}	 

//-------------------------------------
 status = system_delay_uint32 ( &task_time, delta_task_timer );
 switch ( status )
 {
    case TIMER_EXE:
    case TIMER_DISABLED:
        task_time += TASK_PROCESS_TIME; 
      //  event_task();
	  // interval TASK_PROCESS_TIME task 
    key_function ();

	 //------------------------------------------------------------
   if ( TIMER_EXE ==  programm_count_down_uint16 (&mem_system.TIME_UPDATE_LINE1, TASK_PROCESS_TIME))
   {
    SETBIT( mem_system.event_flag, lcd1_update );   
   }

   if ( TIMER_EXE ==  programm_count_down_uint16 (&mem_system.TIME_UPDATE_LINE2, TASK_PROCESS_TIME))
   {
    SETBIT( mem_system.event_flag, lcd2_update );   
   }
   //------------------------------------------------------------
	break;

    case TIMER_RUN:
     break;   
 }
 
 
  if ( CHECKBIT( mem_system.event_flag, lcd1_update ))
  {
	 get_LCD_line1( );
   CLEARBIT( mem_system.event_flag, lcd1_update );
  }

	if ( CHECKBIT( mem_system.event_flag, lcd2_update ))
	{
		get_LCD_line2();
    mem_system.TIME_UPDATE_LINE2 = 1000;
    print_debug_info(lcdBuffer[1]);      
    CLEARBIT( mem_system.event_flag, lcd2_update );
 }
  //------------------------------------------------------------
}

//--------------------------------------------------
//  name     : print_debug_info
//  in       : String 
//  out      : none
//  provide  : print debug message
//-------------------------------------------------- 
void print_debug_info (  String data )
{
 #ifdef DEBUG 
 Serial.println(data);
 #endif
}


void get_LCD_line1(  )
{
int foo;
static bool view_error = false ;
lcdBuffer[0] = "";

if ( view_error )
{  
 for ( foo  = 0; foo < 8 ; foo ++  ) // end_Alarm
 {
   if ( CHECKBIT ( mem_system.ERROR_NOW, BIT (foo) ))
   {
    lcdBuffer[0] += 'x';
   }
   else 
   { 
    lcdBuffer[0] += (foo + 1);
   }
   lcdBuffer[0] += " ";
 }
 mem_system.TIME_UPDATE_LINE1 = 1500;
 } 
 else 
 {
	 lcdBuffer[0] = "1 2 3 4 5 6 7 8";
	 mem_system.TIME_UPDATE_LINE1 = 1200;
 }

 view_error = !view_error;
 print_debug_info(lcdBuffer[0]);			

}	
//-----------------------------------------------------
void get_LCD_line2( void )
{
int foo;
static int view_error = 0;

lcdBuffer[1] = "";

  // проверяем  на установленный бит 
  for ( ; ; view_error++ )
  {   
   
   if ( view_error >= 16 ) view_error = 0;
   
   if ( mem_system.ERROR_NOW == 0 )
   {
	   lcdBuffer[1] = " status - OK    ";
     return;
   }

   if ( CHECKBIT ( mem_system.ERROR_NOW, BIT ( view_error) ) == BIT ( view_error) )
   {
    switch ( view_error )
	  {
	  case 0: lcdBuffer[1] = " ERR0           "; break	;
	  case 1: lcdBuffer[1] = " ERR1           "; break	;
	  case 2: lcdBuffer[1] = " ERR2           "; break	;
	  case 3: lcdBuffer[1] = " ERR3           "; break	;
	  case 4: lcdBuffer[1] = " ERR4           "; break	;
    case 5: lcdBuffer[1] = " ERR5           "; break  ;
    case 6: lcdBuffer[1] = " ERR6           "; break  ;
    case 7: lcdBuffer[1] = " ERR7           "; break  ;
	  default: lcdBuffer[1] = " unknown       "; break	;
	  }
     view_error++;
     return;
   }
}
}

будет натхнення сделаю индикатор





 21:48:02.178 1 2 3 4 5 6 7 8
............ ERR0 
21:48:02.206 
21:48:03.113 ERR1 
21:48:03.315 x x x 4 5 6 7 8 
21:48:04.117 ERR2 
21:48:04.818 1 2 3 4 5 6 7 8
21:48:05.121 ERR0 
21:48:06.025 x x x 4 5 6 7 8 
21:48:06.125 ERR1 
21:48:07.128 ERR2 
21:48:07.529 1 2 3 4 5 6 7 8
21:48:08.132 ERR0 
21:48:08.734 x x x 4 5 6 7 8 
21:48:09.136 ERR1 
21:48:10.139 ERR2 
21:48:10.238 1 2 3 4 5 6 7 8
21:48:11.143 ERR0 
21:48:11.443 x x x 4 5 6 7 8 
21:48:12.146 ERR1 
21:48:12.946 1 2 3 4 5 6 7 8
21:48:13.150 ERR2 
21:48:14.167 x x x 4 5 6 7 8 
............ ERR0 
21:48:14.172 
21:48:15.158 ERR1 
21:48:15.658 1 2 3 4 5 6 7 8
21:48:16.161 ERR2 
21:48:16.863 x x x 4 5 6 7 8 
21:48:17.164 ERR0 
21:48:18.168 ERR1 
21:48:18.366 1 2 3 4 5 6 7 8
21:48:19.170 ERR2 
21:48:19.575 x x x 4 5 6 7 8 
21:48:20.174 ERR0 
21:48:21.076 1 2 3 4 5 6 7 8
21:48:21.177 ERR1 
21:48:22.181 ERR2 
21:48:22.283 x x x 4 5 6 7 8 
21:48:23.184 ERR0 
21:48:23.787 1 2 3 4 5 6 7 8
21:48:24.188 ERR1 
21:48:24.992 x x x 4 5 6 7 8 
21:48:25.192 ERR2 
21:48:26.196 ERR0 
21:48:26.496 1 2 3 4 5 6 7 8
21:48:27.199 ERR1 
21:48:27.701 x x x 4 5 6 7 8 
21:48:28.203 ERR2 
21:48:29.219 1 2 3 4 5 6 7 8
............ ERR0 
21:48:29.224 
22:07:10.775 
22:07:11.761 ERR0 
22:07:11.961 x 2 3 4 5 6 x 8 
22:07:12.764 ERR6 
22:07:13.465 1 2 3 4 5 6 7 8
22:07:13.768 ERR0 
22:07:14.670 x 2 3 4 5 6 x 8 
22:07:14.772 ERR6 
22:07:15.776 ERR0 
22:07:16.174 1 2 3 4 5 6 7 8
22:07:16.779 ERR6 
22:07:17.380 x 2 3 4 5 6 x 8 
22:07:17.782 ERR0 
22:07:18.785 ERR6 
22:07:18.885 1 2 3 4 5 6 7 8
22:07:19.788 ERR0 
22:07:20.091 x 2 3 4 5 6 x 8 
22:07:20.792 ERR6 
22:07:21.596 1 2 3 4 5 6 7 8
22:07:21.796 ERR0 
22:07:22.812 x 2 3 4 5 6 x 8 
............ ERR6 
22:07:22.818 
22:07:23.803 ERR0 
22:07:24.304 1 2 3 4 5 6 7 8
22:07:24.807 ERR6 
22:07:25.511 x 2 3 4 5 6 x 8 
22:07:25.809 ERR0 
22:07:26.813 ERR6 
22:07:27.015 1 2 3 4 5 6 7 8
22:07:27.817 ERR0 
22:07:28.220 x 2 3 4 5 6 x 8 
22:07:28.821 ERR6 
22:07:29.724 1 2 3 4 5 6 7 8
22:07:29.824 ERR0 
22:07:30.828 ERR6 
22:07:30.928 x 2 3 4 5 6 x 8 
22:07:31.831 ERR0 
22:07:32.433 1 2 3 4 5 6 7 8
22:07:32.836 ERR6 
22:07:33.637 x 2 3 4 5 6 x 8 
22:07:33.839 ERR0 
22:07:34.843 ERR6 
22:07:35.142 1 2 3 4 5 6 7 8
22:07:35.846 ERR0 
22:07:36.347 x 2 3 4 5 6 x 8 
22:07:36.851 ERR6 
22:07:37.866 1 2 3 4 5 6 7 8
............ ERR0 
22:07:37.871 
22:07:38.858 ERR6 
22:07:39.058 x 2 3 4 5 6 x 8 
22:07:39.863 ERR0 
22:07:40.562 1 2 3 4 5 6 7 8
22:07:40.866 ERR6 
22:07:41.766 x 2 3 4 5 6 x 8 
22:07:41.868 ERR0 
22:07:42.871 ERR6 
22:07:43.270 1 2 3 4 5 6 7 8
22:07:43.874 ERR0 
22:07:44.478 x 2 3 4 5 6 x 8 
22:07:44.876 ERR6 
22:07:45.882 ERR0 
22:07:45.982 1 2 3 4 5 6 7 8
22:07:46.884 ERR6 
22:07:47.186 x 2 3 4 5 6 x 8 
22:07:47.888 ERR0 
22:07:48.691 1 2 3 4 5 6 7 8
22:07:48.892 ERR6 
22:07:49.909 x 2 3 4 5 6 x 8 
............ ERR0 
22:07:49.915 
22:07:50.899 ERR6 
22:07:51.399 1 2 3 4 5 6 7 8
22:07:51.903 ERR0 
22:07:52.606 x 2 3 4 5 6 x 8 
22:07:52.906 ERR6 
22:07:53.910 ERR0 
22:07:54.109 1 2 3 4 5 6 7 8
22:07:54.914 ERR6 
22:07:55.316 x 2 3 4 5 6 x 8 
22:07:55.917 ERR0 
22:07:56.819 1 2 3 4 5 6 7 8
22:07:56.920 ERR6 
22:07:57.925 ERR0 
22:07:58.025 x 2 3 4 5 6 x 8 
22:07:58.928 ERR6 
22:07:59.530 1 2 3 4 5 6 7 8
22:07:59.931 ERR0 
22:08:00.734 x 2 3 4 5 6 x 8 
22:08:00.936 ERR6 
22:08:01.939 ERR0 
22:08:02.239 1 2 3 4 5 6 7 8
22:08:02.943 ERR6 
22:08:03.444 x 2 3 4 5 6 x 8 
22:08:03.946 ERR0 
22:08:04.964 1 2 3 4 5 6 7 8
............ ERR6 
22:08:04.968 
22:08:05.954 ERR0 
22:08:06.155 x 2 3 4 5 6 x 8 
22:08:06.959 ERR6 
22:08:07.658 1 2 3 4 5 6 7 8
22:08:07.961 ERR0 
22:08:08.863 x 2 3 4 5 6 x 8 
22:08:08.963 ERR6 
22:08:09.966 ERR0 
22:08:10.367 1 2 3 4 5 6 7 8
22:08:10.972 ERR6 
22:08:11.574 x 2 3 4 5 6 x 8 

правильно нужно делать так
* 2 3 4 5 6 x 8
ERR0

x 2 3 4 5 6 * 8
ERR6
)

смотрите код, я посмотрю либу

Остання редакція NoName (2016-10-28 22:11:07)

Неактивний

#11 2016-10-28 22:10:36

Rauf_AF
Учасник
Зареєстрований: 2016-10-28
Повідомлень: 14

Re: Последовательный вывод данных на LCD

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

Неактивний

#12 2016-10-28 22:19:51

NoName
Customer
З Київ
Зареєстрований: 2014-07-08
Повідомлень: 1,446

Re: Последовательный вывод данных на LCD

добавил индикатор без проверки,
с Пн каникулы ))

/*
 * ----------------------------------------------------------------------------
 * "THE BEER-WARE LICENSE" (Revision 00):
 * <devgate.info эт gmail.com> wrote this file.  As long as you retain this notice you
 * can do whatever you want with this stuff. If we meet some day, and you think
 * this stuff is worth it, you can buy me a beer or device ( arduino-ua.com ) in return.   
 * Chingiz   
 * ----------------------------------------------------------------------------
 *  Date create: 2016.10.28  
 *  Date change: 2016.10.28 
 * ----------------------------------------------------------------------------
 */
 
// ARDUINO PIN  CONFIG
// Arduino leonardo
/*
Input and Output

Each of the 20 digital i/o pins on the Leonardo can be used as an input or output, using pinMode(), digitalWrite(), and digitalRead() functions. They operate at 5 volts. Each pin can provide or receive a maximum of 40 mA and has an internal pull-up resistor (disconnected by default) of 20-50 kOhms. In addition, some pins have specialized functions:

Serial: 0 (RX) and 1 (TX). Used to receive (RX) and transmit (TX) TTL serial data using the ATmega32U4 hardware serial capability. Note that on the Leonardo, the Serial class refers to USB (CDC) communication; for TTL serial on pins 0 and 1, use the Serial1 class.
TWI: 2 (SDA) and 3 (SCL). Support TWI communication using the Wire library.
External Interrupts: 3 (interrupt 0), 2 (interrupt 1), 0 (interrupt 2), 1 (interrupt 3) and 7 (interrupt 4). These pins can be configured to trigger an interrupt on a low value, a rising or falling edge, or a change in value. See the attachInterrupt() function for details.
PWM: 3, 5, 6, 9, 10, 11, and 13. Provide 8-bit PWM output with the analogWrite() function.
SPI: on the ICSP header. These pins support SPI communication using the SPI library. Note that the SPI pins are not connected to any of the digital I/O pins as they are on the Uno, They are only available on the ICSP connector. This means that if you have a shield that uses SPI, but does NOT have a 6-pin ICSP connector that connects to the Leonardo's 6-pin ICSP header, the shield will not work.
LED: 13. There is a built-in LED connected to digital pin 13. When the pin is HIGH value, the LED is on, when the pin is LOW, it's off.
Analog Inputs: A0-A5, A6 - A11 (on digital pins 4, 6, 8, 9, 10, and 12). The Leonardo has 12 analog inputs, labeled A0 through A11, all of which can also be used as digital i/o. Pins A0-A5 appear in the same locations as on the Uno; inputs A6-A11 are on digital i/o pins 4, 6, 8, 9, 10, and 12 respectively. Each analog input provide 10 bits of resolution (i.e. 1024 different values). By default the analog inputs measure from ground to 5 volts, though is it possible to change the upper end of their range using the AREF pin and the analogReference() function.
There are a couple of other pins on the board:

AREF. Reference voltage for the analog inputs. Used with analogReference().
Reset. Bring this line LOW to reset the microcontroller. Typically used to add a reset button to shields which block the one on the board.
*/


#include <LiquidCrystal_I2C.h>

#include <Wire.h> 

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


#define DEBUG
#define DEBOUNCE_TIME 100
#define TASK_PROCESS_TIME 10

#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

/*
 DEBUG          	-    view status exe system  >>  debug uart   
 DEBUG_PWM        	-    view change PWM  >>  debug uart   
 NO_EXT_KEY       	-    no use user keybord,   for check system 
 DEBOUNCE_TIME 		100
 TASK_PROCESS_TIME 	10 -    10 ms programm scheduler  
*/

boolean needUpdateLCD =            true;                    // флаг-признак необходимости одновить данные на дисплее
String  lcdBuffer[LCD_HEIGHT];
const unsigned int updateTime =    2000;                    // интервал смены надписей в нижней строке
const unsigned int flashTime =     250;                     // интервал мигания цифр (при аварии)

typedef enum {
TIMER_EXE       = 0,
TIMER_DISABLED  = 1,
TIMER_RUN       = 2,
}TE_TIMER;


#define BIT(x)        (1 << (x))
#define CHECKBIT(x,b)   (x&(b))
#define SETBIT(x,b)     x|=(b)
#define CLEARBIT(x,b)   x&=~(b)
#define TOGGLEBIT(x,b)  x^=(b)
#define count_element_array(x)  sizeof(x)/sizeof(x[0])

char debug_str[100];



#define KEY1  0x01


#define lcd1_update  0x02
#define lcd2_update  0x04

typedef struct {
 unsigned long    time_start_key_press;
 unsigned long    time_start_key_un_press;
 uint16_t         key_status;
 uint16_t         key_interupt;
 uint16_t         event_flag;

 uint16_t         ERROR_NOW;
 uint16_t         ERROR_OLD;

 uint16_t         TIME_UPDATE_LINE1;
 uint16_t         TIME_UPDATE_LINE2;
 } td_system; 

 
 td_system  mem_system; 
 
TE_TIMER programm_count_down_uint16 ( unsigned short *timer , unsigned char shift );
TE_TIMER programm_count_down_uint32 ( unsigned long *timer , unsigned long shift );
TE_TIMER system_delay_uint32 ( unsigned long *timer , unsigned long shift );
void key_function ( void );

void setup()
{
  pinMode     (BACKLIGHT_PIN, OUTPUT);   // sets the pin as output
  pinMode     (BUTTON_PIN, INPUT);   // sets the pin as input
  Serial.begin(9600);          //  setup serial


  lcd.init();                     // инициализация LCD 
  lcd.backlight();                // включаем подсветку

  digitalWrite ( BACKLIGHT_PIN, HIGH ); // ???
  lcd.begin(LCD_WIDTH, LCD_HEIGHT);
  lcd.backlight(); // finish with backlight on // ???
  lcd.clear();

 
  SETBIT( mem_system.event_flag, lcd1_update );
  SETBIT( mem_system.event_flag, lcd2_update );


}

TE_TIMER programm_count_down_uint16 ( unsigned short *timer , unsigned char shift )
{
    if (*timer > 0 )
    {
      if (*timer > shift )
      {
        *timer -= shift;
        return TIMER_RUN;
      }
       else
      {
         *timer = 0;
         return TIMER_EXE;
      }
    }
  return TIMER_DISABLED;
}

TE_TIMER programm_count_down_uint32 ( unsigned long *timer , unsigned long shift )
{
    if (*timer > 0 )
    {
      if (*timer > shift )
      {
        *timer -= shift;
        return TIMER_RUN;
      }
       else
      {
         *timer = 0;
         return TIMER_EXE;
      }
    }
  return TIMER_DISABLED;
}


TE_TIMER system_delay_uint32 ( unsigned long *timer , unsigned long shift )
{
    if ( *timer > 0 )
    {
      if (*timer > shift )
      {
        *timer -= shift;
        return TIMER_RUN;
      }
       else
      { // save delta time
         *timer =  ( shift - *timer );
         return TIMER_EXE;
      }
    }
  return TIMER_DISABLED;
}


void key_function ( void )
{

   TE_TIMER  status; 
   
  if ( digitalRead(BUTTON_PIN))  
  {
   status = programm_count_down_uint32 (&mem_system.time_start_key_press, TASK_PROCESS_TIME);
   mem_system.time_start_key_un_press= DEBOUNCE_TIME;
   switch ( status )
   {
    case TIMER_EXE:
    case TIMER_DISABLED:
		SETBIT ( mem_system.key_status,KEY1);
		SETBIT ( mem_system.key_interupt,KEY1);
    break;
   }
  } else {
   
   mem_system.time_start_key_press = DEBOUNCE_TIME;
   status = programm_count_down_uint32 (&mem_system.time_start_key_un_press, TASK_PROCESS_TIME);

   switch ( status )
   {
    case TIMER_EXE:
    case TIMER_DISABLED:
    CLEARBIT ( mem_system.key_status,KEY1);
    SETBIT   ( mem_system.key_interupt,KEY1);
    break;
   }
  }
}


void loop()
{
 static unsigned long  task_time; 
 // static unsigned long  key_time_start_press; 
 // static unsigned long  key_time_start_unpress;  
 TE_TIMER  status; 

 static unsigned long  hw_old_system_timer = 0; 
        unsigned long  hw_current_system_timer = 0; 

 unsigned long  delta_task_timer; 


mem_system.ERROR_NOW = BIT(0) |  BIT(6) ;
 
 hw_current_system_timer  = millis();
 delta_task_timer         = hw_current_system_timer - hw_old_system_timer;
 hw_old_system_timer      = hw_current_system_timer;
 
if ( mem_system.ERROR_NOW != mem_system.ERROR_OLD )
{
	SETBIT( mem_system.event_flag, lcd1_update );
	SETBIT( mem_system.event_flag, lcd2_update );
	mem_system.ERROR_OLD = mem_system.ERROR_NOW;
}	 

//-------------------------------------
 status = system_delay_uint32 ( &task_time, delta_task_timer );
 switch ( status )
 {
    case TIMER_EXE:
    case TIMER_DISABLED:
        task_time += TASK_PROCESS_TIME; 
      //  event_task();
	  // interval TASK_PROCESS_TIME task 
    key_function ();

	 //------------------------------------------------------------
   if ( TIMER_EXE ==  programm_count_down_uint16 (&mem_system.TIME_UPDATE_LINE1, TASK_PROCESS_TIME))
   {
    SETBIT( mem_system.event_flag, lcd1_update );   
   }

   if ( TIMER_EXE ==  programm_count_down_uint16 (&mem_system.TIME_UPDATE_LINE2, TASK_PROCESS_TIME))
   {
    SETBIT( mem_system.event_flag, lcd2_update );   
   }
   //------------------------------------------------------------
	break;

    case TIMER_RUN:
     break;   
 }
 
 
  if ( CHECKBIT( mem_system.event_flag, lcd1_update ))
  {
	 get_LCD_line1( );
   CLEARBIT( mem_system.event_flag, lcd1_update );
  
    lcd.setCursor(0, 0);
    lcd.print(lcdBuffer[0]);
  }

	if ( CHECKBIT( mem_system.event_flag, lcd2_update ))
	{
		get_LCD_line2();
    mem_system.TIME_UPDATE_LINE2 = 1000;
    print_debug_info(lcdBuffer[1]);      
    CLEARBIT( mem_system.event_flag, lcd2_update );

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

//--------------------------------------------------
//  name     : print_debug_info
//  in       : String 
//  out      : none
//  provide  : print debug message
//-------------------------------------------------- 
void print_debug_info (  String data )
{
 #ifdef DEBUG 
 Serial.println(data);
 #endif
}


void get_LCD_line1(  )
{
int foo;
static bool view_error = false ;
lcdBuffer[0] = "";

if ( view_error )
{  
 for ( foo  = 0; foo < 8 ; foo ++  ) // end_Alarm
 {
   if ( CHECKBIT ( mem_system.ERROR_NOW, BIT (foo) ))
   {
    lcdBuffer[0] += 'x';
   }
   else 
   { 
    lcdBuffer[0] += (foo + 1);
   }
   lcdBuffer[0] += " ";
 }
 mem_system.TIME_UPDATE_LINE1 = 1500;
 } 
 else 
 {
	 lcdBuffer[0] = "1 2 3 4 5 6 7 8";
	 mem_system.TIME_UPDATE_LINE1 = 1200;
 }

 view_error = !view_error;
 print_debug_info(lcdBuffer[0]);			

}	
//-----------------------------------------------------
void get_LCD_line2( void )
{
int foo;
static int view_error = 0;

lcdBuffer[1] = "";

  // проверяем  на установленный бит 
  for ( ; ; view_error++ )
  {   
   
   if ( view_error >= 16 ) view_error = 0;
   
   if ( mem_system.ERROR_NOW == 0 )
   {
	   lcdBuffer[1] = " status - OK    ";
     return;
   }

   if ( CHECKBIT ( mem_system.ERROR_NOW, BIT ( view_error) ) == BIT ( view_error) )
   {
    switch ( view_error )
	  {
	  case 0: lcdBuffer[1] = " ERR0           "; break	;
	  case 1: lcdBuffer[1] = " ERR1           "; break	;
	  case 2: lcdBuffer[1] = " ERR2           "; break	;
	  case 3: lcdBuffer[1] = " ERR3           "; break	;
	  case 4: lcdBuffer[1] = " ERR4           "; break	;
    case 5: lcdBuffer[1] = " ERR5           "; break  ;
    case 6: lcdBuffer[1] = " ERR6           "; break  ;
    case 7: lcdBuffer[1] = " ERR7           "; break  ;
	  default: lcdBuffer[1] = " unknown       "; break	;
	  }
     view_error++;
     return;
   }
}
}

пробуйте, я еще час в онлайне

Остання редакція NoName (2016-10-28 22:21:17)

Неактивний

#13 2016-10-28 22:28:10

Rauf_AF
Учасник
Зареєстрований: 2016-10-28
Повідомлень: 14

Re: Последовательный вывод данных на LCD

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

Неактивний

#14 2016-10-28 22:29:46

Rauf_AF
Учасник
Зареєстрований: 2016-10-28
Повідомлень: 14

Re: Последовательный вывод данных на LCD

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

Неактивний

#15 2016-10-28 22:36:06

NoName
Customer
З Київ
Зареєстрований: 2014-07-08
Повідомлень: 1,446

Re: Последовательный вывод данных на LCD

// сюда попадаем, если есть хоть одна ошибка
    static byte c = 0;

    ///  тут   нелогично  while (!msgFlag[c]) c++;                 // пропускаем сообщения, к которым ошибка не относится
    lcdBuffer[1] = message[c];               // буферизуем сообщение
    c++;                                     // чередуем все сообщения об ошибках
    if (c > MSG_COUNT - 1) c = 0;



    static byte c = 0;

    ///  тут   нелогично  while (!msgFlag[c]) c++;                 // пропускаем сообщения, к которым ошибка не относится
    lcdBuffer[1] = message[c];               // буферизуем сообщение
    c++;                                     // чередуем все сообщения об ошибках
    if (c > MSG_COUNT - 1) c = 0;

замените на
for ( ; c < 8; c++ )
if ( !msgFlag[c] ) break;

Неактивний

#16 2016-10-28 22:44:33

Rauf_AF
Учасник
Зареєстрований: 2016-10-28
Повідомлень: 14

Re: Последовательный вывод данных на LCD

Правильно ли я понял?

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

Неактивний

#17 2016-10-28 22:47:16

NoName
Customer
З Київ
Зареєстрований: 2014-07-08
Повідомлень: 1,446

Re: Последовательный вывод данных на LCD

да,
или так сделайте

  switch ( с )
      {
      case 0: lcdBuffer[1] = " ERR0           "; break    ;
      case 1: lcdBuffer[1] = " ERR1           "; break    ;
      case 2: lcdBuffer[1] = " ERR2           "; break    ;
      case 3: lcdBuffer[1] = " ERR3           "; break    ;
      case 4: lcdBuffer[1] = " ERR4           "; break    ;
    case 5: lcdBuffer[1] = " ERR5           "; break  ;
    case 6: lcdBuffer[1] = " ERR6           "; break  ;
    case 7: lcdBuffer[1] = " ERR7           "; break  ;
      default: lcdBuffer[1] = " unknown       "; break    ;
      }

Неактивний

#18 2016-10-28 22:48:57

Rauf_AF
Учасник
Зареєстрований: 2016-10-28
Повідомлень: 14

Re: Последовательный вывод данных на LCD

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

Неактивний

#19 2016-10-28 22:51:15

Rauf_AF
Учасник
Зареєстрований: 2016-10-28
Повідомлень: 14

Re: Последовательный вывод данных на LCD

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

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

Неактивний

#20 2016-10-28 22:53:47

NoName
Customer
З Київ
Зареєстрований: 2014-07-08
Повідомлень: 1,446

Re: Последовательный вывод данных на LCD

такая штука,
как на картинке
1 может быть  stack overflow
2 большая скорость обмена  LCD,
3 неправильная команда LCD,
что у Вас незнаю )  я зная точно,  msgFlag[8] = 0 должно быть всегда

"
for ( ; c < 8; c++ )
if ( !msgFlag[c] ) break;
А что даёт пробел перед ; в первой строке?"
можно без пробела
for (; c < 8; c++ )

без инициализации c

Остання редакція NoName (2016-10-28 22:55:23)

Неактивний

#21 2016-10-28 22:57:07

NoName
Customer
З Київ
Зареєстрований: 2014-07-08
Повідомлень: 1,446

Re: Последовательный вывод данных на LCD

ладно я JS учить ), лодку вместо  меня  никто не сделает )
успеха )

Неактивний

#22 2016-10-28 22:59:15

Rauf_AF
Учасник
Зареєстрований: 2016-10-28
Повідомлень: 14

Re: Последовательный вывод данных на LCD

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

Неактивний

#23 2016-10-28 23:15:14

NoName
Customer
З Київ
Зареєстрований: 2014-07-08
Повідомлень: 1,446

Re: Последовательный вывод данных на LCD

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

Неактивний

#24 2016-10-29 11:38:36

Rauf_AF
Учасник
Зареєстрований: 2016-10-28
Повідомлень: 14

Re: Последовательный вывод данных на LCD

NoName пише:

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

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

Неактивний

#25 2016-10-29 12:12:36

Green
Учасник
Зареєстрований: 2015-11-08
Повідомлень: 593

Re: Последовательный вывод данных на LCD

NoName, а пачиму здесь без пробела "if (*timer > 0 )", а сдесь с: "if ( *timer > 0 )? Вы уж определитесь, а то как то не аккуратненько...

Неактивний

Швидке повідомлення

Введіть повідомлення і натисніть Надіслати

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