Menu

hsersend and hserreceive with one microcontroller

JANIS
2014-02-13
2014-02-24
  • JANIS

    JANIS - 2014-02-13

    hello! I want to establish data exchange between two microcontrollers, transmit data to one side (one microcontroller transmits, the other microcontroller acts as a receiver) is not a problem, but the data exchange simultaneously (each microcontroller acts as both a transmitter and as a receiver) between microcontrollers I can not made.

    Just RECEIVE and just RECEIVE - no problem,
    16f628a as receiver:
    
        #chip 16f628a, 4
        #config osc=int
        #define USART_BAUD_RATE 9600
        #define USART_BLOCKING
    
        Dir PORTb.2 in 'Rx   hserreceive
        dir portb.3 out                              'PWM
        #define PWM_OUT1 PORTa.1
        dir PWM_OUT1 out
        cycle:
         'SerReceive 1, portanew
        portanew = hSerReceive
        pwmout 1, portanew,  1
        wait 5 ms
        goto cycle
    
    16f88 as transmitter:
    
        #chip 16f88, 4
        #config osc=int
        #define USART_BAUD_RATE 9600
        #define USART_BLOCKING
            Dir PORTb.5 out   ' Tx                            
        dir an1 in  'porta.1
        cycle:
    
        hsersend readad(an1)
    
        wait 5 ms
        goto cycle
    
    with one microcontroller-both transmit and receive - not working:
    
        16f628a as transmitter&receiver:
        #chip 16f628a, 4
        #config osc=int
        #define USART_BAUD_RATE 9600
        #define USART_BLOCKING
    
        Dir PORTb.1 out  ' Tx hsersend
        dir porta.0 in
        Dir PORTb.2 in 'Rx   hserreceive
    
        #define PWM_OUT1 PORTa.1 'PWM
        dir PWM_OUT1 out
    
        cycle:
    
        hsersend porta.0 ' switch - as bit
    
        portanew = hSerReceive
        pwmout 1, portanew,  1
        wait 5 ms
        goto cycle
    
    16f88 as transmitter&receiver:
    
        #chip 16f88, 4
        #config osc=int
        #define USART_BAUD_RATE 9600
        #define USART_BLOCKING
    
        Dir PORTb.5 out   ' Tx                           
        dir an1 in  'porta.1
        dir portb.3 out  'led
    
        dir portb.2 in  'Rx
    
        cycle:
    
        hsersend readad(an1) ' byte
        porta.1 = hSerReceive
        if  porta.1=1 then         
        portb.3=on
        else
        portb.3=off
        end if
    
        wait 5 ms
        goto cycle
    

    how to realize data exchange between the microcontrollers on both sides simultaneously or it is impossible?? I hope to any help!

    Edited to make this readable... please use four tilders to at top and bottom of code.

     

    Last edit: Anobium 2014-02-13
  • Anobium

    Anobium - 2014-02-13

    My thoughts. Is this a sync issue. What do I mean? You have two processors one talking and one listening and they are out of sync.

    Add a connection on a spare port, pull to high with a 4.7k. Then, prior to sending from one device check the port is high (so the port is at this stage an input), if high then pull the port low (so change port to output, then set low), then send the data, then set port to input. Do this for both devices. It will ensure you only send when the other device is in a position to 'listen'.

    However, I would use I2C for this transmission. It would be easier. :-)

     

    Last edit: Anobium 2014-02-13
  • kent_twt4

    kent_twt4 - 2014-02-13

    Another idea is having the receiver wait for an ascii command, like EOT (end of transmission), to toggle between receive and transmit. This would require reserving a dec number (like 255) with HSer send/rec: OR, more overhead on both ends to perform bin2ascii, and asciitobin, type operations to differentiate EOT ascii type commands from the dec numbers.

    Do Until value = 255
    value = HserReceive
    ....
    ....
    Loop
    
     

    Last edit: kent_twt4 2014-02-13
  • JANIS

    JANIS - 2014-02-13

    Thanks for the reply, Anobium!Let's try to connect the resistors.
    My idea is as follows - use 16F88 analog input temperature transfer (byte), but the data it receives for execution configured for output ports(bits). The second micro-controller 16f628 I want to use to indicate temperatures (received data), but the processed information back to the 16F88 output ports.
    Distance between microcontrollers will be 50m, so the data transfer thinking of using MAX485, then I2C can not be used ...? But first I want to run usart between both microcontrollers. Perhaps the need to use other microcontrollers? Sorry for my English. My program code example can run?

     
  • Anobium

    Anobium - 2014-02-13

    @Kent. A great idea. The power of community.

    In my projects (in the past...) I used to send a few "U" or 0x55 as the sync code followed the data. The idea of sending 0x55 is that this is transmitted as "0101010102 this would bring the serial circuit into a steady state. Then, as you recommended, wait until your receive the 0x55's then you know you are in sync.

    Or, simple use Kent's recommendation. :-)

    Thinking about the idea... I could document and put in the help file.

     
  • JANIS

    JANIS - 2014-02-13

    Thank you, kent_twt4 ! Does your idea will work in my case?

     
  • Anobium

    Anobium - 2014-02-13

    Both ideas will work. I would go with the Kents idea. Its easier and you do not need to tie up a port.

    Post your code if you have any issues.

     
  • JANIS

    JANIS - 2014-02-13

    I am a beginner in the world of microcontrollers,Anobium and kent_twt4 are professionals maybe you can give some examples of program code for my case?? My idea of ​​the project is clear to you. Thanks!

     
  • kent_twt4

    kent_twt4 - 2014-02-13

    Use a terminal to act as one of the Pic transceivers. Type in a byte or two with the termination code on the terminal. Have the other Pic echo back what was typed in, or an acknowledgement of some type to confirm.

     
  • JANIS

    JANIS - 2014-02-13

    I connect resistors as recommended anobium, it did not help :((((

     
  • Anobium

    Anobium - 2014-02-14

    Let start again. :-)
    You have at least three options (I am sure there are more), they are: I2C, three wire serial, two wire serial.
    You cannot use I2C as your requirement of 50m will prevent this without adding more complexity.
    You could you use three wire serial. This uses the pull up resistor as I described.
    Finally, you have two wire serial. This is the method Kent recommended and I think will work for you. You do not need pull resistors for this method.

    So, remove the resistors and read on. :-)

    This is not tested code but this is the approach for same chips.

    ~~~~~
    'Chip Settings
    #chip 16F1823,8

    ;Variables
    Dim buffer As string * 1
    Dim syncbyte as Byte
    Dim loopcount as word

    sync = 0x55 ' you can use 255 - your choice

    Do
    ' Send info
    Repeat 3
    HSerSend syncbyte
    end Repeat
    HSerSend readad(0)

        ' get info
        loopcount = 0
        Do Until value = syncbyte
          receivedvalue = HserReceive
          loopcount++
          ' intended to stop endless loop... should work
          if loopcount  > 65000 then exit Do
        Loop
    

    Loop

    ~~~~

     
  • JANIS

    JANIS - 2014-02-15

    Thank anobium! I will report for results!

     
  • Anobium

    Anobium - 2014-02-15

    Sorry, I did think about this again.

    Here is some code for an RS232 Ring Buffer. This does work. If you send three sync codes the next piece of data is treated as the data to be read. So, in this example you can send thee U's and then the next piece of data is shown on the terminal. I do not have two devices handy to test.

    Key parts, the interrupt, the sub and the functions and few constants.

    But, essentially the buffer is stored in a buffer and you read via the function 'bget'. If the buffer is empty then 'bkbhit' is not true.

    Try in integrate this code.

    Good luck.

    ~~~~~
    ;Chip Settings

    chip 16F1937,32

    config LVP=OFF, BODEN=OFF, WDT=OFF, OSC=XT

         #include <outputserial.h>
    
        ' [todo] This is the config for a serial terminal
        ' turn on the RS232 and terminal port.
        ' Define the USART port
        #define USART_BAUD_RATE 9600
        #define USART_BLOCKING true
        ' [todo] Ensure these port addresses are correct
        #define SerInPort PORTc.7
        #define SerOutPort PORTc.6
        'Set pin directions
        Dir SerOutPort Out
        Dir SerInPort In
    
    
        ' [todo] This assumes you are using an ANSI compatible terminal.  Use PUTTY.EXE it is very easy.
    
        wait 1 s
        ANSIERASECREEN
        ANSI ( 0, 2)
        HSerPrint "Started: Serial between two devices"
        ANSI ( 0, 6)
        crlf(2)
    
        DIR PORTA.0 IN
    

    ;Interrupt Handlers
    On Interrupt UsartRX1Ready Call readUSART

    ' all important!
    #define bkbhit (next_in <> next_out)
    #define BUFFER_SIZE 8
    ;Variables
    Dim buffer(BUFFER_SIZE)
    Dim next_in as byte: next_in = 1
    Dim next_out as byte: next_out = 1
    Dim syncbyte as Byte

    syncbyte = 0x55 ' you can use 255 - your choice

    Do
    ' Send info
    ' Repeat 3
    ' HSerSend syncbyte
    ' end Repeat
    ' HSerprint readad(an0)

          do while bkbhit
    

    ' HSerPrint chr(bgetc)

             if bgetc = syncbyte and bgetc = syncbyte and bgetc = syncbyte then
                HSerPrint "sync'ed '"
                HSerPrint chr(bgetc):CRLF
             end if
          Loop
    

    LOOP

    Sub readUSART
    
        buffer(next_in) = HSerReceive
        temppnt = next_in
        next_in = ( next_in + 1 ) % BUFFER_SIZE
        if ( next_in = next_out ) then  ' buffer is full!!
           next_in = temppnt
        end if
    
    End Sub
    
    function bgetc
       wait while !(bkbhit)
       bgetc = buffer(next_out)
       next_out=(next_out+1) % BUFFER_SIZE
    end Function
    
     
  • JANIS

    JANIS - 2014-02-16

    Thank Anobium! It is likely that your version works, but it is difficult. For me. Maybe it is probably easier - in one period of time first microcontroller transmit data, but the other to receive, for example - 100ms one microcontroller transmits , other receive data, then 100ms second microcontroller transmits and receives the first ...?

    For example:
    If time <100 then Hsersend ......
    If time> 100 then Hserreceive .....

    If time = 200 time = 0 then
    .....
    .....

     
  • Anobium

    Anobium - 2014-02-16

    Another go.

    This time I have changed the sync tests. To sync to pics is not easy. To read a pic from a pc... is a lot easier!

    I have documented a little better for you. You will find the byte of interest in the middle of the Do-Loop.

    This time.... we sample the incoming bytes, check for three and then the next is the byte we are interested in. If we do not get a sync byte then we assume that the pic is out of sync and restart the process.

    Over to you for testing. Let us know the results.

    Anobium

    edited. I have got two pics. See attached.
    One is a master and the other a slave. The code is very similar but not same.... the master needs to send the data out (see 16f1937) and the slave need to respond (see 16f1947). It make sense now I have seen it working.

    I am sending a AD value from the master, receiving at the slave and returning from the slave the same value + turn on LED if value is greater than 127, then when the master gets the data from the slave turn on an LED if value (from the slave) is greater than 127. Then, the master send the next value.

    Blows the mind...

     

    Last edit: Anobium 2014-02-16
  • JANIS

    JANIS - 2014-02-16

    anobium thank you! I'll try to experiment on the results I will report,

     
  • Anobium

    Anobium - 2014-02-21

    Any progress? I want to break down the test kit I have here.

    I need to do a project. :-)

     
  • Anobium

    Anobium - 2014-02-21

    Any progress? I want to break down the test kit I have here.

    I need to do a project. :-)

     
  • JANIS

    JANIS - 2014-02-22

    while is not progress: (( I'll try tomorrow's serious. But I have only 2 types of microcontrollers - 16f628a 16F88

     
  • JANIS

    JANIS - 2014-02-24

    hello, anobium! I can not create the code for my chips .... you yourself tried to run your code using test kit? your written code can not compile....

     
  • Anobium

    Anobium - 2014-02-24

    You may have to the serial terminal. Search for [todo] This code is specific to a serial terminal.

     

Log in to post a comment.