LCD Character Editor for Parallax LCD panels

The Parallax 2×16 or 4×20 LCD panels are inexpensive and easy to use. While limited to 2 or 4 lines of text, they do provide for 8 definable characters. This allows a bit of ‘graphical’ manipulation but, doing so in code can be a bit tricky.  I have developed a small, Windows based editor that lets you specify the target for the code, the type of output you want and a graphical way of creating your character.

The LCD Character Editor

lcdchared

Using the application is simple: when it starts, you have a blank canvas. Click in the white squares to turn them on. Create your character this way. When you are done, click Add and the code to create the character appears in the large window. There are a few things you need to enter prior to Adding the character.

First, you need to name the character.  That really means assigning it a special character number (0 to 7.) Enter that in the ‘Special Character # box. Next, you need to tell it which platform to gen the code for … either the Basic Stamp, in which case it creates BASIC code or Arduino, which generates C like syntax. Next, select the type of code you want. The Source + Header option will create a nice beginning to a project file in BASIC Stamp mode or some generic starter code for Arduino.  Source Only just gives you the code that actually gets sent to the display. It uses the binary format. Hex Code APPENDS the hex version of the binary code. You can then cut the format you want.

Save and Load does just what they say.

Clear allows you to start a new character. And, since this is a one character at a time deal, that is why you have a choice of inserting the header code or not. You can create as many characters as you need, maybe create a library and import the characters you want into your project.

Finally, EXIT just shuts down the program.

All character files are stored as text files with the .BS2 extension, even for Arduino…sorry Arduino fans. This was an oversight and might get fixed in a later version.

I make no warranty about this application. It is free to use, even for commercial works, but you cannot sell it.

It was developed with Visual Studio 2005 and requires .net 2.5. You should not have to install anything if you are running Vista or better.

Code Samples:

I. BASIC STAMP, Header and Source:

=============================
‘   {$STAMP BS2}
‘   {$PBASIC 2.5}

‘ =========================================================================
‘ —–[ Program Description ]———————————————
‘ —–[ Revision History ]————————————————
‘ —–[ Variablew ]————————————————
baud            VAR     Byte            ‘ baud rate variable
‘ —–[ I/O Definitions ]————————————————-
TX              PIN     0               ‘ serial output to LCD
‘ —–[ Constants ]——————————————————-

#SELECT $STAMP
#CASE BS2, BS2E, BS2PE
    T2400       CON    396
    T9600       CON     84
    T19K2       CON     32
#CASE BS2SX, BS2P
    T2400       CON     1021
    T9600       CON     240
    T19K2       CON     110
#ENDSELECT

baud=T9600

HIGH(TX)
PAUSE(100)

SEROUT TX, baud, [251]

SEROUT TX, baud, [%01110]
SEROUT TX, baud, [%11011]
SEROUT TX, baud, [%01110]
SEROUT TX, baud, [%10101]
SEROUT TX, baud, [%11111]
SEROUT TX, baud, [%10101]
SEROUT TX, baud, [%10001]
SEROUT TX, baud, [%10001]

II. BASIC STAMP, Source Only

SEROUT TX, baud, [248]

SEROUT TX, baud, [%01110]
SEROUT TX, baud, [%11011]
SEROUT TX, baud, [%01110]
SEROUT TX, baud, [%10101]
SEROUT TX, baud, [%11111]
SEROUT TX, baud, [%10101]
SEROUT TX, baud, [%10001]
SEROUT TX, baud, [%10001]

III. BASIC STAMP, Hex Code

SEROUT TX, baud, [0xE]
SEROUT TX, baud, [0x1B]
SEROUT TX, baud, [0xE]
SEROUT TX, baud, [0x15]
SEROUT TX, baud, [0x1F]
SEROUT TX, baud, [0x15]
SEROUT TX, baud, [0x11]
SEROUT TX, baud, [0x11]

IV. Arduino

#include <SoftwareSerial.h>

SoftwareSerial s(2,1); //receive on 2, and transmit on 1 aka ‘PB1’ aka pin 6
void setup() {
s.begin(9600);// set baud rate to 9600 baud
s.write(12);// clear screen
s.write(17);// turn on backlight

s.write(248)

s.write(B01110);
s.write(B11011);
s.write(B01110);
s.write(B10101);
s.write(B11111);
s.write(B10101);
s.write(B10001);
s.write(B10001);

You can download it, free, from here: LCD Char Editor

Advertisements

Coding for small platforms is nearly a lost art OR why I love tiny computers

There was a time when a computer with 4K of memory was something to behold. Indeed, 4K was enough for a BASIC interpreter AND have room left over for user programs. Most I/O was serial, so ALL of that space was for code. The ‘operating system’ was something called a ‘monitor’ or the BASIC itself. Either way, the I/O code was ‘built’ into either the BASIC or the monitor. And, if you had a video terminal, well, you were THE stuff.

Just a few years later, that 4K grew to 16K then 64K and, suddenly, we are talking MEGAbytes. Wow. Well, funny thing happened, code went from small, tight and mostly efficient to BIG, heavy and bloated.  Code in that 4K system that put a character on the screen took, maybe six bytes suddenly took a DLL, which was probably ten times that or more.  Programmers got complacent, including this one.

I recall one job I had, I was maybe 17, that required me to write an accounting screen for a paging system (remember the pocket pager?) I had 2k for the data entry screen AND the billing code. Plus, the datastream to/from the paging system was like 32 bytes.  In that 32 bytes, I had to squeeze in the client number (10 digits), number of pages, and about two dozen status bits and more. I did it. The software went into a dozen or ‘head end’ systems (hey, it was a SMALL market) but it was my first ‘professional’ gig.

My career took me down the Microsoft/Lotus path. I had all kinds of wonders to code with, Visual Studio, Visual Basic, Lotus Notes, web.  My code, while functional and often clever, was sloppy. I forgot what it was to REALLY code.

Well, I had a shot a programming for the Palm Pilot, which reminded me of my old days, but it didn’t last long and I was back to programming for machines with memory measured in the gigabytes.

Imagine my delight when I discovered the world of Microcontrollers.  These things have big capability, but tiny (and I mean tiny) memory spaces. My current microcontroller project, the Adafruit Trinket, based on the ATMel ATtiny85, has 5,2k of available programming memory and 512 BYTES of RAM (as well as 512 bytes of EEPROM.)

Having found some cool 2×16 LCD panels for five bucks each at Radio Shack, these Trinkets and a bunch of parts, I set out to make a game for my step son.  I’m still working on a game concept that will keep his interest, but I did a proof of concept game based on Space Invaders (my all time favorite game.) So, how can one make a Space Invaders on a TWO line by SIXTEEN character display? Well…you need to be creative. AND…you have to fit it, along with a necessary library, into under 5.1K.

So…what did I do? Well, found an old notebook I kept from my TRS-80 days. Looked at some old Tiny Basic game code and…coded.

BSG001First, I needed an idea. The display I am using, from Parallax, allows for eight special characters.  So, I played around with a few designs and one of them looked like the Battlestar Galactica. After some thought, I had the idea: The Galactica’s Viper squadrons are out on patrol. The Galactica was in a fierce battle that has rendered it nearly immovable, it can only hyperjump. It’s turrets are all damaged, save the forward bank, she can only shoot from her forward cannons.  A Cylon has discovered the Galactica and is taking runs at it.  Problem is, the Cylon is jumping randomly, making a direct hit nearly impossible.  If, however, the Galactica does manage to destroy the Cylon, the Galactica then hyperjumps too.  Then, it all happens again.

Cool, huh?IMG_2758

So, I set out to code it. I put code together to read a switch, move a character back and forth and come up with an interrupt mechanism for the button.

Turns out, it was simpler than I thought.  I had some hiccups with the Arduino IDE (which involved upgrading the toolchain, upgrading part of it again, some choice words…) but got them ironed out and, now, the Colonials are fighting the nasty Cylons again.

First, the source code:

#include <SoftwareSerial.h>

SoftwareSerial s(0,2);
 
// globals
int  cylonpos;
int  oldcylonpos;
int  cyDirection;
int  button;
int  posStart;
int  lin2Start;
int  bsgpos;
// special characters
int  bsg;
int  cylon;
 
// the setup routine runs once when you press reset:
void waitforbutton();
void moveCylon();
 
void setup() {  // initialize the digital pin as an output. 
   s.begin(9600);
   s.write(12);
   s.write(17);
   //define the character
   s.write(249);
   s.write(0x4);
   s.write(0xE);
   s.write(0xE);
   s.write(0x15);
   s.write(0x1F);
   s.write(0x15);
   s.write(0xE);
   s.write(0xE);
  
   // baddies
   s.write(251);

   s.write(uint8_t(0x0));//to handle a goofy issue with ‘0’
   s.write(uint8_t(0x0));
   s.write(0xE);
   s.write(0x15);
   s.write(0x1F);
   s.write(uint8_t(0x0));
   s.write(uint8_t(0x0));
   s.write(uint8_t(0x0));
  
   pinMode(0,INPUT);
   cyDirection=1;
  
} // the loop routine runs over and over again forever:
void loop() {
  int score;
  score=0;
 
  s.write(12);
  s.println("Shoot the Cylon\n");
  s.println("press btn 2 strt");
 
  waitforbutton();
 
  cylon=3;
  bsg=1;
  lin2Start=148;
  posStart=128;
  randomSeed(analogRead(0)); // gen a random seed
 
  bsgpos = 8;
  cylonpos=random(0,15);
  oldcylonpos=cylonpos;
 
  s.write(12);
  s.write(17);
  s.write(posStart + cylonpos);
 
  s.write(cylon);
  s.write(lin2Start+bsgpos);
  s.write(bsg);
 
  while(1){
    /* Game loop */
    int button;
    s.write(22); // kill the cursor
    moveCylon();
    delay(200);
    button=digitalRead(0);
    if(button==HIGH){
      if(cylonpos==bsgpos){
        s.write(132); // center ‘Hit’ on screen
        s.print("** HIT **");
        score ++;  // update score
        delay(3000);
        s.write(12); // clear screen
        s.write(lin2Start); // move cursor to beginning of line
        s.write("Score:");  // put up score
        s.print(score);
        s.write(lin2Start+bsgpos); // Since we shot the Cylon, we have to leave the sector, so…
        s.write(0x20); // go into hyperdrive and erase the BSG
        bsgpos=random(9,15);  // calculate new position
        s.write(lin2Start+bsgpos); //…and, we are here
        s.write(bsg);
        s.write(posStart+cylonpos);
        s.write(0x20);
        cylonpos=random(0,15); // Damn, they found us!
        oldcylonpos=cylonpos;
        moveCylon();
      }
    } 
  }
}
void moveCylon(){
  // sneaky Cylons…they show up anywhere!
  s.write(posStart+oldcylonpos);
  s.write(0x20);
  if (random(0,6)>3){
      //Cylon warped
      cylonpos=random(0,15);
      oldcylonpos=cylonpos;
  }
 
  cylonpos += cyDirection; // figure out which way to move
  if (cylonpos>15){
   cylonpos=15;
   cyDirection=-1;
  }
 
  if (cylonpos<0){
    cylonpos=0;
    cyDirection=1;
  }
  // erase from old spot
  s.write(posStart+oldcylonpos);
  s.write(0x20);
  s.write(posStart+cylonpos);
  s.write(cylon);
  oldcylonpos=cylonpos;
}

void waitforbutton(){
  SoftwareSerial s(0,1);
 
  int button;
  button=digitalRead(0);
  while(button==LOW){
    button=digitalRead(0);
    delay(1);
  } 
  s.write(1); 
  delay(1000);
  s.write(12);
}

SInce the Trinket is limited, I/O wise, I have only five pins, two of which are shared with the USB programmer and one is shared with the red programming LED, it really limits what you can add. At least, for those of us who are electronically challenged. I have my LCD on pin 2 and the switch on pin 0.  The LCD is controlled with a single line, it also has a five volt line (which goes to the USB power) and ground. The switch is connected to power and a 10k ohm resistor. It connects to pin 0. In the LOOP code, there is a While loop that handles the game logic. Inside the loop, it checks the pin for HIGH, which means the button was pressed. It then checks the position of the BSG and the Cylon. If there is a hit, it tells the user that they hit the Cylon and then increments the score, recalculates the positions and does it all again.  Simple, but kind of hard since the Cylon jumps so much.

While the game is not sophisticated, it does show what you can do in 5K of memory, a limited input mechanism and very limited display.  Now, about the game for my step son…

 

It’s the BASIC Stamp!

IMG_2395I was at a local Radio Shack store today and came across a sweet little deal on a BASIC Stamp experimenters kit. Called BASIC Stamp Homework, this little gem contains the BASIC Stamp 2, serial to USB, a prototype board and several bags full of parts, including photocell, resistors, old school seven segment LED, servo and more. 

The BASIC Stamp microcontroller, unlike other similar controllers, uses a flavor of Tiny Basic instead of something like C.  This makes it a good candidate for teaching both programming and electronics to kids and adults. The included book is easy to understand but does not talk down to those who may be experienced and just want experiment with microcontrollers.

In the little bit of time I’ve played with the kit, I was able to program the controller to interpret the amount of ambient light and flash each outer segment of the seven segment display at a rate that corresponded with the amount of light the photocell received as well as make the display count to ‘F’ in hex.  Simple, but oddly satisfying.IMG_2394

When my XGS PIC Basic project is complete, I’m definitely coming back to the BASIC Stamp. I have some ideas that this will be perfect for trying out.

The kit retailed for $99, but was being clearanced by Radio Shack for $29.95. You may or may not find at your local Shack. (Radio Shack, by the way, has a really nice line of do it yourself little kits and a full line of Arduino, Propeller and BASIC Stamp kits, sheilds and parts.)