Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #define ARDUINO_H
- #include <stdint.h>
- #include <stddef.h>
- #include <stdlib.h>
- #include "application.h"
- #include <time.h>
- #ifndef LiquidCrystal_I2C_h
- #define LiquidCrystal_I2C_h
- #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
- #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);
- virtual size_t write(uint8_t); //changed to size_t
- 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
- // LiquidCrystal_I2C V2.0
- // 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);
- }
- inline size_t LiquidCrystal_I2C::write(uint8_t value) {
- send(value, 1);
- return 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);
- Wire.write((int)(_data) | _backlightval);
- Wire.endTransmission();
- }
- void LiquidCrystal_I2C::pulseEnable(uint8_t _data){
- expanderWrite(_data | (1<<2)); // En high
- delayMicroseconds(1); // enable pulse must be >450ns
- expanderWrite(_data & ~(1<<2)); // 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){}
- LiquidCrystal_I2C *lcd;
- String line[4];
- unsigned int LineScroll[4] = {0, 0, 0, 0};
- unsigned long LastTime = 0;
- unsigned long refreshTime = 0;
- unsigned long LastScroll = 0;
- unsigned long TimeDiff = 0;
- bool busMultineLine = false;
- long timestamp = 0;
- String http_get(const char* hostname, String path);
- long currentTimeMilis();
- // ------------- HTTP functions --------------
- /**
- * make http request and return body
- */
- TCPClient client;
- char buffer[1024];
- String http_get(char const* hostname, String path) {
- if (client.connect(hostname, 80)) {
- client.print("GET ");
- client.print(path);
- client.print(" HTTP/1.0\n");
- client.print("HOST: ");
- client.println(hostname);
- client.print("\n");
- // client.print("Connection: close\n\n");
- client.flush();
- } else {
- Serial.println("connection failed");
- client.stop();
- return NULL;
- }
- // Block until first byte is read.
- client.read();
- for (unsigned int i = 0; i < sizeof(buffer) && client.available(); i++) {
- char c = client.read();
- if (c == -1) {
- break;
- }
- buffer[i] = c;
- }
- client.stop();
- String response(buffer);
- int bodyPos = response.indexOf("\r\n\r\n");
- if (bodyPos == -1) {
- Serial.println("can not find http reponse body");
- return NULL;
- }
- return response.substring(bodyPos+4);
- }
- // ------------- DATE / TIME functions --------------
- /**
- * parse a string of the form "2014-01-11T17:17:59+0200"
- */
- long parseDate(String str) {
- // make sure it works with UTC
- //tzset(); // recognize TZ
- // sy/11.Jan.2014: Not sure if setenv works at all...
- // parse date
- struct tm time;
- strptime(str.c_str(), "%Y-%m-%dT%H:%M:%S", &time);
- return (long) mktime(&time); //timegm should be used, but is not available
- }
- /**
- * can parse the timezone offset in the string "2014-01-11T17:17:59+0100"
- */
- long parseTzOffset(String str) {
- // strptime currently does not parse the timezone with %z, so we do it ourself:
- // parse 3 digits the "+0100" which result in 1 hour.
- int offsetHours;
- sscanf(str.c_str(), "%*19s%3d", &offsetHours);
- return offsetHours * 3600;
- }
- /**
- * returns current time in milisceconds, from a http server.
- */
- long currentTimeMilis() {
- Serial.println("getting current time");
- String response = http_get("www.timeapi.org", "/utc/now");
- if (response != NULL) {
- Serial.print("time=");
- Serial.println(response);
- return parseDate(response);
- } else {
- return 0;
- }
- }
- void setup()
- {
- lcd = new LiquidCrystal_I2C(0x4E, 20, 4); // set the LCD address to 0x20 for a 16x2 //SparkCore bug, address is actually 27 but shifted (0x27*2)
- Spark.function("lcd1", line_one);
- Spark.function("lcd2", line_two);
- Spark.function("lcd3", line_three);
- Spark.function("lcd4", line_four);
- RGB.control(true);
- RGB.color(20, 0, 0);
- lcd->init(); // initialize the lcd
- lcd->backlight();
- line[0] = "";
- line[1] = "";
- line[2] = "";
- line[3] = "....";
- lcd->print(".");
- LastTime = millis();
- LastScroll = millis();
- for (unsigned int linePos=0;linePos<4;linePos++) {
- lcd->setCursor(0,linePos);
- for (unsigned int charPos=0;charPos<20;charPos++) {
- if (line[linePos].length() > charPos) lcd->print(line[linePos][charPos]);
- else lcd->print(" ");
- }
- }
- }
- int line_one(String command)
- {
- //this line has the ability to wrap to the second one, so they remain static, with this, the time will be gone
- bool eraseLine2 = false;
- int line_index = 0;
- LineScroll[line_index] = 0;
- command.replace("%20", " ");
- if (busMultineLine) {
- if (command.length() > 19) {
- int splitAt;
- line[line_index] = "";
- for (splitAt=0; splitAt < 20; splitAt++) {
- if (splitAt > 13 && command[splitAt] == ' ') {
- break;
- }
- line[line_index] += command[splitAt];
- }
- line[line_index + 1] = "";
- for (unsigned int x=0; x < 20 && command.length() > (splitAt + x); x++) {
- if (!(x < 2 && (command[splitAt + x] == ' ' || command[splitAt + x] == ','))) {
- line[line_index + 1] += command[splitAt + x];
- }
- }
- } else {
- line[line_index] = command;
- line[line_index + 1] = "";
- eraseLine2 = true;
- }
- } else {
- line[line_index] = command;
- line[line_index + 1] = "";
- eraseLine2 = true;
- }
- lcd->setCursor(0, line_index);
- for (unsigned int x=0; x < 20; x++) {
- if (line[line_index].length() > x) lcd->print(line[line_index][x]);
- else lcd->print(" ");
- }
- if (eraseLine2) {
- lcd->setCursor(0, line_index + 1);
- for (unsigned int x=0; x < 20; x++) {
- if (line[line_index+1].length() > x) lcd->print(line[line_index+1][x]);
- else lcd->print(" ");
- }
- }
- return 1;
- }
- int line_two(String command)
- {
- int line_index = 1;
- LineScroll[line_index] = 0;
- command.replace("%20", " ");
- line[line_index] = command;
- lcd->setCursor(0, line_index);
- for (unsigned int x=0; x < 20; x++) {
- if (line[line_index].length() > x) {
- if (line[line_index][x] == '*') lcd->print((char)223);
- else lcd->print(line[line_index][x]);
- }
- else lcd->print(" ");
- }
- return 1;
- }
- int line_three(String command)
- {
- int line_index = 2;
- LineScroll[line_index] = 0;
- command.replace("%20", " ");
- line[line_index] = command;
- lcd->setCursor(0, line_index);
- for (unsigned int x=0; x < 20; x++) {
- if (line[line_index].length() > x) {
- if (line[line_index][x] == '*') lcd->print((char)223);
- else lcd->print(line[line_index][x]);
- }
- else lcd->print(" ");
- }
- return 1;
- }
- int line_four(String command)
- {
- int line_index = 3;
- LineScroll[line_index] = 0;
- command.replace("%20", " ");
- line[line_index] = command;
- lcd->setCursor(0, line_index);
- for (unsigned int x=0; x < 20; x++) {
- if (line[line_index].length() > x) lcd->print(line[line_index][x]);
- else lcd->print(" ");
- }
- return 1;
- }
- void loop()
- {
- if (millis() > LastScroll + 450UL) {
- for (unsigned int linePos=0;linePos<4;linePos++) {
- if (line[linePos].length() <= 20) continue;
- lcd->setCursor(0,linePos);
- for (unsigned int charPos=0;charPos<20;charPos++) {
- if (charPos + LineScroll[linePos] > line[linePos].length() + 5) lcd->print(line[linePos][charPos - (line[linePos].length() - LineScroll[linePos] + 6)]); //use 4 if want to show begining of line for 450ms longer
- else if (charPos + LineScroll[linePos] > line[linePos].length() - 1) lcd->print(" ");
- else lcd->print(line[linePos][charPos + LineScroll[linePos]]);
- }
- if (line[linePos].length() > 20) LineScroll[linePos]++;
- if (LineScroll[linePos] >= line[linePos].length() + 6) LineScroll[linePos] = 0;
- }
- LastScroll = millis();
- }
- if (millis() > LastTime) {
- timestamp = currentTimeMilis();
- TimeDiff = millis();
- timestamp -= 18000;
- struct tm * timeinfo;
- timeinfo = localtime (×tamp);
- char buffer[80];
- strftime (buffer, 20, "Time: %I:%M %p", timeinfo);
- lcd->setCursor(0, 0);
- lcd->print(buffer);
- LastTime = millis() + (1000 * 60 * 60);
- }
- if (millis() > refreshTime + 60000UL) {
- long tmpTime = timestamp;
- tmpTime += ((millis() - TimeDiff)/1000);
- struct tm * timeinfo;
- timeinfo = localtime (&tmpTime);
- char buffer[80];
- strftime (buffer, 20, "Time: %I:%M %p", timeinfo);
- lcd->setCursor(0, 0);
- lcd->print(buffer);
- refreshTime = millis();
- }
- //
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement