serial coms - again


Closed Thread
Results 1 to 40 of 58

Hybrid View

  1. #1
    malc-c's Avatar
    malc-c Guest


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by HenrikOlsson View Post
    Hi,

    You are looping around polling the RCIF flag 1000 times in one second (basically). But at 115200 baud you're sending ~11500 bytes or characters per second (one startbit, 8 databots, one stopbot = 10bits per character).

    This means you're sending ~11.5 characters every millisecond. The PICs hardware buffer is only 2 levels deep so you're very likely to overrun the buffer before the HSERIN command is able to grab the data.

    At 2400baud you're only sending 240 characters per second so your polling loop will have no problem catching the RCIF flag and jump to the Term_Rx routine before the buffer overruns.

    Does that make sense?

    /Henrik.
    Yes, somewhat - no wonder why I was having problems missing the data... so is it better to reduce the baud rate for the port or reduce the for next loop steps ?

  2. #2
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,612


    Did you find this post helpful? Yes | No

    Default

    Hi Malcolm,
    If the PC starts to send S789 right at the beginning of the Pause 1 statment all four bytes will have been sent before the PIC checks the RCIFlag and your data will be messed up. So, as you say, either check the flag more often or reduce the baudrate so that you are sure that a maximum of two characters can arrive while you are not watching - so to speak.

    Actually, there can be two bytes in the buffer and a third on its way in without messing it up. But as soon as the last bit of that third byte is shifted in you're in trouble if there's no room in the two byte buffer.

    Let me see if I've got the overall scheme correct.
    ** The PIC does its thing, running the PID and everything. Each time thru its main loop it checks the RCIFlag.
    ** The PC, when it needs attention sends a single character "Q" to the PIC and waits.
    ** The PIC sees the RCIFlag and gets the character (there's no problem here since a single character will sit in the buffer untill you get around to read it)
    ** The PIC compares the received character to "Q" and sends something back to say "OK, hit me" - it then goes to the loop we've been discussing.

    That should work..... At 115200 baud two characters takes roughly 175us so you need to check the RCIF flag at least that often. I'd probably go with something like:
    Code:
    WaitHere:
    For I = 0 to 10000
      If RCIF = 1 then GOSUB Term_Rx
      PauseUs 100
    Next
    Keep it up!
    /Henrik.

  3. #3
    malc-c's Avatar
    malc-c Guest


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by HenrikOlsson View Post
    Hi Malcolm,


    Let me see if I've got the overall scheme correct.
    ** The PIC does its thing, running the PID and everything. Each time thru its main loop it checks the RCIFlag.
    ** The PC, when it needs attention sends a single character "Q" to the PIC and waits.
    ** The PIC sees the RCIFlag and gets the character (there's no problem here since a single character will sit in the buffer untill you get around to read it)
    ** The PIC compares the received character to "Q" and sends something back to say "OK, hit me" - it then goes to the loop we've been discussing.


    /Henrik.
    Pretty much it. As far as I understand Charles has programmed his code to send Q when the program is first launched, this was so that we could use Q as a trigger to jump to a subroutine and have the PIC send the data string.... then the user over types the value in the target temperature box and then when the Update button is clicked it sends Snnn to the PIC, followed by Q to refresh the PC application.

    I've tried migrating the test code over to the main code that you were involved in and have discovered one issue. On launching the application the LCD stops running, but I can set the temperature set point via the application on the PC, which upon pressing the Update button the value on the LCD changes to match. However whilst the application is still open the LCD is still not updated. If I then close the application it still locks up and I have to restart the PIC.

    At the moment I've reduced the
    Code:
    FOR TempWD = 0 TO 1000
    to
    Code:
    FOR TempWD = 0 TO 10
    so at 115200 baud rate that should equate to 115 bytes as second (? yes)

    If RCIF=1 it gosubs to the TERM_RX

    Code:
    Term_RX:
    HSERIN [nTest]
        SELECT CASE nTest
        CASE "S"
           TempWD = 0
        HSERIN 1000,RX_Bombed,[DEC3 TempWD]
        normtemp[0] = TempWD   
        SetPoints(0)=normtemp[0]
        goto Term_TX
      
    return
    
    RX_Bombed:
        TimeoutCount = TimeOutCount + 1 
        end select 
        Goto Term_Rx
    Term_TX is simply

    Code:
    Term_TX:
    
    Hserout [DEC3 Temperatures(0)]
    Hserout [DEC3 Temperatures(1)]
    Hserout [DEC3 Temperatures(2)]
    Hserout [DEC3 Temperatures(3)]
    
    HSEROUT [dec3 normtemp[0]]
    HSEROUT [dec3 normtemp[1]]
    ....
    ...
    ...... etc etc 
    
    gosub flushBuffer 
    goto main
    If I close the down the application and even disconnect the cable from the EasyPIC board the PIC is still frozen....

    Any idea ?

  4. #4
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,612


    Did you find this post helpful? Yes | No

    Default

    Hi,
    Changing the FOR-NEXT loop will only change how many times it loops around checking the RCIFlag and therefor the total time it spends waitng for it - not how often it checks it or how many bytes per second that is sent or received.

    For 115200 baud you must check the RCIFlag at least once every ~170us so, like I showed you earlier:
    Code:
    For TempWd = 0 to 10000
      If RCIF then GOSUB Term_Rx
      PauseUs 100     '<----Note PauseUs, as in Pause micro seconds...
    Next
    Goto Main
    This will check the RCIFlag every 100us and it will do it 10000 times, so all in all it will wait one second, if no data is received it'll jump to Main.

    If you by, the LCD stops updating, mean that the data written to the LCD by the main program in the PIC it's because once the PIC sees the initial RCIF caused by the the "Q" beeing received the main code stops and jumps to your receive routines. It then stays there untill you return to the main program so the LCD can't update....

    Code:
    RX_Bombed:
        TimeoutCount = TimeOutCount + 1 
        end select 
        Goto Term_Rx
    Here, you probably don't want to jump back to Term_Tx but instead jump back to either your main program or RETURN depending on how you got to the routine in the first place. That should prevent the PIC from locking up. And you can remove the TeimOutCount thing, that was for my tests....

    You need to implement some form of handshaking when the user presses Update in the application, simmilar to when the app is first started. The PC can't just dump data into the PIC since your application may be off doing something else and miss it. (Since you're not using interrupts).

    Take a pen a piece of paper, think it thru.

    /Henrik.

  5. #5
    malc-c's Avatar
    malc-c Guest


    Did you find this post helpful? Yes | No

    Default

    Ok I see the logic behind the pause statement.

    I've managed to resolve the stalling...

    Code:
     CASE "Q"
            Goto Term_TX
    Just placed that above the CASE "S" and now it works as it should .... strange how the logical things get overlooked !

  6. #6
    malc-c's Avatar
    malc-c Guest


    Did you find this post helpful? Yes | No

    Default Incoming !!

    Need one final bit of assistance. We've made the changes to the PC application so that it sends the complete string back to the PIC. Q tells the PIC to send data, S tells it to expect data

    QS350635250249250250250249250250250249000000000000000000000000000000001501501501500000000000000000Q

    This should then populate the variables as follows

    Code:
    [dec3 normtemp[0]]
    [dec3 normtemp[1]]
    [dec3 normtemp[2]]
    [dec3 normtemp[3]]
    
    [dec3 alarmlow[0]]
    [dec3 alarmlow[1]]
    [dec3 alarmlow[2]]
    [dec3 alarmlow[3]]
    
    [dec3 alarmhigh[0]]
    [dec3 alarmhigh[1]]
    [dec3 alarmhigh[2]]
    [dec3 alarmhigh[3]]
    
    [#StartHour[0] DIG 1,#StartHour[0] DIG 0,#StartMin[0] DIG 1,#StartMin[0] DIG 0]
    [#StartHour[1] DIG 1,#StartHour[1] DIG 0,#StartMin[1] DIG 1,#StartMin[1] DIG 0]
    [#StartHour[2] DIG 1,#StartHour[2] DIG 0,#StartMin[2] DIG 1,#StartMin[2] DIG 0]
    [#StartHour[3] DIG 1,#StartHour[3] DIG 0,#StartMin[3] DIG 1,#StartMin[3] DIG 0]
    
    [#StopHour[0] DIG 1,#StopHour[0] DIG 0,#StopMin[0] DIG 1,#StopMin[0] DIG 0]
    [#StopHour[1] DIG 1,#StopHour[1] DIG 0,#StopMin[1] DIG 1,#StopMin[1] DIG 0]
    [#StopHour[2] DIG 1,#StopHour[2] DIG 0,#StopMin[2] DIG 1,#StopMin[2] DIG 0]
    [#StopHour[3] DIG 1,#StopHour[3] DIG 0,#StopMin[3] DIG 1,#StopMin[3] DIG 0]
    
    [dec3 Droptemp[0]]
    [dec3 Droptemp[1]]
    [dec3 Droptemp[2]]
    [dec3 Droptemp[3]]
    
    [#lightsetHR[0] DIG 1,#lightsetHR[0] DIG 0,#lightsetMN[0] DIG 1,#lightsetMN[0] DIG 0]
    [#lightsetHR[1] DIG 1,#lightsetHR[1] DIG 0,#lightsetMN[1] DIG 1,#lightsetMN[1] DIG 0]
    
    [#lightoffHR[0] DIG 1,#lightoffHR[0] DIG 0,#lightoffMN[0] DIG 1,#lightOFFMN[0] DIG 0]
    [#lightoffHR[1] DIG 1,#lightoffHR[1] DIG 0,#lightoffMN[1] DIG 1,#lightOFFMN[1] DIG 0]
    Now I've used the following to handle the import of things like normtemp etc and that work fine

    Code:
       TempWD = 0
        HSERIN 1000,RX_Bombed,[DEC3 TempWD]
        normtemp[0] = TempWD   
        SetPoints(0)=normtemp[0]
    However I'm having issues formatting the HSERIN sections for the times such as lightsON and Lights OFF and StartHour etc, especially as these are just two digits 00 - 23 for hours and 00 - 59 for mins. MCS reports
    Expected ']'
    but it doesn't hell me where, and adding them to most logical places (like at the end) still results in similar errors

    Any ideas ?
    Last edited by malc-c; - 30th August 2010 at 16:49. Reason: more info on the error

  7. #7
    malc-c's Avatar
    malc-c Guest


    Did you find this post helpful? Yes | No

    Default

    Any reason why
    Code:
    hserout [#StartHour[0] DIG 1,#StartHour[0] DIG 0,#StartMin[0] DIG 1,#StartMin[0] DIG 0]
    compiles, but
    Code:
    hserin [#StartHour[0] DIG 1,#StartHour[0] DIG 0,#StartMin[0] DIG 1,#StartMin[0] DIG 0]
    Throws up an "expected ]" error. I've tried adding ] to nearly all possible permutations and still can't get it nto compile

  8. #8
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,612


    Did you find this post helpful? Yes | No

    Default

    Hi Malcolm,
    You can get that error message when you've missed a comma somewhere in the HSERIN command, look carefully and I think you'll find it.

    Anyway, I took a stab at it here and I think the following should do it:
    Code:
    '-------------------------------------------------------------------------------
    For Counter = 0 to 3
    HSERIN 1000, RX_Bombed, [DEC3 NormTemp[Counter]]
    NEXT
    '-------------------------------------------------------------------------------
    For Counter = 0 to 3
    HSERIN 1000, RX_Bombed, [DEC3 AlarmLow[Counter]]
    NEXT
    '-------------------------------------------------------------------------------
    For Counter = 0 to 3
    HSERIN 1000, RX_Bombed, [DEC3 AlarmHigh[Counter]]
    NEXT
    '-------------------------------------------------------------------------------
    '-------------------------------------------------------------------------------
    For Counter = 0 to 3
    HSERIN 1000, RX_Bombed, [DEC2 StartHour[Counter], DEC2 StartMin[Counter]]
    NEXT
    For Counter = 0 to 3
    HSERIN 1000, RX_Bombed, [DEC2 StopHour[Counter], DEC2 StopMin[Counter]]
    NEXT
    '-------------------------------------------------------------------------------
    '-------------------------------------------------------------------------------
    For Counter = 0 to 3
    HSERIN 1000, RX_Bombed, [DEC3 DropTemp[Counter]]
    NEXT
    '-------------------------------------------------------------------------------
    '-------------------------------------------------------------------------------
    For Counter = 0 to 3
    HSERIN 1000, RX_Bombed, [DEC2 LightSetHR[Counter], DEC2 LightSetMN[Counter]]
    NEXT
    '-------------------------------------------------------------------------------
    It seems to work, I wrote up a bit of code to re-send all the variable back to PC and it looks like in the attached screenshot. Note that I'm only sending the "S" and I'm not waiting for that final "Q" in your datastream.

    /Henrik.

    PS. Here's the code I used to send everything back to the terminal, might be good for further debugging:
    Code:
    HSEROUT ["-------------------------------",10]
    For Counter = 0 to 3
        HSEROUT ["Normtemp ", #Counter, "   : ", DEC3 Normtemp[counter],10]
        HSEROUT ["AlarmHigh ",#Counter, "  : ", Dec3 AlarmHigh[Counter],10]
        HSEROUT ["AlarmLow ",#Counter, "   : ", Dec3 AlarmLow[Counter],10]
        HSEROUT ["Start ",#Counter, "      : ", Dec2 StartHour[Counter],":", DEC2 StartMin,10]
        HSEROUT ["Stop ",#Counter, "       : ", Dec2 StopHour[Counter],":", DEC2 StopMin,10]
        HSEROUT ["Droptemp ",#Counter,"   : ", DEC3 Droptemp[counter],10]
        HSEROUT ["Light set ",#Counter, "  : ", DEC2 LightSetHr, ":", Dec2 LightsetMn,10]
        HSEROUT ["-------------------------------",10]     
    Next 
    HSEROUT ["T H A T ' S   I T   M A L C O L M",10,10]
    Attached Images Attached Images  

Members who have read this thread : 0

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