KS0108 coding problems

EL Wire/Tape/Panels, LEDs, pixels and strips, LCDs and TFTs, etc products from Adafruit

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
Locked
markjames
 
Posts: 74
Joined: Tue Oct 01, 2013 1:28 pm

KS0108 Giving me a headache

Post by markjames »

I've built a few pong clocks using led matrices - this is the first one I've tried to build using a graphical LCD. I'm stuck on something stupid that's making me nuts and I'm sure it's something simple I'm just not seeing. I've stripped the code down to just demo the problem and it's below.

What I'm trying to do is just
  • read the data at position x,y on the screen and save it.
    draw the ball at x,y
    wait some milliseconds for visibility
    restore the data at position x,y to what it was before the ball was drawn.
    increment x and y as necessary
repeat this ad-nauseum

I'm, of course, not drawing just a single space in the actual code - I'm saving a buffer of all the pixels needed - I've just stripped this down for clarity.
The reason I have to read and restore is otherwise the ball will erase the net or the clock numerals.

The code below simply generates a dashed line with a blank space every 6 or so iterations. Video of what it does is here: https://www.dropbox.com/s/wq0zxsttc2nbk ... 1.mp4?dl=0 - pardon the bit of glare.

This has to be a data type problem or a timing issue or something I'm just not understanding. Any help would be appreciated


Code: Select all

#include <glcd.h>
#define GLCD_CS_Invert 1
#include "fonts/allFonts.h"         // system and arial14 fonts are used
#include "bitmaps/allBitmaps.h"       // all images in the bitmap dir 

int courtTop=2;
int courtBottom=58;
int courtLeft=0;
int courtRight=127;

int ballHeight=2; int ballWidth=2;
int ballDirectionY = 1;        // X direction of the ball
int ballDirectionX = 1;        // Y direction of the ball
int ballBuf[40];    //save screen data
int xPos, yPos;

void setup()
{
  GLCD.Init();   // initialise the library, non inverted writes pixels onto a clear screen
  GLCD.SetDisplayMode(NON_INVERTED);
  GLCD.SelectFont(fixednums8x16, BLACK); // font for the default text area
  GLCD.ClearScreen(); 
  xPos = 14;
  yPos = 24;
}

void  loop(){
moveBall();
}
   
void saveRectangle(int x, int y) {
  GLCD.GotoXY(x,y);
  ballBuf[0]=GLCD.ReadData();
}
void restoreRectangle(int x, int y) {
    GLCD.GotoXY(x,y);
    GLCD.WriteData(ballBuf[0]);
  }
void drawBall(int x, int y) {
    GLCD.SetDot(x,y,BLACK);
 }

void moveBall() { 
 xPos += ballDirectionX;
  if (xPos+ballWidth >= courtRight || xPos-ballWidth <= courtLeft)
   ballDirectionX = -ballDirectionX;
   
 yPos += ballDirectionY;
 if (yPos+ballHeight >= courtBottom || yPos-ballHeight <= courtTop)
   ballDirectionY = -ballDirectionY;

saveRectangle(xPos,yPos);
drawBall(xPos,yPos);
delay(30);
restoreRectangle(xPos,yPos);
}
  


User avatar
adafruit_support_rick
 
Posts: 35092
Joined: Tue Mar 15, 2011 11:42 am

Re: KS0108 coding problems

Post by adafruit_support_rick »

Good one. Whatever it is, I'm not seeing it. It's as if GotoXY doesn't work.

markjames
 
Posts: 74
Joined: Tue Oct 01, 2013 1:28 pm

Re: KS0108 coding problems

Post by markjames »

Well, I figured it out and it's a bit odd.

It turns out that the KS0108 display memory is mapped as 8 bytes vertically by 128 columns. The display is 128 wide by 64 high but the 64 high is represented by 8 x 8bit bytes. That makes sense seeing as how it's mono and each pixel is really only on or off.

When you do a GLCD.SetDot you toggle the exact pixel you want.
When you do a GotoXY you move to the exact pixel you want

GLCD.ReadData doesn't work that way. It reads from the nearest byte boundary. But GLCD.WriteData() writes starting at the pixel you're currently on. That's where things go weird and it's also why every few dots are blank.

So - starting with a blank screen readdata anywhere will return 0
If you set 0,0 to black, then go to 0,0 and readdata you'll get a value of 1
if you set 0,1 to black then go to 0,0 and readdata you'll get a value of 3

that all makes sense

BUT

If you set 0,0 to black and 0,1 to black then go to 0,1 and readdata you'll STILL get a value of 3 - in other words readdata will give you the value starting at the beginning of the byte that contains that pixel - not from that pixel down. If you then turn around and writedata() at 0,1 you'll write the byte value 3 starting at 0,1 which will then leave 0,0 black, turn, 0,1 black (expected), and - very confusingly - 0,2 black now.

So.. long story short - the simplest way to save/restore the area you want is just to save the whole column. It only takes 8bytes per column so it's really no big deal.

Hope this helps someone else someday.

Mark

Locked
Please be positive and constructive with your questions and comments.

Return to “Glowy things (LCD, LED, TFT, EL) purchased at Adafruit”