Serial Communication Problem


Closed Thread
Results 1 to 24 of 24
  1. #1
    Join Date
    Apr 2005
    Location
    Virginia
    Posts
    65

    Question Serial Communication Problem

    Hello, I have been wrestling with this for days and thought I'd see if anyone could tell me what I'm doing wrong. I've Googled, gone through some excellent intro PIC books and read the forum here. The closest info I've found is here under the "serial string parsing" thread by billybobbins.

    To give you a picture of the end product:
    I am putting together a program that does four things: 1) Except a serial data stream of up to 40 bytes long, 2) execute commands based on data from the data stream, 3) re-transmit the data stream (nothing added or changed), and 4) count pulses from an encoder using an interrupt.

    My problem is with 1). For the life of me, I cannot get read a stream of serial data as I'd like. I'm trying to create a loop that looks for serial data coming in, reads and stores it into a variable array if any is present and goes onto to perform another function briefly before going back into the original loop.

    I'm in a Catch 22. If I don't use a timeout in the serin command, the program does nothing until data comes in, but when it comes in I have all of the bytes regardless of the size. If I do use a timeout either I get junk or a varying portion of the original data.

    My test data is sent via hyperterminal at 2400 baud 8N1. This is sent as a data file (notepad txt).

    Test data stream is: A00gfhgd00CR+
    where the + is used to identify the end of the stream. Eventually the baud will be 9600 and a line feed will be used to denote the end of a stream, just can't simulate a line feed in notepad.

    Here is the code with the results:

    All code has the following:

    include "modedefs.bas"

    Trisb = %00000000
    Trisc = %01000000
    Portb = %00000000
    Portc = %00000000

    a var byte
    b var byte
    c var byte
    d var byte
    RX var byte[40]
    TX var byte[40]
    i var byte
    dSize var byte
    f var byte
    PDA var byte
    InCheck var byte

    Yes, I have a few extra variables I'm not using in the current program.



    A) Using a for loop and a timeout

    Main:

    serin portc.7, T2400, 100, LED, RX[0]

    If RX[0] != 0 Then ReadPDA

    goto LED

    ReadPDA:

    For i = 1 to 40

    serin portc.7, T2400, RX[i]

    If RX[i] = "+" Then DataOut
    Next



    goto Error 'DataEnd


    LED:

    portb.0 = 1
    pause 10
    portb.0 = 0
    pause 10
    PDA = 0
    goto Main

    DataOut:

    for d = 0 to i
    serout portc.6, T2400, [RX[d]]
    next

    serout portc.6, T2400, [10, 13]

    goto Main

    Error:

    serout portc.6, T2400, ["Error"]

    goto Main

    And the results for five streams sent are:
    0gfhgd00CR+
    A00gfhgd00CR+
    ˜gfhgd00CR+
    A00gfhgd00CR+
    A00gfhgd00CR+

    Okay, not bad, but the first run didn't catch the A0 and the third not only lost the A00 but thought it saw a y with two dots over it instead.

    B) Using a while loop and a timeout


    Main:

    serin portc.7, T2400, 1, LED, RX[0]
    'pause 1
    If RX[0] != 0 Then ReadPDA
    'If RX[0] = 0 Then LED
    goto LED ' ReadPDA 'Error

    LED:

    portb.0 = 1
    pause 10
    portb.0 = 0
    pause 10
    PDA = 0
    goto Main

    ReadPDA:

    counter = 1

    while counter != 40 and RX[counter] != "+"
    serin portc.7,T2400, RX[counter]
    'if RX[counter] = 0 Then LED
    'pause 1
    counter = counter+1
    Wend

    If counter = 40 then Error

    goto DataOut



    DataOut:

    for i = 0 to counter
    serout portc.6, T2400, [RX[i]]
    next

    serout portc.6, T2400, [10, 13]

    goto Main


    Error:

    serout portc.6, T2400, ["Error", 10, 13]

    goto Main


    And the results for five streams sent are:
    00gfhgd00CR++
    : fhgd00CR++
    ‚þ0gfhgd00+
    ó0gfhgd00+
    Óöfhgd00CR+

    Again, if I remove the timeout, the data is perfect but the program doesn't move. I've seen some code with hserin and serin2, but I haven't played with those commands and haven't seen an advantage in using them in this application over serin, at least yet.

    Any help or advice is greatly appreciated! Thanks!

  2. #2
    Join Date
    Oct 2004
    Location
    Hangover, Germany
    Posts
    289


    Did you find this post helpful? Yes | No

    Default

    Oh yeah,

    The PIC is not fast enough to receive several bytes with software.
    You have to use assemblercode inside an Interrupt-Routine with a USART on the PIC.

    Tip: Counting signals is managed through Counters or Timers and you don't need Interrupts.

  3. #3
    Join Date
    Feb 2003
    Location
    Delaware
    Posts
    30


    Did you find this post helpful? Yes | No

    Default hardware UART is the way to go.

    Some advice. Always use a hardware UART when you can.

    I do bullet proof comms using an asm routine and a harware UART. However, if I had a small program and I didn't want to write an assembly interrupt service routine then I would simple poll the interrupt bit. This bit will set whenever a character has come in. It will clear when you remove the character.

    So what chip are you using? Does it have a UART? Can you use it?

    Hope this helps,

    Joe.

  4. #4
    Join Date
    Apr 2005
    Location
    Virginia
    Posts
    65


    Did you find this post helpful? Yes | No

    Question Counters and polling

    Thank you both for the info. Sorry I forgot to mention it earlier, I am using a 18F2525 which has a USART. Now I must admit that my knowledge is extremely limited at this time because I know next to nil about assembly except that it's not a lot of fun and quite complicated when I did try learning it a couple years ago.

    I haven't played with interrupts yet, but I'll be starting with those next week if not today. When you say poll the interrupt bit, bare with me, you mean set portb.2, for example, as an interrupt, read in the character when one is detected into a byte of my array (in this case RX[#]) and continue doing so until I get the last character? Also, I presume I can use another interrupt and hopefully set one as a higher priority than the other?

    Is there an example somewhere on using the counter on the PIC? Haven't had a lot of luck searching on the Net. Or is that used in conjunction with the COUNT command? I want to make sure that any time I receive a pulse from the encoder that it gets counted, this will be a priority over everything else.

    Again, thank you both for your advice.

  5. #5
    Join Date
    Oct 2004
    Location
    Italy
    Posts
    695


    Did you find this post helpful? Yes | No

    Default

    Hi!

    =============================================
    The PicBasic Pro SERIN2 command has an optional
    flow control pin. The SERIN2 command does this
    handshaking flow control on a byte by byte basis.
    Some computers may send several bytes before
    they even check the status of their handshaking lines.
    ==============================================


    The idea below does not use the flow control pin.

    Define first the data frames.

    START character
    The start character is present only one time in
    the data frame. (The first byte). If you use
    Notepad, the START character has to be printable.

    END character
    The end character is present only one time in
    the data frame. (The last byte). If you use
    Notepad, the END character has to be printable.

    DUMMY character(s)
    The DUMMY character is present one or more times
    in the data frame. The frame can have
    from 0 to 42 DUMMY characters.(See example below).
    If you use Notepad, the DUMMY characters need to
    be printable.

    DATA character(s)
    Any value except the values used for the
    START, END and DUMMY characters.
    The frame can have from 1 to 40 DATA
    characters. If you use Notepad, the DATA characters
    need to be printable.

    When you choose the character for START, END
    and DUMMY, choose characters that you will never
    use in the DATA characters. Maybe one day you
    will send DATA to an LCD display, so don't
    waste useful ASCII characters.

    * * *

    Example data frames in a Notepad file:

    S = Start character
    X = DATA character(s)
    E = END character
    D = DUMMY character(s)

    <START><DATA><DUMMY><END>

    The DUMMY character(s) is (are) used only if
    DATA is less than 40 bytes or if you need
    to send DUMMY data frames to the PIC.
    While the PC sends out the dummy data frames
    the PIC has time to do something else.
    (Remember we don't use any flow control).


    The following 5 lines are the Notepad file:

    SXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXE
    SXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXDE
    DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD
    SXXXXXXXXXXDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDE
    SXDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDE

    Where:

    The first line is a data frame with 40 bytes of data.
    The second line is a data frame with 39 bytes of data.
    The third line is a dummy frame.
    The fourth line is a data frame with 10 bytes of data.
    The fifth line is a data frame with 1 byte of data.

    * * * *

    At 9600 baud the PC sends 960 bytes per second.
    (Terminal 8N1, raw ASCII file send).

    The data frames are always 42 bytes long plus the
    two bytes that Notepad will put at the end of
    each line. (CR and LF).
    To send out 44 bytes the PC will need 46 ms
    at 9600 baud.

    * * *

    If the above idea is compatible with your design, I will
    help you with the PicBasic Pro code.


    Best regards,


    Luciano
    Last edited by Luciano; - 28th April 2005 at 19:45.

  6. #6
    Join Date
    Feb 2003
    Location
    Delaware
    Posts
    30


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by elec_mech

    I haven't played with interrupts yet, but I'll be starting with those next week if not today. When you say poll the interrupt bit, bare with me, you mean set portb.2, for example, as an interrupt, read in the character when one is detected into a byte of my array (in this case RX[#]) and continue doing so until I get the last character? Also, I presume I can use another interrupt and hopefully set one as a higher priority than the other?
    Thats not quite what I mean. A pic has a few different interrupts. Things like timer0, received character, and portb.0 are all things that can interrupt the processor. Portb.0 is an external interrupt.

    Now on the 16F devices when an interrupt occurs the program jumps to a set mem location (this is in assembly...not PBP) if you have enabled the interrupt (ie it is not masked). It is up to the programmer to test which interrupt caused the program to jump to the interrupt vector. The programmer also needs to save a bunch of stuff (context saving) upon entering the ISR and then needs to restore it all when leaving the ISR. I am only a little familiar with the 18F parts but I know that they have even more registers associated with interrupts. Now this sounds like alot of work. But there is a trick.

    You see interrupt bits toggle regardless of if you have set up any interrupt registers! This means that if you start a timer and it overflows the timer overflow (TMRIF) bit gets set. So if you where to find out what register and bit will toggle when your event occurs then you poll that bit by doing a compare inside of your loop. Something like :

    Code:
    loop:
    'do some stuff here
    'and some more here
    
    if TMRIF = 1 then                    'now check to see if the timer over flowed
         TMRIF = 0                         'it did so reset the bit
         My_counter = My_counter + 1   'increment the counter
    endif
    
    goto loop
    For this to work you would create an alias to the timers interrupt flag and call it TMRIF. You would also need to start the harware timer by setting the appropriate bit in the appropriate register.

    Now if you where to use the UART you would get a bit set (RCIF, received character interrupt flag) whenever a character came in! And all you would need to do would be to load the character into a variable to reset the bit. This would look something like this:

    Code:
    loop:
    'do some stuff here
    'and some more here
    
    if RCIF = 1 then char_in = RCV_IN
    
    goto loop
    For this example to work you would need to create an alias for the received character interrupt flag and name it RCIF and an alias for the buffer that holds the received character and name it RCV_IN. Also you would need to set up the comms parameters.

    Hope this helps.

    Joe.

    Edit....You REALLY need the data sheet for your PIC!

  7. #7
    Join Date
    Oct 2004
    Location
    Italy
    Posts
    695


    Did you find this post helpful? Yes | No

    Default

    Microchip Application Notes:

    AN774 Asynchronous Communications with the PICmicro® USART
    http://ww1.microchip.com/downloads/e...tes/00774a.pdf

    AN774 Source Code (PIC16, PIC17, PIC18).
    http://ww1.microchip.com/downloads/e...otes/00774.zip


    From Source code ZIP file, Readme18.txt

    There are five code examples for the PIC18F452.
    They can be applied to any PIC18 part, with minor changes.
    Each file has a brief functional description in the header
    at the top of the file. They all receive data and transmit
    the data back, but do so in different ways to demonstrate
    typical applications of the USART.

    Here is a summary of the features of each code example:

    P18_TIRI.ASM Use interrupts for transmit and receive, Circular buffers, Eight bit data
    P18_TPRP.ASM Poll for transmit and receive, Simple buffers, Eight bit data
    P18_TWRP.ASM Poll to receive, Wait to transmit, No buffers, Eight bit data
    P18_2STP.ASM Poll to receive, Wait to transmit, No buffers, Eight bit data, Two stop bits
    P18_PRTY.ASM Poll to receive, Wait to transmit, No buffers, Eight bit data, Even parity bit

    Best regards,

    Luciano

  8. #8
    Join Date
    Feb 2003
    Location
    Delaware
    Posts
    30


    Did you find this post helpful? Yes | No

    Default Good info!

    Thanks for the links Luciano. Very good information.

    Regards,

    Joe.

  9. #9
    Join Date
    Apr 2005
    Location
    Virginia
    Posts
    65


    Did you find this post helpful? Yes | No

    Exclamation Still confused

    Joe and Luciano,

    I appreciate the info up to this point, I do feel I've gotten a better grasp of what I'm trying to do and how the PIC works, yet I am as confused as ever.

    Here's the latest code (not including the tons of modifications I've tried) that appears to do nothing. Joe, I also used the code you presented in the
    "Can an asm interrupt contain gosub to a picbasic routine?" forum question which looked related to this subject.

    Code:

    include "modedefs.bas"

    Trisb = %00000000
    Trisc = %01000000
    Portb = %00000000
    Portc = %00000000
    PIE1 = %00100001 'Allow Timer1 & serial in to cause a periheral interrupt.
    INTCON = %11110000 ' Enable interrupt for Timer0 AND peripherals

    RX var byte[40]
    TX var byte[40]
    i var byte

    RCIF VAR PIR1.5
    ' Alias RCIF (USART Receive Interrupt Flag)



    Main:


    if RCIF = 1 Then
    serin portc.7, T2400, PDA

    'I've also tried: "RCREG = PDA" in place of "serin portc.7, T2400, PDA" to
    'no avail

    else
    goto main
    endif

    goto DataOut


    DataOut:

    serout portc.6, T2400, [10, 13]

    goto Main

    I'm still using the Hyper terminal to check this out.


    I have looked at the App Notes, the datasheet and the forums and I still cannot get my head around this. I believe I am running into a wall looking at the App Notes and datasheets because they explain EXACTLY how the PIC works with serial comms all the while using assembly, while PicBasic Pro takes care of many of these things yet not all. Do I need to set up interrupts, define registers and the like? Again, I appreciate the help, the info thus far has been great, I'm just not applying it right and I can't figure out why.

  10. #10
    Join Date
    Apr 2005
    Location
    Virginia
    Posts
    65


    Did you find this post helpful? Yes | No

    Default Oops

    Whoops, I forgot to include this line immediately under DataOut:

    serout portc.6, T2400, [PDA]

    Sorry.

  11. #11
    Join Date
    Sep 2004
    Location
    montreal, canada
    Posts
    6,898


    Did you find this post helpful? Yes | No

    Default

    Here's something to play with.
    Code:
        '   Program to echo incoming serial data 
        '   Baudrate : 2400 Bauds
        '   Method :   Polling USART interrupts flags
    
        '   Pic Definition
        '   ==============
            ' Using PIC 18F2320 @ 4MHZ and bootloader
            '
            DEFINE LOADER_USED 1
            DEFINE OSC 4
            
        '   Hardware configuration
        '   ======================
            '
            '
            TRISC  = %10000000    ' PORTC.7 is the RX input
                                  ' PORTC.6 is the TX output
        
        '   Serial communication definition
        '   ===============================
            ' Using internal USART and MAX232 to interface to PC
            '
            RCSTA = $90 ' enable serial port, 
                        ' enable continuous receive
                        '
            TXSTA = $24 ' enable transmit, 
                        ' BRGH=1
                        '
            SPBRG = 103 ' set baudrate to 2400                   
            
        '   Alias definition
        '   ================
            '
            '
            RCIF VAR PIR1.5     ' Receive  interrupt flag (1=full , 0=empty)
            TXIF VAR PIR1.4     ' Transmit interrupt flag (1=empty, 0=full)
            OERR var RCSTA.1    ' Overrun error
            CREN var RCSTA.4    ' Continuous receive
                    
        '   Hardware initialisation
        '   =======================
            '
            '
            pause 10 ' safe start-up delay
        
    Main:
        if oerr then  ' Overrun error?
           cren=0     ' clear it
           cren=1
           endif
    
        if RCIF then    ' incomming data?
           TXREG=RCREG  ' take it, send it
           while TXIF=0 ' wait untill transmit buffer is empty
           wend
           endif
        goto main
    the following use HSERIN/HSEROUT statement. Since your PIC have internal USART... why not using it
    Code:
        '   Program to echo incoming serial data 
        '   Baudrate : 2400 Bauds
        '   Method :   Polling USART interrupts flags
    
        '   Pic Definition
        '   ==============
            ' Using PIC 18F2320 @ 4MHZ and bootloader
            '
            DEFINE LOADER_USED 1
            DEFINE OSC 4
            
        '   Hardware configuration
        '   ======================
            '
            '
            TRISC  = %10000000    ' PORTC.7 is the RX input
                                  ' PORTC.6 is the TX output
        
        '   Serial communication definition
        '   ===============================
            ' Using internal USART and MAX232 to interface to PC
            '
            DEFINE HSER_RCSTA 90h ' enable serial port, 
                                  ' enable continuous receive
                                  '
            define HSER_TXSTA 24h ' enable transmit, 
                                  ' BRGH=1
                                  '
            define HSER_SPBRG 103 ' set baudrate to 2400                   
            DEFINE HSER_CLOERR  1 ' automatic clear overrun error  
            
        '   Alias definition
        '   ================
            '
            '
            RCIF VAR PIR1.5     ' Receive  interrupt flag (1=full , 0=empty)
            TXIF VAR PIR1.4     ' Transmit interrupt flag (1=empty, 0=full)
            
        '   Variable definition
        '   ===================
            '
            '
            SerialData var byte
            
        '   Hardware initialisation
        '   =======================
            '
            '
            pause 10 ' safe start-up delay
        
    Main:
        if RCIF then            ' incomming data?
           hserin  [Serialdata] ' take it
           hserout [serialdata] ' send it
           endif
        goto main
    hope this help
    Last edited by mister_e; - 11th May 2005 at 02:41.
    Steve

    It's not a bug, it's a random feature.
    There's no problem, only learning opportunities.

  12. #12
    Join Date
    Apr 2005
    Location
    Virginia
    Posts
    65


    Did you find this post helpful? Yes | No

    Question HSer Woes

    Mister_E,

    Thank you for the lovely code! It works nicely and I've been examining it while referencing the datasheet and I have learned a good deal. I then tried to manipulate it to work with my application and I've hit a wall. Initially I'm trying to look at a string of characters sent via the hyperterminal, particularly the first and last bit.

    Now, perhaps I'm going into overkill with caution, but I only want to store the string into a variable array if the string starts with a ASCII "!". I then want to continue taking the rest of the string until an ASCII "L" is seen.

    The idea being if for some reason or another, I receive a string of data and I start storing the data string at the middle instead of the beginning and miss some data. Here's what I have:

    ' Program to echo incoming serial data
    ' Baudrate : 2400 Bauds
    ' Method : Polling USART interrupts flags

    ' Pic Definition
    ' ==============
    ' Using PIC 18F2320 @ 4MHZ and bootloader
    '
    DEFINE LOADER_USED 1
    DEFINE OSC 4

    ' Hardware configuration
    ' ======================
    '
    '
    TRISC = %10000000 ' PORTC.7 is the RX input
    ' PORTC.6 is the TX output

    ' Serial communication definition
    ' ===============================
    ' Using internal USART and MAX232 to interface to PC
    '
    DEFINE HSER_RCSTA 90h ' enable serial port,
    ' enable continuous receive
    '
    define HSER_TXSTA 24h ' enable transmit,
    ' BRGH=1
    '
    define HSER_SPBRG 103 ' set baudrate to 2400
    DEFINE HSER_CLOERR 1 ' automatic clear overrun error

    ' Alias definition
    ' ================
    '
    '
    RCIF VAR PIR1.5 ' Receive interrupt flag (1=full , 0=empty)
    TXIF VAR PIR1.4 ' Transmit interrupt flag (1=empty, 0=full)
    a var byte
    i var byte
    ' Variable definition
    ' ===================
    '
    '
    SerialData var byte[40]

    ' Hardware initialisation
    ' =======================
    '
    '
    pause 10 ' safe start-up delay

    Main:
    ' Clear - tried using this to clear, but then I get nothing back

    if RCIF then ' incomming data?
    hserin [SerialData[0]] 'Store the first character received in SerialData,
    'at byte 0
    endif

    if SerialData[0] = "!" then RCV 'if the first byte is an ASCII ! then
    'go on to receive rest of data string


    goto Main


    RCV:

    for i = 1 to 40

    hserin [SerialData[i]] ' take it
    if SerialData[i] = "L" then TRS 'if an ASCII L is
    'present stop
    'and output
    'string
    next

    goto Main 'If ASCII L is not detected return to main loop


    TRS:
    for a = 1 to i 'Okay, if I set a = 0 to i, I get a ! in
    'front of everything when it outputs
    'i.e. if I send !#00CL I get !!#00CL
    'back. Why, I don't know.
    hserout [SerialData[a]] ' send it
    next 'endif
    hserout [10,13] 'line feed and carriage return
    goto Main





    Alright, if I send !#X00CL I get back !#X00CL, which is great! However, and here's the where the confusion starts, if I send 123456ABCDEF#, I get nothing back, again, good news right? But, if I follow that string with !#X00CL, I get back 123456ABCDEF#!#X00CL. I am hitting a wall here.

    It seems as though the program stores up to 41 (0 to 40) bytes from a serial string (this because in my code I set SerialData to store up to 41 bytes, from 0 to 40). Once it sees 41 bytes, it resets itself and starts anew until it sees an ASCII L. For example, if I send 123456ABCDEF# three times then follow with !#X00CL I get back #1X00CL.

    Is there a way to tell the program to write and erase to only SerialData[0] until a specific character is seen? ASCII ! in this case. Or am I missing something else altogether? Thanks!

  13. #13
    Join Date
    Sep 2004
    Location
    montreal, canada
    Posts
    6,898


    Did you find this post helpful? Yes | No

    Default

    this should give you a hand!
    Code:
        '   Program to echo incoming serial data 
        '   Baudrate : 2400 Bauds
        '   Method :   Polling USART interrupts flags
    
        '   Pic Definition
        '   ==============
            ' Using PIC 18F2320 @ 4MHZ and bootloader
            '
            DEFINE LOADER_USED 1
            DEFINE OSC 4
            
        '   Hardware configuration
        '   ======================
            '
            '
            TRISC  = %10000000    ' PORTC.7 is the RX input
                                  ' PORTC.6 is the TX output
        
        '   Serial communication definition
        '   ===============================
            ' Using internal USART and MAX232 to interface to PC
            '
            RCSTA=$90 ' enable serial port, 
                      ' enable continuous receive
                      '
            TXSTA=$24 ' enable transmit, 
                      ' BRGH=1
                      '
            SPBRG=103 ' set baudrate to 2400                   
            DEFINE HSER_CLOERR   1 
            
        '   Alias definition
        '   ================
            '
            '
            RCIF VAR PIR1.5     ' Receive  interrupt flag (1=full , 0=empty)
            TXIF VAR PIR1.4     ' Transmit interrupt flag (1=empty, 0=full)
            CREN var RCSTA.4    ' Receiver enable bit
            
        '   Variable definition
        '   ===================
            '
            '
            SerialString var byte[40]
            Counter      var byte
            Success      var bit
            i            var byte
            
        '   Hardware initialisation
        '   =======================
            '
            '
            pause 100 ' safe start-up delay
    
    Main:
       clear
       if RCIF then               ' incomming data?
          I=RCREG                 ' take it
          if i !="!" then discard ' is it the header character?
          Redo:
              hserin 500,discard,[i]  ' get next character, if it's too long
                                      ' get out of here and wait the next header
                                      ' character
                                      '
              if i ="L" then discard  ' is it the end?
              serialstring[counter]=i ' Store into the array
              counter=counter+1       '
              goto Redo      
          Discard:
                  if i="L" then success=1 ' Yeah i got a valid string
          endif
      
       if success then
          cren=0  ' Disable Receiver
          hserout ["String received : ",str serialstring\counter,13,10,_
                   "Character count : ", dec counter,13,10]
          cren=1  ' Enable receiver
          endif
       goto main
    Steve

    It's not a bug, it's a random feature.
    There's no problem, only learning opportunities.

  14. #14
    Join Date
    Apr 2005
    Location
    Virginia
    Posts
    65


    Did you find this post helpful? Yes | No

    Question Replacing the clear command?

    Steve,

    Thank you for the code, it worked beautifully. I did notice that moving the clear command down to the very bottom right before the 'goto main' worked better. I think the data came in so fast that if the timing were off I missed some data streams.

    I have a question regarding the clear command. I understand it completely clears the ram which prevents a constant repeating loop of a single data input stream. Is there another way to specifically clear or erase whatever register or ram location the USART uses? I ask because I am running several if then statements that require checking the status of certain variables and if I use the clear command, I lose the original status/data in those variables.

    I've tried using RCIF = 0 and RCREG = 0 to no avail. I've also tried the ERASECODE $FAEh to clear the RCREG register, but this command doesn't work in PicBasic Pro with the 18F2525 chip I'm using. Any suggestions?

    Again, thanks again for the code, I've been playing with it all day, making mistakes, gaining victories and generally learning a lot in the process.

  15. #15
    Join Date
    Sep 2004
    Location
    montreal, canada
    Posts
    6,898


    Did you find this post helpful? Yes | No

    Default

    You're welcome.

    You'll clear then RCREG by reading it 2 times

    TempVar=RCREG
    TempVar=RCREG
    Steve

    It's not a bug, it's a random feature.
    There's no problem, only learning opportunities.

  16. #16
    Join Date
    Apr 2005
    Location
    Virginia
    Posts
    65


    Did you find this post helpful? Yes | No

    Talking Solution!

    Upon having another set of eyes look at my code and using the debugger I'm learning to use slowly with more interest, I forgot to clear the counter and i variables. Effectively it was continuing to loop because those variables still had values assigned. Thank you for your time and help Steve, I do appreciate it.

    To anyone else who may be interested in receiving a serial string, reading it and then doing something based upon a character(s) received, let me know and I'll post some really nice code to play with.

    Thanks again to Joe, Luciano, and Steve. I learned a great deal by all the info and code posted.

  17. #17
    Dalomir's Avatar
    Dalomir Guest


    Did you find this post helpful? Yes | No

    Post Same programming

    I put the schematic in the attachement of this post.

    Its an usart with 2 PIC18F452 linked together by PIN 25 and PIN 26

    One receive a paralelle 4 bits number from a numerical keyboard, light LED at PIN 2, 3, 4, 5, 6, 8, 9 and 10 to show that number and send that number directly to the other PIC RX PIN.

    Thats other PIC then receive that serial number and lights LED in the same way as the other PIC, showing that the number was successfully sent.

    If anyone has a code that would make it work, I would really appreciate.
    Attached Images Attached Images  

  18. #18
    leemin's Avatar
    leemin Guest


    Did you find this post helpful? Yes | No

    Default help

    To anyone else who may be interested in receiving a serial string, reading it and then doing something based upon a character(s) received, let me know and I'll post some really nice code to play with.

    yupe. i need a program to receive a serial string, reading it and then doing something. my string is something like this X-Addr-Mode-Data(30bytes)-Y
    where X stand for SOT and Y stand for EOT. Addr is use to indicate the dedicated address value i want to send data.

    my code is something like below:
    include "modedefs.bas"
    DEFINE SHIFT_PAUSEUS 20
    define OSC 20
    DEFINE HSER_CLOERR 1 ' automatic clear overrun error

    TRISA=%11110000
    TRISB= %11111011
    TRISC.6 = 1
    TRISC.7 = 0

    symbol Addr_Data_In=porta.4
    symbol en=porta.3
    symbol stb=porta.2
    symbol clk=porta.1
    symbol data_out=porta.0

    SPBRG = 32 ' Set baud rate to 9600
    RCSTA = $90 ' Enable serial port and continuous receive
    TXSTA = $24 ' Enable transmit and asynchronous mode
    RCIF VAR PIR1.5 ' Receive interrupt flag (1=full , 0=empty)
    TXIF VAR PIR1.4 ' Transmit interrupt flag (1=empty, 0=full)
    OERR var RCSTA.1 ' Overrun error
    CREN var RCSTA.4 ' Continuous receive
    ADCON1=6

    display: if RCIF then
    i=RCREG
    if i != "X" then discard

    redo: hserin 500,discard,[i]
    if i="Y" then discard
    serialstring[counter]=i
    counter=counter+1
    goto redo

    discard: if i="Y" then success=1
    endif
    if success then
    cren = 0
    if (serialstring[0] <> address_Value) then reset
    if serialstring[1] = $30 then turn_off_led
    serialstring[2]=a29
    serialstring[3]=a28
    serialstring[4]=a27
    serialstring[5]=a26
    serialstring[6]=a25
    serialstring[7]=a24
    serialstring[8]=a23
    serialstring[9]=a22
    serialstring[10]=a21
    serialstring[11]=a20
    serialstring[12]=a19
    serialstring[13]=a18
    serialstring[14]=a17
    serialstring[15]=a16
    serialstring[16]=a15
    serialstring[17]=a14
    serialstring[18]=a13
    serialstring[19]=a12
    serialstring[20]=a11
    serialstring[21]=a10
    serialstring[22]=a9
    serialstring[23]=a8
    serialstring[24]=a7
    serialstring[25]=a6
    serialstring[26]=a5
    serialstring[27]=a4
    serialstring[28]=a3
    serialstring[29]=a2
    serialstring[30]=a1
    serialstring[31]=a0
    endif
    reset: cren=1 ' Enable receiver
    goto display

  19. #19
    Join Date
    Apr 2005
    Location
    Virginia
    Posts
    65


    Did you find this post helpful? Yes | No

    Default

    I need to sift through my code and pull out the serial stuff (it's a long code as it stands) and reply to you this evening. What PIC are you using by the way?

    Also, could you describe what you want to do again in more detail? I'm a little confused when you say X stands for SOT and Y for EOT. I'm still a newbie in programming, but I'm sure I can help you with this. So far I gather you want to receive a serial string and read it. You then want the PIC to do something by way of transmitting another serial string and placing the characters in a specific location along that string? Which is no problem I just want to make sure I'm giving you what you want.

    -Tony

  20. #20
    Join Date
    Apr 2005
    Location
    Virginia
    Posts
    65


    Did you find this post helpful? Yes | No

    Default Sample Code

    Okay, I brought this home, tweaked it with a different programmer and when I try to compile it, it says it is unable to "fit variables". I'm think this will work as it stands, but you may find some errors on my part.

    In any event, this waits for serial data and once received looks at the first two characters to be sure the string is what you expect it to be. You can take this out if your serial input changes every time (the first two and last two characters in a string). If you ever expect more than 40 bytes on a single serial string be sure to change that in the variable definitions.

    The branch command really comes in handy for looking at a single character at a specific location in the string and doing different things instead of using the if command.

    Take a look at this and see if it helps. Feel free to ask questions.

    -Tony
    Attached Files Attached Files
    Last edited by elec_mech; - 26th August 2005 at 01:13. Reason: Forgot attachment

  21. #21
    Join Date
    Apr 2005
    Location
    Virginia
    Posts
    65


    Did you find this post helpful? Yes | No

    Default P.s.

    ASII Table - All important to serial comms - Check this out:
    http://www.lookuptables.com/

  22. #22
    leemin's Avatar
    leemin Guest


    Did you find this post helpful? Yes | No

    Exclamation

    ok. thanks for you all previous help. i can work with the USART interrupt with my code already but now i encounter with a new problem.
    im using 16f877a.
    i need to receive a string of command from computer. then execute some function after received a valid command. now i need to execute the blinking effect by toggling the enable pin to let the led on and off continuosly untill another set string of command come in and either stop blinking or continue blinking.
    but now i found out that the blinking sub-routine is a dead loop. when i continuosly execute the blink function and a new string command come in from computer my firmware will hang there.
    any solution for this?
    i need you all suggestion.
    thanks

  23. #23
    Join Date
    Sep 2004
    Location
    Mentor, Ohio
    Posts
    352


    Did you find this post helpful? Yes | No

    Smile

    Hi Leemin,

    It's a great idea to have the micro do as much as possible but sometimes it's necessary to have external hardware do some work to free up the micro to do other things more important. Add a gated pulsing circuit that you only need the micro to turn on and off. This can be a single chip circuit like using a CD4093 or even a CD4060. A CD4060 lets you choose flash rates juct by selecting the appropriate output. These are simple circuits and only require a few discretes to finish the job. Let the micro do the more serious stuff.

    BobK

  24. #24
    Join Date
    Feb 2005
    Location
    Essex, UK
    Posts
    154


    Did you find this post helpful? Yes | No

    Default

    With some of these examples using USART, do you have to use a MAX232 IC or can the PICs ports be connected straight to the DB9 serial connector?

    Better still, does anyone have an example connection schematic.

    Many thanks,

    Steve

Similar Threads

  1. Replies: 18
    Last Post: - 4th July 2017, 14:26
  2. serial communication problem
    By kindaichi in forum Serial
    Replies: 13
    Last Post: - 11th March 2010, 16:37
  3. Replies: 5
    Last Post: - 20th March 2006, 01:34
  4. Problem in Serial Communication
    By uuq1 in forum mel PIC BASIC Pro
    Replies: 2
    Last Post: - 5th June 2005, 07:17
  5. Replies: 8
    Last Post: - 11th November 2004, 20:08

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