This sketch implements a simple serial receive terminal program for monitoring serial debug messages from another
board.
Connect GND to target board GND Connect RX line to TX line of target board Make sure the target and terminal have the same baud rate
and serial stettings!
The sketch works with the ILI9341 TFT 240x320 display and the called up libraries.
The sketch uses the hardware scrolling feature of the display. Modification of this sketch may lead to problems
unless the ILI9341 data sheet has been understood!
Written by Vittorio Margherita during February 2015
BSD license applies, all text above must be included in any redistribution
In most cases characters don't get lost at 9600 baud but it is a good idea to increase the serial Rx buffer from 64
to 512 or 1024 bytes especially if higher baud rates are used (this sketch does not need much RAM).
#include "Wire.h"
// this is needed even tho we aren't using it
#include "Adafruit_STMPE610.h"
#include "Adafruit_GFX_AS.h"
// Core graphics library
#include "Adafruit_ILI9341_AS.h"
// Hardware-specific library
#include "SPI.h"
// These are the pins used for the UNO, we must use hardware SPI
#define _sclk 13
#define _miso 12 // Not used
#define _mosi 11
#define _cs 10
#define _rst 7
#define _dc 9
#define BOXSIZE 40
//Touch definitions
#define STMPE_CS 8
#define TS_MINX 150
#define TS_MINY 130
#define TS_MAXX 3800
#define TS_MAXY 4000
// Must use hardware SPI for speed
Adafruit_ILI9341_AS tft = Adafruit_ILI9341_AS(_cs, _dc, _rst);
Adafruit_STMPE610 ts = Adafruit_STMPE610(STMPE_CS);
// The scrolling area must be a integral multiple of TEXT_HEIGHT
#define TEXT_HEIGHT 16 // Height of text to be printed and scrolled
// Number of lines in bottom fixed area (lines counted from bottom of screen)
#define BOT_FIXED_AREA 0
// Number of lines in top fixed area (lines counted from top of screen) was 16
#define TOP_FIXED_AREA 16
// The initial y coordinate of the top of the scrolling area
uint16_t yStart = TOP_FIXED_AREA + BOXSIZE;
// yArea must be a integral multiple of TEXT_HEIGHT
uint16_t yArea = 320-(TOP_FIXED_AREA + BOXSIZE) -BOT_FIXED_AREA;
// The initial y coordinate of the top of the bottom text line
uint16_t yDraw = 320 - BOT_FIXED_AREA - TEXT_HEIGHT;
// Keep track of the drawing x coordinate
uint16_t xPos = 0;
// For the byte we read from the serial port
byte data = 0;
// A few test varaibles used during debugging
boolean change_colour = 1;
boolean selected = 1;
boolean IsLogStart = 0; //Menu setting
boolean Is9600 = 1; //Menu setting
boolean Retrasmit;
//char Buffer[35][10]; //array of strings (requires more space)
//int BufferCurrent = 0;
int menu[6] = { 1, 0, 0, 1, 0, 0 };
int MovePoint = 0;
// We have to blank the top line each time the display is scrolled,
// but this takes up to 13 milliseconds
// for a full width line, meanwhile the serial buffer may be filling... and
// overflowing
// We can speed up scrolling of short text lines by just blanking the
// character we drew
int blank[18]; // We keep all the strings pixel lengths to optimise the
// speed of the top line blanking
void setup() {
// Setup the TFT display
tft.init();
ts.begin();
tft.setRotation(0);
tft.fillScreen(ILI9341_BLACK);
// Setup scroll area
setupScrollArea(TOP_FIXED_AREA + BOXSIZE, BOT_FIXED_AREA);
// Setup baud rate and draw top banner
Serial.begin(9600);
tft.setTextColor(ILI9341_WHITE, ILI9341_BLUE);
tft.fillRect(0, 0, 240, 16, ILI9341_BLUE);
tft.drawCentreString(" Margherita Datascope - 9600 baud ", 120, 0, 2);
// Change colour for scrolling zone
tft.setTextColor(ILI9341_WHITE, ILI9341_BLACK);
// Zero the array
for (byte i = 0; i < 18; i++) blank[i] = 0;
// make the Lateral selection buttons
tft.fillRect(0, TOP_FIXED_AREA, BOXSIZE, BOXSIZE, ILI9341_RED);
tft.fillRect(BOXSIZE , TOP_FIXED_AREA, BOXSIZE, BOXSIZE, ILI9341_YELLOW);
tft.fillRect(BOXSIZE * 2 , TOP_FIXED_AREA, BOXSIZE, BOXSIZE, ILI9341_GREEN);
tft.fillRect(BOXSIZE * 3 , TOP_FIXED_AREA, BOXSIZE, BOXSIZE, ILI9341_CYAN);
tft.fillRect(BOXSIZE * 4 , TOP_FIXED_AREA, BOXSIZE, BOXSIZE, ILI9341_BLUE);
tft.fillRect(BOXSIZE * 5 , TOP_FIXED_AREA, BOXSIZE, BOXSIZE, ILI9341_MAGENTA);
SetMenu();
DrawMenu();
}
void SetMenu(){
//Set the Empty menu
tft.setTextColor(ILI9341_WHITE, ILI9341_RED);
tft.drawCentreString("9600", (BOXSIZE / 2), (TOP_FIXED_AREA / 2) + (BOXSIZE / 2), 2);
tft.setTextColor(ILI9341_WHITE, ILI9341_YELLOW);
tft.drawCentreString("14400", (BOXSIZE * 2) - (BOXSIZE / 2), (TOP_FIXED_AREA / 2) + (BOXSIZE / 2), 2);
tft.setTextColor(ILI9341_WHITE, ILI9341_GREEN);
tft.drawCentreString("Start", (BOXSIZE * 3) - (BOXSIZE / 2), (TOP_FIXED_AREA / 2) + (BOXSIZE / 2), 2);
tft.setTextColor(ILI9341_WHITE, ILI9341_CYAN);
tft.drawCentreString("Stop", (BOXSIZE * 4) - (BOXSIZE / 2), (TOP_FIXED_AREA / 2) + (BOXSIZE / 2), 2);
tft.setTextColor(ILI9341_WHITE, ILI9341_BLUE);
tft.drawCentreString("Forw", (BOXSIZE * 5) - (BOXSIZE / 2), (TOP_FIXED_AREA / 2) + (BOXSIZE / 2), 2);
tft.setTextColor(ILI9341_WHITE, ILI9341_MAGENTA);
tft.drawCentreString("Stay", (BOXSIZE * 6) - (BOXSIZE / 2), (TOP_FIXED_AREA / 2) + (BOXSIZE / 2), 2);
}
void Raise9600() {
tft.setTextColor(ILI9341_WHITE, ILI9341_BLACK);
tft.drawCentreString("9600", (BOXSIZE / 2), (TOP_FIXED_AREA / 2) + (BOXSIZE / 2), 2);
//Set the main header
tft.setTextColor(ILI9341_WHITE, ILI9341_BLUE);
tft.fillRect(0, 0, 240, 16, ILI9341_BLUE);
tft.drawCentreString(" Margherita Datascope - 9600 baud ", 120, 0, 2);
}
void Raise14400() {
tft.setTextColor(ILI9341_WHITE, ILI9341_BLACK);
tft.drawCentreString("14400", (BOXSIZE * 2) - (BOXSIZE / 2), (TOP_FIXED_AREA / 2) + (BOXSIZE / 2), 2);
//Set the main header
tft.setTextColor(ILI9341_WHITE, ILI9341_BLUE);
tft.fillRect(0, 0, 240, 16, ILI9341_BLUE);
tft.drawCentreString(" Margherita Datascope - 14400 baud ", 120, 0, 2);
}
void RaiseStart() {
tft.setTextColor(ILI9341_WHITE, ILI9341_BLACK);
tft.drawCentreString("Start", (BOXSIZE * 3) - (BOXSIZE / 2), (TOP_FIXED_AREA / 2) + (BOXSIZE / 2), 2);
}
void RaiseStop() {
tft.setTextColor(ILI9341_WHITE, ILI9341_BLACK);
tft.drawCentreString("Stop", (BOXSIZE * 4) - (BOXSIZE / 2), (TOP_FIXED_AREA / 2) + (BOXSIZE / 2), 2);
}
void RaiseForward() {
tft.setTextColor(ILI9341_WHITE, ILI9341_BLACK);
tft.drawCentreString("Forw", (BOXSIZE * 5) - (BOXSIZE / 2), (TOP_FIXED_AREA / 2) + (BOXSIZE / 2), 2);
}
void RaiseStay() {
tft.setTextColor(ILI9341_WHITE, ILI9341_BLACK);
tft.drawCentreString("Stay", (BOXSIZE * 6) - (BOXSIZE / 2), (TOP_FIXED_AREA / 2) + (BOXSIZE / 2), 2);
}
void DrawMenu() {
if (Is9600 == 1) {
Raise9600();
Serial.end();
Serial.begin(9600);
}
else
{
Raise14400();
Serial.end();
Serial.begin(14400);
}
if (IsLogStart == 1)
RaiseStart();
else
RaiseStop();
if (Retrasmit == 1)
RaiseForward();
else
RaiseStay();
}
void loop(void) {
// These lines change the text colour when the serial buffer is emptied
// These are test lines to see if we may be losing characters
// Also uncomment the change_colour line below to try them
//
// if (change_colour){
// change_colour = 0;
// if (selected == 1) {tft.setTextColor(ILI9341_CYAN, ILI9341_BLACK); selected = 0;}
// else {tft.setTextColor(ILI9341_MAGENTA, ILI9341_BLACK); selected = 1;}
//}
if (!ts.bufferEmpty()) {
TS_Point p = ts.getPoint();
p.x = map(p.x, TS_MINX, TS_MAXX, 0, tft.width());
p.y = map(p.y, TS_MINY, TS_MAXY, 0, tft.height());
MenuSelection(p);
}
while (Serial.available()) {
//read in any case data from the port (flush)
data = Serial.read();
//check if we reached the end of the buffer (Requires more space on Arduino
// if (BufferCurrent == 150) BufferCurrent = 0;
//If the user pressed the start button then:
if (IsLogStart == 1) {
if (data == '\r' || xPos > 231) {
xPos = 0;
yDraw = scroll_line(); // It takes about 13ms to scroll 16 pixel lines
}
if (data > 31 && data < 128) {
//Draw the char at the right position
xPos += tft.drawChar(data, xPos, yDraw, 2);
//If the signal must be retrasmitted
if (Retrasmit == 1)
Serial.write(data);
// Keep a record of line lengths
blank[(17 + (yStart - (TOP_FIXED_AREA + BOXSIZE)) / TEXT_HEIGHT) % 18] = xPos;
}
//change_colour = 1; // Line to indicate buffer is being emptied
}
}
}
void MenuSelection(TS_Point p)
{
int16_t selection;
if (p.y < (BOXSIZE + TOP_FIXED_AREA)) { //is in the menuBar
selection = p.x / BOXSIZE;
}
SetMenu();
switch ((int)selection) {
case 0:
Is9600 = 1;
break;
case 1:
Is9600 = 0; //14400
break;
case 2:
IsLogStart = 1;
break;
case 3:
IsLogStart = 0;
break;
case 4:
Retrasmit = 1;
break;
case 5:
Retrasmit = 0;
break;
}
DrawMenu();
}
// ##############################################################################################
// Call this function to scroll the display one text line
// ##############################################################################################
int scroll_line() {
int yTemp = yStart; // Store the old yStart, this is where we draw the next line
// Use the record of line lengths to optimise the rectangle size we need to erase the top line
tft.fillRect(0,yStart,blank[(yStart-(TOP_FIXED_AREA + BOXSIZE))/TEXT_HEIGHT],TEXT_HEIGHT, ILI9341_BLACK);
// Change the top of the scroll area
yStart+=TEXT_HEIGHT;
// The value must wrap around as the screen memory is a circular buffer
if (yStart >= 320 - BOT_FIXED_AREA) yStart = (TOP_FIXED_AREA + BOXSIZE) + (yStart - 320 + BOT_FIXED_AREA);
// Now we can scroll the display
scrollAddress(yStart);
return yTemp;
}
// ##############################################################################################
// Setup a portion of the screen for vertical scrolling
// ##############################################################################################
// We are using a hardware feature of the display, so we can only scroll in portrait orientation
void setupScrollArea(uint16_t TFA, uint16_t BFA) {
tft.writecommand(ILI9341_VSCRDEF); // Vertical scroll definition
tft.writedata(TFA >> 8);
tft.writedata(TFA);
tft.writedata((320-TFA-BFA)>>8);
tft.writedata(320-TFA-BFA);
tft.writedata(BFA >> 8);
tft.writedata(BFA);
}
// ##############################################################################################
// Setup the vertical scrolling start address
// ##############################################################################################
void scrollAddress(uint16_t VSP) {
tft.writecommand(ILI9341_VSCRSADD); // Vertical scrolling start address
tft.writedata(VSP>>8);
tft.writedata(VSP);
}