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.

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

Sending Photos and Video Over the Internet!
Easy
  • 1,719
  • 25

Full instructions

Record video, perform object and face recognition, take a time-lapse or whatever else with a Particle Photon and the 5-megapixel Arducam!

A Tone Generator with LCD Display!
Easy
  • 35
  • 1

Full instructions

This is a tone selector with the ability to change the buzzer frequency by a potentiometer and to see the result on a 16x2 display.

Arduino Keyless Door Lock System with Keypad and LCD
Easy
  • 629
  • 11

Full instructions

Learn how to make an Arduino-controlled door lock system that uses a keypad!

Wireless Bagpipe
Easy
  • 376
  • 6

Full instructions

Convert a 3D-printed bagpipe chanter into a BLE MIDI instrument.

Arduino Easy Weather Station With BME280 Sensor
Easy
  • 912
  • 8

Full instructions

Dear friends welcome to another Arduino project tutorial! In this tutorial we are going to take a first look at the new BME280 sensor, a ...

ioTank
Easy
  • 261
  • 2

Full instructions

An indoor environment monitor for the internet of things which senses temperature, humidity, ultraviolet, and clear light intensity

ioTank

Team Object Syndicate LLC

ProjectsCommunitiesTopicsContestsLiveAppsBetaFree StoreBlogAdd projectSign up / Login
Feedback