Our new official repo is on github
LCD Smartie version 5.6 is released!
Download it now: https://github.com/LCD-Smartie/LCDSmartie/releases

Atmel serial backpack

Discussion about LCD's and other related hardware

Moderators: _X7JAY7X_, caesar, IFR, mattcro, limbo, Fast351, hydrolisk1792

ReverseEngineered
Plugin Author
Posts: 192
Joined: January 18th, 2006, 11:09 pm
Location: Saskatoon, Saskatchewan, Canada

Post by ReverseEngineered »

Currently the micro's clock is at 16MHz while the UART is communicating at 9600bps.

I have stripped the code down to essentially nothing (polling read of the UART buffer, writing any bytes to the LCD as soon as it reads them (using more-than-ample delays at each point), and if I even write a string of 20 X's through a terminal application, it will (usually) cause the micro to reset. Why? I don't know. The most I've been able to tell is that it ends up in random parts of the code. For example, I tried rewriting the UART receive ISR to check that the receive was successful, and to print a . (period) if it wasn't, then hang in an infinite for loop. Believe it or not, I was able to trigger this multiple times. The stack is used very little (the main loop is one large function that does nothing, the ISR makes no calls other than the write to the LCD, which is also one large function). I've checked the assembly and interrupts are disabled during this ISR.

How is ANYTHING causing a code jump inside of this for loop? No idea. Perhaps there's noise somewhere, or perhaps there's an error in the micro that I'm unaware of (there is no pulished errata, but the micro itself could be damaged). My only other mega16 has a bad spot in the flash memory, so I can't swap and test at the moment (more on the way soon).

Once I can get this problem solved, the rest works perfectly. As long as I'm not sending data as fast as I can, all of the commands I have implemented so far work flawlessly (using the changes I have made since the published demo code I gave you). I even implemented a 16-byte FIFO to try to decrease the number of lost bytes, and though this made it harder to crash, it still did, even though a buffer overflow was never detected. Other than a hardware problem, I'm fresh out of ideas.


Once I have a couple more micros in hand I will get back to work on it. The week of Feb 15th I have off of school, but until then I'm in the midst of midterms, so I won't be making much more progress until then.

If any other people knowledgable in AVRs sees any significant error in the demo code (aside from my misunderstood LCD initialization sequence), please let me know. Perhaps it can help me hunt this bug down and bite it in the ass.

penjuin
Hardware Genie - Plugin Author
Posts: 42
Joined: June 28th, 2005, 3:42 am
Location: Australia

Post by penjuin »

Can you send me a copy of the stripped down code? Ill compile it for one of my unused mega8s and then we'll know if the micro is the problem. Do you use a max232 or some kind of transistor setup?

Ever heard of header files? :P The code might be a lot easier to understand for other people if the functions were arranged in a few headers.

How is the atmel getting arguments? If it isnt, you might want to change

Code: Select all

int main(int argc, char *argv[]) 
to

Code: Select all

int main(void)

_X7JAY7X_
Hardware Genie - Plugin Author
Posts: 374
Joined: February 16th, 2005, 10:24 pm
Location: Michigan

Post by _X7JAY7X_ »

I was looking at your code. I havent done C in a while but everything looks fine. Mine is written in basic and I have it like this:

LOOP
GET DATA 'from UART

IF DATA = 254 THEN

COMMANDS

END IF

PRINT DATA
GOTO LOOP

You wrote the LCD functions yourself? Are you sure that the timing is correct? You should not need a FIFO stack.

J

ReverseEngineered
Plugin Author
Posts: 192
Joined: January 18th, 2006, 11:09 pm
Location: Saskatoon, Saskatchewan, Canada

Post by ReverseEngineered »

Sorry I haven't responded in a while, been busy so haven't had a chance to look into it more.

Yes, I'm well aware of header files, it was just testing code. Normally I would seperate things better, but after getting it to the point where I was satisfied that it worked for me, I wanted others to give it a quick shot. You will notice near the top that I do have a list of function declarations, but yes, they should be (and will be) put into a seperate header file as I progress through everything.

As for the arguments, I've found that gcc complains if you change these; obviously there are no arguments used, so the compiler just optimizes them away, but you are correct in saying they really have no place there--it's just to apease the compiler.

The BASIC you have there is essentially what my ripped down code is. Unfortunately, by the time I wrote that post I had ripped my code down so much that there was nothing left (or at least nothing worth posting). As soon as I get some time (probably starting this weekend), I will clean everything up and start doing some bottom-up testing, making small modules and working my way up from there (as I usually do). I had some ATmega8's come in today (my supplier is backordered on mega16's at the moment), so I'll be sure to convert the code over to that and try again. Shouldn't take much, just need to double check the register names.

Yes I wrote my own LCD code, mainly because most of the LCD code out there is only 4-bit, which I'm not particularly a fan of. I originally used busy-flag checking to determine when to return from a function. In the testing I changed this to delay loops, which were all the next-integer above the values given in the datasheets (listed as 40us for simple commands, 1.64ms for longer operations). I didn't appear to have any problems with missed commands or anything. The major problem was that the micro would reset, and do other strange things (like somehow jump out of an infinite loop, even with interrupts disabled). Definitely sounded like a hardware problem. If I had a scope I would have checked to ensure I didn't have really bad noise in the power supply (wouldn't be the first time bus contention has killed me). Perhaps tomorrow after school I'll toss it on the scopes here and see what's happening.

As I had mentioned before, this week is all midterms, but next week I have off, so I'll be able to make lots of progress. I fully plan on being finished by the end of next week (took me that long to make an entire learning-remote in assembly, without any prior knowledge about micros).

Hopefully I'll have a chance to take a stab at it tonight or tomorrow evening. I'll let you know how things progress, and I'll try to get some cleaner, more useful code up here soon (what I posted before is already quite out of date compared to what I have at home).

_X7JAY7X_
Hardware Genie - Plugin Author
Posts: 374
Joined: February 16th, 2005, 10:24 pm
Location: Michigan

Post by _X7JAY7X_ »

Do you have a watchdog timer on the ATMEGA? If so is it disabled?

J

_X7JAY7X_
Hardware Genie - Plugin Author
Posts: 374
Joined: February 16th, 2005, 10:24 pm
Location: Michigan

Post by _X7JAY7X_ »

Reverse how is your matrix display coming? You have a working version yet?

J

ReverseEngineered
Plugin Author
Posts: 192
Joined: January 18th, 2006, 11:09 pm
Location: Saskatoon, Saskatchewan, Canada

Post by ReverseEngineered »

I've been busy with other things unfortunately (as I half expected).

My first step will be to convert a few things so that we can use it on the ATmega8. I'm doing this because it's more appropriate for this purpose, other people have them available, and my ATmega16 shipment is on backorder.

I'm also working on several other things at the moment, so my only breadboard has been rather full. I just finished picking up lots of supplies (including PCB making materials), so I should have more than just working code for you (schematics and PCBs as well).

This moment's project is making a simple PCB with a MAX232 on it, so that I can plug serial into my breadboard whenever I need it. Unfortunately, life has been intruding on my schedule the last few days. I plan on immersing myself in it tomorrow and being finished by Friday. I'll let you know more as time goes on.

ReverseEngineered
Plugin Author
Posts: 192
Joined: January 18th, 2006, 11:09 pm
Location: Saskatoon, Saskatchewan, Canada

Post by ReverseEngineered »

Alrighty, finally had a chance to sit down and setup my ATmega8. It can now use the ATmega8 (just needed to change a couple pins, since it has fewer than the 16), and it's no longer crashing (must have been a bad chip).

As in the test code I showed you, it uses an 8-bit interface and only supports basic commands (clear, home, and set position). I'm working on a "set character" command at the moment. With that, we should have nearly enough to finish. All I have to add on after that is a PWM output for adjusting the screen brightness. Unfortunately the ATmega8 doesn't make this easy (the only 8-bit port is the same one that contains the PWM output pins), so I'll have to suck it up and bit-bang the output from a timer interrupt. Not a big deal, since the frequency can be quite low (60Hz can't be seen, especially from an LED backlight). I just have to make sure that interrupts are still enabled inside of this interrupt, since we want to be able to process serial requests as fast as possible. (Though at 9600bps, the processor is more than capable of finishing the entire timer interrupt before another byte comes).

I don't plan on sleeping tonight until the character generation is done. PWM should be a snap. So in other words, I expect it all to be finished tonight. I'll post again in the morning, hopefully with a schematic, tested PCB layout, and working code.

ReverseEngineered
Plugin Author
Posts: 192
Joined: January 18th, 2006, 11:09 pm
Location: Saskatoon, Saskatchewan, Canada

Post by ReverseEngineered »

Okay, so, everything works beautifully.....well, almost. All the necessary commands are recognized, it can handle 38400 baud, and it even has contrast and backlight adjustments (using PWM).

So what's the problem? Well, bit-banged PWM is hardly stable, and this is no exception. I didn't realize just how high of a frequency it would take to achieve good PWM output, and because both the contrast and backlight wires actually consume considerable currents, making a smoothing filter isn't much of an option either.

The problem I am having is that, the faster the interrupt is triggered, the better the output is, but the more often it "drops out". It appears as though the interrupt is being retriggered (which isn't unbelievable considering it's an 8-bit timer overflow at full clock speed, 256 cycles). The weird thing is though, this is my only interrupt, and it only happens when the chip is receiving a lot of data (sound familiar?) I'm continuing testing to see if I can get that fixed, and if not, I might have to change things around so that I can use the PWM pins (which would work for sure, but requires so effort to relocate the existing signals).

Other than that though, the minimum set of features work wonderfully. The rest of my day is shot (I started writing this around 3PM...it's now 9:30PM), so I won't be getting time to finish it. However, I do plan on working on it as time permits. Hopefully tomorrow night I'll post the basic version, without the PWM stuff.

ReverseEngineered
Plugin Author
Posts: 192
Joined: January 18th, 2006, 11:09 pm
Location: Saskatoon, Saskatchewan, Canada

Post by ReverseEngineered »

Link: mo-simple.zip

Alrighty, here's what I've got. This is "mo-simple"; just the basics that you need to get by (including the backlight on/off functionality). This works beautifully with LCDSmartie.

I don't have time to make a schematic yet (talk about a pain in the ass), but the hookup is really easy to do. The actual pin connections are listed in mo-simple.h. You'll want/need to have the ATmega8 datasheet handy for its pinout. Hook a MAX232 up between your serial cable and the RXD/TXD pins on the micro. The LCD pins DB0-DB7 go to PB0-PB7 of the micro. Yes, two of these are your XTAL pins, so you have to enable the 8MHz internal oscillator (change the low fuse byte from e4 to e1). RS is PC0, R/W is PC1, and E is PC2. You're on your way.

The PC3 output will allow you to control the backlight, but you can't hook it up directly (not enough current). I found my backlight ran without a resistor at 5V, so this is what I did. Grab any old NPN transistor (I used a 2N3904). Hook PC2 up to a 100ohm resistor and that to the base of the transistor. Hook the emitter to ground and the collector to Pin 14 (backlight cathode) of the LCD. Hook Pin 13 (backlight anode) to 5V. This should work. If you need a resistor (you should try one first, just in case), hook it up between the collector and Pin 14.

As long as you have the low fuse set to get an 8MHz oscillator and you don't mind using 38400 baud (the highest available at the moment), just program the .hex file onto the micro.


I realize these instructions are far from fool-proof, but I will be drawing schematics later as I get time. I will get those ready before I continue developing more features in the code (which will undoubtedly require switching back to 4-bit I/O).


Check back periodically for "mo-cool" and "mo-complete". :P


PS: If you plan on trying to build this yourself, make sure you have the absolute latest version of WinAVR (at least 20060214). They have finally caught up and used all the latest libraries (which means we can use the cool new chips). If you are compiling under Linux, edit the Makefile appropriately, and make sure you have atleast avr-libc-1.4.2 and gcc-3.4.5.

_X7JAY7X_
Hardware Genie - Plugin Author
Posts: 374
Joined: February 16th, 2005, 10:24 pm
Location: Michigan

Post by _X7JAY7X_ »

Rev you may just make me work on mine some more. This atmel version is coming along quickly. Whats next for yours? What displays are supported?

J

ReverseEngineered
Plugin Author
Posts: 192
Joined: January 18th, 2006, 11:09 pm
Location: Saskatoon, Saskatchewan, Canada

Post by ReverseEngineered »

It should work with any <= 80 character displays. Making it work with 40x4 displays should be a simple fix (just need to start keeping track of which line I'm on and toggling an extra ctrl pin).

As soon as I convert everything to 4-bit (working on that at work right now, even though I can't test it with LCDSmartie on my laptop) I should be able to use the output compare pins and do PWM to adjust brightness and contrast. After that GPO pins and keypad input would be nice, but that will require porting it back to the ATmega16, which I plan on doing anyway when my shipment comes in (much easier to work with all those extra pins). Finally, I want to implement the entire MO command set, as it is in the LCD204 (which I noticed has some errors; set brightness should be 152, not 153).

So, there's a lot more to go, but what we have at the moment should work for most people who just want a simple interface. I'll probably keep two versions: one on a chip like the ATmega28 that is small, cheap, uses 4-bit I/O, and just provides what I have right now (mo-simple). Then I'll have an ATmega16 version (or some other 40-pin chip) that does everything, including GPO and keypad inputs (mo-complete). That will all come in time.

If you're looking at doing similar work with your PIC version, feel free to use my code. It's all in C, so it should be a simple matter of changing the base routines and the rest should "just work". Note that what I've posted right now is still beta (considering I haven't put my name on it yet, and haven't written seperate documentation). Once I'm satisfied that it works on all displays, and after I move to 4-bit I/O, I'll release a final version, which I will announce and make a website for.

In the mean time, feel free to use parts of my code, and please try it with as many displays as possible. I'd like to make sure that it works 100%, but my resources are limited (I have a 16x1 and a 20x4, that's it).


As before, expect to see schematics and PCB layouts once the code is finalized.

_X7JAY7X_
Hardware Genie - Plugin Author
Posts: 374
Joined: February 16th, 2005, 10:24 pm
Location: Michigan

Post by _X7JAY7X_ »

I already have a stable and long-tested BASIC version. I do not use C compilers. I will be working on integrating the 40x4 display and GPO ports, then on to buttons.

J

ReverseEngineered
Plugin Author
Posts: 192
Joined: January 18th, 2006, 11:09 pm
Location: Saskatoon, Saskatchewan, Canada

Post by ReverseEngineered »

After reverse engineering the 4-bit initialization sequence (man is the online documentation ever sparse), I have 4-bit I/O working with the PWM brightness and contrast outputs. I'm just about to test it with LCDSmartie, but so far the output has been beautiful. Helps when the PWM frequency is 30kHz instead of 2kHz, and when it's all done automatically in the backgound by the waveform generator.

I have started into "mo-cool", which uses the PWM with 4-bit I/O above, has a single GPO pin, and implements many of the advanced MO commands (all of the cursor movement commands so far, perhaps the bar graph and big digit commands as well). I expect it will completely emulate the LCD2041. Then the next step to "mo-complete" will be 8-bit I/O, 8 GPO pins, keypad inputs, and 40x4 display support (is this really common?).

Ah yes, and I already noticed one problem with "mo-simple": I forgot to check for the underline/block cursor commands! They are written, just didn't check for them in the main loop. Oops! Easy fix, should have that updated tonight. Other than that, only testing and schematics tonight. I'm going to see if I can't build a PCB tonight (though I only have a couple of hours to spare).

_X7JAY7X_
Hardware Genie - Plugin Author
Posts: 374
Joined: February 16th, 2005, 10:24 pm
Location: Michigan

Post by _X7JAY7X_ »

Reverese, I started working on my PIC version somemore. I got the contrast and backlight working on PWM pins. I have the GPO setup but it doesnt work right. I was wondering what command you have for the GPO and how you are testing it in smartie, since apparently the only way to activate a GPO is in the actions.

J

ReverseEngineered
Plugin Author
Posts: 192
Joined: January 18th, 2006, 11:09 pm
Location: Saskatoon, Saskatchewan, Canada

Post by ReverseEngineered »

I haven't implemented the GPO so far, but I have noticed a discrepency in the specifications from the MO manuals. For the LCD2041 (which has one GPO pin), it shows that the GPO command has no parameters. However, in the later command summary it shows a single parameter (the GPO number), but does not specify the range. In the LK204 manual, it does list this as having a range of 1-6. I presume this is how LCDSmartie implements it. I found a similar error with the LK204 description of the backlight brightness command (it says 152, but should say 153).

Once I get home tonight I'll toss in a single GPO and see if I can get it working (actually, it's already written, just not tested).

_X7JAY7X_
Hardware Genie - Plugin Author
Posts: 374
Joined: February 16th, 2005, 10:24 pm
Location: Michigan

Post by _X7JAY7X_ »

I have 4 GPO pins right now. I got them to work once through smartie by putting in the action if file(log.file) = 1 then GPO(4,1) or whatever. I then manually changed the log.file from 0 to 1. The GPO turned on once and that was it. It is weird. I will look at it more later tonight or tommorrow night.

I do not know if I am going to implement the 4x40 LCD support unless I get someone that wants it. Mainly for the fact that it will use another pin and I would rather use that pin for a GPO or a button. I was thinking that I could make a simple program that could change a EEPROM bit in the micro, if the bit is true use a pin for 4x40 if it is false use it for a button or GPO. This is a long way off though.

J

ReverseEngineered
Plugin Author
Posts: 192
Joined: January 18th, 2006, 11:09 pm
Location: Saskatoon, Saskatchewan, Canada

Post by ReverseEngineered »

Your idea with the EEPROM bit is essentially how I plan to go about it. However, I also plan on using the ATmega8515 for the final one (mo-complete), which, with 40 pins, should be able to provide every single function mentioned (6 GPOs, 10pin keypad connector, 4bit LCD, etc). I'll have to draw that out first before I know for sure, but should worse come to worse, I'll use EEPROM bits to choose between (for example) GPOs or a keypad connector.

_X7JAY7X_
Hardware Genie - Plugin Author
Posts: 374
Joined: February 16th, 2005, 10:24 pm
Location: Michigan

Post by _X7JAY7X_ »

A 40 pin chip would solve alot of problems but I am trying to keep the cost down. That was why I originally used the 16F628A. It cost like $2 and has in internal oscillator. I am using a mid-priced 28 pin chip now but with the LCD using 7 pins, the 2 pwms, the uart(s)... there isnt alot left. I see the MO has it where you can use the pins as either Buttons or GPOs. It is interesting, but makes the programming a bit more complicated and it is nice to have a complete port of GPOS or buttons. The good thing about using a 40 pin, say the 16f877 is that I can use a bootloader with it and it can be reflashed without a programmer. However, that would take a bit of doing with my compiler.

J

ReverseEngineered
Plugin Author
Posts: 192
Joined: January 18th, 2006, 11:09 pm
Location: Saskatoon, Saskatchewan, Canada

Post by ReverseEngineered »

Ah yes, that's an excellent idea. Incorporating a bootloader with the AVR is a little more difficult than with the PIC, but not by much. It would certainly be a good learning experience. :D

I know what you mean by the 40-pin devices being expensive. The 40-pin ATmega16 is $8.16 CDN, while the ATmega8 is only $4.54 CDN. Of course, I could use the ATmega8515, which is 40-pin, a little easier to get ahold of, and only $6.54. Changing from the 16 to the 8515 wouldn't be too difficult. Flash memory definitely isn't a problem (mo-simple is < 1k).

Your reason for avoiding 40-pin chips is exactly why I am creating 2 or 3 different versions. That way somebody could use a smaller, cheaper, easier to build circuit, or could use the more expensive but complete version.

One thing to keep in mind with the keypad is that RS232 is supposed to be -12V to +12V. While the zener trick works at bringing these levels down to TTL at a low cost, this only works for receiving. There is no simple way to bump the voltages back up to RS232 levels to send to the computer, which is required for sending back the keycodes. Considering the cost of a MAX232 ($4.11 CDN, unless you can get the cheaper version from TI), the extra cost of a 40-pin chip shouldn't be a limiting factor.

_X7JAY7X_
Hardware Genie - Plugin Author
Posts: 374
Joined: February 16th, 2005, 10:24 pm
Location: Michigan

Post by _X7JAY7X_ »

Yes, I was thinking about making my simple version have one GPO and a button or two with 4x40 support. Then if I have time use a 40 pin PIC. There is a cheap way to do RS232 conversion. Check out http://www.ise.pw.edu.pl/~wzab/picadc/picadc.html . I have made the simple one and it works fine. However, you have to make sure that the RTS and DTS lines are driven by the program. Smartie already does this.

Serial does not have to be +12v to -12v. It can be +5v to -5v. That is what most laptops use.

J

ReverseEngineered
Plugin Author
Posts: 192
Joined: January 18th, 2006, 11:09 pm
Location: Saskatoon, Saskatchewan, Canada

Post by ReverseEngineered »

Correct, it doesn't have to be +/-12, it could also be +/-5, 12 is just the standard. My original point though was that a negative voltage is necessary.

I looked at that PICADC, and that's a very interesting way of acquiring the negative voltage. It's feasible, but I think I might want to analyze what happens when the DTR/RTS line is driven negative (i.e. LCDSmartie is off, or the computer is restarted). I don't have time to look deeply into it, but at first glance it appears you will forward bias the base-collector; which could be very bad for the transistor. Either way, it's certainly a possible approach to reduce costs.

_X7JAY7X_
Hardware Genie - Plugin Author
Posts: 374
Joined: February 16th, 2005, 10:24 pm
Location: Michigan

Post by _X7JAY7X_ »

Are you having problems with the GPOs turning on and then off real quickly? I am thinking it may be something with smartie because the flash function works correctly. Limbo is looking into this but I was wondering if you were having a problem with this?

J

ReverseEngineered
Plugin Author
Posts: 192
Joined: January 18th, 2006, 11:09 pm
Location: Saskatoon, Saskatchewan, Canada

Post by ReverseEngineered »

Haven't had a chance. I'm installing Delphi 2005 at the moment (hoping to make a ULCD_KS, so that LCDSmartie can handle any KS0073 LCDs, which are actually kind of common). I just got my board all set up here, so I'll work on that next. I'll let you know within the next couple of hours.

ReverseEngineered
Plugin Author
Posts: 192
Joined: January 18th, 2006, 11:09 pm
Location: Saskatoon, Saskatchewan, Canada

Post by ReverseEngineered »

For your GPO problem, is your GPO pin sharing a port with one of your other pins (like the data or control pins?). If so, and you write to the entire port, you might change the value of your GPO pin. This was happening in my source code after I changed to 4-bit mode. To fix this, try using a line like this each time you write:

PORT = (PORT & ~MASK) | (VALUE & MASK);

Where PORT is the port you are writing to, VALUE is what you are trying to write, and MASK is a bitmask of the bits you are trying to write to. This is what I did to fix it.

I quickly added the GPO to my newer program (mo-cool) and it works fine now. The only quirk I noticed is that, when LCDSmartie sends the GPO commands, it sends them twice, i.e. says ON twice when turning on. I looked at ULCD_MO.pas and it doesn't seem to be coming from there. Perhaps it has something to do with the way the action itself is written? Not particularly important...

Post Reply