I have a father/son project, the PS2You Display, mostly complete, except for resolving some compile errors in the project's code. The project is located here: http://www.instructables.com/id/PS2You-Go-anywhere-LED-digital-message-board/?ALLSTEPS . I have read a few things about library references and this maybe coming from a pre-Ver 1 of Arduino, but couldn't verify that. I have added a couple libraries to the sketch that eliminated a couple compile errors.
The compile error is referencing this line:
dots = pgm_read_byte_near(&myfont[c][col]);
Error:
PS2YouDisplay.ino: In function 'void drawChar(int, int, char)':
PS2YouDisplay:263: error: 'myfont' was not declared in this scope
I could not find the term myfont anywhere else in the project, but I'm sure Windows Search may not have read the contents of all support files/libraries. I'm unsure of the function of myfont.
The sketch:
#include <ht1632_cmd.h>
#include <images.h>
/*
PS/2/You -- Takes text input from a PS/2 keyboard and displays it on
cascaded Sure 0832 LED matrix panels.
Thanks to the authors of the PS2Keyboard (Ext2) and MatrixDisplay libraries
on which this project is based.
See the README.txt file for instructions on controlling the display output
with the keyboard and editing font glyphs.
This code is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This code is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <string.h>
#include <MatrixDisplay.h>
#include <DisplayToolbox.h>
#include <font.h>
#include <PS2Keyboard.h>
const int numLines = 6; // Max number of lines
const int displayTime = 1500; // Length of time in milliseconds to display each line
const int gapTime = 10; // Time gap between lines
const int maxLineLength = 100; // Maximum length of a line in characters
String textLines[numLines]; // Array of text lines
int textLength; // Holds current line length in pixels
int strLength; // Holds current line length in characters
int currentLine = 0; // Index of current line
int mode = 2; // Determines whether in input (1) or output (2) mode
char defaultText[numLines][30] = {{"Hello World!"},{"Welcome to PS/2/You"},{"Start typing..."}};
// Character lookup string -- used to map the characters from the keyboard onto the font data array
// (This should probably be moved to program memory in some form in the future)
String charLookup = " 0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!@#$%^&*(),-.?></\\|[]_=+:'\"{}";
// Memory test
extern int __bss_end;
extern int *__brkval;
/* DISPLAY LIBRARY SETUP */
// Parameters for Matrix Display initialization:
// Number of displays = 3
// Data pin = 10
// WR pin == 11
// Shadow buffer = true
// Macro to make it the initDisplay function a little easier to understand
#define setMaster(dispNum, CSPin) initDisplay(dispNum,CSPin,true)
#define setSlave(dispNum, CSPin) initDisplay(dispNum,CSPin,false)
// Initialize matrix
MatrixDisplay disp(3,11,10, true);
DisplayToolbox toolbox(&disp);
// Prepare boundaries
uint8_t X_MAX = 0;
uint8_t Y_MAX = 0;
/* KEYBOARD SETUP */
#define KBD_CLK_PIN 3
#define KBD_DATA_PIN 7
#define is_printable(c) (!(c&0x80))
PS2Keyboard keyboard;
void setup() {
//Serial.begin(9600);
for(int i=0; i<numLines; i++){
textLines[i] = defaultText[i];
//Serial.println(defaultText[i]);
}
// Initialize the keyboard class
keyboard.begin(KBD_DATA_PIN);
// Fetch display bounds
X_MAX = disp.getDisplayCount() * (disp.getDisplayWidth()-1)+3;
Y_MAX = disp.getDisplayHeight()-1;
// Prepare displays
disp.setMaster(0,4);
disp.setSlave(1,5);
disp.setSlave(2,6);
}
void loop() {
while (keyboard.available()) {
// read the key
byte c = keyboard.read();
if (mode == 2){
mode = 1; // If any keyboard data is entered, switch to input mode
prevLine();
if(c != PS2_KC_ENTER){ // Ditch the first char entered on going into input mode
return;
}
}
//Serial.println(c);
if (c == PS2_KC_ENTER) { // Pressing enter goes into output mode
mode = 2;
} else if (c == PS2_KC_ESC) { // ESC erases current line
textLines[currentLine] = "";
} else if (c == PS2_KC_UP) { // Up arrow goes to previous line (or loops to last line)
prevLine();
} else if (c == PS2_KC_DOWN) { // Down arrow goes to next line
nextLine();
} else if (c == PS2_KC_BKSP) { // Truncate the current line by one character
String thisLine = textLines[currentLine];
textLines[currentLine] = thisLine.substring(0,(thisLine.length()-1));
} else if (strLength < maxLineLength && is_printable(c)){ // Otherwise add the character to the line, if the line is not too long
textLines[currentLine] += char(c);
if(get_free_memory() < 80){
low_memory_alert();
}
}
}
strLength = textLines[currentLine].length(); // Number of characters in the string
textLength = (strLength*6); // Width of string in pixels
// Convert the String into a char array
char* text;
char textMem[maxLineLength];
for(int i=0;i<maxLineLength;i++){
textMem[i]=textLines[currentLine][i];
}
text = textMem;
if(mode == 2){ // Output mode
if(strLength > 1){
if(textLength < (X_MAX +1)){
fixedText(text);
delay(displayTime);
disp.clear();
disp.syncDisplays();
delay(gapTime);
}else{
scrollText(text);
delay(gapTime);
}
}
nextLine();
}else{ // Input mode
if(textLength > X_MAX){ // If the line is longer than the display, trim off the beginning
int displayLengthChars = (X_MAX/6)+1;
char out[displayLengthChars];
int startChar = (strLength - displayLengthChars);
for(int i = 0; i < displayLengthChars; i++){
startChar++;
out[i] = text[startChar];
}
fixedText(out);
}else{
fixedText(text);
}
}
}
void nextLine(){
if(currentLine < (numLines -1)){
currentLine++;
}else{
currentLine = 0;
}
}
void prevLine(){
if(currentLine > 0){
currentLine--;
} else {
currentLine = (numLines -1);
}
}
// Scroll a line of text across the display
/* This is a fairly inefficient function. It uses drawString() to
redraw repeatedly as it moves. Not a problem in this case, but if
faster scrolling was needed it should probably be rewritten to use
disp.shiftLeft() instead */
void scrollText(char* text){
int y=1;
int endPos = 0 - textLength;
int loopCount = 0;
for(int Xpos = X_MAX; Xpos > endPos; Xpos--){
if(loopCount > 10){ // Check for incoming keyboard data every 10 loops
loopCount = 0;
if(keyboard.available()){
return;
}
}
loopCount++;
disp.clear();
drawString(Xpos,y,text);
disp.syncDisplays();
}
}
// Write a line of static (non-scrolling) text to the display
void fixedText(char* text){
int y = 1;
int x = 0;
disp.clear();
drawString(x,y,text);
disp.syncDisplays();
}
// Output a string to the display
void drawString(int x, uint8_t y, char* c){
for(char i=0; i< strLength; i++){
drawChar(x, y, c[i]);
x+=6; // Width of each glyph
}
}
// Output a single character to the display
void drawChar(int x, int y, char c){
int dots;
c = charLookup.indexOf(c);
for (char col=0; col< 5; col++) {
if((x+col+1)>0 && x < X_MAX){ // dont write to the display buffer if the location is out of range
dots = pgm_read_byte_near(&myfont[c][col]); // < -- compile error myfont
for (char row=0; row < 7; row++) {
if (dots & (64>>row)) // only 7 rows.
toolbox.setPixel(x+col, y+row, 1);
else
toolbox.setPixel(x+col, y+row, 0);
}
}
}
}
// Warn if we're running out of RAM
void low_memory_alert(){
for(int i=0; i < 3; i++){
int y = 1;
int x = 0;
disp.clear();
drawString(x,y," MEMORY LOW! ");
disp.syncDisplays();
delay(500);
disp.clear();
disp.syncDisplays();
delay(500);
disp.clear();
}
}
// Memory check
int get_free_memory(){
int free_memory;
if((int)__brkval == 0)
free_memory = ((int)&free_memory) - ((int)&__bss_end);
else
free_memory = ((int)&free_memory) - ((int)__brkval);
Serial.println(free_memory);
return free_memory;
}
Any help appreciated.