diff --git a/LiquidCrystal_I2C/LiquidCrystal_I2C.cpp b/LiquidCrystal_I2C/LiquidCrystal_I2C.cpp new file mode 100644 index 0000000..08a41f7 --- /dev/null +++ b/LiquidCrystal_I2C/LiquidCrystal_I2C.cpp @@ -0,0 +1,315 @@ +// Based on the work by DFRobot + +#include "LiquidCrystal_I2C.h" +#include +#if defined(ARDUINO) && ARDUINO >= 100 + +#include "Arduino.h" + +#define printIIC(args) Wire.write(args) +inline size_t LiquidCrystal_I2C::write(uint8_t value) { + send(value, Rs); + return 1; +} + +#else +#include "WProgram.h" + +#define printIIC(args) Wire.send(args) +inline void LiquidCrystal_I2C::write(uint8_t value) { + send(value, Rs); +} + +#endif +#include "Wire.h" + + + +// When the display powers up, it is configured as follows: +// +// 1. Display clear +// 2. Function set: +// DL = 1; 8-bit interface data +// N = 0; 1-line display +// F = 0; 5x8 dot character font +// 3. Display on/off control: +// D = 0; Display off +// C = 0; Cursor off +// B = 0; Blinking off +// 4. Entry mode set: +// I/D = 1; Increment by 1 +// S = 0; No shift +// +// Note, however, that resetting the Arduino doesn't reset the LCD, so we +// can't assume that its in that state when a sketch starts (and the +// LiquidCrystal constructor is called). + +LiquidCrystal_I2C::LiquidCrystal_I2C(uint8_t lcd_Addr,uint8_t lcd_cols,uint8_t lcd_rows) +{ + _Addr = lcd_Addr; + _cols = lcd_cols; + _rows = lcd_rows; + _backlightval = LCD_NOBACKLIGHT; +} + +void LiquidCrystal_I2C::init(){ + init_priv(); +} + +void LiquidCrystal_I2C::init_priv() +{ + Wire.begin(); + _displayfunction = LCD_4BITMODE | LCD_1LINE | LCD_5x8DOTS; + begin(_cols, _rows); +} + +void LiquidCrystal_I2C::begin(uint8_t cols, uint8_t lines, uint8_t dotsize) { + if (lines > 1) { + _displayfunction |= LCD_2LINE; + } + _numlines = lines; + + // for some 1 line displays you can select a 10 pixel high font + if ((dotsize != 0) && (lines == 1)) { + _displayfunction |= LCD_5x10DOTS; + } + + // SEE PAGE 45/46 FOR INITIALIZATION SPECIFICATION! + // according to datasheet, we need at least 40ms after power rises above 2.7V + // before sending commands. Arduino can turn on way befer 4.5V so we'll wait 50 + delay(50); + + // Now we pull both RS and R/W low to begin commands + expanderWrite(_backlightval); // reset expanderand turn backlight off (Bit 8 =1) + delay(1000); + + //put the LCD into 4 bit mode + // this is according to the hitachi HD44780 datasheet + // figure 24, pg 46 + + // we start in 8bit mode, try to set 4 bit mode + write4bits(0x03 << 4); + delayMicroseconds(4500); // wait min 4.1ms + + // second try + write4bits(0x03 << 4); + delayMicroseconds(4500); // wait min 4.1ms + + // third go! + write4bits(0x03 << 4); + delayMicroseconds(150); + + // finally, set to 4-bit interface + write4bits(0x02 << 4); + + + // set # lines, font size, etc. + command(LCD_FUNCTIONSET | _displayfunction); + + // turn the display on with no cursor or blinking default + _displaycontrol = LCD_DISPLAYON | LCD_CURSOROFF | LCD_BLINKOFF; + display(); + + // clear it off + clear(); + + // Initialize to default text direction (for roman languages) + _displaymode = LCD_ENTRYLEFT | LCD_ENTRYSHIFTDECREMENT; + + // set the entry mode + command(LCD_ENTRYMODESET | _displaymode); + + home(); + +} + +/********** high level commands, for the user! */ +void LiquidCrystal_I2C::clear(){ + command(LCD_CLEARDISPLAY);// clear display, set cursor position to zero + delayMicroseconds(2000); // this command takes a long time! +} + +void LiquidCrystal_I2C::home(){ + command(LCD_RETURNHOME); // set cursor position to zero + delayMicroseconds(2000); // this command takes a long time! +} + +void LiquidCrystal_I2C::setCursor(uint8_t col, uint8_t row){ + int row_offsets[] = { 0x00, 0x40, 0x14, 0x54 }; + if ( row > _numlines ) { + row = _numlines-1; // we count rows starting w/0 + } + command(LCD_SETDDRAMADDR | (col + row_offsets[row])); +} + +// Turn the display on/off (quickly) +void LiquidCrystal_I2C::noDisplay() { + _displaycontrol &= ~LCD_DISPLAYON; + command(LCD_DISPLAYCONTROL | _displaycontrol); +} +void LiquidCrystal_I2C::display() { + _displaycontrol |= LCD_DISPLAYON; + command(LCD_DISPLAYCONTROL | _displaycontrol); +} + +// Turns the underline cursor on/off +void LiquidCrystal_I2C::noCursor() { + _displaycontrol &= ~LCD_CURSORON; + command(LCD_DISPLAYCONTROL | _displaycontrol); +} +void LiquidCrystal_I2C::cursor() { + _displaycontrol |= LCD_CURSORON; + command(LCD_DISPLAYCONTROL | _displaycontrol); +} + +// Turn on and off the blinking cursor +void LiquidCrystal_I2C::noBlink() { + _displaycontrol &= ~LCD_BLINKON; + command(LCD_DISPLAYCONTROL | _displaycontrol); +} +void LiquidCrystal_I2C::blink() { + _displaycontrol |= LCD_BLINKON; + command(LCD_DISPLAYCONTROL | _displaycontrol); +} + +// These commands scroll the display without changing the RAM +void LiquidCrystal_I2C::scrollDisplayLeft(void) { + command(LCD_CURSORSHIFT | LCD_DISPLAYMOVE | LCD_MOVELEFT); +} +void LiquidCrystal_I2C::scrollDisplayRight(void) { + command(LCD_CURSORSHIFT | LCD_DISPLAYMOVE | LCD_MOVERIGHT); +} + +// This is for text that flows Left to Right +void LiquidCrystal_I2C::leftToRight(void) { + _displaymode |= LCD_ENTRYLEFT; + command(LCD_ENTRYMODESET | _displaymode); +} + +// This is for text that flows Right to Left +void LiquidCrystal_I2C::rightToLeft(void) { + _displaymode &= ~LCD_ENTRYLEFT; + command(LCD_ENTRYMODESET | _displaymode); +} + +// This will 'right justify' text from the cursor +void LiquidCrystal_I2C::autoscroll(void) { + _displaymode |= LCD_ENTRYSHIFTINCREMENT; + command(LCD_ENTRYMODESET | _displaymode); +} + +// This will 'left justify' text from the cursor +void LiquidCrystal_I2C::noAutoscroll(void) { + _displaymode &= ~LCD_ENTRYSHIFTINCREMENT; + command(LCD_ENTRYMODESET | _displaymode); +} + +// Allows us to fill the first 8 CGRAM locations +// with custom characters +void LiquidCrystal_I2C::createChar(uint8_t location, uint8_t charmap[]) { + location &= 0x7; // we only have 8 locations 0-7 + command(LCD_SETCGRAMADDR | (location << 3)); + for (int i=0; i<8; i++) { + write(charmap[i]); + } +} + +// Turn the (optional) backlight off/on +void LiquidCrystal_I2C::noBacklight(void) { + _backlightval=LCD_NOBACKLIGHT; + expanderWrite(0); +} + +void LiquidCrystal_I2C::backlight(void) { + _backlightval=LCD_BACKLIGHT; + expanderWrite(0); +} + + + +/*********** mid level commands, for sending data/cmds */ + +inline void LiquidCrystal_I2C::command(uint8_t value) { + send(value, 0); +} + + +/************ low level data pushing commands **********/ + +// write either command or data +void LiquidCrystal_I2C::send(uint8_t value, uint8_t mode) { + uint8_t highnib=value&0xf0; + uint8_t lownib=(value<<4)&0xf0; + write4bits((highnib)|mode); + write4bits((lownib)|mode); +} + +void LiquidCrystal_I2C::write4bits(uint8_t value) { + expanderWrite(value); + pulseEnable(value); +} + +void LiquidCrystal_I2C::expanderWrite(uint8_t _data){ + Wire.beginTransmission(_Addr); + printIIC((int)(_data) | _backlightval); + Wire.endTransmission(); +} + +void LiquidCrystal_I2C::pulseEnable(uint8_t _data){ + expanderWrite(_data | En); // En high + delayMicroseconds(1); // enable pulse must be >450ns + + expanderWrite(_data & ~En); // En low + delayMicroseconds(50); // commands need > 37us to settle +} + + +// Alias functions + +void LiquidCrystal_I2C::cursor_on(){ + cursor(); +} + +void LiquidCrystal_I2C::cursor_off(){ + noCursor(); +} + +void LiquidCrystal_I2C::blink_on(){ + blink(); +} + +void LiquidCrystal_I2C::blink_off(){ + noBlink(); +} + +void LiquidCrystal_I2C::load_custom_character(uint8_t char_num, uint8_t *rows){ + createChar(char_num, rows); +} + +void LiquidCrystal_I2C::setBacklight(uint8_t new_val){ + if(new_val){ + backlight(); // turn backlight on + }else{ + noBacklight(); // turn backlight off + } +} + +void LiquidCrystal_I2C::printstr(const char c[]){ + //This function is not identical to the function used for "real" I2C displays + //it's here so the user sketch doesn't have to be changed + print(c); +} + + +// unsupported API functions +void LiquidCrystal_I2C::off(){} +void LiquidCrystal_I2C::on(){} +void LiquidCrystal_I2C::setDelay (int cmdDelay,int charDelay) {} +uint8_t LiquidCrystal_I2C::status(){return 0;} +uint8_t LiquidCrystal_I2C::keypad (){return 0;} +uint8_t LiquidCrystal_I2C::init_bargraph(uint8_t graphtype){return 0;} +void LiquidCrystal_I2C::draw_horizontal_graph(uint8_t row, uint8_t column, uint8_t len, uint8_t pixel_col_end){} +void LiquidCrystal_I2C::draw_vertical_graph(uint8_t row, uint8_t column, uint8_t len, uint8_t pixel_row_end){} +void LiquidCrystal_I2C::setContrast(uint8_t new_val){} + + diff --git a/LiquidCrystal_I2C/LiquidCrystal_I2C.h b/LiquidCrystal_I2C/LiquidCrystal_I2C.h new file mode 100644 index 0000000..faf19fb --- /dev/null +++ b/LiquidCrystal_I2C/LiquidCrystal_I2C.h @@ -0,0 +1,126 @@ +//YWROBOT +#ifndef LiquidCrystal_I2C_h +#define LiquidCrystal_I2C_h + +#include +#include "Print.h" +#include + +// commands +#define LCD_CLEARDISPLAY 0x01 +#define LCD_RETURNHOME 0x02 +#define LCD_ENTRYMODESET 0x04 +#define LCD_DISPLAYCONTROL 0x08 +#define LCD_CURSORSHIFT 0x10 +#define LCD_FUNCTIONSET 0x20 +#define LCD_SETCGRAMADDR 0x40 +#define LCD_SETDDRAMADDR 0x80 + +// flags for display entry mode +#define LCD_ENTRYRIGHT 0x00 +#define LCD_ENTRYLEFT 0x02 +#define LCD_ENTRYSHIFTINCREMENT 0x01 +#define LCD_ENTRYSHIFTDECREMENT 0x00 + +// flags for display on/off control +#define LCD_DISPLAYON 0x04 +#define LCD_DISPLAYOFF 0x00 +#define LCD_CURSORON 0x02 +#define LCD_CURSOROFF 0x00 +#define LCD_BLINKON 0x01 +#define LCD_BLINKOFF 0x00 + +// flags for display/cursor shift +#define LCD_DISPLAYMOVE 0x08 +#define LCD_CURSORMOVE 0x00 +#define LCD_MOVERIGHT 0x04 +#define LCD_MOVELEFT 0x00 + +// flags for function set +#define LCD_8BITMODE 0x10 +#define LCD_4BITMODE 0x00 +#define LCD_2LINE 0x08 +#define LCD_1LINE 0x00 +#define LCD_5x10DOTS 0x04 +#define LCD_5x8DOTS 0x00 + +// flags for backlight control +#define LCD_BACKLIGHT 0x08 +#define LCD_NOBACKLIGHT 0x00 + +#define En B00000100 // Enable bit +#define Rw B00000010 // Read/Write bit +#define Rs B00000001 // Register select bit + +class LiquidCrystal_I2C : public Print { +public: + LiquidCrystal_I2C(uint8_t lcd_Addr,uint8_t lcd_cols,uint8_t lcd_rows); + void begin(uint8_t cols, uint8_t rows, uint8_t charsize = LCD_5x8DOTS ); + void clear(); + void home(); + void noDisplay(); + void display(); + void noBlink(); + void blink(); + void noCursor(); + void cursor(); + void scrollDisplayLeft(); + void scrollDisplayRight(); + void printLeft(); + void printRight(); + void leftToRight(); + void rightToLeft(); + void shiftIncrement(); + void shiftDecrement(); + void noBacklight(); + void backlight(); + void autoscroll(); + void noAutoscroll(); + void createChar(uint8_t, uint8_t[]); + void setCursor(uint8_t, uint8_t); +#if defined(ARDUINO) && ARDUINO >= 100 + virtual size_t write(uint8_t); +#else + virtual void write(uint8_t); +#endif + void command(uint8_t); + void init(); + +////compatibility API function aliases +void blink_on(); // alias for blink() +void blink_off(); // alias for noBlink() +void cursor_on(); // alias for cursor() +void cursor_off(); // alias for noCursor() +void setBacklight(uint8_t new_val); // alias for backlight() and nobacklight() +void load_custom_character(uint8_t char_num, uint8_t *rows); // alias for createChar() +void printstr(const char[]); + +////Unsupported API functions (not implemented in this library) +uint8_t status(); +void setContrast(uint8_t new_val); +uint8_t keypad(); +void setDelay(int,int); +void on(); +void off(); +uint8_t init_bargraph(uint8_t graphtype); +void draw_horizontal_graph(uint8_t row, uint8_t column, uint8_t len, uint8_t pixel_col_end); +void draw_vertical_graph(uint8_t row, uint8_t column, uint8_t len, uint8_t pixel_col_end); + + +private: + void init_priv(); + void send(uint8_t, uint8_t); + void write4bits(uint8_t); + void expanderWrite(uint8_t); + void pulseEnable(uint8_t); + uint8_t _Addr; + uint8_t _displayfunction; + uint8_t _displaycontrol; + uint8_t _displaymode; + uint8_t _numlines; + uint8_t _cols; + uint8_t _rows; + uint8_t _backlightval; +}; + +#endif diff --git a/LiquidCrystal_I2C/LiquidCrystal_I2C.o b/LiquidCrystal_I2C/LiquidCrystal_I2C.o new file mode 100644 index 0000000..bca78e0 Binary files /dev/null and b/LiquidCrystal_I2C/LiquidCrystal_I2C.o differ diff --git a/LiquidCrystal_I2C/README.md b/LiquidCrystal_I2C/README.md new file mode 100644 index 0000000..aee58d3 --- /dev/null +++ b/LiquidCrystal_I2C/README.md @@ -0,0 +1,2 @@ +# LiquidCrystal_I2C +LiquidCrystal Arduino library for the DFRobot I2C LCD displays diff --git a/LiquidCrystal_I2C/examples/CustomChars/CustomChars.pde b/LiquidCrystal_I2C/examples/CustomChars/CustomChars.pde new file mode 100644 index 0000000..492612d --- /dev/null +++ b/LiquidCrystal_I2C/examples/CustomChars/CustomChars.pde @@ -0,0 +1,70 @@ +//YWROBOT +//Compatible with the Arduino IDE 1.0 +//Library version:1.1 +#include +#include + +#if defined(ARDUINO) && ARDUINO >= 100 +#define printByte(args) write(args); +#else +#define printByte(args) print(args,BYTE); +#endif + +uint8_t bell[8] = {0x4,0xe,0xe,0xe,0x1f,0x0,0x4}; +uint8_t note[8] = {0x2,0x3,0x2,0xe,0x1e,0xc,0x0}; +uint8_t clock[8] = {0x0,0xe,0x15,0x17,0x11,0xe,0x0}; +uint8_t heart[8] = {0x0,0xa,0x1f,0x1f,0xe,0x4,0x0}; +uint8_t duck[8] = {0x0,0xc,0x1d,0xf,0xf,0x6,0x0}; +uint8_t check[8] = {0x0,0x1,0x3,0x16,0x1c,0x8,0x0}; +uint8_t cross[8] = {0x0,0x1b,0xe,0x4,0xe,0x1b,0x0}; +uint8_t retarrow[8] = { 0x1,0x1,0x5,0x9,0x1f,0x8,0x4}; + +LiquidCrystal_I2C lcd(0x27,20,4); // set the LCD address to 0x27 for a 16 chars and 2 line display + +void setup() +{ + lcd.init(); // initialize the lcd + lcd.backlight(); + + lcd.createChar(0, bell); + lcd.createChar(1, note); + lcd.createChar(2, clock); + lcd.createChar(3, heart); + lcd.createChar(4, duck); + lcd.createChar(5, check); + lcd.createChar(6, cross); + lcd.createChar(7, retarrow); + lcd.home(); + + lcd.print("Hello world..."); + lcd.setCursor(0, 1); + lcd.print(" i "); + lcd.printByte(3); + lcd.print(" arduinos!"); + delay(5000); + displayKeyCodes(); + +} + +// display all keycodes +void displayKeyCodes(void) { + uint8_t i = 0; + while (1) { + lcd.clear(); + lcd.print("Codes 0x"); lcd.print(i, HEX); + lcd.print("-0x"); lcd.print(i+16, HEX); + lcd.setCursor(0, 1); + for (int j=0; j<16; j++) { + lcd.printByte(i+j); + } + i+=16; + + delay(4000); + } +} + +void loop() +{ + +} + diff --git a/LiquidCrystal_I2C/examples/HelloWorld/HelloWorld.pde b/LiquidCrystal_I2C/examples/HelloWorld/HelloWorld.pde new file mode 100644 index 0000000..6dfdee8 --- /dev/null +++ b/LiquidCrystal_I2C/examples/HelloWorld/HelloWorld.pde @@ -0,0 +1,28 @@ +//YWROBOT +//Compatible with the Arduino IDE 1.0 +//Library version:1.1 +#include +#include + +LiquidCrystal_I2C lcd(0x27,20,4); // set the LCD address to 0x27 for a 16 chars and 2 line display + +void setup() +{ + lcd.init(); // initialize the lcd + lcd.init(); + // Print a message to the LCD. + lcd.backlight(); + lcd.setCursor(3,0); + lcd.print("Hello, world!"); + lcd.setCursor(2,1); + lcd.print("Ywrobot Arduino!"); + lcd.setCursor(0,2); + lcd.print("Arduino LCM IIC 2004"); + lcd.setCursor(2,3); + lcd.print("Power By Ec-yuan!"); +} + + +void loop() +{ +} diff --git a/LiquidCrystal_I2C/examples/SerialDisplay/SerialDisplay.pde b/LiquidCrystal_I2C/examples/SerialDisplay/SerialDisplay.pde new file mode 100644 index 0000000..fdbbc64 --- /dev/null +++ b/LiquidCrystal_I2C/examples/SerialDisplay/SerialDisplay.pde @@ -0,0 +1,34 @@ +/* + * Displays text sent over the serial port (e.g. from the Serial Monitor) on + * an attached LCD. + * YWROBOT + *Compatible with the Arduino IDE 1.0 + *Library version:1.1 + */ +#include +#include + +LiquidCrystal_I2C lcd(0x27,20,4); // set the LCD address to 0x27 for a 16 chars and 2 line display + +void setup() +{ + lcd.init(); // initialize the lcd + lcd.backlight(); + Serial.begin(9600); +} + +void loop() +{ + // when characters arrive over the serial port... + if (Serial.available()) { + // wait a bit for the entire message to arrive + delay(100); + // clear the screen + lcd.clear(); + // read all the available characters + while (Serial.available() > 0) { + // display each character to the LCD + lcd.write(Serial.read()); + } + } +} diff --git a/LiquidCrystal_I2C/keywords.txt b/LiquidCrystal_I2C/keywords.txt new file mode 100644 index 0000000..8c450a9 --- /dev/null +++ b/LiquidCrystal_I2C/keywords.txt @@ -0,0 +1,46 @@ +########################################### +# Syntax Coloring Map For LiquidCrystal_I2C +########################################### + +########################################### +# Datatypes (KEYWORD1) +########################################### + +LiquidCrystal_I2C KEYWORD1 + +########################################### +# Methods and Functions (KEYWORD2) +########################################### +init KEYWORD2 +begin KEYWORD2 +clear KEYWORD2 +home KEYWORD2 +noDisplay KEYWORD2 +display KEYWORD2 +noBlink KEYWORD2 +blink KEYWORD2 +noCursor KEYWORD2 +cursor KEYWORD2 +scrollDisplayLeft KEYWORD2 +scrollDisplayRight KEYWORD2 +leftToRight KEYWORD2 +rightToLeft KEYWORD2 +shiftIncrement KEYWORD2 +shiftDecrement KEYWORD2 +noBacklight KEYWORD2 +backlight KEYWORD2 +autoscroll KEYWORD2 +noAutoscroll KEYWORD2 +createChar KEYWORD2 +setCursor KEYWORD2 +print KEYWORD2 +blink_on KEYWORD2 +blink_off KEYWORD2 +cursor_on KEYWORD2 +cursor_off KEYWORD2 +setBacklight KEYWORD2 +load_custom_character KEYWORD2 +printstr KEYWORD2 +########################################### +# Constants (LITERAL1) +########################################### diff --git a/LiquidCrystal_I2C/library.json b/LiquidCrystal_I2C/library.json new file mode 100644 index 0000000..5a23a39 --- /dev/null +++ b/LiquidCrystal_I2C/library.json @@ -0,0 +1,15 @@ +{ + "name": "LiquidCrystal_I2C", + "keywords": "LCD, liquidcrystal, I2C", + "description": "A library for DFRobot I2C LCD displays", + "repository": + { + "type": "git", + "url": "https://github.com/marcoschwartz/LiquidCrystal_I2C.git" + }, + "frameworks": "arduino", + "platforms": + [ + "atmelavr" + ] +} \ No newline at end of file diff --git a/LiquidCrystal_I2C/library.properties b/LiquidCrystal_I2C/library.properties new file mode 100644 index 0000000..e64a7f5 --- /dev/null +++ b/LiquidCrystal_I2C/library.properties @@ -0,0 +1,9 @@ +name=LiquidCrystal I2C +version=1.1.2 +author=Frank de Brabander +maintainer=Marco Schwartz +sentence=A library for I2C LCD displays. +paragraph= The library allows to control I2C displays with functions extremely similar to LiquidCrystal library. THIS LIBRARY MIGHT NOT BE COMPATIBLE WITH EXISTING SKETCHES. +category=Display +url=https://github.com/marcoschwartz/LiquidCrystal_I2C +architectures=avr diff --git a/Disp1602.cpp b/Lsd_print/Lsd_print.cpp similarity index 65% rename from Disp1602.cpp rename to Lsd_print/Lsd_print.cpp index e79b898..2a0afe3 100644 --- a/Disp1602.cpp +++ b/Lsd_print/Lsd_print.cpp @@ -1,87 +1,100 @@ -#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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "lcdpcf8574.h" +#include "pcf8574.h" +#include "i2cmaster.h" +#include "lsd.h" +#include + +struct DisplayData { + char topLine[64]; + int value1; + int value2; + int value3; +}; + +struct TextCounter { + unsigned long startTime; + int incrementValue; +}; + +TextCounter textCounter; + +void Lsd_inciliation() { + lcd_init(LCD_DISP_ON_BLINK); // инициализация дисплея + lcd_home(); // домой курсор + lcd_led(0); // вкл подсветки + textCounter.startTime = millis(); // Запоминаем время запуска программы +} + +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); +} + + +void printLsd(const char * inputText) +{ + unsigned long currentTime = millis(); // Текущее время + // Проверяем, прошло ли 500 мс с момента последнего увеличения incrementValue + if (currentTime - textCounter.startTime >= 500) { + textCounter.incrementValue++; // Увеличиваем incrementValue на 1 + textCounter.startTime = currentTime; // Обновляем время + } + + DisplayData displayData; + strncpy(displayData.topLine, inputText, 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 +} + diff --git a/Lsd_print/lsd.h b/Lsd_print/lsd.h new file mode 100644 index 0000000..2b495ce --- /dev/null +++ b/Lsd_print/lsd.h @@ -0,0 +1,8 @@ +#ifndef Lsd_print_h +#define Lsd_print_h +#include + +void Lsd_inciliation(); +void printLsd(const char* inputText); + +#endif \ No newline at end of file diff --git a/MyLCD/MyLCD.h b/MyLCD/MyLCD.h new file mode 100644 index 0000000..2a167ba --- /dev/null +++ b/MyLCD/MyLCD.h @@ -0,0 +1,22 @@ + +#ifndef MYLCD_H_ +#define MYLCD_H_ + + +// +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "lcdpcf8574.h" +#include "pcf8574.h" +#include "i2cmaster.h" + + +#endif \ No newline at end of file diff --git a/MyLCD/i2cmaster.h b/MyLCD/i2cmaster.h new file mode 100644 index 0000000..e1f01af --- /dev/null +++ b/MyLCD/i2cmaster.h @@ -0,0 +1,42 @@ +#ifndef _I2CMASTER_H +#define _I2CMASTER_H + +// , i2c +#define I2C_READ 1 + +// , i2c +#define I2C_WRITE 0 + +// +#define SCL_CLOCK 100000L + +// +void i2c_init(void); + +// +void i2c_stop(void); + +// +unsigned char i2c_start(unsigned char addr); + +// () +unsigned char i2c_rep_start(unsigned char addr); + +// , - , +void i2c_start_wait(unsigned char addr); + + // +unsigned char i2c_write(unsigned char data); + +// +unsigned char i2c_readAck(void); + +// +unsigned char i2c_readNak(void); + +// +unsigned char i2c_read(unsigned char ack); + +// +#define i2c_read(ack) (ack) ? i2c_readAck() : i2c_readNak(); +#endif diff --git a/MyLCD/keywords.txt b/MyLCD/keywords.txt new file mode 100644 index 0000000..26f60da --- /dev/null +++ b/MyLCD/keywords.txt @@ -0,0 +1,10 @@ +lcd_init KEYWORD2 +lcd_clrscr KEYWORD2 +lcd_home KEYWORD2 +lcd_gotoxy KEYWORD2 +lcd_led KEYWORD2 +lcd_putc KEYWORD2 +lcd_puts KEYWORD2 +lcd_puts_p KEYWORD2 +lcd_command KEYWORD2 +lcd_data KEYWORD2 \ No newline at end of file diff --git a/lcdpcf8574.cpp b/MyLCD/lcdpcf8574.cpp similarity index 96% rename from lcdpcf8574.cpp rename to MyLCD/lcdpcf8574.cpp index e0829c3..c5808d5 100644 --- a/lcdpcf8574.cpp +++ b/MyLCD/lcdpcf8574.cpp @@ -1,316 +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); // отправляем настройки -} +#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/MyLCD/lcdpcf8574.h similarity index 97% rename from lcdpcf8574.h rename to MyLCD/lcdpcf8574.h index b9059de..d5c35b0 100644 --- a/lcdpcf8574.h +++ b/MyLCD/lcdpcf8574.h @@ -1,110 +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<= 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; +#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/MyLCD/pcf8574.h similarity index 97% rename from pcf8574.h rename to MyLCD/pcf8574.h index 34a9439..420cc49 100644 --- a/pcf8574.h +++ b/MyLCD/pcf8574.h @@ -1,21 +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 +#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/MyLCD/twimaster.cpp b/MyLCD/twimaster.cpp new file mode 100644 index 0000000..2fad0d7 --- /dev/null +++ b/MyLCD/twimaster.cpp @@ -0,0 +1,117 @@ +#include "MyLCD.h" + +// инициализация интерфейса i2c +void i2c_init(void) +{ + // предделитель тактовой частоты равен 1 + TWSR = 0; + // рассчет скорости передачи данных + TWBR = ((F_CPU/SCL_CLOCK)-16)/2; +} + +// передача условия СТАРТ на шину +unsigned char i2c_start(unsigned char address) +{ + uint8_t twst; + + // отправка условия СТАРТ + TWCR = (1< - -#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 deleted file mode 100644 index 0d25b61..0000000 --- a/display_functions.h +++ /dev/null @@ -1,24 +0,0 @@ -#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/hdlc/main.c b/hdlc/main.c index db27ab5..e336703 100644 --- a/hdlc/main.c +++ b/hdlc/main.c @@ -1,5 +1,5 @@ //#include "hdlc.h" -#include "stdio.h" + #include "client.h" int main(){ diff --git a/i2c_functions.c b/i2c_functions.c deleted file mode 100644 index 5ccac3f..0000000 --- a/i2c_functions.c +++ /dev/null @@ -1,24 +0,0 @@ -#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 deleted file mode 100644 index 555e732..0000000 --- a/i2c_functions.h +++ /dev/null @@ -1,12 +0,0 @@ -#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/main.c b/main.c deleted file mode 100644 index 1fa31e8..0000000 --- a/main.c +++ /dev/null @@ -1,53 +0,0 @@ -#include -#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/main_sketch/main_sketch.ino b/main_sketch/main_sketch.ino new file mode 100644 index 0000000..e8eac90 --- /dev/null +++ b/main_sketch/main_sketch.ino @@ -0,0 +1,73 @@ +#include "lcd.h" +#include "client.h" +#include "uart.h" +#include "stdbool.h" +#include "stdio.h" + +struct Client hdlc; +bool flag_connection = false; + +void setup() { + Lsd_inciliation(); + UART_init(); + init_hdlc_client(&hdlc, 200); +} + +void loop() { + if (!flag_connection){ + hdlc_control_t frame; + hdlc_connect(&hdlc, &frame); + uint8_t buffer; + hdlc_get_raw_frame(&hdlc, &frame, &buffer, sizeof(buffer)); + + UART_send(&buffer, sizeof(buffer)); + + bool flag_recive = true; + while(flag_recive){ + uint8_t buffer; + UART_receive(&buffer, sizeof(buffer)); + + int err = hdlc_timeout_handler(&hdlc, 1); + if (err != 0){ + return err; + } + + int ret = hdlc_decode_recived_raw_data(&hdlc, &fake_buffer, sizeof(fake_buffer), 0, 0); + + if (ret == -6){ + uint8_t buffer; + hdlc_get_raw_frame(&hdlc, &hdlc->frame_rej, &buffer, sizeof(buffer)); + UART_send(&buffer, sizeof(buffer)); + } + + if (ret == 0 && client->state == READY_STATE){ + flag_connection = true; + } + } + } else { + bool flag_recive = true; + while(flag_recive){ + uint8_t buffer; + UART_receive(&buffer, sizeof(buffer)); + + int err = hdlc_timeout_handler(&hdlc, 1); + if (err != 0){ + return err; + } + + uint8_t recived_data; + size_t len_recived_data; + + int ret = hdlc_decode_recived_raw_data(&hdlc, &fake_buffer, sizeof(fake_buffer), &recived_data, &len_recived_data); + + if (ret == -6){ + uint8_t buffer; + hdlc_get_raw_frame(&hdlc, &hdlc->frame_rej, &buffer, sizeof(buffer)); + UART_send(&buffer, sizeof(buffer)); + } + + printLsd(recived_data); + } + } + +} \ No newline at end of file diff --git a/sketch_sep19a.ino b/sketch_sep19a.ino deleted file mode 100644 index 2816b91..0000000 --- a/sketch_sep19a.ino +++ /dev/null @@ -1,83 +0,0 @@ -#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 deleted file mode 100644 index e843baa..0000000 --- a/пример с библиотеками ардуино.txt +++ /dev/null @@ -1,55 +0,0 @@ -#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 deleted file mode 100644 index 9d293cc..0000000 --- a/типо с.txt +++ /dev/null @@ -1,93 +0,0 @@ -#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(); -} -} -}