I’m attempting to make race timers using two photons and an iPhone. The photon based timers send a UDP keep alive every one second and another one when the beam is broken. The master timer should also be the WiFi access point. I can’t figure out how to use WiFi.listen and system_mode and system thread to make this work. I used wireshark and never saw a packet sent from the times… Here’s the code
int led = D1; // This LED will flash every 1 second as to signify that a keepalive sent.
int onboardLED = D7; // This built-in, tiny LED will flash when a beam break is sent
int BEAM_BREAK = D2; // This is the input for the button pressed.
uint8_t buf[8]; // buffer to send beam break
uint8_t ping[8]; // buffer to send keepalive
uint8_t inbuf[80];
uint8_t assoIpAddr[4]; // IP address of the iPhone in order to send UNICAST as opposed to BROADCAST
UDP Udp; // UDP control
byte mac[6]; // the MAC address of your4+ Wifi shield
volatile bool isAssociated; // if TRUE, the iPhone has responded with it's IP address. From that point forward,
// then this app sill used the destination IP addres listed in assoIpAddr
IPAddress destIP; // the IP address to send keep-alives, and beam breaks
volatile bool beamBroken; // When, true, the beam has been broken.
int counter; // generic counter for counting the number of delay times.
SYSTEM_THREAD(ENABLED); // Really don't understand what this is or how to use it.
void setup() {
pinMode(led, OUTPUT); // keepalive LED indicater
pinMode(onboardLED, OUTPUT); // signal break was sent
pinMode(BEAM_BREAK, INPUT_PULLUP); // signal when button pressed signaling beam break
attachInterrupt(BEAM_BREAK, brokenBeam, FALLING); // This sets microswitch as an Interrupt.
WiFi.listen();
Udp.begin (8496); // use this port must differe from sending port
// get the MAC address of this device. It will be used in the
// protocol to identiry which device is sending the message
WiFi.macAddress(mac);
while ( (mac[0] == 0) && (mac[1] == 0) && (mac[2] == 0) ) {
WiFi.macAddress(mac);
delay(250);
}
ping[0] = 0x1; // Initialize keep alive buffer, with command 1 & 1 as the
ping[1] = 0x1; // first two bytes.
ping[2] = mac[5]; ping[3] = mac[4]; ping[4] = mac[3]; ping[5] = mac[2]; ping[6] = mac[1]; ping[7] = mac[0];
buf[0] = 0x1; // Initialize beam break buffer, with command 1 & 2 as the
buf[1] = 0x2; // first two bytes. This is used until association then swithed to 1 & 3
buf[2] = mac[5]; buf[3] = mac[4]; buf[4] = mac[3]; buf[5] = mac[2]; buf[6] = mac[1]; buf[7] = mac[0];
// IP address storage, first for broadcase, then uicast
assoIpAddr[0] = 255; assoIpAddr[1] = 255; assoIpAddr[2] = 255; assoIpAddr[3] = 255;
destIP = IPAddress(assoIpAddr[0],assoIpAddr[1],assoIpAddr[2],assoIpAddr[3]);
isAssociated = FALSE;
BEAM_BREAK = FALSE;
}
void loop() {
digitalWrite(onboardLED, HIGH); // Signal the process has begun
// Delay for 1 sec, checking every 10 msec to see if the beam was broken.
// If the beam was broken, send a UCP message and then delay for the rest of
// the 1 sec
counter = 100;
for ( int i = 0; i < counter; i++ ) {
delay(10);
if ( BEAM_BREAK == TRUE ) {
BEAM_BREAK = FALSE;
Udp.sendPacket(buf, 8, destIP, 6948);
digitalWrite(onboardLED, HIGH);
delay ( 10 * (counter - i));
break;
}
}
// Send a keep alive message and turn off the processing LED
Udp.beginPacket(destIP,6948); // Create a broadcast UDP packet
Udp.write(ping,8);
Udp.endPacket();
digitalWrite(led, LOW);
// If we are still in broadcast mode, check to see if the iPhone has sent it's IP address
// which will be used to assoiate this communication and move to UNICAST. The UDP
// message is started with a single command byte of 0x11 followed by 4 bytes of an IP address
if ( ! isAssociated ) {
int packetSize;
// wait for an incomming packet
for( int k = 0; k < 25; k++ ) {
if( 0 < (packetSize = Udp.parsePacket())) break;
delay(20);
}
// If you got a packet (> 0), read it and process it
if ( packetSize > 0 ) {
Udp.read( inbuf, 5);
if ( inbuf[0] == 0x11 ) {
assoIpAddr[0] = inbuf[1];
assoIpAddr[1] = inbuf[2];
assoIpAddr[2] = inbuf[3];
assoIpAddr[3] = inbuf[4];
ping[1] = 0x3;
isAssociated = TRUE;
}
}
}
digitalWrite(led, HIGH);
digitalWrite(onboardLED, LOW);
}
//
// This function sends a broadcast message each time the button is pressed
static void brokenBeam(){
BEAM_BREAK = TRUE;
}