🔮Adafruit sale all weekend long – use the code ADATHX for 15% off! 🔮
0

Teensy / Airlift locking up with UDP
Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.

Teensy / Airlift locking up with UDP

by tcweller on Thu Oct 29, 2020 1:44 am

I'm working on an OSC message receiver using Teensy 3.6 and Adafruit AirLift ESP32 WiFi co-processor. I'm using WiFiNINA and CNMAT/OSC libraries. Another project using the same hardware for sending OSC over the network from the Teensy went off very easily. This receiving code, which is based on examples from the libraries above, also works mostly as expected and I'm able to route OSC messages successfully to functions.

The problem I'm running into is that after a period of several minutes the whole thing locks up and is unresponsive until power cycle. It isn't throwing any OSC errors prior to this.

I've gone through the code below many times to reduce it down to sending debugging messages over serial so I can eliminate as many factors as possible. Nothing else is connected to the build. The wiring is default SPI (as shown in the code)

I've built a few UDP-OSC test routines to consistently send simple OSC messages. I send the device a constant stream of modestly sized (16) packets at times between 10 and 60 ms. I ran the identical routine in a loop and it locked up at: 14.1 min, 9.2 min, 28.0 min, 6.5 min. It seems kinda random and clearly doesn't quit after a certain number, frequency, or size of OSC messages.

Things that I've tested/tried:

* Although I'd like this thing to be able to handle OSC messages coming in pretty fast, I tried reducing the speed of the messages. A much slower test routine (by a factor of 10) still resulted in a lockup after 6.3 min. When I slowed this waaaaay down to one message per second it seems like it runs a bit longer before locking up - nearly an hour. But that isn't really practical for this application.

* I've tried a 5VDC power supply that provides 1 amp and it has no effect. The docs mention 250mA spikes, but a 1 amp supply should be able to handle this plus the teensy with no problem. So it seems the lock up still happens regardless of available power. I took the temp of the coprocessor and its about 91-94 deg F. Not sure if that is overly hot or not. Also tried testing without noLowPowerMode() called -- still locked up after 48.9min and the latency was just terrible.

* I tried stripping all the USB over serial stuff in case there was a conflict with that. No effect.

* Slowing down the rate of the creation of OSCBundle bundleIN; by 1, 2, 5, 10 and 50ms. At 50 it starts to miss a lot of incoming data. None of the speeds successfully stop the lockup. Without that delay interval, the lockup still happened at 5.3 minutes and then 27.5 min - so I don't see much of a correlation, but maybe it locks up a little slower on average.

* The same lock up happens on a Teensy LC and a different Airlift -- so I doubt it is a problem with connections or faulty hardware. Using the LC it happens after roughly the same amount of time. I did notice that the LC didn't handle OSC dispatching as quickly as the 3.6, which is what I'd expect.

Things I'm wondering about:

* I'm not crazy about constantly polling the co-processor in the main loop. The AirLift has a GP0 pin (currently not connected) which the docs say can "let you know data is ready for reading" but I wasn't able to find a good example using this to check for incoming UDP data.

* Is there a way using these libraries to make sure SPI speed is set ideally? The AirLift talks at 8MHz SPI -- and I think that is the baud rate that WiFiNINA is using, but I don't know how to check that this is indeed how fast they're actually communicating. I'm pretty new to this library and SPI in general.

* I'm using the WiFiNINA version from AdaFruit because the latest version doesn't provide a way to assign pins. The firmware on the Airlift is as-shipped version 1.2.2. I didn't see a compelling reason to update this since the newer version seemed to just have added BLE which I don't need.

* I'd really like to get this working and would be open to using another library if someone has working code they're willing to share.
Attachments
teensy_airlift_udp_osc.ino
(4.57 KiB) Not downloaded yet

tcweller
 
Posts: 7
Joined: Mon Oct 26, 2020 10:45 am

Re: Teensy / Airlift locking up with UDP

by tcweller on Fri Oct 30, 2020 3:47 pm

I've narrowed this problem down even further and moved the reset/busy pins around to make sure there wasn't something going on with that.

This problem has nothing to do with OSC and I'm pretty sure I've isolated it to Udp.parsePacket().

Below is the code that I'm running straight out of the WiFiNINA Adafruit fork examples -- just a couple debugging additions and pin defs for the Teensy.

Any help with this?

Code: Select all | TOGGLE FULL SIZE
/*
  WiFi UDP Send and Receive String

 This sketch wait an UDP packet on localPort using the WiFi module.
 When a packet is received an Acknowledge packet is sent to the client on port remotePort

 created 30 December 2012
 by dlf (Metodo2 srl)

 */


#include <SPI.h>
#include <WiFiNINA.h>

// Configure the pins used for the ESP32 connection
#if defined(TEENSYDUINO)
  #define SPIWIFI      SPI  // The SPI port
  #define SPIWIFI_SS     10   // Chip select pin
  #define ESP32_RESETN   6    // Reset pin
  #define SPIWIFI_ACK    9   // a.k.a BUSY or READY pin
  #define ESP32_GPIO0   -1
#endif

#include <WiFiUdp.h>

int status = WL_IDLE_STATUS;
#include "arduino_secrets.h"
///////please enter your sensitive data in the Secret tab/arduino_secrets.h
char ssid[] = SECRET_SSID;        // your network SSID (name)
char pass[] = SECRET_PASS;    // your network password (use for WPA, or use as key for WEP)
int keyIndex = 0;            // your network key Index number (needed only for WEP)

unsigned int localPort = 2390;      // local port to listen on

char packetBuffer[255]; //buffer to hold incoming packet
char  ReplyBuffer[] = "acknowledged";       // a string to send back

WiFiUDP Udp;

void setup() {
  //Initialize serial and wait for port to open:
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }

  WiFi.setPins(SPIWIFI_SS, SPIWIFI_ACK, ESP32_RESETN, ESP32_GPIO0, &SPIWIFI);
  // check for the WiFi module:
  if (WiFi.status() == WL_NO_MODULE) {
    Serial.println("Communication with WiFi module failed!");
    // don't continue
    while (true);
  }

  String fv = WiFi.firmwareVersion();
  if (fv < "1.0.0") {
    Serial.println("Please upgrade the firmware");
  }

  // attempt to connect to Wifi network:
  while (status != WL_CONNECTED) {
    Serial.print("Attempting to connect to SSID: ");
    Serial.println(ssid);
    // Connect to WPA/WPA2 network. Change this line if using open or WEP network:
    status = WiFi.begin(ssid, pass);

    // wait 10 seconds for connection:
    delay(10000);
  }
  Serial.println("Connected to wifi");
  printWifiStatus();

  Serial.println("\nStarting connection to server...");
  // if you get a connection, report back via serial:

  // disable low power mode - critical for low latency operation
  WiFi.noLowPowerMode();
 
  Udp.begin(localPort);
}

void loop() {
  unsigned long currentMillis = millis();
  // if there's data available, read a packet
  int packetSize = Udp.parsePacket();
  if (packetSize) {
    Serial.print("Received packet of size ");
    Serial.println(packetSize);
    Serial.print("From ");
    IPAddress remoteIp = Udp.remoteIP();
    Serial.print(remoteIp);
    Serial.print(", port ");
    Serial.println(Udp.remotePort());

    // read the packet into packetBufffer
    int len = Udp.read(packetBuffer, 255);
    if (len > 0) {
      packetBuffer[len] = 0;
    }
    Serial.println("Contents:");
    Serial.println(packetBuffer);

    Serial.print("time: ");
    Serial.println(currentMillis);

    delay(10);
    // no need for replies
    /*
    // send a reply, to the IP address and port that sent us the packet we received
    Udp.beginPacket(Udp.remoteIP(), Udp.remotePort());
    Udp.write(ReplyBuffer);
    Udp.endPacket();
    */
  }
}


void printWifiStatus() {
  // print the SSID of the network you're attached to:
  Serial.print("SSID: ");
  Serial.println(WiFi.SSID());

  // print your board's IP address:
  IPAddress ip = WiFi.localIP();
  Serial.print("IP Address: ");
  Serial.println(ip);

  // print the received signal strength:
  long rssi = WiFi.RSSI();
  Serial.print("signal strength (RSSI):");
  Serial.print(rssi);
  Serial.println(" dBm");
}



Here is an example of the bash script I'm using to send UDP:

Code: Select all | TOGGLE FULL SIZE
for i in {1..10000}
do
  echo "/s_new" > /dev/udp/192.168.1.35/2390
  sleep .3s
  echo "/n_free" > /dev/udp/192.168.1.35/2390
  sleep .3s
done

tcweller
 
Posts: 7
Joined: Mon Oct 26, 2020 10:45 am

Please be positive and constructive with your questions and comments.