lopy to raspberry pi 3 serial connection



  • Hi! I'm trying to get lopy to RPi serial connection to work (https://github.com/Bucknalla/lopy-raspberrypi). I'm on a RPI 3 and have troubleshooted for an entire day now and I surrender. Could someone please try to help me?

    From the RPI I have tried /dev/serial0, /dev/ttyS0, /dev/ttyAMA0. I have tried jumper cables from tx-tx, tx-rx, with and without ground. Tried changing the mode of the GPIO form ALT5 to ALT0. Nothing works

    The RPI sends the data or at least it writes data to the serial port (no crash at least). But nothing comes up on the Lopy (loops to see if uart1.any() returns True).

    All the settings is equal to the example code

    Help me please :)



  • @hsn548 Here is the code I used to get it working. Be sure to place the jumper cables in the right place. I had the cables in the wrong place at first. 1_1519046569556_IMG_3501.jpg 0_1519046569555_IMG_3500.jpg

    The following code works for me (i made a class for all the code on the RPI. Just import it and make a new PiGateway() and call its methods).

    RPi code:

    #run script as super user (e.g. $ sudo python3 sendlora.py)
    import serial, time

    class PiGateway:
    
        def __init__(self):
            self.ser = serial.Serial('/dev/serial0', 115200, timeout=10)
    
        def readFile(self, filename):
            f = open(filename,'r')
            content = f.read()
            f.close()
            return content
    
        def sendToLopy(self, device_id, data):
            n = 254
            id = "id=" + str(device_id)
            sendingDone = "sending done"
            #split data into 255 byte chunks for sending
            splitData = [data[i:i+n] for i in range(0, len(data), n)]
            #send device_id first. Wait one second between each packet to prevent collisions.
            self.ser.write(bytes(id, 'utf-8'))
            time.sleep(1)
            for dataChunk in splitData:
                #send each chunjk of data
                self.ser.write(bytes(dataChunk,'utf-8'))
                time.sleep(1)
            #send a string notifying that the transmission is done
            self.ser.write(bytes(sendingDone, 'utf-8'))   
    
        def getFromLopy(self):
            while True:
                if (self.ser.in_waiting > 0):
                    received = self.ser.read(self.ser.in_waiting).decode('utf-8')
                    return received
                time.sleep(1)
    

    on the Lopy the code was the following:

    import machine, time, pycom
    pycom.heartbeat(False)
    pycom.rgbled(0x000000)
    uart1 = UART(1, 115300, bits=8, parity=None, stop=1)
    uart1.init(baudrate=115200, bits=8, parity=None, stop=1)
    
    while True:
        if uart1.any():
            receiving = uart1.read().decode('utf-8')
            #Do something with what you receive here
            #I used exec(receiving) -> entire code sent from Rpi to be executed on Lopy. It works
            time.sleep(5)
            #remember to break here sometime
        time.sleep(1)
    

    Good luck



  • @thomand1000 Hi Thomas, Can you please share your working code? as i am also having the same problem... I shall be really thankful.. :D



  • @robert-hh Thank you very much! It didn't work right away, but I decided to try to eliminate faulty cables etc. So I made one script for each direction and tested them individually. I now have communication both ways, so then I just need to get the logic for when to read and write right and I'm good. For anyone struggling with this in the future the following worked for me (the initialization of both sides are like before):

    Lopy->Rpi

    code on the lopy:

    uart1.write('some string')
    

    code on the Rpi:

    print(ser.read(ser.in_waiting))
    

    Rpi -> lopy

    code on the Rpi:

    ser.write('some string')
    

    code on the lopy:

    print(uart1.read())
    

    Thanks for everyone helping me! :)



  • @thomand1000 Yes, like Robert said, you should be reading on one machine and writing on the other initially. Also, for clarity, specify bits, parity and stop also on the RPi side..



  • @thomand1000 It seems that in both code samples you first send something, and then wait for a response. I would have expected that you interlock that, so whwn you send something form one side, you would wait for data on the other side.
    The fact that you see somthing on the rpi side might be caused by buffering in the serial driver for any data that might arrive, even when no instance is waiting for it.



  • @zappfinger

    lopy code:

    from machine import UART
    import pycom, time
    
    pycom.heartbeat(False) # turn off heartbeat
    
    uart1 = UART(1, 115200, bits=8, parity=None, stop=1)
    uart1.init(baudrate=115200, bits=8, parity=None, stop=1)
    
    while True:
        uart1.write('test')
        if uart1.any():
            data = uart1.readall()
            pycom.rgbled(0xFF0000) # set LED to RED on if data received
            if data == b'send':
                uart1.write("SendToPi")
                pycom.rgbled(0x00FF00) # set LED to GREEN if data is b'send'
            time.sleep(1)
            pycom.rgbled(0x000000)
        time.sleep(0.25)
    

    RPi code:

    import serial
    
    with serial.Serial('/dev/serial0', 115200, timeout=10) as ser:
        ser.write(b'send')
        print(ser.read(4)) #prints b'test'. So link from lopy seems ok. 
    
    print("Data Sent")
    

    Now the messages from the lopy to the Rpi go through, but not the other way. It doesn't look like uart1.any() returns True at any point.

    Any suggestions or help would be awesome!

    Thanks :)



  • @thomand1000 That does not look good. Can you share your code on both sides?



  • @crumble Thank you very much. And all you other guys also. That did the trick. I'm trying to send the string b'send', but b'dsen' is received at the lopy. But this is probably an easy fix right?

    And b'sending this string' gets received as b'tringsending this s'

    Has this something to do with uarts readall or readline methods?



  • @crumble said in lopy to raspberry pi 3 serial connection:

    Please tell us the settings which works on your machine ;)

    It's running now. I had to do the following settings on the Pi3:
    in /boot/config.txt

    enable_uart=1
    dtoverlay=pi3-miniuart-bt
    

    I don't know if it necessary but i called as well

    sudo systemctl disable hciuart
    

    After these changes and reboot I had a stable serial device without noise on
    /dev/ttyAMA0

    Without these settings I got a lot of noise on /dev/ttyS0. Noise was gone after I had send a few lines from the Pi3.



  • @thomand1000 I struggle right now with the Pi3 and a PC via serial. The Bluetooth of the Pi3 interferes with the UART. You have to disable the bluetooth on the Pi3 to get predictable results. Sadly I can't help you, 'cause it is not running at the moment so I may have to do the frequency settings of the GPU as well. Simply google for pi3 serial and bluetooth.

    Please tell us the settings which works on your machine ;)



  • @zappfinger That#s what @thomand1000 tried first. And it still could be used. The only thing that does not work is UART methods. Instead you have to use input() and print(), or sys.stdin.readxxx() and sys.stdout.writexxx(). Both input() and sys.stdin.readxxx() calls however are blocking, and there is no safe way to tell whether data is waiting.



  • @thomand1000 Another approach is to not use the GPIO at all. Just connect the Pi3 and LoPy via USB. That way the LoPy also gets it's power form the Pi, while you can use serial comms over the USB. Works very well with <-Pi->Arduino. I see no reason why it should not work with the LoPy. Another advantage is that you do not expose the vulnerable GPIO pins...



  • @thomand1000 remove the lopy, so you just use the USB/Serial adapter of the expansion board.



  • @thomand1000
    Yes, in code it is but did you connected cables to P3/P4?
    Sometimes simplest thing is right.
    If all is connected right (GND have priority)
    then try @robert-hh advice and look if you got something on PC from and also to lopy

    Also try code without LORA between RPi and Lopy



  • @livius Yes.
    uart1 = UART(1, 115200, bits=8, parity=None, stop=1)
    uart1.init(baudrate=115200, bits=8, parity=None, stop=1, timout_chars=2, pins=("P3","P4")
    uart1.write("Connected...")

    And then in a loop check if uart1.any() and uart1.readall()

    But nothing.

    Thanks for the reply



  • @thomand1000
    Are you sure that you use UART1 not UART0?
    P3/P4 or G11/G24



  • Thanks for the quick answer. I didn't quite understand everything you said. I'm trying a 2-way communication channel so I thought it was tx (lopy)->rx (rpi) and tx(rpi) -> rx(lopy). And Gnd (lopy) to gnd (rpi). But this is wrong?

    What do you mean by "pull of the lopy"?

    Thanks! @robert-hh



  • @thomand1000 First of all: the GND connection is a MUST. Besides that, the connection is RX-RX and RX-TX. Then I would check is the RPI is actually sending. You could a USB/Serial adapter to connect it to your PC. If you don't have one, but the pycom expansion board, you can use that one: pull of take out the LoPy and connect P1 and GND to TX and GND of your rpi, using patch cables. In the PC setup you use to have the REPL, you should see what the RPI is sending.
    If it does, you can re-plug the LoPy , connect P1 to P4 and use you PC keyboard as input source. If you get something, then you know, that the connections are right.
    Then it's up to the code.


 

Pycom on Twitter