Last active
October 13, 2016 11:39
-
-
Save pfeerick/ba5fbdde56bcf29a7d6637ced28cd938 to your computer and use it in GitHub Desktop.
Oak NRF receiver code. Generates a local web page to see latest data, and relays data to Particle as events.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <ESP8266WiFi.h> | |
#include <WiFiClient.h> | |
#include <ESP8266WebServer.h> | |
#include <ESP8266mDNS.h> | |
#include <SPI.h> | |
#include "nRF24L01.h" | |
#include "RF24.h" | |
#include <elapsedMillis.h> | |
elapsedMillis updateIP; //declare global if you don't want it reset every time loop runs | |
SYSTEM_MODE(SEMI_AUTOMATIC) | |
//needed for printDetails | |
#define printf Serial.printf | |
#define sprintf(...) os_sprintf( __VA_ARGS__ ) | |
#define CE_PIN 10 | |
#define CSN_PIN 5 | |
// Set up nRF24L01 radio on SPI bus plus pins 10 & 5 (CE & CSN) | |
RF24 radio(CE_PIN, CSN_PIN); | |
// Single radio pipe address for the 2 nodes to communicate. | |
const uint64_t pipes[3] = { 0xF0F0F0F0E1LL, 0xF0F0F0F0D2LL, 0xF0F0F0F0D3LL }; | |
const int STATUS_LED = 1; | |
float temp = 0.0; | |
char tmpStr[8]; | |
char myIpString[24]; | |
IPAddress myIp; | |
ESP8266WebServer server(80); | |
unsigned long lastParticlePublish = 0; | |
typedef struct { | |
float voltage; | |
float temperature; | |
} | |
sensorData; | |
sensorData receivedData; | |
void handleRoot() { | |
digitalWrite(STATUS_LED, 1); | |
String tempStr = dtostrf(receivedData.temperature, 5, 2, tmpStr); | |
String voltStr = dtostrf(receivedData.voltage, 5, 2, tmpStr); | |
uint32_t heapFree = ESP.getFreeHeap(); | |
String heapStr = F("Heap remaining: "); | |
heapStr += String(heapFree); | |
heapStr += F(" of 81920 bytes"); | |
int seconds = (int) ((millis() / 1000) % 60) ; | |
int minutes = (int) (((millis() / 1000) / 60) % 60); | |
int hours = (int) ((millis() / 1000) / 3600); | |
int days = (int) ((millis() / 1000) / 86400); | |
char uptimeStr[30]; | |
sprintf(uptimeStr, "System uptime: %id %02i:%02i:%02i", days, hours, minutes, seconds); | |
String lastUpdateStr = ""; | |
if (lastParticlePublish != 0) | |
{ | |
unsigned long updateTime = ((millis() - lastParticlePublish) / 1000); | |
if (updateTime < 60) | |
{ | |
lastUpdateStr = F("From approximately "); | |
lastUpdateStr += String(updateTime); | |
lastUpdateStr += F(" seconds ago"); | |
} | |
else | |
{ | |
updateTime = (((millis() - lastParticlePublish) / 1000) / 60); | |
lastUpdateStr = F("From approximately "); | |
lastUpdateStr += String(updateTime); | |
lastUpdateStr += F(" minute(s) ago"); | |
} | |
} | |
String page = F("<html><head>"); | |
page += F("<title>Oak 5 NRF Temperature Hub</title>"); | |
page += F("<meta http-equiv=\"refresh\" content=\"60\">"); //auto-refresh page every 60 seconds | |
page += F("<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">"); //resize page to device screen width | |
page += F("</head><body>"); | |
//if (receivedData.temperature == -999.99) | |
if (lastParticlePublish == 0) | |
{ | |
page += F("No readings received since powerup."); | |
} | |
else | |
{ | |
page += F("Latest temp reading: <b>"); | |
page += tempStr; | |
page += F(" °C</b></br>"); | |
page += F("Latest sensor voltage: <b>"); | |
page += voltStr; | |
page += F("v</b>"); | |
page += F("</br><small>"); | |
page += lastUpdateStr; | |
page += F("</small></br>"); | |
} | |
page += (F("<hr><small>")); | |
page += heapStr; | |
page += F("</br>"); | |
page += uptimeStr; | |
page += F("</small>"); | |
page += F("</body></html>"); | |
server.send(200, "text/html", page); | |
digitalWrite(STATUS_LED, 0); | |
} | |
void handleNotFound() { | |
digitalWrite(STATUS_LED, 1); | |
String message = "File Not Found\n\n"; | |
message += "URI: "; | |
message += server.uri(); | |
message += "\nMethod: "; | |
message += (server.method() == HTTP_GET) ? "GET" : "POST"; | |
message += "\nArguments: "; | |
message += server.args(); | |
message += "\n"; | |
for (uint8_t i = 0; i < server.args(); i++) { | |
message += " " + server.argName(i) + ": " + server.arg(i) + "\n"; | |
} | |
server.send(404, "text/plain", message); | |
digitalWrite(STATUS_LED, 0); | |
} | |
void setup(void) | |
{ | |
pinMode(STATUS_LED, OUTPUT); | |
Serial.begin(115200); | |
Serial.println("Sketch starting: NRF Receiver v0.2"); | |
while (WiFi.status() != WL_CONNECTED) | |
{ | |
delay(100); | |
Serial.print("."); | |
} | |
myIp = WiFi.localIP(); | |
Serial.print("IP address: "); | |
Serial.println(myIp); | |
sprintf(myIpString, "%d.%d.%d.%d", myIp[0], myIp[1], myIp[2], myIp[3]); | |
Particle.variable("ipAddress", myIpString); | |
if (Particle.connected() == false) | |
{ | |
Particle.connect(); | |
} | |
Particle.begin(); //OakTerm | |
Particle.publish("oak/userrom/startup", "NRF Receiver v0.2", PRIVATE); | |
if (MDNS.begin("oak5")) | |
{ | |
Serial.println("MDNS responder started"); | |
} | |
//starting radio stuff | |
radio.begin(); | |
//specific to my sensor configuration | |
radio.setChannel(50); | |
radio.setRetries(15, 15); | |
radio.setPALevel(RF24_PA_MAX); | |
radio.setPayloadSize(8); | |
radio.setDataRate(RF24_250KBPS); | |
radio.openWritingPipe(pipes[0]); // write via 1st address as this is Rx | |
radio.openReadingPipe(1, pipes[1]); // read via 2nd address as this is Rx | |
radio.startListening(); | |
// Dump the configuration of the rf unit to serial for debugging | |
radio.printDetails(); | |
//Start HTTP server | |
server.on("/", handleRoot); | |
server.on("/inline", []() { | |
server.send(200, "text/plain", "this works as well"); | |
}); | |
server.onNotFound(handleNotFound); | |
server.begin(); | |
Serial.println("HTTP server started"); | |
MDNS.addService("http", "tcp", 80); | |
//MDNS.addService("ws", "tcp", 81); | |
receivedData.temperature = -999.99; | |
receivedData.voltage = -999.99; | |
} | |
void loop(void) | |
{ | |
//if radio, else HTTP client | |
if ( radio.available() ) | |
{ | |
digitalWrite(STATUS_LED, HIGH); | |
radio.read( &receivedData, sizeof(receivedData) ); | |
Serial.print("Sensor Supply Voltage: "); | |
Serial.println(receivedData.voltage); | |
Serial.print("Temperature: "); | |
Serial.println(receivedData.temperature); | |
//prevent sending to particle more frequently than every 4 seconds | |
if (millis() - lastParticlePublish > 4000) | |
{ | |
dtostrf(receivedData.temperature, 5, 2, tmpStr); | |
Particle.publish("nrfTemp/temperature", tmpStr, PRIVATE); | |
dtostrf(receivedData.voltage, 5, 2, tmpStr); | |
Particle.publish("nrfTemp/supplyVoltage", tmpStr, PRIVATE); | |
lastParticlePublish = millis(); | |
} | |
digitalWrite(STATUS_LED, LOW); | |
} | |
else | |
{ | |
server.handleClient(); | |
} | |
//refresh IP variable every 60 seconds in case of DHCP IP shift | |
if (updateIP > 60000) //renew every 60 seconds | |
{ | |
myIp = WiFi.localIP(); | |
sprintf(myIpString, "%d.%d.%d.%d", myIp[0], myIp[1], myIp[2], myIp[3]); | |
updateIP = 0; // reset the counter to 0 so the counting starts over... | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment