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

Thread: Teensy 4.1 UDP crash with more then 24 bytes?

  1. #1
    Junior Member
    Join Date
    Mar 2021
    Posts
    2

    Teensy 4.1 UDP crash with more then 24 bytes?

    First my code and out put and then my questions and observations:

    code running on Teensy:
    Code:
    #include <NativeEthernet.h>
    #include <NativeEthernetUdp.h>
    
    #include <FastLED.h>
    
    #define UDP_TX_PACKET_MAX_SIZE 1480
    
    // How many leds in your strip?
    #define NUM_LEDS 14
    
    
    #define DATA_PIN 3
    #define CLOCK_PIN 2
    
    // Enter a MAC address and IP address for your controller below.
    // The IP address will be dependent on your local network:
    byte mac[] = {
      0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED
    };
    IPAddress ip(10, 10, 10, 10);
    
    // Define the array of leds
    CRGB leds[NUM_LEDS];
    
    unsigned int localPort = 8887;      // local port to listen on
    
    // buffers for receiving and sending data
    char packetBuffer[UDP_TX_PACKET_MAX_SIZE];  // buffer to hold incoming packet,
    char ReplyBuffer[] = "acknowledged";        // a string to send back
    
    // An EthernetUDP instance to let us send and receive packets over UDP
    EthernetUDP Udp;
    
    void setup() {
      // You can use Ethernet.init(pin) to configure the CS pin
      //Ethernet.init(10);  // Most Arduino shields
      //Ethernet.init(5);   // MKR ETH shield
      //Ethernet.init(0);   // Teensy 2.0
      //Ethernet.init(20);  // Teensy++ 2.0
      //Ethernet.init(15);  // ESP8266 with Adafruit Featherwing Ethernet
      //Ethernet.init(33);  // ESP32 with Adafruit Featherwing Ethernet
    
      // start the Ethernet
      Ethernet.begin(mac, ip);
    
      // Open serial communications and wait for port to open:
      Serial.begin(9600);
      while (!Serial) {
        ; // wait for serial port to connect. Needed for native USB port only
      }
    
      // Check for Ethernet hardware present
      if (Ethernet.hardwareStatus() == EthernetNoHardware) {
        Serial.println("Ethernet shield was not found.  Sorry, can't run without hardware. :(");
        while (true) {
          delay(1); // do nothing, no point running without Ethernet hardware
        }
      }
      if (Ethernet.linkStatus() == LinkOFF) {
        Serial.println("Ethernet cable is not connected.");
      }
    
      // start UDP
      Udp.begin(localPort);
      
      FastLED.addLeds<APA102, DATA_PIN, CLOCK_PIN, BGR>(leds, NUM_LEDS);  // BGR ordering is typical
     
      Serial.println(UDP_TX_PACKET_MAX_SIZE);
      Serial.println("end of setup");
    }
    
    void loop() {
      // if there's data available, read a packet
      uint32_t packetSize;
      if (packetSize = Udp.parsePacket()) Serial.println("gotone");
      if (packetSize) {
        Serial.print("Received packet of size ");
        Serial.println(packetSize);
        Serial.print("From ");
        IPAddress remote = Udp.remoteIP();
        for (int i=0; i < 4; i++) {
          Serial.print(remote[i], DEC);
          if (i < 3) {
            Serial.print(".");
          }
        }
        Serial.print(", port ");
        Serial.println(Udp.remotePort());
    
        // read the packet into packetBufffer
        Udp.read(packetBuffer, UDP_TX_PACKET_MAX_SIZE);
        Serial.println("Contents:");
        Serial.printf(packetBuffer);
        Serial.println();
    
        FastLED.clear();
        FastLED.show();
        uint32_t dataCounter = 0;
          for (uint32_t i = 0; i < packetSize; i++)
          {
            leds[i].r = packetBuffer[dataCounter+2];
            leds[i].g = packetBuffer[dataCounter+1];
            leds[i].b = packetBuffer[dataCounter  ];
            dataCounter += 3;
            Serial.println(dataCounter);
            
          }
        
       // leds = packetBuffer;
        FastLED.show();
    
        // send a reply to the IP address and port that sent us the packet we received
        Udp.beginPacket(Udp.remoteIP(), Udp.remotePort());
        Serial.println("out");
        Udp.write(ReplyBuffer);
        Serial.println("out2");
        Udp.endPacket();
        Serial.println("out3");
      }
      delay(1);
      
    }
    Python code running from my computer:

    Code:
    import socket
    import time
    
    with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as sock:
        sock.connect(("10.10.10.10", 8887))
        
        while True:
        
            sock.send(bytes.fromhex("220000002200000022220000002200000022220000002200"))
            print(sock.recvfrom(1500))
            time.sleep(1)
            sock.send(bytes.fromhex("002200220022220000222200000022002200222222000022"))
            print(sock.recvfrom(1500))
            time.sleep(1)
            sock.send(bytes.fromhex("000022002200220022002222002200220022002222002200"))
            print(sock.recvfrom(1500))
            time.sleep(1)
            print('done')
    when running this Python code from my computer everything works as expected and if we change the Python code to:

    Code:
    import socket
    import time
    
    with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as sock:
        sock.connect(("10.10.10.10", 8887))
        
        while True:
        
            sock.send(bytes.fromhex("220000002200000022220000002200000022220000002200"))
            print(sock.recvfrom(1500))
            time.sleep(1)
            sock.send(bytes.fromhex("002200220022220000222200000022002200222222000022"))
            print(sock.recvfrom(1500))
            time.sleep(1)
            sock.send(bytes.fromhex("000022002200220022002222002200220022002222002200444444"))
            print(sock.recvfrom(1500))
            time.sleep(1)
            print('done')
    Now things start to go off the rails... I added 3 more bytes to the last message and here is the output I get from the Python:

    Code:
    (b'acknowledged', ('10.10.10.10', 8887))
    (b'acknowledged', ('10.10.10.10', 8887))
    (b'acknowledged$fDt\x8e\xbbC\xa9\x01\xec\xb3\xad', ('10.10.10.10', 8887))
    done
    The serial out from the teensy looks good and the LEDs all update correctly but the last acknowledged statement from my Python looks to have some garbage in it.

    If I change the Python again:

    Code:
    import socket
    import time
    
    with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as sock:
        sock.connect(("10.10.10.10", 8887))
        
        while True:
        
            sock.send(bytes.fromhex("220000002200000022220000002200000022220000002200"))
            print(sock.recvfrom(1500))
            time.sleep(1)
            sock.send(bytes.fromhex("002200220022220000222200000022002200222222000022"))
            print(sock.recvfrom(1500))
            time.sleep(1)
            sock.send(bytes.fromhex("000022002200220022002222002200220022002222002200444444444444444444444444444444"))
            print(sock.recvfrom(1500))
            time.sleep(1)
            print('done')
    Adding more bytes to the last massage again the teensy crashes. It will no longer respond to pings. Here is the out from the Python:

    Code:
    (b'acknowledged', ('10.10.10.10', 8887))
    (b'acknowledged', ('10.10.10.10', 8887))
    And here is the output from the serial of the teensy:

    Code:
    1480
    
    end of setup
    
    gotone
    
    Received packet of size 24
    
    From 10.10.10.1, port 57503
    
    Contents:
    
    "
    
    3
    
    6
    
    9
    
    12
    
    15
    
    18
    
    21
    
    24
    
    27
    
    30
    
    33
    
    36
    
    39
    
    42
    
    45
    
    48
    
    51
    
    54
    
    57
    
    60
    
    63
    
    66
    
    69
    
    72
    
    out
    
    out2
    
    out3
    
    gotone
    
    Received packet of size 24
    
    From 10.10.10.1, port 57503
    
    Contents:
    
    
    
    3
    
    6
    
    9
    
    12
    
    15
    
    18
    
    21
    
    24
    
    27
    
    30
    
    33
    
    36
    
    39
    
    42
    
    45
    
    48
    
    51
    
    54
    
    57
    
    60
    
    63
    
    66
    
    69
    
    72
    
    out
    
    out2
    
    out3
    So this looks to me like a buffer or an array somewhere is being overrun but the odd thing is that serial output seems to die long before the teensy does because I get the last FastLED.show() as the LED strip is displaying the third packet as expected. I don't seem to get anything from the serial output about processing the third packet so it makes it difficult to figure out where things are jumping off the rails. I know the last packet was processed because the LED strip is displaying it. Also, the fact the the Teensy stops responding to the network is bad (it's just dead). I see that the UDP_TX_PACKET_MAX_SIZE default size is 24 bytes and that seems to be the biggest size packet that the teensy is fine with handling increasing UDP_TX_PACKET_MAX_SIZE doesn't seem to buy you anything. What good is UDP_TX_PACKET_MAX_SIZE? Why does it exists and why is it set so low? I'm not sure UDP_TX_PACKET_MAX_SIZE is even the problem but it seems suspicious. I don't think my code is bad but my programing skills aren't the best. I think something is getting messed up in teensy NativeEthernet.

    I'm using a fresh install of Arduino 1.8.13, 1.53 Teensyduino, and I grab a new version of NativeEthernet 1.0.5

    I think version of NativeEthernet 1.0.1 came with Teensyduino, and that version seems to handle less bytes then 1.0.5 before crashing.

    Please any help will be grateful I have six teensy 4.1 I want to use for a big project... I'm trying to get them to replace 10 esp32 boards because the wireless isn't reliable.

  2. #2
    I noticed you are running outside of the leds array, the length is 14 and you are accessing up to packetSize which is 24,24,27. It could be causing your problem. The garbage data in your third acknowledge message may be from your code overwriting the null character at the end of your char array and causing it to continue printing until it hits the next one. I assume you wanted something like i < packetSize/3 but you could still run into an issue if you don't check whether it is greater than the size of the leds array and handle it accordingly.

    Code:
        uint32_t dataCounter = 0;
          for (uint32_t i = 0; i < packetSize; i++)
          {
            leds[i].r = packetBuffer[dataCounter+2];
            leds[i].g = packetBuffer[dataCounter+1];
            leds[i].b = packetBuffer[dataCounter  ];
            dataCounter += 3;
            Serial.println(dataCounter);
            
          }

  3. #3
    Junior Member
    Join Date
    Mar 2021
    Posts
    2
    Yeah, that's defiantly a problem. I think the UDP_TX_PACKET_MAX_SIZE sent me down the wrong rabbit hole because it fit so well... I couldn't catch my mistake because the serial output was dyeing before I could see the problem.

    Thank you

    more testing I go.

  4. #4
    No problem, hopefully that's the issue. I'm not even sure if UDP_TX_PACKET_MAX_SIZE does anything inside of the library, I quickly searched for it but I didn't get any hits. I would assume it's just a standard way of declaring the buffer array size and using it across your program in that case but I could be wrong. Good luck with your project!

Posting Permissions

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