PDA

View Full Version : Another Serin/Serout Problem!



jmbanales21485
- 1st June 2007, 16:35
Hello All!

i, like many others, have a serin/serout problem, and after much research i have manged to get through 80% of it.

So i am planing on using my 16f688 PIC as an LCD driver and be able to communicate any other PIC to it via serial communication. (so i won't have to connect 6 cables to the pic anytime i want to use the LCD). I am using a 16 char by 2 line LCD

So far I have the serial communication working and am able to talk to the LCDDriverPic from any other PIC. The problem is how to determine the amount of characters i recieve from the pic.

for example on the transmitter side i have:
serout SerialOut, mode, ["LCD", $FE, 1, "transmit", CR]
i am transmitting at 2400 baud, sends "LCD" to initialize LCDDriver, and then sends the LCD commands, which in this case is $FE, 1, "transmit"

on the reciever i have :
serin2 SerialIn, mode, [WAIT("LCD"), testHEX, testHEX2, STR testSTR\16\CR]
I am receiving at 2400 baud, it will wait for "LCD" and receive the data. the string testSTR will receive 16 characters.

when i do this my LCD will display "transmit" (GOOD!!!) BUT will fill the remaining 8 slots with random characters (BAD).

so i need to know if there is a way of determining the last leter of a string sent or something that gives me an indication that its done transmitting so the receiving side won't fill the remaining characters with random. attached is a sample code that i have and works (except for the random characters issue)

thank you all in advanced!

skimask
- 1st June 2007, 16:51
on the transmitter side i have:
serout SerialOut, mode, ["LCD", $FE, 1, "transmit", CR]
i am transmitting at 2400 baud, sends "LCD" to initialize LCDDriver, and then sends the LCD commands, which in this case is $FE, 1, "transmit"

on the reciever i have :
serin2 SerialIn, mode, [WAIT("LCD"), testHEX, testHEX2, STR testSTR\16\CR]
I am receiving at 2400 baud, it will wait for "LCD" and receive the data. the string testSTR will receive 16 characters.

when i do this my LCD will display "transmit" (GOOD!!!) BUT will fill the remaining 8 slots with random characters (BAD).

so i need to know if there is a way of determining the last leter of a string sent or something that gives me an indication that its done transmitting so the receiving side won't fill the remaining characters with random. attached is a sample code that i have and works (except for the random characters issue)

thank you all in advanced!

Your answer is right there in the code you wrote!
Your transmit routine sends:
L, C, D, $FE, 1, t, r, a, n, s, m, i, t, CR
The last character of the string you sent is the character right before the 'CR' (ASCII code decimal 13).
Write a subroutine to search for that character and zero it out along with anything else past that character in the string.

jmbanales21485
- 2nd June 2007, 03:38
skimask,

i appreciate your quick response!

so i corrected the code so that it searches for the carriage return, CR, (ASCII 13) through the 16 character array it receives. I had it displayed every character one-by-one and it seems that it receives "0" (NULL) after the string is done.

for example, i send
serout SerialOut, mode, ["LCD", $FE, 1, "transmit", CR]

and i receive it and search for CR
serin2 SerialIn, mode, [WAIT("LCD"), testHEX, testHEX2, STR testSTR\16\CR]
for i = 0 to 15
LCDOUT $FE, 1, testSTR[i] 'display character in LCD
pause 1000
if testSTR[i] = 13 then 'CR = 13 ascii
last = i
goto proceed
endif
next i
proceed:
for i1 = 0 to last
LCDOUT testSTR[last]
next i1

I send "transmit" and i receive "transmit00000000"
its like it fills the remaining slots of the 16 byte array with zero's. I know there is a simple solution to this i just need someone to help me oversee this. am i passing the variables correctly? am i receiving the variables correctly? should i change the code entirely and start fresh? should i quit this problem and just go out somewhere?

any help is appreciated. thank you

skimask
- 2nd June 2007, 06:12
serout SerialOut, mode, ["LCD", $FE, 1, "transmit", CR]

20 bucks says you haven't given CR any definition...
Something like:
cr var byte : cr = 13......

EDIT:
And you're using CR as a 'STR' terminating character.
If you fix the TX part, and leave the RX part the same, I believe the CR will be thrown out, not sure about it though...

jmbanales21485
- 6th June 2007, 16:29
so after a couple of days of trouble shooting and debugging i finally got this LCD Driver thing to work. my problem was that i was using serout and needed to use serout2. with serout2 i can send ascii value numbers so if i send DEC 123, i will recieve the string "123" where as with serout if i send 123 i will receive "{" and i couldn't use the operator "DEC" with serout because the compiler would say that i have a syntax error.

so this is defenitely NOT the most effecient way of making an LCD driver but it works for me. i have to initialize serout2 everytime with the "start" string and end it with the "null" (ascii 0) character. i also changed it so that the LCD commands are as follows:
"$FE, 1" = 1
"$FE, 2" = 2
"$FE, $0C" = 3
"$FE, $0E" = 4
"$FE, $0F" = 5
"$FE, $10" = 6
"$FE, $14" = 7
"$FE, $80" = 8
"$FE, $C0" = 9

so here is my code:
===============Transmitter===============
Define OSC 4 'osc at 4 MHZ

TRISA = %000000 'PORTA.5 output rest input
TRISC = %111111 'PORTC INPUT
ANSEL = 0 '0 analog inputs
CMCON0 = 7 'comparators off

LCD var PORTA.1
T2400 con 396 '2400 baud

counter VAR WORD
counter = 1
loopa:
serout2 LCD, T2400, ["start", 1, 0] ' 1 = $FE, 1clear screan
pause 5
serout2 LCD, T2400, ["start", 9, "Second Line", 0] ' 9 = $FE, $C0
pause 5
serout2 LCD, T2400, ["start", 8, "counter = ", DEC (counter), 0] ' 8 = $FE, $80
pause 2000
counter = counter + 1
goto loopa
===============Reciever=================
Define OSC 4 'OSC at 4 MHZ
Define LCD_DREG PORTC 'Port for LCD Data
Define LCD_DBIT 0 'Use lower 4 bits of Port
Define LCD_EREG PORTA 'Port for Enable (E) bit
Define LCD_EBIT 4 'Port Pin for E bit
Define LCD_RSREG PORTA 'Port for RegisterSelect (RS) bit
Define LCD_RSBIT 5 'Port Pin for RS bit
Define LCD_BITS 4 'Using 4-bit bus
Define LCD_LINES 2 'Using 2 line Display
Define LCD_COMMANDUS 2000 ' Command Delay (uS)
Define LCD_DATAUS 50 'Data Delay (uS)

TRISA = %000100 'Set PORTA.0 as input rest output
TRISC = %000000 'Set PORTA as OUTPUT
ANSEL = 0 '0 analog inputs
CMCON0 = 7 'Disable analog comparator

SerialIn var PORTA.2 'Serial Input
mode con 396 '2400 baud

first VAR BYTE
initial VAR BYTE
last VAR BYTE
i1 VAR BYTE
testSTR VAR BYTE[30]

i1 = 0
pause 1000
lcdout $FE, $0F 'clear screen
lcdout $FE, 1
LCDOUT "LCD WORKS"
pause 2000
LCDOUT $FE, 1
begin:
serin2 SerialIn, mode, [WAIT ("start"), STR testSTR\30\0]
for i1 = 0 to 29
if testSTR[i1] = 0 then
last = i1
i1 = 29
endif
next i1

first = testSTR[0]
initial = 0
last = last - 1

if (first >= 0) and (first <= 9) then
initial = 1
endif
if (first >= 10) and (first <= 15) then
initial = 2
endif

if first = 1 then
LCDOUT $FE, 1
GOTO writeW
endif
if first = 2 then
LCDOUT $FE, 2
GOTO writeW
endif
if first = 3 then
LCDOUT $FE, $0C
GOTO writeW
endif
if first = 4 then
LCDOUT $FE, $0E
GOTO writeW
endif
if first = 5 then
LCDOUT $FE, $0F
GOTO writeW
endif
if first = 6 then
LCDOUT $FE, $10
GOTO writeW
endif
if first = 7 then
LCDOUT $FE, $14
GOTO writeW
endif
if first = 8 then
LCDOUT $FE, $80
GOTO writeW
endif
if first = 9 then
LCDOUT $FE, $C0
GOTO writeW
endif

writeW:
for i1 = initial to last
LCDOUT testSTR[i1]
next i1
goto begin


by the way thank you skimask, if it wasn't for your bright idia of searching for the fricken character in the Rx i probably wouldv blanked out and not have figured it out.

Ioannis
- 7th June 2007, 07:06
I wonder, why don't you use the UART that the F688 has?

Things are going to be much faster and reliable.

Now for the crap characters that remain in the string when you end it with less characters than 16.

An idea would be to have a FOR/NEXT loop and check where is the CR and fill the rest of the array with space character.

Have not tested but will give you a start:

for i=0 to 15
if testSTR[i]=13 then exit_for
next i

goto rest of the program

exit_for:
for j=i to 15
testSTR[i]=" "
next j

Ioannis

jmbanales21485
- 7th June 2007, 16:20
UART huh? ive seen it around in the forums but never actually sat there and read what it was. i'll have to look into it and see how it works so that i can implement it on the lcd driver. so far it has been working great the way that i set it up with the serout2. its not as fast as uart probably but right now i just wanted something that could read an 8 pin chip so i can trouble shoot it.

skimask
- 7th June 2007, 16:26
UART huh? ive seen it around in the forums but never actually sat there and read what it was. i'll have to look into it and see how it works so that i can implement it on the lcd driver. so far it has been working great the way that i set it up with the serout2. its not as fast as uart probably but right now i just wanted something that could read an 8 pin chip so i can trouble shoot it.

UART = Universal Asychronous Receiver Transmitter - the basis for all serial ports.
You're using SERIN and SEROUT. Those are softwart 'bit-banged' versions.
The UART is the all-in-one, hardware, version of what the SERIN/SEROUT commands do. It can work in the background, rather than tying up your program waiting for the next character to come along. The UART will catch a character and hold it (within reason) until your program goes out and gets it. With SERIN, you have to 'sit' in that command (within reason again) until the next character comes along.