ok after a bit of experimentation I've got something working - thought it might be worth documenting here in case anyone else finds this useful.
this is the code for the NodeMCU/Wemos - I'm using VSCode/PlatformIO but should work just as well as an INO file in the Arduino IDE.
#include <Arduino.h>
#include <Wire.h>
#include <Adafruit_PWMServoDriver.h>
#include <ESP8266WiFi.h>
#include <E131.h>
const char ssid[] = "xxxxxx"; /* Replace with your SSID */
const char passphrase[] = "xxxxxxxxxx"; /* Replace with your WPA2 passphrase */
E131 e131;
// called this way, it uses the default address 0x40
Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver();
// you can also call it with a different address you want
//Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver(0x41);
// Depending on your servo make, the pulse width min and max may vary, you
// want these to be as small/large as possible without hitting the hard stop
// for max range. You'll have to tweak them as necessary to match the servos you
// have!
#define SERVOMIN 125 // this is the 'minimum' pulse length count (out of 4096)
#define SERVOMAX 575 // this is the 'maximum' pulse length count (out of 4096)
uint8_t max_servos = 16;
void setup() {
Serial.begin(115200);
delay(10);
Serial.println("16 channel Servo test!");
e131.begin(ssid, passphrase);
pwm.begin();
pwm.setPWMFreq(60);
}
void loop() {
uint16_t num_channels = e131.parsePacket();
/* Process channel data if we have it */
if (num_channels) {
//Serial.printf("P:%u - ", e131.stats.num_packets);
for (size_t servonum = 0; servonum < max_servos; servonum++) {
int value = e131.data[servonum];
int pulse = map(value, 1, 255, SERVOMIN, SERVOMAX);
Serial.printf("%hd->%hd ", servonum, value );
//Serial.printf("%hd->%hd:%u ", servonum, value, pulse );
if (value > 0) {
pwm.setPWM(servonum, 0, pulse );
}
}
Serial.printf("\n");
yield();
}
}
There are 16 servo's connected to a PCA9685 with separate PSU and the NodeMCU supplies the servo position from the value in the E1.31 packet.
Chris