#include #include #include "src/list/src/list.h" LiquidCrystal lcd(12, 11, 5, 4, 3, 2); //#define REFRESH 1 #define DEBUG uint8_t up_arrow[8] = {0x04,0x0E,0x1F,0x1F,0x00,0x00,0x00,0x00}; uint8_t down_arrow[8] = {0x00,0x00,0x00,0x1F,0x1F,0x0E,0x04,0x04}; typedef struct InfoState { char* info; int len; int fullLines; int Nlines; int lastlinelen; char *pos1, *pos2, *pos3; list_t *wrap; list_iterator_t *it; } InfoState; void setup() { Serial.begin(9600); lcd.begin(16, 2); lcd.createChar(0, up_arrow); lcd.createChar(1, down_arrow); lcd.setCursor(0, 0); lcd.print("..............."); lcd.setCursor(0, 1); lcd.print("..............."); } void loop() { char* cinfo = "Far far away, a\n\nbehind the word mountains, far from the countries Vokalia and Consonantia, there live the blind texts."; //String info = "hello,`world!wwwwwwwwwwwwwwww"; InfoState st; initInfoScreen(&st, cinfo); #ifdef DEBUG Serial.println(String("len: ") + st.len); #endif #ifdef DEBUG Serial.println("down"); #endif for (int i = 0; i < 3; ++i) { delay(1000); scrollDown(&st); } #ifdef DEBUG Serial.println("up"); #endif for (int i = 0; i < 5; ++i) { delay(1000); scrollUp(&st); } #ifdef DEBUG Serial.println("down2"); #endif for (int i = 0; i < 3; ++i) { delay(1000); scrollDown(&st); } #ifdef DEBUG Serial.println("up2"); #endif for (int i = 0; i < 5; ++i) { delay(1000); scrollUp(&st); } delay(3000); } list_t* aux_gen_wrap_list(list_t* wrap, char* text) { if (wrap == NULL) { wrap = list_new(); } char* curr = text; int suf = 0; list_node_t *node; if (list_rpush(wrap, list_node_new(0)) == NULL) { return NULL; } while (*curr != '\0') { //printf("suf: %d\tpos: %d\n", suf, (unsigned int)(curr-text)); if (suf < 15) { if (*curr != '\n' && *curr != '\r') { ++suf; } else { if (list_rpush(wrap, list_node_new((unsigned int)(curr-text))) == NULL) { return NULL; } suf = 0; } } else { if (list_rpush(wrap, list_node_new((unsigned int)(curr-text))) == NULL) { return NULL; } suf = (*curr != '\n' && *curr != '\r') ? 1 : 0; } ++curr; } if (list_rpush(wrap, list_node_new(strlen(text))) == NULL) { return NULL; } return wrap; } void initInfoState(InfoState* st, char* text) { st->info = text; st->len = strlen(text); st->fullLines = st->len / 15; st->Nlines = (st->len + 14) / 15; st->lastlinelen = st->len % 15; st->pos1 = text; st->pos2 = text; st->pos3 = text; st->wrap = list_new(); st->wrap = aux_gen_wrap_list(st->wrap, st->info); st->it = list_iterator_new(st->wrap, LIST_HEAD); } void initInfoScreen(InfoState* st, char* text) { initInfoState(st, text); lcd.setCursor(0, 0); /* if (*(st->pos1) == '\n' || *(st->pos1) == '\r') { lcd_blank_line(); ++st->pos1; ++st->pos2; } else { st->pos2 += lcd_print_line(st->pos1); } lcd.setCursor(0, 1); if ((*(st->pos2) == '\n' || *(st->pos2) == '\r') && *(st->pos2 - 1) == *(st->pos2)) { lcd_blank_line(); } else { lcd_print_line(st->pos2); } #ifdef DEBUG //Serial.println(String("pos1: ") + st->pos1); //Serial.println(String("pos2: ") + st->pos2); Serial.println("init"); Serial.print(st->pos1-st->info); Serial.println(String(" ")+(st->pos2-st->info)); #endif */ } void scrollDown(InfoState* st) { st->pos1 = st->pos2; lcd.setCursor(0, 0); if ((*(st->pos1) == '\n' || *(st->pos1) == '\r') && *(st->pos1 - 1) == *(st->pos1)) { lcd_blank_line(); ++st->pos1; ++st->pos2; } else { st->pos2 += lcd_print_line(st->pos1); } lcd.setCursor(0, 1); if ((*(st->pos2) == '\n' || *(st->pos2) == '\r') && *(st->pos2 - 1) == *(st->pos2)) { lcd_blank_line(); } else { lcd_print_line(st->pos2); } #ifdef DEBUG //Serial.println(String("pos1: ") + st->pos1); //Serial.println(String("pos2: ") + st->pos2); Serial.print(st->pos1-st->info); Serial.println(String(" ")+(st->pos2-st->info)); #endif } void scrollUp(InfoState* st) { if (st->pos1 > st->info) { st->pos2 = st->pos1; int i = 1; int va = 1; /* int bound = min(st->pos1, 15); Serial.println(String("bound: ")+bound); while (i < bound) { if (st->info[st->pos1-i] != '\n' && st->info[st->pos1-i] != '\r') { ++i; } else if (i == 1){ ++i; ++bound; } else { break; } } */ /* while (i < st->pos1-st->info && va < 15) { if (st->info[st->pos1-i] != '\n' && st->info[st->pos1-i] != '\r') { ++i; ++va; } else if (i == 1){ ++i; } else { break; } } st->pos1 -= i; */ bool is_blank = false; while (st->pos1 > st->info && va <= 15) { if (*(st->pos1) != '\n' && *(st->pos1) != '\r') { ++i; ++va; } else if (*(st->pos1 - 1) == *(st->pos1)) { is_blank = true; --st->pos1; break; } --st->pos1; } while (st->pos1 > st->info && (*(st->pos1) == '\n' || *(st->pos1) == '\r')) { --st->pos1; } //st->pos1 -= i; lcd.setCursor(0, 0); if (is_blank) { lcd_blank_line(); } else { lcd_print_line(st->pos1); } lcd.setCursor(0, 1); if ((*(st->pos2) == '\n' || *(st->pos2) == '\r') && *(st->pos2 - 1) == *(st->pos2)) { lcd_blank_line(); } else { lcd_print_line(st->pos2); } } #ifdef DEBUG //Serial.println(String("pos1: ") + st->pos1); //Serial.println(String("pos2: ") + st->pos2); Serial.print(st->pos1-st->info); Serial.println(String(" ")+(st->pos2-st->info)); #endif } int lcd_print_line(char* str) { int i = 0; int va = 0; /* int bound = min(strlen(str), 15); while (i < bound) { if (str[i] != '\n' && str[i] != '\r') { lcd.print(str[i++]); } else if (i == 0){ ++i; ++bound;} else { break; } } */ int slen = strlen(str); while (i < slen && va < 15) { if (str[i] != '\n' && str[i] != '\r') { lcd.print(str[i++]); ++va; } else if (i == 0){ ++i; } else { break; } } if (va < 15) { #if !REFRESH for (int j = 15 - va; j > 0; --j) { lcd.print(' '); } #endif ++i; } return i; } /* Separate a substring that can be printed on one line, and return the original string position corresponding to the end of the substring. */ /* char* aux_sub_line(char* str, char substr[16]) { int suf = 0; char* curr = str; memset(substr, 0, 16); while (*curr != '\0' && suf < 15) { if (*curr != '\n' && *curr != '\r') { substr[suf++] = *(curr++); } else if (curr == str){ ++curr; } else { break; } } #if !REFRESH while (suf < 15) { substr[suf++] = ' '; } #endif return curr; } char* aux_sub_line_rev(char* str, char substr[16]) { int suf = 0; char* curr = str; memset(substr, 0, 16); while (*curr != '\0' && suf < 15) { if (*curr != '\n' && *curr != '\r') { substr[suf++] = *(curr--); } else if (curr == str){ --curr; } else { break; } } } */ void lcd_blank_line() { for (int i = 0; i < 15; ++i) { lcd.print(' '); } }