PDA

View Full Version : Trouble with Serin2 and variable size



Ryan7777
- 30th September 2006, 08:26
Hi all,

I need help with serin2, Im using a pic16F648A to control a parallel 20X4 LCD
with the famous chipset everyone knows and loves. the problem is that when i try to receive serial data (sent from a BS2p) i only seem to get a bytes worth of data tho i have my holding variable set to a word. I PBP alot but never really messed with serin much, I know people dont like treading into the whole parallel to serial LCD conversion waters because someone makes alot of money making these things, but come on, its hobby electronics! i just want to get some serial data in and some words on an LCD out.. no big deal.
I've tried using DEC, not using DEC, in both Pbasic and PBP, i've tried using STR variables in PBP and get gibberish out of the LCD.. i'd like to be able to use all the characters on my display! please, someone help.

my BS2p Code: (for testing, not for my end use)

PAUSE 2000
main:

SEROUT 0,17405, [DEC 0] ' displays on fine as long as DEC is in PBP code
PAUSE 1000 ' in front of variable "holder" both in serin2 and
' LCDOUT

PAUSE 1000
SEROUT 0,17405, ["hello"] ' only get the "h"

SEROUT 0,17405, [DEC 255] ' same as DEC 0, get it just fine

PAUSE 1000
SEROUT 0,17405, [DEC 266] ' displays as 6....

SEROUT 0,17405, [DEC 65535] ' wrap around i guess? 65528 is displayed!
PAUSE 1000
GOTO main

My PBP code: (again.. not final)

CMCON = 7 ' Turn off un-needed PIC hardware
VRCON = 0
CCP1CON = 0
INTCON = 0

holder var word

pause 1000

Main:
PAUSE 1000 ' allow LCD to self-initialize first
LCDOUT $FE, %00110000 ' send wakeup sequence to LCD
PAUSE 5 ' pause required by LCD specs
LCDOUT $FE, %00110000
PAUSE 0 ' pause required by LCD specs
LCDOUT $FE, %00110000
PAUSE 0 ' pause required by LCD specs
LCDOUT $FE, %00100000 ' set data bus to 4-bit mode
LCDOUT $FE, %00001100 ' display on without cursor
LCDOUT $FE, %00000110 ' auto-increment cursor
lcdout $FE, 1
pause 1
lcdout "waiting on BS2p" ' displays on LCD just fine!
goto main2:

main2:
holder = 0

serin2 PORTB.0, 16780, [dec holder] ' required to get decimal numbers out!
' else LCD displays junk, or ASCII?
lcdout $FE, 1

pause 10

lcdout dec holder ' dec needs to be there or junk comes
' out of LCD, never get any more
pause 2000 ' from a word than the first using
' anything!
goto main2:

DynamoBen
- 30th September 2006, 18:14
First off, it is much easier to deal with bytes and convert bytes into words as you need to. In the past when doing this sort of thing I have used a byte array. The issue with a word variables is that when you receive one byte the routine can stall because it’s expecting a second byte.

The second thing you will want to utilize is the timeout for SERIN2. The reason is if something should occur the program can bailout and continue functioning.

Finally, if you can use HSERIN it will make things easier. Yes you will need supporting hardware for RS-232 (MAX232) but its worth it because the onboard UART has a two byte buffer. In addition, your main code continues to run and receives data based on interrupts; you're not polling the serial pin all the time to recieve data. When you poll you run the risk of missing something.

Below is some sample code. You can adjust it as you see fit. You could receive bytes one at a time with a loop; this would allow you to keep track of the overall length of the incoming packet. Once you received the packet, you can act on it as you see fit.

holder var BYTE[20] ' There are generally 16 or 20 char per line

serin2 PORTB.0, 16780, Data_Error,[STR holder\20\13] ' receive terminates when a CR is received

lcdout $FE,1,STR holder\20

Data_Error: ' Bail-out for the serial command
return

sayzer
- 30th September 2006, 18:46
Hi DynamoBen,

What I understand from your explanation is that if there is nothing coming from Serin pin, then program will keep waiting until something starts coming in. So that the next instruction can be executed.

If my understanding is correct, then in Ryan7777's case, while there is nothing incoming, the next lcdout line will never execute; thus LCD will not show anything.

Am I right? I had something similar but I did not catch the reason. May be this is why.

DynamoBen
- 30th September 2006, 18:52
sayzer, that is correct. I'm not entirely sure that is the problem that Ryan7777 is having, but he will experience it at some point.

Providing a timeout make the code more resilient to problem as they occur.

Darrel Taylor
- 30th September 2006, 21:01
Ryan,

Serial to Parallel LCD is one of the easiest things you can do with a PIC. But you're making it harder than it needs to be.

All of the initialization of the LCD is handled by PicBasic Pro. You don't need all that stuff in-between Main: and goto main2.

Simple initialization...
LCDOUT $FE, 1
PAUSE 500

Next, you are sending ASCII numbers from the BS2, so they are ready to display. Converting the ASCII to a WORD, then converting the WORD back to ASCII is counter productive and just waists time that you need since the data is comming in faster than it can do the conversions.

Also, by converting to words, it eliminates the possibility of sending Commands, which you'll need to do, to move the curson to where you want to put the text.

All you really need to do is receive 1 byte at a time, and pass it on to the LCDOUT command.
LCDloop:
SERIN2 PORTB.0, 16780, [INbyte]
LCDOUT INbyte
GOTO LCDloop

While that will get you closer to what you want, you really should use the USART with HSERIN. There's not much time between incomming characters, and if they are sent too fast from the BS2 (can't imagine a BS2 being FAST), you might miss a character. If that happens you can add some CHAR Pacing on the BS2 to slow things down a bit. But if you use HSERIN, you won't have to worry about it.

For the USART, you don't need a MAX232, just make the BS2 send RS232 in TRUE mode, instead of inverted.

Ryan7777
- 5th October 2006, 08:04
thank you all for the replys!
You guys sure do love the usart, I'll more than likely be using it, but for now im using serin2. Im using the internal osc and i was told the USART can cause problems if running at 4mHz, also i dont feel like extra hardware while just playing around on the breadboard.. (i.e Xtal, MAX232 and all the caps... ) but i will keep it in mind when i move on to building something final. also dont need the time out yet, im still trying to get a grasp on the code at hand, there wouldnt be anywhere to jump to atm... the following code is working as before, (T.Y. Ben) i still get garbage after my text like:

hello█ █ █ █ █ █ █ █ █ █ █ █ █ █

which im guessing is the leftover array bytes all set to zero, which is a predefined character in my LCD which happens to be a big black block with some of its upper pixels missing (?) any idea's how to get around that? (getting rid of holder = 0 does nothing, still get the same result)

also if i do what Darrel says, what do i send the PIC? could you give me an example of what i should be sending it, and what will come out on my LCD?
maybe $48,$45,$4C,$4C$4F (hello)?


holder VAR BYTE[20]
LCDOUT $FE, 1
PAUSE 1000

main:
holder = 0
SERIN2 PORTB.0, 16780, [ str holder\20\13]
LCDOUT $FE,1, STR holder\20
PAUSE 2000

goto main:

BS2p Pbasic Code:

Start:
SEROUT 0,17405, ["hello",13]
PAUSE 1000
GOTO Start:

DynamoBen
- 5th October 2006, 17:40
A couple of things about what you have.

First off holder=0 doesn't really do anything. I would suspect you were hoping it would make all the bytes 0 in the array. That isn't the case. You would need to create a loop that places a zero in each byte of the array. Second, you don't have a timeout. Without a timeout, you run the real possibility the code will stall.

I altered the code to address some of the issues you are running into. Keep in mind there are a least 3 different ways (maybe more) to accomplish what you are asking. It’s really a matter of style and application, neither of which I can decide for you. In this version of the code, I added length and command. Command handles the command portion of LCDOut (see manual). Length tells the string command when to stop. This should eliminate the blocks. Using this approach, you need to expand the string you are sending from the stamp. (See below) If you didn’t want to specify a length you would need to create a loop to collect the data byte by byte and then use the terminating character that was in the code before. Here again both work, it depends on style and application. Enjoy.




Holder var byte[20]
Length var byte
Command var byte

main:
serin2 PORTB.0, 16780, Data_Error,[Command, Length ,STR holder\20\Length]
LCDOUT $FE,Command, STR holder\Length
goto main

BS2p Pbasic Code:

Start:
SEROUT 0,17405, [1,5,"hello"] ‘ 1=LCD Clear, 5=Length of hello
PAUSE 1000
GOTO Start



In regards to HSERIN, like the rest of us you will eventually run into a problem and you will need to use hserin to solve it. Usually this occurs when your code starts doing other things and polling for serial data becomes impractical. We all get there at some point.