Hello,
I converted a sketch I had that was using Serial to NativeEthernet. I noticed that after a few hours, the Teensy seems to either reboot or hang. I was wondering if someone could have a look at my sketch and see if I made any errors that could lead to this ?
The program uses OSC to set timing values on pins (mostly using elapsedMillis) in order to strobe some lights.
I converted a sketch I had that was using Serial to NativeEthernet. I noticed that after a few hours, the Teensy seems to either reboot or hang. I was wondering if someone could have a look at my sketch and see if I made any errors that could lead to this ?
The program uses OSC to set timing values on pins (mostly using elapsedMillis) in order to strobe some lights.
Code:
#include <SPI.h>
#include <NativeEthernet.h>
#include <NativeEthernetUdp.h>
#include <elapsedMillis.h>
#include <OSCBundle.h>
#include <OSCBoards.h>
EthernetUDP Udp;
uint8_t mac[6];
const byte NUM_CHANNELS = 16;
byte PINS[NUM_CHANNELS] = { 2, 3, 4, 5, 6, 30, 31, 32, 33, 36, 37, 40, 41, 13, 22, 23 };
uint16_t OSC_INPUT_PORT = 3333;
typedef struct {
elapsedMillis elapsedTime;
uint32_t onTime;
uint32_t offTime;
byte pin;
bool enable;
} channel;
channel channels[NUM_CHANNELS];
void teensyMAC(uint8_t *mac) {
for(uint8_t by=0; by<2; by++) mac[by]=(HW_OCOTP_MAC1 >> ((1-by)*8)) & 0xFF;
for(uint8_t by=0; by<4; by++) mac[by+2]=(HW_OCOTP_MAC0 >> ((3-by)*8)) & 0xFF;
Serial.printf("MAC: %02x:%02x:%02x:%02x:%02x:%02x\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
}
void setup() {
Serial.begin(9600);
teensyMAC(mac);
// Default IP address
IPAddress ip(169, 254, mac[4], mac[5]);
if (Ethernet.begin(mac) == 0) {
Serial.println("Failed to configure Ethernet using DHCP");
// DHCP failed, so use a fixed IP address:
Ethernet.begin(mac, ip);
}
Udp.begin(OSC_INPUT_PORT);
char deviceName[13];
sprintf(deviceName, "Goutteur-%02x%02x", mac[4], mac[5]);
MDNS.begin(deviceName, 1);
MDNS.addService("_osc._udp", OSC_INPUT_PORT);
Serial.println(Ethernet.localIP());
for (byte c = 0 ; c < NUM_CHANNELS ; c++) {
channels[c].onTime = 1000;
channels[c].offTime = 2000;
channels[c].enable = true;
channels[c].pin = PINS[c];
pinMode(channels[c].pin, OUTPUT);
}
}
void processLed() {
for (byte c = 0 ; c < NUM_CHANNELS ; c++)
{
if (channels[c].enable) {
if (channels[c].elapsedTime <= channels[c].onTime) {
digitalWrite(channels[c].pin, HIGH);
}
if (channels[c].elapsedTime > channels[c].onTime) {
digitalWrite(channels[c].pin, LOW);
}
if (channels[c].elapsedTime > channels[c].onTime + channels[c].offTime) {
channels[c].elapsedTime = 0;
}
}
}
}
void setInterval(OSCMessage &msg) {
if (msg.isInt(0) && msg.isInt(1) && msg.isInt(2)) {
int c = msg.getInt(0);
// All channels
if (c == 255) {
for (byte i = 0 ; i < NUM_CHANNELS ; i++) {
channels[i].enable = true;
channels[i].onTime = msg.getInt(1);
channels[i].offTime = msg.getInt(2);
channels[i].elapsedTime = 0;
}
// Single channel
} else if (c >= 0 && c < NUM_CHANNELS) {
channels[c].enable = true;
channels[c].onTime = msg.getInt(1);
channels[c].offTime = msg.getInt(2);
channels[c].elapsedTime = 0;
}
}
}
void on(OSCMessage &msg) {
if (msg.isInt(0)) {
int c = msg.getInt(0);
// All channels
if (c == 255) {
for (byte i = 0 ; i < NUM_CHANNELS ; i++) {
channels[i].enable = false;
digitalWrite(channels[i].pin, HIGH);
}
// Single channel
} else if (c >= 0 && c < NUM_CHANNELS) {
channels[c].enable = false;
digitalWrite(channels[c].pin, HIGH);
}
}
}
void off(OSCMessage &msg) {
if (msg.isInt(0)) {
int c = msg.getInt(0);
// All channels
if (c == 255) {
for (byte i = 0 ; i < NUM_CHANNELS ; i++) {
channels[i].enable = false;
digitalWrite(channels[i].pin, LOW);
}
// Single channel
} else if (c >= 0 && c < NUM_CHANNELS) {
channels[c].enable = false;
digitalWrite(channels[c].pin, LOW);
}
}
}
void reset(OSCMessage &msg) {
if (msg.isInt(0)) {
int c = msg.getInt(0);
// All channels
if (c == 255) {
for (byte i = 0 ; i < NUM_CHANNELS ; i++) {
channels[i].elapsedTime = 0;
}
// Single channel
} else if (c >= 0 && c < NUM_CHANNELS) {
channels[c].elapsedTime = 0;
}
}
}
void loop() {
OSCBundle bundleIN;
int size;
processLed();
if( (size = Udp.parsePacket())>0) {
while(size--)
bundleIN.fill(Udp.read());
}
if(!bundleIN.hasError()) {
bundleIN.dispatch("/setInterval", setInterval);
bundleIN.dispatch("/reset", reset);
bundleIN.dispatch("/on", on);
bundleIN.dispatch("/off", off);
}
Ethernet.maintain();
}