Announcement

Collapse
No announcement yet.

Error handling in serial communication

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Error handling in serial communication

    I use 19200bps baudrate to send data from rcm5600w microcontroller to picasso display 4.3". Before I sending data from rabbit to picasso, I try to send data from the rabbit to the serial port of the computer and I look the data in hyperterminal, all goes according to expectations.

    when I replace the computer with picasso, the data appeared in realtime, but after a moment data seemed to freeze. I am sure the error occurred in serial communication of picasso. Is the correct way to handle serial communication error in picasso like this? Thanks.

    Code:
    if((com1_Full() & (com1_Count()==0)) || com1_Error())
        com1_Init(packetIn, SERIN_BUFFER, 0);
    endif

    Completed Code:
    Code:
    // constant
    #CONST
    TOUCH_HANDSHAKING 0x40
    
    MASTER_ID 0xFF
    SLAVE_ID 0x01
    STX 0x02
    ETX 0x03
    ACK 0x06
    NAK 0x15
    
    BAUDRATE 1920 // DON'T CHANGE
    SERIN_BUFFER 255 // DON'T CHANGE
    RX_TMOUT 100
    #END
    
    // member variable
    var packetIn[SERIN_BUFFER];
    
    // function
    func reqHandshaking()
        var BCC, dt, n, pSTX, tmOut;
    
        // request handshake to rabbit
        serout1(STX);               BCC := 0;
        serout1(MASTER_ID);         BCC ^= MASTER_ID;
        serout1(TOUCH_HANDSHAKING); BCC ^= TOUCH_HANDSHAKING;
        serout1(ETX);               BCC ^= ETX;
        serout1(BCC);
    
        // read response of rabbit
        mem_Set(packetIn, NULL, sizeof(packetIn));
        n    :=  0;
        pSTX :=  -1;
        tmOut:= RX_TMOUT;
        while(tmOut--)
            if((com1_Full() & (com1_Count()==0)) || com1_Error())
                com1_Init(packetIn, SERIN_BUFFER, 0);
            endif
            if((dt := serin1())>=0)
                packetIn[n] := dt&0xFF;
                if(n==0 && packetIn[0]==STX)
                    tmOut:= RX_TMOUT;
                    pSTX := 0;
                    BCC  := 0;
                    n++;
                    continue;
                else if(n>0 && pSTX==0)
                    tmOut:= RX_TMOUT;
                    if(n==6 && packetIn[n-1]==ETX)
                        if(packetIn[n]==BCC)
                            if(packetIn[1]==SLAVE_ID)
                                if(packetIn[2]==TOUCH_HANDSHAKING)
                                    return (packetIn[3]<<4 + packetIn[4]);
                                endif
                            endif
                        endif
                    endif
                    BCC ^= packetIn[n];
                    n++;
                endif
            endif
            if(n>sizeof(packetIn)-1) break;
        wend
        return -1;
    endfunc
    Last edited by edha; 21st January 2015, 04:24 AM.
    Best Regards

    Edha

  • #2
    Hmm, well (com1_Full() & (com1_Count()==0)) can never be true, as, when com1_Full() is true, com1_Count will be SERIN_BUFFER.

    Anyway 'com1_Full()' and 'com1_Count()==SERIN_BUFFER' are effectively the same thing.

    I also wonder if you meant '&&' rather than '&' although the effect here will be the same.

    So maybe just fixing the above will fix your code, but that depends on what else is going on.

    Note that com1_Init(packetIn, SERIN_BUFFER, 0); could actually be com1_Init(packetIn, SERIN_BUFFER*2, 0); due to the word architecture of Picaso
    Mark

    Comment


    • #3
      Thanks for quick reply. I think & is a bitwise operator when applies to integer operands and so short-circuit when applies to bool operands, But && is a logical operator that applies to bool operands. Its right?

      Still freeze, the data appeared in realtime but after a moment data seemed to freeze.
      Is there any other way to read the serial data using an interrupt, not a poll?
      Best Regards

      Edha

      Comment


      • #4
        Yes, correct, I would have just done it the other way around in this case, but obviously that's just personal preference, I guess.

        I normally have a large comms buffer and 'poll' com_count() for being >= the required amount of data... Then you don't need to check for serin() being >= 0.

        If you can't work it out, perhaps by adding a few strategic 'prints', post some code that I can 'just run' and information about what I need to send to see the issue
        Mark

        Comment


        • #5
          Yes you are correct, I changed the code to be like this and my problem solved. Thanks .

          Code:
              while(tmOut--)
          
                  // serial error handle
                  if(com1_Full() || com1_Count()==SERIN_BUFFER || com1_Error())
                      com1_Init(packetIn, SERIN_BUFFER, 0);
                      break;
                  endif
          
                  // is data ready in buffer?
                  if(com1_Count()>0)
          
                      // read data from buffer
                      dt := serin1();
          
                      // is valid data?
                      if(dt>=0 && dt<=0xFF)
                          // process valid data in here
                      endif
          
                  endif
              wend
          Last edited by edha; 21st January 2015, 04:25 AM.
          Best Regards

          Edha

          Comment

          Working...
          X