#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 enum InfoRet { IR_UNKNOWN = -1, IR_NORMAL = 0, IR_UNSUCCESS } InfoRet; typedef struct InfoState { char* info; list_node_t *pos1, *pos2, *pos3; list_t *wrap; } InfoState; void lcd_blank_line() { for (int i = 0; i < 15; ++i) { lcd.print(' '); //putchar(' '); } } int lcd_print_between(char* str, int pos1, int pos2) { //int i = 0; int va = 0; char* p = str+pos1; //int slen = strlen(str); while (p < str+pos2) { if (*p != '\n' && *p != '\r') { lcd.print(*p); //putchar(*p); ++va; } //else //if (i == 0){ ++i; } else //{ // break; //} ++p; } if (va < 15) { for (int j = 15 - va; j > 0; --j) { lcd.print(' '); //putchar(' '); } } //putchar('!'); return va; } 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(-1)) == 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((int)(curr-text))) == NULL) { return NULL; } return wrap; } void initInfoState(InfoState* st, char* text) { st->info = text; st->wrap = list_new(); st->wrap = aux_gen_wrap_list(st->wrap, st->info); st->pos1 = list_at(st->wrap, 0); st->pos2 = st->pos3 = NULL; } InfoRet initInfoScreen(InfoState* st, char* text) { initInfoState(st, text); //printf("%d\n", st->wrap->len); if (st->pos1 == NULL) { return IR_UNKNOWN; } lcd.setCursor(0, 0); if ((st->pos2 = st->pos1->next)) { //printf("hello\n"); //printf("%d\n", st->pos2->val); int tmp = lcd_print_between(st->info, 0, (int)st->pos2->val); //printf("%d\n", tmp); //printf("%d\n", st->wrap->len); if ((st->pos3 = st->pos2->next)) { //printf("\n"); lcd.setCursor(0, 1); //printf("%d\n", st->pos2->val); //printf("%d\n", st->pos3->val); int tmp = lcd_print_between(st->info, (int)st->pos2->val, (int)st->pos3->val); //printf("%d\n", tmp); //printf("%d\n", st->wrap->len); } else { //printf("\n"); lcd.setCursor(0, 1); lcd_blank_line(); } } else { return IR_UNKNOWN; } return IR_NORMAL; } InfoRet scrollDown(InfoState* st) { if (st->pos2) { st->pos1 = st->pos2; } else { return IR_UNKNOWN; } if (st->pos3) { st->pos2 = st->pos3; } else { return IR_UNSUCCESS; } lcd.setCursor(0, 0); int tmp = lcd_print_between(st->info, (int)st->pos1->val, (int)st->pos2->val); if ((st->pos3 = st->pos3->next)) { //printf("\n"); lcd.setCursor(0, 1); int tmp = lcd_print_between(st->info, (int)st->pos2->val, (int)st->pos3->val); } else { //printf("\n"); lcd.setCursor(0, 1); lcd_blank_line(); } return IR_NORMAL; } InfoRet scrollUp(InfoState* st) { if (st->pos2) { st->pos3 = st->pos2; } else { return IR_UNKNOWN; } if (st->pos1 == NULL) { return IR_UNKNOWN; } else if ((int)st->pos1->val == -1) { return IR_UNSUCCESS; } else { st->pos2 = st->pos1; } if ((st->pos1 = st->pos1->prev)) { lcd.setCursor(0, 0); if (st->pos1->val == -1) { int tmp = lcd_print_between(st->info, 0, (int)st->pos2->val); } else { int tmp = lcd_print_between(st->info, (int)st->pos1->val, (int)st->pos2->val); } } else { return IR_UNKNOWN; } //printf("\n"); lcd.setCursor(0, 1); int tmp = lcd_print_between(st->info, (int)st->pos2->val, (int)st->pos3->val); return IR_NORMAL; } void destoryInfoState(InfoState* st) { st->pos1 = st->pos2 = st->pos3 = NULL; list_destroy(st->wrap); st->info = NULL; } 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); for (int i = 0; i < 10; ++i) { delay(1000); scrollDown(&st); } for (int i = 0; i < 10; ++i) { delay(1000); scrollUp(&st); } /* #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); } /* int lcd_print_line(char* str) { int i = 0; int va = 0; 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; } */