diff --git a/Disp1602.cpp b/Disp1602.cpp new file mode 100644 index 0000000..e79b898 --- /dev/null +++ b/Disp1602.cpp @@ -0,0 +1,87 @@ +#include + +#include + +LiquidCrystal_I2C lcd(0x27, 16, 2); + +struct DisplayData { + char topLine[64]; + int value1; + int value2; + int value3; +}; + +struct TextCounter { + unsigned long startTime; + int incrementValue; +}; + +TextCounter textCounter; + +void setup() { + lcd.begin(16, 2); + textCounter.startTime = millis(); // Запоминаем время запуска программы +} + +void loop() { + unsigned long currentTime = millis(); // Текущее время + + // Проверяем, прошло ли 500 мс с момента последнего увеличения incrementValue + if (currentTime - textCounter.startTime >= 500) { + textCounter.incrementValue++; // Увеличиваем incrementValue на 1 + textCounter.startTime = currentTime; // Обновляем время + } + + DisplayData displayData; + strncpy(displayData.topLine, "we are responsible for those who have been tame ", sizeof(displayData.topLine) - 1); + displayData.topLine[sizeof(displayData.topLine) - 1] = '\0'; + displayData.value1 = 500; + displayData.value2 = 800; + displayData.value3 = 855; + + // Буферы для заполнения данных + char buffer1[17]; + char buffer2[17]; + + // Заполнение буфера 1 + fillBuffer1(displayData.topLine, buffer1, sizeof(buffer1), textCounter.incrementValue); + + // Заполнение буфера 2 + fillBuffer2(displayData.value1, displayData.value2, displayData.value3, buffer2, sizeof(buffer2)); + + // Создание массива для вывода на дисплей + char displayArray[32]; + strncpy(displayArray, buffer1, 16); // Копирование первых 16 символов из buffer1 в displayArray + strncpy(displayArray + 16, buffer2, 16); // Копирование первых 16 символов из buffer2 в displayArray, начиная с позиции 16 + + // Вывод данных на экран + lcd.setCursor(0, 0); + lcd.print(displayArray); + + lcd.setCursor(0, 1); + lcd.print(displayArray + 16); // Вывод второй половины displayArray +} + +void fillBuffer1(const char * source, char * buffer, size_t bufferSize, int incrementValue) { + int startIndex = incrementValue % strlen(source); // Определяем начальный индекс на основе incrementValue + int endIndex = startIndex + 16; + + if (endIndex > strlen(source)) { + // Если endIndex превышает длину строки source, переносим его на начало строки + endIndex = endIndex - strlen(source); + + // Копируем символы с конца строки source + strncpy(buffer, source + startIndex, strlen(source) - startIndex); + + // Копируем оставшиеся символы с начала строки source + strncat(buffer, source, endIndex); + } else { + strncpy(buffer, source + startIndex, endIndex - startIndex); + } + + buffer[endIndex - startIndex] = '\0'; // Установка нулевого символа в конце буфера +} + +void fillBuffer2(int value1, int value2, int value3, char * buffer, size_t bufferSize) { + snprintf(buffer, bufferSize, "%d.%d.%d", value1, value2, value3); +} \ No newline at end of file diff --git a/display_functions.c b/display_functions.c new file mode 100644 index 0000000..76b8f9d --- /dev/null +++ b/display_functions.c @@ -0,0 +1,64 @@ +#include "display_functions.h" +#include + +#define LCD_ADDRESS 0x27 // Адрес дисплея на шине I2C +#define LCD_WIDTH 16 // Ширина дисплея в символах +#define LCD_HEIGHT 2 // Высота дисплея в строках + +void lcd_send_command(uint8_t command) { + Wire.beginTransmission(LCD_ADDRESS); + i2c_send_byte(0x80); // Co = 0, Rs = 0 (управляющий байт) + i2c_send_byte(command); + Wire.endTransmission(); +} + +void lcd_send_data(uint8_t data) { + Wire.beginTransmission(LCD_ADDRESS); + i2c_send_byte(0xC0); // Co = 0, Rs = 1 (байт данных) + i2c_send_byte(data); + Wire.endTransmission(); +} + +void lcd_send_string(const char *str) { + while (*str) { + lcd_send_data(*str); + str++; + } +} + +void lcd_clear() { + lcd_send_command(0x01); // Очистка дисплея + _delay_ms(2); // Небольшая пауза для завершения очистки +} + +void lcd_init() { + Wire.begin(); + lcd_send_command(0x38); // Установка интерфейса: 8 бит данных, 2 строки, 5x8 точек + lcd_send_command(0x08); // Отключение дисплея, курсора и мигания курсора + lcd_send_command(0x01); // Очистка дисплея + _delay_ms(2); // Небольшая пауза для завершения очистки + lcd_send_command(0x06); // Установка направления текста: курсор увеличивается, сдвиг дисплея + lcd_send_command(0x0C); // Включение дисплея без курсора и мигания курсора +} + +void lcd_print_char(char c) { + lcd_send_data(c); +} + +void lcd_print_string(const char *str) { + lcd_send_string(str); +} + +void lcd_update(const DisplayData *displayData, const TextCounter *textCounter) { + lcd_clear(); // Очистка дисплея перед выводом новой информации + + // Вывод данных на первую строку + lcd_send_command(0x80); // Установка курсора на начало первой строки + lcd_send_string(displayData->topLine); + + // Вывод данных на вторую строку + lcd_send_command(0xC0); // Установка курсора на начало второй строки + char buffer[17]; + snprintf(buffer, sizeof(buffer), "%d.%d.%d", displayData->value1, displayData->value2, displayData->value3); + lcd_send_string(buffer); +} diff --git a/display_functions.h b/display_functions.h new file mode 100644 index 0000000..0d25b61 --- /dev/null +++ b/display_functions.h @@ -0,0 +1,24 @@ +#ifndef DISPLAY_FUNCTIONS_H +#define DISPLAY_FUNCTIONS_H + +#include "i2c_functions.h" +#include + +struct DisplayData { + char topLine[64]; + int value1; + int value2; + int value3; +}; + +struct TextCounter { + unsigned long startTime; + int incrementValue; +}; + +void lcd_init(); +void lcd_print_char(char c); +void lcd_print_string(const char *str); +void lcd_update(const DisplayData *displayData, const TextCounter *textCounter); + +#endif diff --git a/i2c_functions.c b/i2c_functions.c new file mode 100644 index 0000000..5ccac3f --- /dev/null +++ b/i2c_functions.c @@ -0,0 +1,24 @@ +#include "i2c_functions.h" +#include + +// Здесь можно вставить код инициализации I2C, если требуется + +void i2c_delay() { + _delay_us(2); +} + +void i2c_start() { + // Реализация отправки стартового условия I2C +} + +void i2c_stop() { + // Реализация отправки стопового условия I2C +} + +void i2c_send_byte(uint8_t data) { + // Реализация отправки одного байта данных по I2C +} + +void i2c_send_bytes(const uint8_t *data, uint8_t length) { + // Реализация отправки массива данных (длиной length) по I2C +} diff --git a/i2c_functions.h b/i2c_functions.h new file mode 100644 index 0000000..555e732 --- /dev/null +++ b/i2c_functions.h @@ -0,0 +1,12 @@ +#ifndef I2C_FUNCTIONS_H +#define I2C_FUNCTIONS_H + +#include + +void i2c_delay(); +void i2c_start(); +void i2c_stop(); +void i2c_send_byte(uint8_t data); +void i2c_send_bytes(const uint8_t *data, uint8_t length); + +#endif diff --git a/lcdpcf8574.cpp b/lcdpcf8574.cpp new file mode 100644 index 0000000..e0829c3 --- /dev/null +++ b/lcdpcf8574.cpp @@ -0,0 +1,316 @@ +#include "MyLCD.h" + +// задержеки через асемблер +#define lcd_e_delay() __asm__ __volatile__( "rjmp 1f\n 1:" ); +#define lcd_e_toggle() toggle_e() + + +volatile uint8_t dataport = 0; + +static void toggle_e(void); + +// сама реализация задержек +static inline void _delayFourCycles(unsigned int __count) +{ + if ( __count == 0 ) + __asm__ __volatile__( "rjmp 1f\n 1:" ); + else + __asm__ __volatile__ ( + "1: sbiw %0,1" "\n\t" + "brne 1b" + : "=w" (__count) + : "0" (__count) + ); +} + +// тупа оборачиваем функцию в макрос +#define delay(us) _delayFourCycles( ( ( 1*(F_CPU/4000) )*us)/1000 ) + +// переключение пина для начала записи команды +static void toggle_e(void) +{ + pcf8574_setoutputpinhigh(LCD_PCF8574_DEVICEID, LCD_E_PIN); + lcd_e_delay(); + pcf8574_setoutputpinlow(LCD_PCF8574_DEVICEID, LCD_E_PIN); +} + + +// отправка байта для контроллера LCD +static void lcd_write(uint8_t data,uint8_t rs) +{ + if (rs) //отправка данных (RS=1, RW=0) + dataport |= _BV(LCD_RS_PIN); + else // отпрака инструкций(RS=0, RW=0) + dataport &= ~_BV(LCD_RS_PIN); + dataport &= ~_BV(LCD_RW_PIN); + pcf8574_setoutput(LCD_PCF8574_DEVICEID, dataport); + + // отправка старшего полубайта + dataport &= ~_BV(LCD_DATA3_PIN); + dataport &= ~_BV(LCD_DATA2_PIN); + dataport &= ~_BV(LCD_DATA1_PIN); + dataport &= ~_BV(LCD_DATA0_PIN); + if(data & 0x80) dataport |= _BV(LCD_DATA3_PIN); + if(data & 0x40) dataport |= _BV(LCD_DATA2_PIN); + if(data & 0x20) dataport |= _BV(LCD_DATA1_PIN); + if(data & 0x10) dataport |= _BV(LCD_DATA0_PIN); + pcf8574_setoutput(LCD_PCF8574_DEVICEID, dataport); + lcd_e_toggle(); + + // отправка младшего полубайта + dataport &= ~_BV(LCD_DATA3_PIN); + dataport &= ~_BV(LCD_DATA2_PIN); + dataport &= ~_BV(LCD_DATA1_PIN); + dataport &= ~_BV(LCD_DATA0_PIN); + if(data & 0x08) dataport |= _BV(LCD_DATA3_PIN); + if(data & 0x04) dataport |= _BV(LCD_DATA2_PIN); + if(data & 0x02) dataport |= _BV(LCD_DATA1_PIN); + if(data & 0x01) dataport |= _BV(LCD_DATA0_PIN); + pcf8574_setoutput(LCD_PCF8574_DEVICEID, dataport); + lcd_e_toggle(); + + // завершаем передачу + dataport |= _BV(LCD_DATA0_PIN); + dataport |= _BV(LCD_DATA1_PIN); + dataport |= _BV(LCD_DATA2_PIN); + dataport |= _BV(LCD_DATA3_PIN); + pcf8574_setoutput(LCD_PCF8574_DEVICEID, dataport); +} + +// чтение байта +static uint8_t lcd_read(uint8_t rs) +{ + uint8_t data; + + if (rs) // запись данных (RS=1, RW=0) + dataport |= _BV(LCD_RS_PIN); + else // запись инструкций (RS=0, RW=0) + dataport &= ~_BV(LCD_RS_PIN); + dataport |= _BV(LCD_RW_PIN); + pcf8574_setoutput(LCD_PCF8574_DEVICEID, dataport); + + pcf8574_setoutputpinhigh(LCD_PCF8574_DEVICEID, LCD_E_PIN); + lcd_e_delay(); + // чтение страшего полубайта + data = pcf8574_getoutputpin(LCD_PCF8574_DEVICEID, LCD_DATA0_PIN) << 4; + pcf8574_setoutputpinlow(LCD_PCF8574_DEVICEID, LCD_E_PIN); + + lcd_e_delay(); + + pcf8574_setoutputpinhigh(LCD_PCF8574_DEVICEID, LCD_E_PIN); + lcd_e_delay(); + // чтение младшего полубайта + data |= pcf8574_getoutputpin(LCD_PCF8574_DEVICEID, LCD_DATA0_PIN) &0x0F; + pcf8574_setoutputpinlow(LCD_PCF8574_DEVICEID, LCD_E_PIN); + + return data; +} + +// ждем пока ЖК освободится +static uint8_t lcd_waitbusy(void) + +{ + register uint8_t c; + + // ждем + while ( (c=lcd_read(0)) & (1<= LCD_START_LINE2) && (pos < LCD_START_LINE4) ) + addressCounter = LCD_START_LINE3; + else if ( (pos >= LCD_START_LINE3) && (pos < LCD_START_LINE2) ) + addressCounter = LCD_START_LINE4; + else + addressCounter = LCD_START_LINE1; +#endif + lcd_command((1<>4; + dataport |= _BV(LCD_DATA0_PIN); // _BV(LCD_FUNCTION_8BIT)>>4; + pcf8574_setoutput(LCD_PCF8574_DEVICEID, dataport); + + // дрючим дисплей чтобы он начал работать + lcd_e_toggle(); + delay(4992); + lcd_e_toggle(); + delay(64); + lcd_e_toggle(); + delay(64); + + // переходим в 4 битный режим + dataport &= ~_BV(LCD_DATA0_PIN); + pcf8574_setoutput(LCD_PCF8574_DEVICEID, dataport); + lcd_e_toggle(); + delay(64); + + + lcd_command(LCD_FUNCTION_DEFAULT); // настраиваем кол-во строк + lcd_command(LCD_DISP_OFF); // вырубаем дисплей + lcd_clrscr(); // чистим экран + lcd_command(LCD_MODE_DEFAULT); // запускаемся в стандартном режиме + lcd_command(dispAttr); // отправляем настройки +} diff --git a/lcdpcf8574.h b/lcdpcf8574.h new file mode 100644 index 0000000..b9059de --- /dev/null +++ b/lcdpcf8574.h @@ -0,0 +1,110 @@ +#ifndef LCD_H +#define LCD_H + +#define LCD_PCF8574_INIT 1 // pcf + +#define LCD_PCF8574_DEVICEID 0 //id - +#define LCD_FUNCTION_DEFAULT LCD_FUNCTION_4BIT_2LINES + +// : / , / +#define LCD_ENTRY_DEC 0x04 // , +#define LCD_ENTRY_DEC_SHIFT 0x05 // , +#define LCD_ENTRY_INC_ 0x06 // , . +#define LCD_ENTRY_INC_SHIFT 0x07 // , + +// / , / , +#define LCD_DISP_OFF 0x08 // +#define LCD_DISP_ON 0x0C // , +#define LCD_DISP_ON_BLINK 0x0D // , , +#define LCD_DISP_ON_CURSOR 0x0E // , +#define LCD_DISP_ON_CURSOR_BLINK 0x0F // , , + +// / +#define LCD_MOVE_CURSOR_LEFT 0x10 // +#define LCD_MOVE_CURSOR_RIGHT 0x14 // +#define LCD_MOVE_DISP_LEFT 0x18 // +#define LCD_MOVE_DISP_RIGHT 0x1C // + +// : +#define LCD_FUNCTION_4BIT_1LINE 0x20 // 4- , , 5x7 +#define LCD_FUNCTION_4BIT_2LINES 0x28 // 4- , , 5x7 +#define LCD_FUNCTION_8BIT_1LINE 0x30 // 8- , , 5x7 +#define LCD_FUNCTION_8BIT_2LINES 0x38 // 8- , , 5x7 + +#define LCD_LINES 2 // - +#define LCD_DISP_LENGTH 16 // - +#define LCD_LINE_LENGTH 0x40 // +#define LCD_START_LINE1 0x00 // DDRM 1 +#define LCD_START_LINE2 0x40 // DDRM 2 +#define LCD_WRAP_LINES 1 // + + + +#define LCD_DATA0_PIN 4 // +#define LCD_DATA1_PIN 5 // +#define LCD_DATA2_PIN 6 // +#define LCD_DATA3_PIN 7 // +#define LCD_RS_PIN 0 // RS +#define LCD_RW_PIN 1 // RW +#define LCD_E_PIN 2 // +#define LCD_LED_PIN 3 // + + +// HD44780U. +#define LCD_CLR 0 // +#define LCD_HOME 1 // +#define LCD_ENTRY_MODE 2 // +#define LCD_ENTRY_INC 1 // +#define LCD_ENTRY_SHIFT 0 // +#define LCD_ON 3 // +#define LCD_ON_DISPLAY 2 // +#define LCD_ON_CURSOR 1 // +#define LCD_ON_BLINK 0 // +#define LCD_MOVE 4 // +#define LCD_MOVE_DISP 3 // +#define LCD_MOVE_RIGHT 2 // +#define LCD_FUNCTION 5 // +#define LCD_FUNCTION_8BIT 4 // 8 +#define LCD_FUNCTION_2LINES 3 // +#define LCD_FUNCTION_10DOTS 2 // +#define LCD_CGRAM 6 // CG RAM +#define LCD_DDRAM 7 // DD RAM +#define LCD_BUSY 7 // + +// +#define LCD_MODE_DEFAULT ((1< +#include +#include "display_functions.h" + +// Основной код вашего проекта + +int main() { + // Настройка портов и другие инициализации + + lcd_init(); // Инициализация дисплея + + // Ваш код в функции setup() + + while (1) { + unsigned long currentTime = millis(); // Текущее время + // Проверяем, прошло ли 500 мс с момента последнего увеличения incrementValue + if (currentTime - textCounter.startTime >= 500) { + textCounter.incrementValue++; // Увеличиваем incrementValue на 1 + textCounter.startTime = currentTime; // Обновляем время + } + + DisplayData displayData; + strncpy(displayData.topLine, "we are responsible for those who have been tame ", sizeof(displayData.topLine) - 1); + displayData.topLine[sizeof(displayData.topLine) - 1] = '\0'; + displayData.value1 = 500; + displayData.value2 = 800; + displayData.value3 = 855; + // Буферы для заполнения данных + char buffer1[17]; + char buffer2[17]; + // Заполнение буфера 1 + fillBuffer1(displayData.topLine, buffer1, sizeof(buffer1), textCounter.incrementValue); + // Заполнение буфера 2 + fillBuffer2(displayData.value1, displayData.value2, displayData.value3, buffer2, sizeof(buffer2)); + // Создание массива для вывода на дисплей + char displayArray[32]; + strncpy(displayArray, buffer1, 16); // Копирование первых 16 символов из buffer1 в displayArray + strncpy(displayArray + 16, buffer2, 16); // Копирование первых 16 символов из buffer2 в displayArray, начиная с позиции 16 + + // Вывод данных на экран + lcd.setCursor(0, 0); + lcd.print(displayArray); + lcd.setCursor(0, 1); + lcd.print(displayArray + 16); // Вывод второй половины displayArray + + // Ваш код в функции loop() может быть здесь или в другом месте + + // Обновление данных на дисплее + lcd_update(&displayData, &textCounter); + } + + return 0; +} diff --git a/pcf8574.cpp b/pcf8574.cpp new file mode 100644 index 0000000..082ebc6 --- /dev/null +++ b/pcf8574.cpp @@ -0,0 +1,115 @@ +#include "MyLCD.h" +uint8_t pcf8574_pinstatus[PCF8574_MAXDEVICES]; + +// инициализация pcf +void pcf8574_init() { + #if PCF8574_I2CINIT == 1 + // инитим i2c + i2c_init(); + _delay_us(10); + #endif + uint8_t i = 0; + for(i=0; i= 0 && deviceid < PCF8574_MAXDEVICES)) { + data = pcf8574_pinstatus[deviceid]; + } + return data; +} + +// получаем статус пинов вывода +int8_t pcf8574_getoutputpin(uint8_t deviceid, uint8_t pin) { + int8_t data = -1; + if((deviceid >= 0 && deviceid < PCF8574_MAXDEVICES) && (pin >= 0 && pin < PCF8574_MAXPINS)) { + data = pcf8574_pinstatus[deviceid]; + data = (data >> pin) & 0b00000001; + } + return data; +} + +// настройка вывода +int8_t pcf8574_setoutput(uint8_t deviceid, uint8_t data) { + if((deviceid >= 0 && deviceid < PCF8574_MAXDEVICES)) { + pcf8574_pinstatus[deviceid] = data; + i2c_start(((PCF8574_ADDRBASE+deviceid)<<1) | I2C_WRITE); + i2c_write(data); + i2c_stop(); + return 0; + } + return -1; +} + +// установить выходные контакты, заменить фактический статус устройства из pinstart для i2c +int8_t pcf8574_setoutputpins(uint8_t deviceid, uint8_t pinstart, uint8_t pinlength, int8_t data) { + if((deviceid >= 0 && deviceid < PCF8574_MAXDEVICES) && (pinstart - pinlength + 1 >= 0 && pinstart - pinlength + 1 >= 0 && pinstart < PCF8574_MAXPINS && pinstart > 0 && pinlength > 0)) { + uint8_t b = 0; + b = pcf8574_pinstatus[deviceid]; + uint8_t mask = ((1 << pinlength) - 1) << (pinstart - pinlength + 1); + data <<= (pinstart - pinlength + 1); + data &= mask; + b &= ~(mask); + b |= data; + pcf8574_pinstatus[deviceid] = b; + //рестартим + i2c_start(((PCF8574_ADDRBASE+deviceid)<<1) | I2C_WRITE); + i2c_write(b); + i2c_stop(); + return 0; + } + return -1; +} + +// настройка пинов вывода +int8_t pcf8574_setoutputpin(uint8_t deviceid, uint8_t pin, uint8_t data) { + if((deviceid >= 0 && deviceid < PCF8574_MAXDEVICES) && (pin >= 0 && pin < PCF8574_MAXPINS)) { + uint8_t b = 0; + b = pcf8574_pinstatus[deviceid]; + b = (data != 0) ? (b | (1 << pin)) : (b & ~(1 << pin)); + pcf8574_pinstatus[deviceid] = b; + //рестартим + i2c_start(((PCF8574_ADDRBASE+deviceid)<<1) | I2C_WRITE); + i2c_write(b); + i2c_stop(); + return 0; + } + return -1; +} + +// установка высокого уровня на выходных пинах +int8_t pcf8574_setoutputpinhigh(uint8_t deviceid, uint8_t pin) { + return pcf8574_setoutputpin(deviceid, pin, 1); +} + +// установка низкого уровня на выходных пинах +int8_t pcf8574_setoutputpinlow(uint8_t deviceid, uint8_t pin) { + return pcf8574_setoutputpin(deviceid, pin, 0); +} + +// получение входных данных +int8_t pcf8574_getinput(uint8_t deviceid) { + int8_t data = -1; + if((deviceid >= 0 && deviceid < PCF8574_MAXDEVICES)) { + i2c_start(((PCF8574_ADDRBASE+deviceid)<<1) | I2C_READ); + data = ~i2c_readNak(); + i2c_stop(); + } + return data; +} + +// получение входного контакта (высокий или низкий) +int8_t pcf8574_getinputpin(uint8_t deviceid, uint8_t pin) { + int8_t data = -1; + if((deviceid >= 0 && deviceid < PCF8574_MAXDEVICES) && (pin >= 0 && pin < PCF8574_MAXPINS)) { + data = pcf8574_getinput(deviceid); + if(data != -1) { + data = (data >> pin) & 0b00000001; + } + } + return data; +} \ No newline at end of file diff --git a/pcf8574.h b/pcf8574.h new file mode 100644 index 0000000..34a9439 --- /dev/null +++ b/pcf8574.h @@ -0,0 +1,21 @@ +#ifndef PCF8574_H_ +#define PCF8574_H_ + +#define PCF8574_ADDRBASE (0x27) // - + +#define PCF8574_I2CINIT 1 // i2c + +#define PCF8574_MAXDEVICES 1 // - +#define PCF8574_MAXPINS 8 // - + +void pcf8574_init(); +int8_t pcf8574_getoutput(uint8_t deviceid); +int8_t pcf8574_getoutputpin(uint8_t deviceid, uint8_t pin); +int8_t pcf8574_setoutput(uint8_t deviceid, uint8_t data); +int8_t pcf8574_setoutputpins(uint8_t deviceid, uint8_t pinstart, uint8_t pinlength, int8_t data); +int8_t pcf8574_setoutputpin(uint8_t deviceid, uint8_t pin, uint8_t data); +int8_t pcf8574_setoutputpinhigh(uint8_t deviceid, uint8_t pin); +int8_t pcf8574_setoutputpinlow(uint8_t deviceid, uint8_t pin); +int8_t pcf8574_getinput(uint8_t deviceid); +int8_t pcf8574_getinputpin(uint8_t deviceid, uint8_t pin); +#endif diff --git a/sketch_sep19a.ino b/sketch_sep19a.ino new file mode 100644 index 0000000..2816b91 --- /dev/null +++ b/sketch_sep19a.ino @@ -0,0 +1,83 @@ +#include "MyLCD.h" + +struct DisplayData { + char topLine[64]; + int value1; + int value2; + int value3; +}; + +struct TextCounter { + unsigned long startTime; + int incrementValue; +}; + +TextCounter textCounter; + +void setup() { + lcd_init(LCD_DISP_ON_BLINK); // инициализация дисплея + lcd_home(); // домой курсор + lcd_led(0); // вкл подсветки + textCounter.startTime = millis(); // Запоминаем время запуска программы +} + +void loop() { + unsigned long currentTime = millis(); // Текущее время + // Проверяем, прошло ли 500 мс с момента последнего увеличения incrementValue + if (currentTime - textCounter.startTime >= 500) { + textCounter.incrementValue++; // Увеличиваем incrementValue на 1 + textCounter.startTime = currentTime; // Обновляем время + } + + DisplayData displayData; + strncpy(displayData.topLine, "we are responsible for those who have been tame ", sizeof(displayData.topLine) - 1); + displayData.topLine[sizeof(displayData.topLine) - 1] = '\0'; + displayData.value1 = 500; + displayData.value2 = 800; + displayData.value3 = 855; + + // Буферы для заполнения данных + char buffer1[17]; + char buffer2[17]; + + // Заполнение буфера 1 + fillBuffer1(displayData.topLine, buffer1, sizeof(buffer1), textCounter.incrementValue); + + // Заполнение буфера 2 + fillBuffer2(displayData.value1, displayData.value2, displayData.value3, buffer2, sizeof(buffer2)); + + // Создание массива для вывода на дисплей + char displayArray[32]; + strncpy(displayArray, buffer1, 16); // Копирование первых 16 символов из buffer1 в displayArray + strncpy(displayArray + 16, buffer2, 16); // Копирование первых 16 символов из buffer2 в displayArray, начиная с позиции 16 + + // Вывод данных на экран + lcd_gotoxy(0, 0); + lcd_puts(displayArray); + + lcd_gotoxy(0, 1); + lcd_puts(displayArray + 16); // Вывод второй половины displayArray +} + +void fillBuffer1(const char* source, char* buffer, size_t bufferSize, int incrementValue) { + int startIndex = incrementValue % strlen(source); // Определяем начальный индекс на основе incrementValue + int endIndex = startIndex + 16; + + if (endIndex > strlen(source)) { + // Если endIndex превышает длину строки source, переносим его на начало строки + endIndex = endIndex - strlen(source); + + // Копируем символы с конца строки source + strncpy(buffer, source + startIndex, strlen(source) - startIndex); + + // Копируем оставшиеся символы с начала строки source + strncat(buffer, source, endIndex); + } else { + strncpy(buffer, source + startIndex, endIndex - startIndex); + } + buffer[endIndex - startIndex] = '\0'; // Установка нулевого символа в конце буфера +} + +void fillBuffer2(int value1, int value2, int value3, char* buffer, size_t bufferSize) { + snprintf(buffer, bufferSize, "%d.%d.%d", value1, value2, value3); +} diff --git a/пример с библиотеками ардуино.txt b/пример с библиотеками ардуино.txt new file mode 100644 index 0000000..e843baa --- /dev/null +++ b/пример с библиотеками ардуино.txt @@ -0,0 +1,55 @@ +#include +#include + +LiquidCrystal_I2C lcd(32, 16, 2); + +byte MasArray[32] = { + 78, 69, 71, 82, 32, 77, 65, 78, 68, 65, 82, 73, 78, 33, 33, 33, + 32, 32, 32, 32, 46, 32, 32, 32, 32, 46, 32, 32, 32, 46, 37, 33 +}; + +char colum1[17]; +char colum2[17]; + +unsigned long previousTime = 0; +const unsigned long interval = 200; + +void delay_ms(unsigned long milliseconds) { + unsigned long startTime = millis(); + while (millis() - startTime < milliseconds) { + // Wait until the specified time has passed + } +} + +void setup() { + Serial.begin(9600); + lcd.init(); + lcd.backlight(); + + for (int i = 0; i < 32; i++) { + if (i < 16) { + colum1[i] = (char)MasArray[i]; + } else { + colum2[i - 16] = (char)MasArray[i]; + } + } + colum1[16] = '\0'; + colum2[16] = '\0'; +} + +void loop() { + unsigned long currentTime = millis(); + + if (currentTime - previousTime >= interval) { + previousTime = currentTime; + + for (int i = 15; i > 0; i--) { + lcd.setCursor(i, 0); + lcd.print(colum1); + lcd.setCursor(0, 1); + lcd.print(colum2); + delay_ms(200); // Use the custom delay_ms() function instead of delay() + lcd.clear(); + } + } +} diff --git a/типо с.txt b/типо с.txt new file mode 100644 index 0000000..9d293cc --- /dev/null +++ b/типо с.txt @@ -0,0 +1,93 @@ +#include + +#define LCD_ADDRESS 0x27 +#define LCD_ROWS 2 +#define LCD_COLUMNS 16 + +byte MasArray[32] = { +78, 69, 71, 82, 32, 77, 65, 78, 68, 65, 82, 73, 78, 33, 33, 33, +32, 32, 32, 32, 46, 32, 32, 32, 32, 46, 32, 32, 32, 46, 37, 33 +}; + +char colum1[17]; +char colum2[17]; + +unsigned long previousTime = 0; +const unsigned long interval = 200; + +void delay_ms(unsigned long milliseconds) { +unsigned long startTime = millis(); +while (millis() - startTime < milliseconds) { +// Wait until the specified time has passed +} +} + +void lcdCommand(uint8_t command) { +Wire.beginTransmission(LCD_ADDRESS); +Wire.write(0x00); +Wire.write(command); +Wire.endTransmission(); +} + +void lcdWrite(uint8_t value) { +Wire.beginTransmission(LCD_ADDRESS); +Wire.write(0x40); +Wire.write(value); +Wire.endTransmission(); +} + +void lcdSetCursor(uint8_t row, uint8_t col) { +uint8_t row_offsets[] = { 0x00, 0x40 }; +uint8_t offset = row_offsets[row] + col; +lcdCommand(0x80 | offset); +} + +void lcdClear() { +lcdCommand(0x01); // Clear display +delay_ms(2); // Delay for clear display command +} + +void lcdInit() { +Wire.begin(); +lcdCommand(0x38); // Function set: 8-bit mode, 2 lines, 5x8 font +lcdCommand(0x0C); // Display control: Display ON, Cursor OFF, Blinking OFF +lcdClear(); +} + +void lcdPrint(const char* str) { +while (*str) { +lcdWrite(*str++); +} +} + +void setup() { +Serial.begin(9600); +lcdInit(); + +for (int i = 0; i < 32; i++) { +if (i < 16) { +colum1[i] = (char)MasArray[i]; +} else { +colum2[i - 16] = (char)MasArray[i]; +} +} +colum1[16] = '\0'; +colum2[16] = '\0'; +} + +void loop() { +unsigned long currentTime = millis(); + +if (currentTime - previousTime >= interval) { +previousTime = currentTime; + +for (int i = 15; i > 0; i--) { +lcdSetCursor(i, 0); +lcdPrint(colum1); +lcdSetCursor(0, 1); +lcdPrint(colum2); +delay_ms(200); // Use the custom delay_ms() function instead of delay() +lcdClear(); +} +} +}