Wrap Up: Scrolling text not yet working
This commit is contained in:
parent
a4c9d29cfb
commit
aabbb214d0
3 changed files with 350 additions and 0 deletions
177
serial_text_scroller/display.ino
Normal file
177
serial_text_scroller/display.ino
Normal file
|
@ -0,0 +1,177 @@
|
||||||
|
/*
|
||||||
|
==============================================
|
||||||
|
Functions needed for manipulating the displays
|
||||||
|
==============================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
void initDisplay();
|
||||||
|
void updateDisplay();
|
||||||
|
char* scrolltext(const char* text, unsigned int tick, int chars);
|
||||||
|
char* scrolltext(const char* text, unsigned int tick);
|
||||||
|
|
||||||
|
#define LCD 1 // Use the LCD instead of OLED
|
||||||
|
|
||||||
|
#if LCD == 1
|
||||||
|
// Use LCD
|
||||||
|
// include the library code:
|
||||||
|
#include <LiquidCrystal.h>
|
||||||
|
|
||||||
|
const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 3, d7 = 2;
|
||||||
|
LiquidCrystal display(rs, en, d4, d5, d6, d7);
|
||||||
|
|
||||||
|
#define DISPLAY_COLS 16
|
||||||
|
#define DISPLAY_ROWS 2
|
||||||
|
|
||||||
|
#else
|
||||||
|
// OLED display
|
||||||
|
#include <SPI.h>
|
||||||
|
#include <Wire.h>
|
||||||
|
#include <Adafruit_GFX.h>
|
||||||
|
#include <Adafruit_SSD1306.h>
|
||||||
|
|
||||||
|
//Functionality
|
||||||
|
const int rs = 4;
|
||||||
|
Adafruit_SSD1306 display(rs);
|
||||||
|
|
||||||
|
#define NUMFLAKES 10
|
||||||
|
#define XPOS 0
|
||||||
|
#define YPOS 1
|
||||||
|
#define DELTAY 2
|
||||||
|
|
||||||
|
#define DISPLAY_COLS 21
|
||||||
|
#define DISPLAY_ROWS 4
|
||||||
|
|
||||||
|
|
||||||
|
#define LOGO16_GLCD_HEIGHT 16
|
||||||
|
#define LOGO16_GLCD_WIDTH 16
|
||||||
|
static const unsigned char PROGMEM logo16_glcd_bmp[] =
|
||||||
|
{ B00000000, B11000000,
|
||||||
|
B00000001, B11000000,
|
||||||
|
B00000001, B11000000,
|
||||||
|
B00000011, B11100000,
|
||||||
|
B11110011, B11100000,
|
||||||
|
B11111110, B11111000,
|
||||||
|
B01111110, B11111111,
|
||||||
|
B00110011, B10011111,
|
||||||
|
B00011111, B11111100,
|
||||||
|
B00001101, B01110000,
|
||||||
|
B00011011, B10100000,
|
||||||
|
B00111111, B11100000,
|
||||||
|
B00111111, B11110000,
|
||||||
|
B01111100, B11110000,
|
||||||
|
B01110000, B01110000,
|
||||||
|
B00000000, B00110000 };
|
||||||
|
|
||||||
|
#if (SSD1306_LCDHEIGHT != 32)
|
||||||
|
#error("Height incorrect, please fix Adafruit_SSD1306.h!");
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
void initDisplay() {
|
||||||
|
// Initialise the Display
|
||||||
|
display.begin(DISPLAY_COLS, DISPLAY_ROWS);
|
||||||
|
display.noAutoscroll();
|
||||||
|
display.clear();
|
||||||
|
}
|
||||||
|
void updateDisplay( const unsigned int tick ) {
|
||||||
|
|
||||||
|
// Update the Display
|
||||||
|
display.clear();
|
||||||
|
display.setCursor(5, 0);
|
||||||
|
display.print("|");
|
||||||
|
|
||||||
|
display.setCursor(0, 0);
|
||||||
|
display_scrolltext(line_buffer[line_buffer_read], tick , 5);
|
||||||
|
|
||||||
|
|
||||||
|
display.setCursor(0, DISPLAY_ROWS);
|
||||||
|
display.print("LPS:");
|
||||||
|
display.print( lps );
|
||||||
|
|
||||||
|
display.setCursor(10, DISPLAY_ROWS);
|
||||||
|
display.print("T:");
|
||||||
|
display.print( tick );
|
||||||
|
}
|
||||||
|
|
||||||
|
void display_scrolltext(const char* text, const unsigned int tick) {
|
||||||
|
return display_scrolltext(text, tick, DISPLAY_COLS);
|
||||||
|
}
|
||||||
|
void display_scrolltext(const char* text, const unsigned int tick, const int nchars) {
|
||||||
|
int len = strlen(text);
|
||||||
|
|
||||||
|
char new_text[nchars];
|
||||||
|
|
||||||
|
// text fits in nchars characters
|
||||||
|
if ( len <= nchars )
|
||||||
|
{
|
||||||
|
for( int i = 0; i < len; i++){
|
||||||
|
new_text[i] = text[i];
|
||||||
|
}
|
||||||
|
for (int i = len; i < nchars; i++ ) {
|
||||||
|
new_text[i] = ' ';
|
||||||
|
}
|
||||||
|
display.print(new_text);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const char separator[] = "-";
|
||||||
|
const unsigned int scroll_speed = 1;
|
||||||
|
const int sep_len = strlen(separator);
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
int offset = (scroll_speed * tick) % (len + sep_len);
|
||||||
|
|
||||||
|
// copy string from offset until the end, or until nchars have been reached
|
||||||
|
for ( i = 0; i < nchars && i < len - offset; i++ ) {
|
||||||
|
new_text[i] = text[offset+i];
|
||||||
|
}
|
||||||
|
Serial.println(i);
|
||||||
|
|
||||||
|
// pad with separator;
|
||||||
|
for (int j = 0 ; i < nchars && j < sep_len ; j++ ) {
|
||||||
|
|
||||||
|
new_text[i++] = separator[j];
|
||||||
|
}
|
||||||
|
Serial.println(i);
|
||||||
|
|
||||||
|
|
||||||
|
// copy from beginning until nchars reached
|
||||||
|
for ( ; i < nchars; i++ ) {
|
||||||
|
new_text[i] = text[i - sep_len - (len - offset) ];
|
||||||
|
}
|
||||||
|
Serial.println(i);
|
||||||
|
// Somewhere this null byte is rewritten
|
||||||
|
new_text[nchars] = '\0';
|
||||||
|
display.print(new_text);
|
||||||
|
Serial.println(new_text);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
ABCDE
|
||||||
|
-+ +-
|
||||||
|
|
||||||
|
chars = 4; // length of output
|
||||||
|
len = 6 // length of string
|
||||||
|
offset = 3 // offset of output
|
||||||
|
|
||||||
|
==> 'DE - AB'
|
||||||
|
int newlen = len + strlen(separator);
|
||||||
|
char newtext[newlen];
|
||||||
|
|
||||||
|
for ( int i = 0; i < len; i++ ) {
|
||||||
|
newtext[i] = text[i];
|
||||||
|
}
|
||||||
|
for ( int i = 0; i < strlen(separator); i++ ) {
|
||||||
|
newtext[len + i] = separator[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
// text does not fit in chars characters
|
||||||
|
// TODO: this works ugly, I want a separator in between start and end
|
||||||
|
for ( int i = 0; i < chars; i ++ ) {
|
||||||
|
display.print(newtext[(offset + i) % (newlen)]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
66
serial_text_scroller/serial.ino
Normal file
66
serial_text_scroller/serial.ino
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
/*
|
||||||
|
=======================================================
|
||||||
|
Serial Input Capability using the Serial Event Function
|
||||||
|
=======================================================
|
||||||
|
*/
|
||||||
|
#define SERIAL_INPUT_MAX_LENGTH 30
|
||||||
|
|
||||||
|
void handleInputBuffer( const char* input_buffer );
|
||||||
|
void serialEvent();
|
||||||
|
|
||||||
|
char serial_input_buffer[SERIAL_INPUT_MAX_LENGTH+1]; // holds incoming data
|
||||||
|
int serial_input_buffer_index = 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
SerialEvent occurs whenever a new data comes in the
|
||||||
|
hardware serial RX. This routine is run between each
|
||||||
|
time loop() runs, so using delay inside loop can delay
|
||||||
|
response. Multiple bytes of data may be available.
|
||||||
|
*/
|
||||||
|
void serialEvent() {
|
||||||
|
bool serial_input_buffer_complete = false;
|
||||||
|
|
||||||
|
while (Serial.available()) {
|
||||||
|
// get the new byte and add it to the buffer
|
||||||
|
serial_input_buffer[serial_input_buffer_index] = (char) Serial.read();
|
||||||
|
|
||||||
|
// if the incoming character is a newline, set a flag
|
||||||
|
// so we can
|
||||||
|
if ( serial_input_buffer[serial_input_buffer_index] == '\n'
|
||||||
|
|| serial_input_buffer[serial_input_buffer_index] == '\0'
|
||||||
|
|| serial_input_buffer_index == SERIAL_INPUT_MAX_LENGTH
|
||||||
|
) {
|
||||||
|
serial_input_buffer_complete = true;
|
||||||
|
serial_input_buffer[serial_input_buffer_index] = '\0';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Increase the index
|
||||||
|
serial_input_buffer_index++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( serial_input_buffer_complete ) {
|
||||||
|
handleInputBuffer( serial_input_buffer );
|
||||||
|
|
||||||
|
// Reset flag and buffer
|
||||||
|
serial_input_buffer_complete = false;
|
||||||
|
serial_input_buffer_index = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Handle a command, make sure this is short as serialEvent() uses this function
|
||||||
|
*/
|
||||||
|
void handleInputBuffer( const char* input_buffer ){
|
||||||
|
// Handle Incoming Line
|
||||||
|
for ( int i = 0; i < STR_MAX_LENGTH ; i++ ) {
|
||||||
|
// Stop copying when null character found.
|
||||||
|
if ( input_buffer[i] == '\0' || input_buffer[i] == '\n') {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
line_buffer[line_buffer_write][i] = input_buffer[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
line_buffer_write = ((line_buffer_write + 1 ) % LINE_BUFFER_SIZE );
|
||||||
|
}
|
107
serial_text_scroller/serial_text_scroller.ino
Normal file
107
serial_text_scroller/serial_text_scroller.ino
Normal file
|
@ -0,0 +1,107 @@
|
||||||
|
/*
|
||||||
|
Have a Serial connection send lines to be displayed on a screen / display.
|
||||||
|
If the display is too small, scroll the text along the display.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define BAUD_RATE 9600
|
||||||
|
#define STR_MAX_LENGTH 20
|
||||||
|
#define LINE_BUFFER_SIZE 4
|
||||||
|
|
||||||
|
|
||||||
|
void initDisplay();
|
||||||
|
void updateDisplay( const unsigned int tick );
|
||||||
|
void serialEvent();
|
||||||
|
|
||||||
|
|
||||||
|
char line_buffer[LINE_BUFFER_SIZE][STR_MAX_LENGTH + 1] = {// Small Ringbuffer to collect lines
|
||||||
|
"Liquid Crystal Boob",
|
||||||
|
"Captain",
|
||||||
|
"Pilot",
|
||||||
|
"Snippy"
|
||||||
|
};
|
||||||
|
int line_buffer_read = 0; // Index of Ringbuffer
|
||||||
|
int line_buffer_write = 0; // Index of Ringbuffer
|
||||||
|
|
||||||
|
const unsigned int timer_lps = 1000;
|
||||||
|
const unsigned int timer_display = 1000;
|
||||||
|
const unsigned int timer_print_line_buffers = 10000;
|
||||||
|
const unsigned int timer_switch_line_buffer = timer_print_line_buffers;
|
||||||
|
|
||||||
|
long lastMillis_lps = 0;
|
||||||
|
long lastMillis_display = 0;
|
||||||
|
long lastMillis_switch_line_buffer = 0;
|
||||||
|
long lastMillis_print_line_buffers = 0;
|
||||||
|
|
||||||
|
long loops = 0;
|
||||||
|
long lps = 0;
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
Serial.begin(BAUD_RATE);
|
||||||
|
initDisplay();
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
long currentMillis = millis();
|
||||||
|
loops++;
|
||||||
|
|
||||||
|
// Estimate Loops per Seconds
|
||||||
|
if ( currentMillis - lastMillis_lps > timer_lps ) {
|
||||||
|
lastMillis_lps = currentMillis;
|
||||||
|
|
||||||
|
lps = loops;
|
||||||
|
loops = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update Screen once per 1s
|
||||||
|
if ( currentMillis - lastMillis_display > timer_display ) {
|
||||||
|
lastMillis_display = currentMillis;
|
||||||
|
|
||||||
|
updateDisplay( (currentMillis / 1000) );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Display next line in line_buffer
|
||||||
|
if ( currentMillis - lastMillis_switch_line_buffer > timer_switch_line_buffer ) {
|
||||||
|
lastMillis_switch_line_buffer = currentMillis;
|
||||||
|
|
||||||
|
line_buffer_read = (line_buffer_read + 1 ) % LINE_BUFFER_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Print all Line Buffers once every 10 seconds
|
||||||
|
if ( currentMillis - lastMillis_print_line_buffers > timer_print_line_buffers ) {
|
||||||
|
lastMillis_print_line_buffers = currentMillis;
|
||||||
|
|
||||||
|
Serial.println(F("========================="));
|
||||||
|
Serial.println(F("Printing all Line buffers"));
|
||||||
|
Serial.println(F("========================="));
|
||||||
|
|
||||||
|
for (int i = 0; i < LINE_BUFFER_SIZE ; i++) {
|
||||||
|
if ( line_buffer_read == i )
|
||||||
|
{
|
||||||
|
Serial.print('r');
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Serial.print(' ');
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( line_buffer_write == i )
|
||||||
|
{
|
||||||
|
Serial.print('w');
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Serial.print(' ');
|
||||||
|
}
|
||||||
|
|
||||||
|
Serial.print(" Line ");
|
||||||
|
Serial.print( i );
|
||||||
|
Serial.print(": '");
|
||||||
|
Serial.print( line_buffer[i] );
|
||||||
|
Serial.print("' ");
|
||||||
|
|
||||||
|
Serial.println();
|
||||||
|
}
|
||||||
|
Serial.println(F("========================="));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in a new issue