Things used in this project

Code

photon-gateway.ideC/C++
The "gateway" code for the Photon
#include "application.h"

// Output debugging information to serial
// #define SERIAL_DEBUG

// Output debugging information to Particle.publish(...)
// #define PUBLISH_DEBUG

// Your local time zone
#define TIME_ZONE -5;

// The port to listen for UDP broadcast messages
#define BROADCAST_PORT 9877

// The publish event to use
#define PUBLISH_EVENT "statsd"

// Use the onboard RGB LED to blink when a packet is processed
#define USE_LED

UDP udp;

void setup() {
#ifdef SERIAL_DEBUG
	Serial.begin(9600);
	Time.zone(TIMEZONE);
#endif

	udp.begin(BROADCAST_PORT);
}


void loop() {
	checkUDP();
}


// See if we've received a packet
void checkUDP() {
	if (udp.parsePacket() > 0) {
#ifdef USE_LED
		RGB.control(true);
		RGB.color(127, 0, 0);
#endif

		char packetBuffer[64] = "";
	    udp.read(packetBuffer, 64);

	    parsePacket(String(packetBuffer));

		delay(100);

#ifdef USE_LED
	    RGB.control(false);
#endif
	}
}


// Parse the packet for a checksum
void parsePacket(String packet) {
	uint32_t checksum = 0;
	packet.trim();

#ifdef SERIAL_DEBUG
	Serial.print(timestamp());
	Serial.print("<<< ");
	Serial.println(packet);
#endif

#ifdef PUBLISH_DEBUG
	Particle.publish("debug", packet, 60, PRIVATE);
#endif

	// Calculate checksum up to ";"
	for(uint8_t i=0; i<packet.lastIndexOf(";"); i++) {
		checksum += ord(packet.charAt(i));
	}

	// Get the checksum sent with the packet
	String str_checksum = packet.substring(packet.lastIndexOf(";")+1);

	if(String(checksum, HEX)==str_checksum)
		sendPacket(packet.substring(0, packet.lastIndexOf(";")));
	else {
		String pub = packet+" :: checksum "+str_checksum+" != "+String(checksum, HEX);
#ifdef SERIAL_DEBUG
		Serial.print(timestamp());
		Serial.print("!!! checksum does not match: ");
		Serial.print(str_checksum);
		Serial.print(" != ");
		Serial.println(String(checksum, HEX));
#endif

#ifdef PUBLISH_DEBUG
		Particle.publish("error", pub, 60, PRIVATE);
#endif
	}
}


// Forward the packet on to Particle.publish(...)
void sendPacket(String packet) {
#ifdef SERIAL_DEBUG
	Serial.print(timestamp());
	Serial.print(">>> ");
	Serial.println(packet);
#endif
	Particle.publish(PUBLISH_EVENT, packet);
}


// Convert ASCII character to its integer value
uint8_t ord(char b) {
	uint8_t a;
	a = b-'0';
	return a;
}


#ifdef SERIAL_DEBUG
String timestamp() {
	return "["+Time.format(Time.now(), "%F %T")+"] ";
}
#endif
esp8266.inoC/C++
The code for the ESP8266 with a DS18B20 temperature sensor
#include <ESP8266WiFi.h>
#include <WiFiUdp.h>
#include <OneWire.h>

extern "C" {
  #include "user_interface.h"
}

//#define  DEBUG_SERIAL

// The arbitrary name for this device
#define DEVICE_NAME       "iot"

// Wifi network name
#define WIFI_SSID         "MyNetwork"

// Wifi network password
#define WIFI_PASS         "p455w0rd"

// UDP port to broadcast on
#define BROADCAST_PORT     9877

// UDP IP address to broadcast to
#define BROADCAST_ADDRESS "255.255.255.255"

// External "status" LED
#define LED_PIN            14

// How long to sleep
#define SLEEP_DURATION     55

// How long to wait (in seconds) before going back to sleep
#define POST_DATA_DELAY    1

bool statusLED = false;
uint16_t timeToConnect = 0;

char packetBuffer[UDP_TX_PACKET_MAX_SIZE];

OneWire ds(5);

WiFiUDP udp;

float t = 185;

void setup() {
#ifdef DEBUG_SERIAL
  Serial.begin(115200);
  Serial.println("");
  Serial.println("BEGIN");
#endif
  timeToConnect = millis();
  
  pinMode(LED_PIN, OUTPUT);
  digitalWrite(LED_PIN, HIGH);
  
  WiFi.begin(WIFI_SSID, WIFI_PASS);
  
  udp.begin(BROADCAST_PORT);
}

void loop() {
  readSensors();
  sendData();
}


void readSensors() {
  // Loop until we get a reasonable value
  while(t>150) {
    t = getTempF();
    delay(50);
  }
}


void sendData() {
  digitalWrite(LED_PIN, LOW);
  
  // Connect to the wifi network
  if(connect()) {
    // Assemble the UDP packet
    udp.beginPacket(BROADCAST_ADDRESS, BROADCAST_PORT);
    
    String str = String(DEVICE_NAME)+";f:"+String(t, 2)+"|g,conn:"+String(millis()-timeToConnect)+"|g";
    
    str += ";"+checksum(str);
    
    char data[str.length()];
    str.toCharArray(data, str.length()+1);
        
  #ifdef DEBUG_SERIAL
    Serial.print("> ");
    Serial.print(str.length()+1);
    Serial.print(": ");
    Serial.println(data);
  #endif
    
    // Send the packet!
    udp.write(data, str.length());
    udp.endPacket();
    
    // Wait for things to settle down
    delay(POST_DATA_DELAY*1000);
    
    // Disconnect from wifi
    WiFi.disconnect();
    
    digitalWrite(LED_PIN, HIGH);
    
#ifdef DEBUG_SERIAL
    Serial.print("Sleeping for ");
    Serial.println(SLEEP_DURATION);
#endif
    
    // Go to sleep!
    system_deep_sleep_set_option(0);
    system_deep_sleep(SLEEP_DURATION * 1000000);
  }

  digitalWrite(LED_PIN, HIGH);
}


float getTempC() {
  byte data[12];
  byte addr[8];
  
  if(!ds.search(addr)) {
    ds.reset_search();
    return -1000;
  }
  
  if(OneWire::crc8(addr, 7)!=addr[7]) {
#ifdef DEBUG_SERIAL
    Serial.println("CRC is not valid!");
#endif
    return -1000;
  }
  
  if(addr[0] != 0x10 && addr[0] != 0x28) {
#ifdef DEBUG_SERIAL
    Serial.println("Device is not recognized");
#endif
    return -1000;
  }
  
  ds.reset();
  ds.select(addr);
  ds.write(0x44, 1);
  
  byte present = ds.reset();
  ds.select(addr);
  ds.write(0xBE);
  
  for(uint8_t i=0; i<9; i++) {
    data[i] = ds.read();
  }
  
  ds.reset_search();
  
  byte MSB = data[1];
  byte LSB = data[0];
  
  float tempRead = ((MSB<<8) | LSB);
  return tempRead/16;
}


float getTempF() {
  return getTempC() * 9/5 + 32;
}


uint8_t ord(char b) {
  uint8_t a;
  a = b-'0';
  return a;
}


String checksum(String s) {
  uint16_t crc = 0;
  
  for(uint8_t i=0; i<s.length(); i++) {
    crc += ord(s.charAt(i));
  }
  
  return String(crc, HEX);
}


bool connect() {
 #ifdef DEBUG_SERIAL
   Serial.print("Connecting: ");
 #endif
 
  while(WiFi.status() != WL_CONNECTED) {
    if(millis()%100==0) {
#ifdef DEBUG_SERIAL
      Serial.print(".");
#endif
      statusLED = !statusLED;
      digitalWrite(LED_PIN, statusLED);
      delay(1);
    }
  }
  
#ifdef DEBUG_SERIAL
  Serial.println(" done!");
#endif

  return true;
}

Credits

Avatar
Garrett Bartley

Husband, father, maker.

Contact

Replications

Did you replicate this project? Share it!

I made one

Love this project? Think it could be improved? Tell us what you think!

Give feedback

Comments

Similar projects you might like

ESP8266 NodeMCU WiFi IoT Garage Door Opener Relay with Cayen
Easy
  • 24
  • 2

In this project, we will use an ESP8266 with Cayenne to control a Garage Door Opener.

2-Way Particle Photon Communication
Easy
  • 123
  • 4

Full instructions

Make two Particle Photons "talk" via the usage of webhooks!

E-Paper Weather Display with Photon and IFTTT
Easy
  • 591
  • 6

Full instructions

Create a beautiful medium for weather information using Particle's cloud services and IFTTT.

IFTTT - Enabled Sensors with Particle Photon
Easy
  • 651
  • 11

Full instructions

Connect any sensor to Particle Photon and use it to trigger an IFTTT action with just a few lines of code.

Web-Based Universal Remote for Under $4 (Probably)
Easy
  • 1,249
  • 8

Don't buy a universal remote, make one. It's cheaper, funner, universal-er, kind of, and you get to learn the ESP8266, kind of.

Safe City: A Device to Keep You Safe
Easy
  • 560
  • 5

Full instructions

The device will keep you safe. Just have to click a button and your precise location will be shared.

Sign up / LoginProjectsPlatformsTopicsContestsLiveAppsBetaFree StoreBlog