Skip to content

Instantly share code, notes, and snippets.

@pfeerick
Last active October 13, 2016 11:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pfeerick/ba5fbdde56bcf29a7d6637ced28cd938 to your computer and use it in GitHub Desktop.
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.
#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(" &deg;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