I have problems sending a proper Timestamp from the Teensy to the network with OSC.
This is a confusing problem, because timestamps in TimeLib.h and OSCTiming.h have wildly different layouts. While TimeLib works with unix timestamps, osc has a fixed-point 8byte format, starting at epoch 1900.
My steps so far:
seems to me like oscTime() calculates it's time solely from elapsed millis(), and completely ignores the system clock. see code.
i am not sure on how to proceed. should I manually fill up an osctime struct from the data i retrieve by the methods in TimeLib? I guess that might be possible.
Would it be a good idea to have conversion like that in latchOscTime?
This is a confusing problem, because timestamps in TimeLib.h and OSCTiming.h have wildly different layouts. While TimeLib works with unix timestamps, osc has a fixed-point 8byte format, starting at epoch 1900.
My steps so far:
- equipping a Teensy 3.2 with a quartz - success
- making sure I can set the time by OSC command - partial success only unix timestamps so far, as seen in TimeTeensy3 example
- reading out the time with oscTime() again - fail...
- attaching it to the osc bundle success
- sending it over the wire success
seems to me like oscTime() calculates it's time solely from elapsed millis(), and completely ignores the system clock. see code.
i am not sure on how to proceed. should I manually fill up an osctime struct from the data i retrieve by the methods in TimeLib? I guess that might be possible.
Would it be a good idea to have conversion like that in latchOscTime?
Code:
/*
* Teensy Code for 3.2
*
Read out some buttons, make an OSC bundle and send it over UDP.
Receive some pwm values for some LED.
Code contains stuff for debouncing the buttons.
*/
// use the quarz
#include <TimeLib.h>
// retrieve mac from teensy
#include "T3Mac/T3Mac.h"
#include <SPI.h>
#include <Ethernet.h>
#include <EthernetUdp.h>
// pins 9, 10, 11, 12, 13 are used by ethernet
// pin 4 might be used by sd card
#include <OSCBundle.h>
#include <OSCBundle.h>
#include <OSCData.h>
#include <OSCTiming.h>
#include <Bounce2.h>
const char MyName[] = "GetHim_A";
IPAddress ip(192, 168, 2, 107); // my IP
IPAddress outIp(192, 168, 2, 108); // target server
const unsigned int localPort = 9999; // local port to listen on
const unsigned int outPort = 9998;
unsigned int buttonPin[] = {5, 6, 7, 8};
unsigned int ledPin[] = {20, 21, 22, 23}; // A6 - A9 are pwm
EthernetUDP Udp;
Bounce buttons[4];
elapsedMillis watch;
void setup() {
// set the Time library to use Teensy 3.2's RTC to keep time
setSyncProvider(getTeensy3Time);
Serial.begin(115200);
// while (!Serial); // Wait for Arduino Serial Monitor to open
delay(100);
// populates the mac variable
read_mac();
print_mac();
Serial.println();
if (timeStatus()!= timeSet) {
Serial.println("Unable to sync with the RTC");
} else {
Serial.println("RTC has set the system time");
}
Ethernet.begin(mac,ip);
Udp.begin(localPort);
Serial.println(Ethernet.localIP());
for (int i=0;i<4;i++) pinMode(buttonPin[i], INPUT_PULLUP);
for (int i=0;i<4;i++) pinMode(ledPin[i], OUTPUT);
for (int i=0;i<4;i++) buttons[i] = Bounce(buttonPin[i], 10); // 10ms debounce
}
time_t getTeensy3Time()
{
return Teensy3Clock.get();
}
void updateLed(OSCMessage &mes){
for (int i = 0; i < 4; i++){
int signal = mes.getInt(i);
analogWrite(ledPin[i], signal);
}
}
void updateClock(OSCMessage &mes) {
Serial.println("attempting to update clock");
time_t signal = mes.getInt(0);
Serial.println(signal);
Teensy3Clock.set(signal); // set the RTC
setTime(signal);
timeToSerial();
}
void printTime(OSCMessage &mes) {
timeToSerial();
}
void timeToSerial() {
// digital clock display of the time
Serial.print(hour());
printDigits(minute());
printDigits(second());
Serial.print(" ");
Serial.print(day());
Serial.print(" ");
Serial.print(month());
Serial.print(" ");
Serial.println(year());
}
void printDigits(int digits){
// utility function for digital clock display: prints preceding colon and leading 0
Serial.print(":");
if(digits < 10)
Serial.print('0');
Serial.print(digits);
}
void loop(){
OSCBundle bundle;
// receive
int size = Udp.parsePacket();
if (size > 0) {
while (size--) {
bundle.fill(Udp.read());
}
if (!bundle.hasError()) {
bundle.dispatch("/led", updateLed);
bundle.dispatch("/unixtime", updateClock);
bundle.dispatch("/printtime", printTime);
} else {
OSCErrorCode error = bundle.getError();
Serial.print("error: ");
Serial.println(error);
}
bundle.empty();
}
for (int i=0;i<4;i++) {
// buttons[i].update();
// int pressed = 1 - buttons[i].read();
int pressed = 1 - digitalRead(buttonPin[i]);
String addressString = String("/").concat(MyName).concat("/b").concat(i);
char address[addressString.length()+1];
addressString.toCharArray(address, addressString.length()+1);
bundle.add(address).add(pressed);
}
bundle.setTimetag(oscTime());
String addressString = String("/").concat(MyName).concat("/millis");
char address[addressString.length()+1];
addressString.toCharArray(address, addressString.length()+1);
bundle.add(address).add((long int)millis());
// bundle.add(address).add(oscTime());
Udp.beginPacket(outIp, outPort);
bundle.send(Udp); // send the bytes to the SLIP stream
Udp.endPacket(); // mark the end of the OSC Packet
bundle.empty(); // empty the bundle to free room for a new one
}