Sparkfun "Huge" 160x128 glcd

I would like to buy the Sparkfun "Huge" lcd (ill link to it next post, it won't let me) but it doesn't have a pinout that matches any of the ones for the GLCDs for code already written. Has anybody used one of these things with an arduino, and how did they do it, or does somebody know how to do it.

Also, if it requires some new code be written, i cant really do it because im not that good at that part of coding, but there is some code for an ATMega168 on the sparkfun page specifically for this GLCD. (Ill link to that next post also).

This is the LCD

The Tut with the Code:
http://www.sparkfun.com/commerce/tutorial_info.php?tutorials_id=120

I did a quick google search for "t6963c arduino", and came up with one very promising link for you:

http://en.radzio.dxp.pl/t6963/

It's not Arduino code, but it is avr-gcc code, so it shouldn't be too hard to adapt.

I have a couple of T6963-based LCDs I picked up surplus a few years ago, and have been planning to use that code to interface one to an Arduino. But I can't guarantee I'll get it done anytime soon, because I don't actually know the displays are good, and I have a couple of other projects ahead of that in the queue.

Ran

I downloaded the code, renamed the c files to c++ and everything is working ok except for the port definitions/data. Anything to do with the port and pins doesn't work because obviously Arduino doesn't do ports and pins the same way as avr-gcc.

http://en.radzio.dxp.pl/t6963/t6963c.c

i get the following arduino errors:
t6963c.cpp: In function 'void GLCD_InitalizeInterface()':
t6963c.cpp:28: error: 'DDRA' was not declared in this scope
t6963c.cpp:29: error: 'PC0' was not declared in this scope
t6963c.cpp:29: error: 'PC1' was not declared in this scope
t6963c.cpp:29: error: 'PC2' was not declared in this scope
t6963c.cpp:29: error: 'PC3' was not declared in this scope
t6963c.cpp:29: error: 'PC4' was not declared in this scope
t6963c.cpp:29: error: 'PC5' was not declared in this scope
t6963c.cpp: In function 'unsigned char GLCD_ChceckStatus()':
t6963c.cpp:40: error: 'DDRA' was not declared in this scope
t6963c.cpp:42: error: 'PC1' was not declared in this scope
t6963c.cpp:42: error: 'PC2' was not declared in this scope
t6963c.cpp:44: error: 'PINA' was not declared in this scope
t6963c.cpp: In function 'void GLCD_WriteCommand(unsigned char)':
t6963c.cpp:57: error: 'PORTA' was not declared in this scope
t6963c.cpp:59: error: 'PC0' was not declared in this scope
t6963c.cpp:59: error: 'PC2' was not declared in this scope
t6963c.cpp: In function 'void GLCD_WriteData(unsigned char)':
t6963c.cpp:72: error: 'PORTA' was not declared in this scope
t6963c.cpp:74: error: 'PC0' was not declared in this scope
t6963c.cpp:74: error: 'PC2' was not declared in this scope
t6963c.cpp:74: error: 'PC3' was not declared in this scope
t6963c.cpp: In function 'unsigned char GLCD_ReadData()':
t6963c.cpp:87: error: 'DDRA' was not declared in this scope
t6963c.cpp:89: error: 'PC1' was not declared in this scope
t6963c.cpp:89: error: 'PC2' was not declared in this scope
t6963c.cpp:89: error: 'PC3' was not declared in this scope
t6963c.cpp:91: error: 'PINA' was not declared in this scope
t6963c.cpp: In function 'void GLCD_Initalize()':
t6963c.cpp:291: error: 'PC4' was not declared in this scope
t6963c.cpp:296: error: 'PC5' was not declared in this scope

any help fixing this would be great, because i still don't really understand avr-gcc code for pin data.

Actually, the Arduino environment uses avr-gcc to compile programs.

The T6963C code was written for a "first generation" AVR, and the ATMega chips used by Arduinos are slightly different. Try adding this to the top of the .c files (above the first "#include"):

#define __AVR_ATmega168P__ 1

Charge the "PORTA", "DDRA", and "PINA" in t6963c.h to "PORTD", "DDRD", and "PIND".

That should get rid of a bunch of errors. Unfortunately, it will also cost you the use of the serial port when the LCD is hooked up, because D0 and D1 are used for that. My tentative plan is to dedicate a CPU to the LCD, and control it as an I2C slave, so I wouldn't care about losing the serial port.

You can also look at how the KS0108-based LCDs are done: Arduino Playground - GLCDks0108. The interface might be similar enough that you'd only need to change a few graphics chip opcodes and/or display memory addresses to make that library work with the Sparkfun LCD.

Or it might not: I haven't gotten that far in my own investigation yet.

Ran

im running the duemillinove with the 328P. should i add a #define AVR_ATmega328P 1 instead?

Also, i realized an issue. I planned to add a touchpad so i could, pretty much draw on the lcd with absolute positioning, but the LCD will take up all the pins. Is there any way around this without buying the same lcd with the serial connection? and if i did that how would i control it? I thought about maybe the idea that some of the lines are high or low all the time, which would free up enough to use the other device (a touchpad that only needs two pins). I will see if i can identify any lines that are constant high/low, and that would fix that.

i tried the above line, got rid of all the errors except

t6963c.cpp: In function 'void GLCD_InitalizeInterface()':
t6963c.cpp:30: error: 'PC0' was not declared in this scope
t6963c.cpp:30: error: 'PC1' was not declared in this scope
t6963c.cpp:30: error: 'PC2' was not declared in this scope
t6963c.cpp:30: error: 'PC3' was not declared in this scope
t6963c.cpp:30: error: 'PC4' was not declared in this scope
t6963c.cpp:30: error: 'PC5' was not declared in this scope
t6963c.cpp: In function 'unsigned char GLCD_ChceckStatus()':
t6963c.cpp:43: error: 'PC1' was not declared in this scope
t6963c.cpp:43: error: 'PC2' was not declared in this scope
t6963c.cpp: In function 'void GLCD_WriteCommand(unsigned char)':
t6963c.cpp:60: error: 'PC0' was not declared in this scope
t6963c.cpp:60: error: 'PC2' was not declared in this scope
t6963c.cpp: In function 'void GLCD_WriteData(unsigned char)':
t6963c.cpp:75: error: 'PC0' was not declared in this scope
t6963c.cpp:75: error: 'PC2' was not declared in this scope
t6963c.cpp:75: error: 'PC3' was not declared in this scope
t6963c.cpp: In function 'unsigned char GLCD_ReadData()':
t6963c.cpp:90: error: 'PC1' was not declared in this scope
t6963c.cpp:90: error: 'PC2' was not declared in this scope
t6963c.cpp:90: error: 'PC3' was not declared in this scope
t6963c.cpp: In function 'void GLCD_Initalize()':
t6963c.cpp:292: error: 'PC4' was not declared in this scope
t6963c.cpp:297: error: 'PC5' was not declared in this scope

Yes, you should switch to define'ing AVR_ATmega328P. I don't think it'll make much of a difference, since I don't believe it changes any I/O addresses. But it might, so it's best to do it right.

The error messages for PC0, etc. looks like a problem with the preprocessor. You can cheat your way around it for now by editing t6963c.h and changing the #defines to PC0, PC1, etc. near the top of the file to just plain 0, 1, 2 ...

It's tacky, but it should keep you going until there's time to figure out what the correct solution is.

The high pin consumption is the very reason I'm planning to try the dedicated CPU chip with I2C. Personally, I'm too cheap to go to an Arduino Mega because of that problem, but you might feel differently. Especially if you have projects in mind that could use lots of pins.

Ran

i don't currrently have the budget for a mega and the lcd. I have no clue what I2C is, haven't looked at it yet, but if you could explain how to use it in this case it would be helpful. I also thought about using analog pins for inputting the touchpad. i would write a little extention library for guessing HIGH or LOW and returning it based on Analog pins. Should be pretty easy.

I understand about the budget: mine is really tight, too.

I2C is sort of like "USB for micros": you can connect several peripheral using just 2 Arduino pins (plus a ground). If you you type it into the "Search" box at the top of the page, you'll get lots of info about it.

I think there are some examples from people who've done resistive touchscreens, too. You should also try that (and maybe "touch screen" as separate words) in the site search.

Ran

ok, well i kind of understand what it is and what it does, what i need, but still no clue how to use it. i searched on the playground for some tutorials, and they kinda confused me. the I2C chips i found were TI, and i think i can get them sampled.
I2C at TI

Should those work ok. if they will i might try to find similar ones from a different maker because TI is not known for giving away samples of cheaper parts. I think i understand how to use the I2C enough to use it, but i have no clue how i would use it in this case. I take it all new code would need to be written in the library to send the data over I2C instead of directly to the pins.

edit: i found somebody using a touchscreen with the exact same display driver. I realized something though. why drive the lcd on I2C, when it would take only 2 pins for the touchpad. I also don't know how to impliment that. Im still a little confused about I2C. When i get my hands on one, i might figure it out more, but at the moment, im still at a bit of a loss to how to use it.

well i looked. i am just going to go with the LCD with the "serial backpack". Sparkfun has code to run it. i may need help adapting it though for arduino

http://www.sparkfun.com/Code/Graphic_LCD_Backpack-ATMega168.zip is the zip file with the code for an ATMega168. shouldnt be too hard to adapt.

Well, the reason to hook up the display via I2C or serial is that, unless your goal is making your own version of a Gameboy, the purpose of the LCD is to display information about what the computer is doing. Like spinning motors, or clicking solenoids, or checking the door and window switches on your security system, or counting the quarks being emitted from your underground tank of heavy water. Most of those jobs take up I/O pins, so you don't want to spend 3/4 of them on the display.

There are other I2C I/O chips out there, like the MCP23008 (Microchip) and the PCF8574 (various), available from places like Mouser and Digi-Key. The PCF8574 is also available from BG Micro, one of my favorite surplus dealers, that has many deals on fun stuff for electronics tinkerers.

The Sparkfun serial LCD is similar to what I have in mind for I2C, but the difference would be that, instead of implementing a "terminal-like" protocol, I'd make a version of this library that takes the function call parameters and passes just those over the I2C interface. Then the "slave" CPU would run the original library, and pass the parameters to it. The big plus is that it retains compatibility with all the code people have already written, while freeing up I/O pins and memory for them to do other things with the "master" CPU.

Ran

well the thing is im still quite inexperienced in the area of microcontrollers and still prefer the simplest method. I found somebody that seems to have an arduino library for this lcd using the sparkfun Serial backpack. The only reason i would see myself trying to tackle I2C yet would be if somebody provided code and schematics. At this point i don't have much knowledge about how to do the more complicated stuff like I2C, and rely on others to provide the how-to's.

My plan was to do something more than just displaying info. I could use the Serial Debugging for that. The idea i have is to basically use the synaptics touchpad, get absolute positioning data from it, scale it to the resolution of the display and turn the corresponding pixel on.

I really appriciate your help though. I just don't see myselft doing I2C yet.

well, i cant get the person at sparkfun with the code to respond. Does anybody think they can help edit the code posted above to work with the arduino with a 328?

I've been working with this LCD, and it almost works. I have difficulty with the screen clearing when it should not, and with what seems like mis-interpretted commands, especially line-drawing end points.

I see that there was a code re-write, but I ordered this after the code was changed, and the SparkFun site assures purchasers that recent devices (such as mine) have the new code.

So, looking at the code, I see problems. I am not new to firmware, although I am new to the AVR processors.

For instance, in the code snippet:

else if (RX_array[RX_read] == 12)//^l
{
//need 5 bytes
for (y = 0; y < 5; y++)
{
RX_read++;
if(RX_read >= 416) RX_read = 0;
while(RX_in == RX_read);//wait for byte
}

line(RX_array[RX_read], RX_array[RX_read-4], RX_array[RX_read-3], RX_array[RX_read-2], RX_array[RX_read+-1]);
RX_read++;
if(RX_read >= 416) RX_read = 0;
}

Notice that the RX_read index is allowed to wrap to zero, BUT there are two problems:

  1. the interrupt layer code assures us that we will never wrap the buffer while in a command, thus it should not be necessary to wrap to zero, and
  2. if we ever did wrap to zero, the code that follows which access at negative offsets from RX_read will read bogus data.

I guess I'll need to fix some of these problems, since I want to have reliable use of the display. Maybe I'll implement X_ON/X_OFF at the same time to better manage timing.

The question is, what tools (hopefully FREE) do I need to build, compile, and flash this code? The serial backpack has a 6 pin header (unpopulated), which looks to be the ISP connector. What would I need for a compiler/linker/assembler/loader/programmer? I have the Arduino development environment for "sketches", but nothing else for AVR.

-- Carl

Is the AVR processor an 8 bit or a 16 bit processor? In other words, when memory is written, such as when incrementing a 16 bit variable, is the store of the new 16 bit value done with one instruction or with two?

If the AVR is an 8 bit processor, then the buffer managment code will likely fail since it depends on an atomic comparison of two 16 bit values, one of which is being updated in the interrupter handler.

On the assumption that the AVR is an 8-bit processor, I'll update the code and re-release it to SparkFun, if I can get the tools together to rebuilt it, and reflash the LCD backpack.

Is the AVR processor an 8 bit or a 16 bit processor? In other words, when memory is written, such as when incrementing a 16 bit variable, is the store of the new 16 bit value done with one instruction or with two?

Keep in mind that the Atmel AVR chips are of the Harvard architecture where it has separate code (flash) memory and data (SRAM) memory. The code memory is of 16 bit in length while data memory is of 8 bits. The internal registers and ALU are of 8 bit size.

If the AVR is an 8 bit processor, then the buffer managment code will likely fail since it depends on an atomic comparison of two 16 bit values, one of which is being updated in the interrupter handler.

There are statements that allow disabling and then reenabling interrupts such that one can copy a integer or larger variable in the main program flow so as not have the value change because of ISR statements, i.e. atomic access. http://arduino.cc/en/Reference/NoInterrupts http://arduino.cc/en/Reference/Interrupts

On the assumption that the AVR is an 8-bit processor, I'll update the code and re-release it to SparkFun, if I can get the tools together to rebuilt it, and reflash the LCD backpack.

Thanks for confirming about the processor. I have the assembly listing and sure enough, the 16 bit index is accessed with two instructions -- the perfect setup for bugs. Unprotected pointers only work for circular buffers if the pointer/index accesses are atomic, and they aren't.

I have a couple of Arduino processors (one small, one Mega), and I've seen references to using one as an AVR programmer. How do you flash code into AVR chips?

There are some other changes I'd like to make if there is code or data space to do so. One would be to make the buffer be 512 bytes to make the index wrapping code simpler. Another would be to make the command intro character be displayable (such as by doubling it). A third would be to add some kind of X-on/X-off protocol so that the sending side needn't guess how fast to send characters.

BTW, nice to meet you, and thanks again for the response.

-- Carl

I've modified the code to, I hope, work a little more strongly. The changes are:

  1. change the input buffer to a real 512 byte circular buffer,
  2. implement X_ON/X_OFF, with
    a) periodic X_ON sent in case it was lost in the receiver.
    b) X_OFF point of 3/4 buffer size
    c) X_ON point of 1/2 buffer size

With the changes, the data size (BSS) is slightly larger, and the program (TEXT) size is about 800 bytes smaller.

If I success in flashing and running this (and if it fixed the bugs I was chasing), I'll send the code back to SparkFun. Aside from SparkFun, is there another common repository that code should be checked in to?

Next step is to build a way to program the chip on the LCD backpack. I'll try the "Arduino as ISP" hack mentioned several places around the net.

Of course, it must be debugged, too. :slight_smile:

-- Carl

I have a couple of Arduino processors (one small, one Mega), and I've seen references to using one as an AVR programmer. How do you flash code into AVR chips?

http://arduino.cc/en/Tutorial/ArduinoISP