Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 13 of 13

Thread: Teensy 4.0/4.1 to Raspberry Pi wired communication over 1-2 meters

  1. #1
    Junior Member
    Join Date
    Feb 2021
    Posts
    5

    Teensy 4.0/4.1 to Raspberry Pi wired communication over 1-2 meters

    The project I am working on has a pi and teensy communicating where the teensy controls a bunch of stepper motors and recieves sensor input, and that data is sent to a pi to be diplayed for the user on a large touch screen. The display allows inputs to be sent to control motor positions and speeds (basically an HMI).

    What is the best way to communicate between the two? I figured i2c is out because of the cable distance, so would Serial, CAN, or USB be appropriate? The two will likely be connected by USB anyway to do OTA updates. I'd like to use the 4.0 since it's a tad smaller and things are going to be tight in my control box, but if I have to use a 4.1 it isn't too much of a problem. Thanks!

  2. #2
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    24,454
    USB can do 2 meters. It's the way needing the least amount of extra hardware, just a good quality 2 meter cable. USB provides power, but for 2 meters make sure the cable has #24 or larger wires for the power. Cheap cables have tiny #28 or #30 wires which cause too much voltage loss if going a long distance.

    Serial using RS422 / RS485 can go a long distance, but you need the transceiver hardware on both ends.

    CAN bus also needs transceivers, and you'll need a CAN add-on board since Raspberry Pi doesn't have CAN built in.

    Ethernet is the other good way to work over long distance. There you'd need Teensy 4.1 and the ethernet kit, and of course an ethernet cable. Ethernet has the nice advantage that it's magnetically coupled, so you don't have to worry about ground loops or ground difference if the 2 aren't powered from a common source.

  3. #3
    Junior Member
    Join Date
    Feb 2021
    Posts
    5
    Thanks for the help. Ethernet seems like it may be the way to go.

    Does the ethernet kit just break the pins out to be used with an RJ45 connector? Because of the physical requirements, most of my connectors are industrial m12 style plugs. Is it possible to wire striaght to the board if I'm not using a standard ethernet plug or does the ethernet kit have some other functionality needed to facilitate data transfer?

  4. #4
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    24,454
    Quote Originally Posted by jackson View Post
    Does the ethernet kit just break the pins out to be used with an RJ45 connector?
    The connector is a "magjack", which means is more than just a plain RJ45. It has the ethernet magnetic coupling parts built in.

    The kit does more or less just break out the pins, but to a magjack. It also has 1 capacitor. Scroll down to the bottom of that page for the schematic and datasheet on the magjack.

  5. #5
    Junior Member
    Join Date
    Apr 2021
    Posts
    13
    Hello! I have a similar project I am working on. I have two motors, and each motor has an encoder sending data to my Teensy 4.1. The hardware is also ready to go; I soldered the magjack Ethernet setup. Now I am trying to send the data from my Teensy encoder to my Raspberry Pi 4B. Could you direct me to the correct software for this? Do I need to configure my Pi in order to receive this data? I read somewhere about the <Ethernet.h> library vs the <NativeEthernet.h> library. Do you mind explaining the difference? Thank you!

  6. #6
    Quote Originally Posted by hannahgill12 View Post
    Hello! I have a similar project I am working on. I have two motors, and each motor has an encoder sending data to my Teensy 4.1. The hardware is also ready to go; I soldered the magjack Ethernet setup. Now I am trying to send the data from my Teensy encoder to my Raspberry Pi 4B. Could you direct me to the correct software for this? Do I need to configure my Pi in order to receive this data? I read somewhere about the <Ethernet.h> library vs the <NativeEthernet.h> library. Do you mind explaining the difference? Thank you!
    NativeEthernet was created to take advantage of the ethernet controller built inside the iMXRT chip. This should be more efficient and faster than an external controller, which is what the WIZNET is. The WIZNET controller uses the Ethernet.h. With the Teensy 4.1, NativeEthernet is the preferred library.

    Start with this example: https://github.com/vjmuzik/NativeEth...eiveString.ino

    Then write your UDP receiver on the pi.

    I've used python with this code to receive binary UDP packets on port 5555 on windows. Should work on the RPi, or may need some slight tweaks.

    Code:
    import socket
    import sys
    import hexdump
    
    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    sock.bind( ( '192.168.1.77', 5555) )  # (host, port) because AF_INET
    print("Listening...")
    
    while True:
        packet=sock.recv(2048)
        length = len(packet)
        print('Received', length, "| ", end='')
      
        if (length > 2 ):
            x = 0
            while x < length:
                char = format(packet[x],'02x')
                if ( x > (2 + packet[3]) ):
                    print ('     ', end='')
                else:
                    print ('0x',char,' ', sep='', end='')
                x = x + 1
            print('')
            print(' | ', end='')
            print(packet)
        else:
            print(packet)
    192.168.1.77' is the IP of my windows PC. Be sure to open up port 5555 on the Windows firewall of the packets will get blocked.
    Last edited by TeensyWolf; 04-23-2021 at 05:09 AM. Reason: clarification

  7. #7
    Junior Member
    Join Date
    Apr 2021
    Posts
    13
    Thanks TeensyWolf!

    I tried running the python code on my pi, but I don't have the hexdump module and I'm not sure how to open up the 5555 port (or what that means exactly). Do you mind clarifying?

    Also, how do I find the IP of my Raspberry Pi? Is it the same or different than the IP address in the UDPSendReceiveString code for the Teensy?

    Thanks!
    Hannah

  8. #8
    Ports are usually blocked by computer firewalls, by default. At least, they should be. This is to protect the computer from bad actors trying to send data into ports.

    On Raspbian terminal, type this to open the firewall for port 5555.

    Code:
    sudo ufw allow 5555
    This should open for UDP as well as TCP packets. If you have something listening (python), then the UDP packets should get thru.

    You can find your Raspberry Pi's IP address by typing this into terminal

    Code:
    ifconfig
    It will return something like this

    Code:
    eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
            inet 192.168.20.10  netmask 255.255.255.0  broadcast 192.168.20.255
            inet6 fe80::7d88:cb48:b2d5:ed31  prefixlen 64  scopeid 0x20<link>
            ether b8:27:eb:6a:5c:ff  txqueuelen 1000  (Ethernet)
            RX packets 3383323  bytes 746246998 (711.6 MiB)
            RX errors 0  dropped 0  overruns 0  frame 0
            TX packets 507067  bytes 66524730 (63.4 MiB)
            TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
    In this case 192.168.20.10 is my eth0 (wired ethernet) IP address

    You will also get more if you have WiFi hardware running, it will show as wlan0, wlan1, etc.

    Let me look at that Python code, get something that will compile & run on Raspian. Standby.

  9. #9
    The Python code I had was printing binary packets.

    If you are sending ASCII strings, you can use this, found over here: https://www.raspberrypi.org/forums/v...c.php?t=184241

    Code:
    import socket
    
    UDP_IP = "192.168.20.10" # IP address of the Raspberry Pi
    UDP_PORT = 5555 # UDP Port teensy is sending data to
    
    sock = socket.socket(socket.AF_INET, # Internet
    socket.SOCK_DGRAM) # UDP
    sock.bind((UDP_IP, UDP_PORT))
    
    while True:
      data, addr = sock.recvfrom(1024) # buffer size is 1024 bytes
      print("received message:", data)
    Binary data will still print, but it will start with b'\x

  10. #10
    Junior Member
    Join Date
    Apr 2021
    Posts
    13
    On the example "UDPSendReceiveString" at this link: https://github.com/vjmuzik/NativeEth...eiveString.ino

    Do I change the localPort to match the UDP_PORT on the Pi? So I should set both to 5555, even though it comes in the Native Ethernet code as 8888?

    I'm getting the following error on my Pi interface:

    sock.bind((UDP_IP, UDP_PORT))
    OSError: [Errno 99] Cannot assign requested address


    Thanks,
    Hannah

  11. #11
    Quote Originally Posted by hannahgill12 View Post
    On the example "UDPSendReceiveString" at this link: https://github.com/vjmuzik/NativeEth...eiveString.ino

    Do I change the localPort to match the UDP_PORT on the Pi? So I should set both to 5555, even though it comes in the Native Ethernet code as 8888?

    I'm getting the following error on my Pi interface:

    sock.bind((UDP_IP, UDP_PORT))
    OSError: [Errno 99] Cannot assign requested address


    Thanks,
    Hannah
    Your error is likely because your UDP_IP is wrong, this needs to be the eth0 IP of the Raspberry Pi. Do a ifconfig on pi terminal to get the IP address of the eth0. Post here if you are unsure.

    The UDPSendReceiveString.ino example requires you to send a UDP packet to the Teensy first, then it mirrors it back on the incoming IP address.

    Each UDP device will have an LOCAL port for incoming packets, the device will listen on this port. So NativeEthernet uses 8888, so the Pi should send stuff to this port. I don't have an example for any Python code to do this for you at moment. Everything I've been talking about is Teensy sending UDP packet and Pi receiving it and displaying it. Try to get that working first.

    You can hard-code the Raspberry pi's IP address by adding this at/after line 25 (change it to the raspberry pi's address) in example UDPSendReceiveString.ino

    Code:
      IPAddress destinationIP(192, 168, 20, 10);
    Then change your loop code to just spit out a UDP packet to the raspberry pi, port 5555 once every second:

    Code:
    void loop() {  
      Udp.beginPacket(destinationIP, 5555);
      Udp.write(ReplyBuffer);
      Udp.endPacket();
      delay(1000);
    }
    Are you direct cable connected pi to teensy? If so, you will have to configure the IP address on the pi manually - see https://www.raspberrypi.org/document...uration/tcpip/

  12. #12
    Junior Member
    Join Date
    Apr 2021
    Posts
    13
    THANK YOU TeensyWolf! After some time sifting through this, I got it figured out and it makes sense now

    I have the Pi receiving UDP messages from the Teensy. Did you happen to find any Python code for sending UDP messages back to the Teensy from the Pi?

    Thank you again for your help!

  13. #13
    Hey, you're welcome. I don't have any examples I've tested, but found this, might be a good place for you to start: https://linuxhint.com/send_receive_udp_python/

    I think once you have it working one way, the other way is easy to figure out.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •