update testline.ino
This commit is contained in:
parent
dba5c6b3a8
commit
4aa6302f63
1 changed files with 193 additions and 245 deletions
438
testline.ino
438
testline.ino
|
@ -10,17 +10,191 @@ LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
|
||||||
uint8_t up_arrow[8] = {0x04,0x0E,0x1F,0x1F,0x00,0x00,0x00,0x00};
|
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};
|
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 {
|
typedef struct InfoState {
|
||||||
char* info;
|
char* info;
|
||||||
int len;
|
list_node_t *pos1, *pos2, *pos3;
|
||||||
int fullLines;
|
|
||||||
int Nlines;
|
|
||||||
int lastlinelen;
|
|
||||||
char *pos1, *pos2, *pos3;
|
|
||||||
list_t *wrap;
|
list_t *wrap;
|
||||||
list_iterator_t *it;
|
|
||||||
} InfoState;
|
} 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() {
|
void setup() {
|
||||||
Serial.begin(9600);
|
Serial.begin(9600);
|
||||||
lcd.begin(16, 2);
|
lcd.begin(16, 2);
|
||||||
|
@ -37,9 +211,17 @@ void loop() {
|
||||||
//String info = "hello,`world!wwwwwwwwwwwwwwww";
|
//String info = "hello,`world!wwwwwwwwwwwwwwww";
|
||||||
InfoState st;
|
InfoState st;
|
||||||
initInfoScreen(&st, cinfo);
|
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
|
#ifdef DEBUG
|
||||||
Serial.println(String("len: ") + st.len);
|
//Serial.println(String("len: ") + st.len);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
|
@ -73,198 +255,14 @@ void loop() {
|
||||||
delay(1000);
|
delay(1000);
|
||||||
scrollUp(&st);
|
scrollUp(&st);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
delay(3000);
|
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 lcd_print_line(char* str) {
|
||||||
int i = 0;
|
int i = 0;
|
||||||
int va = 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);
|
int slen = strlen(str);
|
||||||
while (i < slen && va < 15) {
|
while (i < slen && va < 15) {
|
||||||
if (str[i] != '\n' && str[i] != '\r') {
|
if (str[i] != '\n' && str[i] != '\r') {
|
||||||
|
@ -287,55 +285,5 @@ int lcd_print_line(char* str) {
|
||||||
}
|
}
|
||||||
return 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(' ');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue