Another Serin/Serout Problem!


Closed Thread
Results 1 to 8 of 8
  1. #1

    Default Another Serin/Serout Problem!

    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!
    Attached Files Attached Files

  2. #2
    skimask's Avatar
    skimask Guest


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by jmbanales21485 View Post
    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.

  3. #3


    Did you find this post helpful? Yes | No

    Default

    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

  4. #4
    skimask's Avatar
    skimask Guest


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by jmbanales21485 View Post
    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...
    Last edited by skimask; - 2nd June 2007 at 06:14. Reason: Just noticed....

  5. #5


    Did you find this post helpful? Yes | No

    Default

    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.

  6. #6
    Join Date
    Nov 2003
    Location
    Greece
    Posts
    3,807


    Did you find this post helpful? Yes | No

    Default

    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
    Last edited by Ioannis; - 7th June 2007 at 07:13.

  7. #7


    Did you find this post helpful? Yes | No

    Default

    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.

  8. #8
    skimask's Avatar
    skimask Guest


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by jmbanales21485 View Post
    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.

Similar Threads

  1. Strange problem with Serin/Serout on 16F628
    By Atom058 in forum mel PIC BASIC Pro
    Replies: 23
    Last Post: - 22nd August 2008, 00:16
  2. Problem to compile my program
    By wagner in forum Off Topic
    Replies: 5
    Last Post: - 7th July 2008, 20:17
  3. USART Problem , but don't know where, in pc? or in PIC?
    By precision in forum mel PIC BASIC Pro
    Replies: 0
    Last Post: - 15th July 2007, 08:12
  4. Hardware problem or what ?
    By Steve S. in forum mel PIC BASIC Pro
    Replies: 8
    Last Post: - 4th March 2007, 21:39
  5. 1 slave 1 master 1 MAX232 1 problem ?
    By SuB-ZeRo in forum mel PIC BASIC Pro
    Replies: 19
    Last Post: - 31st July 2005, 22:59

Members who have read this thread : 1

You do not have permission to view the list of names.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts