SparkFun Forums 

Where electronics enthusiasts find answers.

Have questions about a SparkFun product or board? This is the place to be.
By PhracturedBlue
#5827
I purchased a SerLCD a while back (it is definitely a 1.1 despite having v2.0 silkscreened on it), and I have finally gotten around to starting the project that will actually use it.
I'm writing my code in C, as it will get large, once it is completed, and it is a nicer environment for me to work in.

So far, my test involves sampling the A/D converter every 5 seconds, and writing the output to the LCD as hex.

the code loop looks like this:
Code: Select all
	sendChar(0xFE);
	sendChar(0x01);
    while(1)
    {
		set_bit(adcon0, GO_DONE); //start A/D
		while(! test_bit(flags, SAMPLEREADY) && ! test_bit(flags, ADREADY))
			;
		sendChar(0xFE);
		sendChar(0x01);
		if(led_on) {
			clear_bit(porta, 2);
			led_on=0;
			sendChar('0');
		} else {
			set_bit(porta, 2);
			led_on=1;
			sendHexByte(adresh);
		}
		flags=0;
    }
The interrupt routine takes care of setting 'flags', and sendChar just waites for TXIF, and loads the value into TXREG. The led istuff is just temporary for visualization (led attached to RA2). sendHexByte converts the value into a hex representation (00-FF) and calls sendChar twice.

The problem is that with the above code, I only ever see a single character displayed on the screen (if the A/D converter is reading 0x34) I get '3'. Now If I remove the screen-clear in the loop, it displays everything correctly (but of course does not reset the display) like 34,0,34,0,.... I can also add a set of 'cursor-forwards,cursor-back' commands inside sendHexByte(between sending the 1st and 2nd character), and everything will display correctly with the above code (alernating 34 and 0).

I am using a 16F88 with the 8MHz internal clock. I have looked over the assembly code, and the copiler hasn't done anything screwy. I don't have a logic-analyzer handy, but I think I can see both bytes being sent (as opposed to the single '0' I use as a reference)

This is my first foray into PIC programming, and my first attempt at using the SerLCD, but I'm getting kinda frustrated, and I can't seem to figure out what is wrong.

In case it is useful, here is the sendHexByte code:
Code: Select all
void sendHexByte(char n)
{
    char h;
    h=(n>>4)&0xF;
    n=n&0xF;
    if( h>=10 )
        sendChar((h-10)+'A');
    else
        sendChar(h+'0');
//	sendChar(0xFE);
//	sendChar(0x14);
//	sendChar(0xFE);
//	sendChar(0x10);
    if( n>=10 )
        sendChar((n-10)+'A');
    else
        sendChar(n+'0');
}
Any ideas what might be wrong?
User avatar
By sparky
#5887
Start simple. The SerLCD receives serial characters, so get your PIC to output the letter 'r' every second to the UART. You should be able to connect a MAX232 circuit and verify that the PIC is outputting the letter 'r' to a terminal window on your computer.

Setting up the PIC UART correctly is 90% of the battle. Once you've got this proven, rip out the MAX232 circuit and attach the SerLCD to the PIC's UART. Power up the circuit and you should get 'r' displayed one after another, every second, on the LCD.

Once you have this, you're home free. Setup your firmware to do whatever and output to the UART - which will then be displayed on the LCD.

-Nathan
By PhracturedBlue
#5909
sparky wrote:Start simple. The SerLCD receives serial characters, so get your PIC to output the letter 'r' every second to the UART. You should be able to connect a MAX232 circuit and verify that the PIC is outputting the letter 'r' to a terminal window on your computer.

Setting up the PIC UART correctly is 90% of the battle. Once you've got this proven, rip out the MAX232 circuit and attach the SerLCD to the PIC's UART. Power up the circuit and you should get 'r' displayed one after another, every second, on the LCD.

Once you have this, you're home free. Setup your firmware to do whatever and output to the UART - which will then be displayed on the LCD.

-Nathan
Actually, I do't think the issue is with the UART. I can send 'r' quite easily to the SerLCD moule, and that works great. It is specific to the '0xFE 0x01' instruction. If I send for instance:
0x01 0xFE 0x30 0x31 0x32

which should do a screen-clear followed by '123' I get a screen clear followed by '13' (the 2 gets dropped)
If I send one character per second, it works correctly (I get screen-clear, '123'). If I don't send the screen-clear (just use move cursor commands) I can send the characters as quickly as I like and they all get displayed. So it is seems that the serLCD module wants me to pause after a screen-clear. My solution at the moment is to always send a 'space, backspace' command after a screen-clear, which appears to work acceptably, it is just unexpected.
User avatar
By sparky
#6063
Hi,

It's been awhile since I've played with the SerLCD. Looking over the datasheet, you're sending the command before the 254 opening.

You have to send 254 (0xFE) first to let the LCD know a command is coming, then send whatever command, 0x01 clear screen in this case.

Clear screen is one of the slowest commands that you can issue (~100ms if memory serves, check the datasheet). It's can be better to send ' ' characters (white space) 16 times than it is to clear the screen.

-Nathan
By PhracturedBlue
#6162
Thanks, yeah I've bascially just been sending (16-#char) spaces when writing to the screen. this seems to work well so far (btw, I was sending 0xFE before the 0x01, in case it wasn't clear). I hadn't looked at the code, but I assumed that the serLCD would buffer the commands such that i could send them immedately following each other, rather than waiting for the LCD to respond. But, regardless, I have my system working pretty well now. If only I had realized that the EMI from switching a 240V relay was going to cause me problems, I could have this whole thing working already, rather than having to wait for a solid-state relay to arrive....I hate EMI

In a slightly different vein, I am planning on using the single uart on the 16F88 to drive both a TLPA and the serLCD module. Unfortunately the serLCD runs at 9600BPS, and the TLPA can ony handle 4800. Actually, it's not really a huge deal, as I don't want to broadcast to both at the same time (sending different info to each)

My current plan is to use a Maxim 4544 SPDT digital-controlled switch to select the source. Is there a way to do this without needing aditional coponents? (I know I could have built a switch with two transistors, but why bother)