Author Topic: Oak with data dashboards  (Read 4924 times)

maximo80

  • Newbie
  • *
  • Posts: 17
Oak with data dashboards
« on: March 31, 2016, 11:28:19 pm »
Hi everyone,
Waiting for oak dashboard i am trying to find the best option now, and i have seen 2 very good options:
- Freeboard
- Ubidots
I chose ubidots because it looks better but both looks well.
I read all information to send data but i couldn't, i checked as a photon particle, with arduino ide but it doesn't work well, and when i tried as esp8266 i have library problems with wifi.config, I found some script woks but not very well.

Has anyone tried it?
Thanks

PeterF

  • Hero Member
  • *****
  • Posts: 881
Re: Oak with data dashboards
« Reply #1 on: April 01, 2016, 03:26:57 am »
Ubidots does look nice, doesn't it.

It might be worth trying to mash together their generic ESP8266 sketch and exeng's thingspeak posting code, and throwing out most of their wifi setup code, and only leaving the sort of stuff exeng used, as the particle wifiroutines does most of that anyway. If get a chance on Sunday I'll have a crack at it.

Pete

defragster

  • Sr. Member
  • ****
  • Posts: 467
Re: Oak with data dashboards
« Reply #2 on: April 01, 2016, 03:41:11 am »
Erik posted on KS some note on the dashboard features today:

Quote
Dirty Engineer about 22 hours ago 
@ Creator - When will the real time dashboard and historical data features be implemented? Also when will the HW design files of the Oak be released?

Creator Erik Kettenburg about 18 hours ago 
@DirtyEngineer - hardware files are already available at http://digistump.com/wiki/oak/sources
As mentioned in the last update - Dashboard will be ready within a couple weeks, unless the birth of my next child is early, in which case it will be about a month or so.
Historical data features are something that Particle is implementing for their Electron and the Oak - they are quite actively working on it and have added events with TTLs as a first step, now accessing old messages is next I believe, and then probably more permanent storage. If their implementation doesn't provide the level of features we promised then we will fill in the gaps with our own service on top of their cloud. You can also connect Particle to SparkFun Data and Adafruit.io for more historical data options in the mean time.

maximo80

  • Newbie
  • *
  • Posts: 17
Re: Oak with data dashboards
« Reply #3 on: April 02, 2016, 12:41:01 am »
hi,

I finally was able to post data to ubidots, but I realize after 2 hours the connection get down and oak looks as disconnected of particle ( on dashboard appears without blue point ), could it have some internal oak sleep task?

I will make some other tests.

Regards,

PeterF

  • Hero Member
  • *****
  • Posts: 881
Re: Oak with data dashboards
« Reply #4 on: April 02, 2016, 05:10:03 pm »
There shouldn't be any internal sleep tasks - either the Oak is doing what it's told, or something went wrong!TM. I've had Oaks running 24x7 for a few weeks now, one doing deepSleeps as it is a sensor node, and the other running all the time, as it is a display module. So did you just whack together something from the generic ESP8266 I mentioned earlier, or did you use some other code?

I have cobbled together some code for the unidots dashboard, and it seems to be working ok so far. It basically starts up, gets the reading (ditches the first in case it is wrong as usually is), if there was no fails published temp to particle and unidots, if there was a fail, publish so to particle, and then deepSleep for one minute, which causes the unit to completely go to sleep, and the reset after 60 seconds in order to wake up and start all over again. After some stress testing for a day or two, I'll be changing it to 10 minute intervals. If you want to use it, you just need to put in your API and variable keys just above the setup function.

The retry code around getTemp is because I eneded up with a load of 'P' (or is it PAR?) variant DS18B20 temperature sensors, and they are a bit stubborn in giving up the temperature - I think a longer delay is needed between asking for and getting the temperature, but a retry was a serviceable quick fix until I go back and work it out.

Code: [Select]
// Initial DS18B20 code: OneWire DS18S20, DS18B20, DS1822 Temperature Example
// Initial Thingspeak code: exeng thingspeak oak code example
// Initial ubidots code: ubidots ESP8266 as stand-alone Module example

#define STATUS_LED 1
#define DS18S20_PIN 2

//#define DEBUG
#define DEBUG_OI Serial

#ifdef DEBUG
#define   DebugBegin(...) DEBUG_OI.begin(__VA_ARGS__)
#define   DebugPrint(...) DEBUG_OI.print(__VA_ARGS__)
#define   DebugPrintln(...) DEBUG_OI.println(__VA_ARGS__)
#define   DebugWrite(...) DEBUG_OI.write(__VA_ARGS__)
#else
// Define the counterparts that cause the compiler to generate no code
#define   DebugBegin(...) (void(0))
#define   DebugPrint(...) (void(0))
#define   DebugPrintln(...) (void(0))
#define   DebugWrite(...) (void(0))
#endif

#include <OneWire.h>

#include <WiFiClient.h>
#include <ESP8266WiFi.h>

OneWire  ds(DS18S20_PIN);  //(a 4.7K resistor is necessary)
char tempStr[8];
float tempC = 0.0;
int retries = 0;

int status = WL_IDLE_STATUS;     // the Wifi radio's status
WiFiClient client;

//Unidots variables
String idvariable = "----------Put your variableid in here---------";
String token = "----------Put your token here-----------";

void setup(void)
{
  //Particle.publish("DS18x20_Temperature");
  DebugBegin(9600);

  pinMode(STATUS_LED, OUTPUT);
  digitalWrite(STATUS_LED, LOW);
 
  while ( WiFi.status() != WL_CONNECTED)
  {
    digitalWrite(STATUS_LED, HIGH);
    status = WiFi.begin();
    // wait 10 seconds for connection:
    delay(10000);
    digitalWrite(STATUS_LED, LOW);
  }

  //ditch first reading from DS18B20
  tempC = getTemp();

  if (tempC <= -1000 && retries < 5)
  {
    tempC = getTemp();
    retries++;
  }
}

void loop(void)
{
  if (tempC <= -1000 && retries < 5)
  {
    tempC = getTemp();
    retries++;
  }
  //tempF = celsius * 1.8 + 32.0;

  dtostrf(tempC, 5, 2, tempStr);

  // either publish error state to particle, or temperature to particle and thingspeak
  if(tempC <= -1000)
  {
    Particle.publish("ubidots_DS18B20 Error", tempStr, 60, PRIVATE);
  }
  else
  {
    Particle.publish("ubidots_tempC", tempStr, 60, PRIVATE);
    updateUnidots(tempC);
  }

  DebugPrint("  Temperature = ");
  DebugPrint(tempC);
  DebugPrintln(" Celsius");
  //  DebugPrint(tempF);
  //  DebugPrintln(" Fahrenheit");

  // power save for 60 seconds
  ESP.deepSleep(60 * 1000000, WAKE_RF_DEFAULT);
}

float getTemp()
{
  byte i;
  byte present = 0;
  byte type_s;
  byte data[12];
  byte addr[8];
  float celsius, fahrenheit;

  if ( !ds.search(addr)) {
    DebugPrintln("No more addresses.");
    DebugPrintln();
    ds.reset_search();
    delay(250);
    return -1000.00;
  }

  DebugPrint("ROM =");
  for ( i = 0; i < 8; i++) {
    DebugWrite(' ');
    DebugPrint(addr[i], HEX);
  }

  if (OneWire::crc8(addr, 7) != addr[7]) {
    DebugPrintln("CRC is not valid!");
    return -2000.0;
  }
  DebugPrintln();

  // the first ROM byte indicates which chip
  switch (addr[0]) {
    case 0x10:
      DebugPrintln("  Chip = DS18S20");  // or old DS1820
      type_s = 1;
      break;
    case 0x28:
      DebugPrintln("  Chip = DS18B20");
      type_s = 0;
      break;
    case 0x22:
      DebugPrintln("  Chip = DS1822");
      type_s = 0;
      break;
    default:
      DebugPrintln("Device is not a DS18x20 family device.");
      return -3000.0;
  }

  ds.reset();
  ds.select(addr);
  ds.write(0x44, 1);        // start conversion, with parasite power on at the end

  delay(1000);     // maybe 750ms is enough, maybe not
  // we might do a ds.depower() here, but the reset will take care of it.

  present = ds.reset();
  ds.select(addr);
  ds.write(0xBE);         // Read Scratchpad

  DebugPrint("  Data = ");
  DebugPrint(present, HEX);
  DebugPrint(" ");
  for ( i = 0; i < 9; i++) {           // we need 9 bytes
    data[i] = ds.read();
    DebugPrint(data[i], HEX);
    DebugPrint(" ");
  }
  DebugPrint(" CRC=");
  DebugPrint(OneWire::crc8(data, 8), HEX);
  DebugPrintln();

  // Convert the data to actual temperature
  // because the result is a 16 bit signed integer, it should
  // be stored to an "int16_t" type, which is always 16 bits
  // even when compiled on a 32 bit processor.
  int16_t raw = (data[1] << 8) | data[0];
  if (type_s) {
    raw = raw << 3; // 9 bit resolution default
    if (data[7] == 0x10) {
      // "count remain" gives full 12 bit resolution
      raw = (raw & 0xFFF0) + 12 - data[6];
    }
  } else {
    byte cfg = (data[4] & 0x60);
    // at lower res, the low bits are undefined, so let's zero them
    if (cfg == 0x00) raw = raw & ~7;  // 9 bit resolution, 93.75 ms
    else if (cfg == 0x20) raw = raw & ~3; // 10 bit res, 187.5 ms
    else if (cfg == 0x40) raw = raw & ~1; // 11 bit res, 375 ms
    //// default is 12 bit resolution, 750 ms conversion time
  }
  celsius = (float)raw / 16.0;
  return celsius;
}

boolean updateUnidots(float value)
{
// if you get a connection, report back via serial:
  int num=0;
  String var = "{\"value\": " + String(value)+"}";
  num = var.length();
  if (client.connect("things.ubidots.com", 80)) {
    DebugPrintln("connected ubidots");
    delay(100);
    client.println("POST /api/v1.6/variables/"+idvariable+"/values HTTP/1.1");
    DebugPrintln("POST /api/v1.6/variables/"+idvariable+"/values HTTP/1.1");
    client.println("Content-Type: application/json");
    DebugPrintln("Content-Type: application/json");
    client.println("Content-Length: "+String(num));
    DebugPrintln("Content-Length: "+String(num));
    client.println("X-Auth-Token: "+token);
    DebugPrintln("X-Auth-Token: "+token);
    client.println("Host: things.ubidots.com\n");
    DebugPrintln("Host: things.ubidots.com\n");
    client.print(var);
    DebugPrint(var+"\n");
  }
  else {
    // if you didn't get a connection to the server:
    DebugPrintln("ubidots connection failed");
    DebugPrintln("NotConnected");
    return false;
  }

  return true; //successful connection
}
« Last Edit: April 02, 2016, 08:35:14 pm by pfeerick »

maximo80

  • Newbie
  • *
  • Posts: 17
Re: Oak with data dashboards
« Reply #5 on: April 03, 2016, 11:25:18 pm »
Thanks, now it is working perfectly.
I was using other sketch example but yours work better!!!
So I'm monitoring the energy consumption in my home and my refresh is every 5 sec. I was doubting about it but checking it out during 24h there is no connection problem!!
My second step is to record these data in a sql database or where I can analyse better the regular consumption.
Regards,

efifi

  • Newbie
  • *
  • Posts: 2
Re: Oak with data dashboards
« Reply #6 on: June 05, 2016, 12:59:07 am »
FYI - I had trouble until i realised the TOKEN is under your API Credentials

You should have something like this

//Unidots variables
String idvariable = "5753bd797624421dabeb65b3";
String token = "tIgatwJc22AB8u4FkxzKqTBeeoCqyZ";

Thanks for the help - works beautifully.

maximo80

  • Newbie
  • *
  • Posts: 17
Re: Oak with data dashboards
« Reply #7 on: January 19, 2017, 10:48:24 pm »
Hi PeterF,

After looking for many things I tried to make it works properly with my new code but after several hours it goes down and it does not send any data.
Could you help me to find where is the error?

#include <OneWire.h>
#include <DallasTemperature.h>
#include <WiFiClient.h>
#include <ESP8266WiFi.h>

/*-----( Declare Constants and Pin Numbers )-----*/
#define ONE_WIRE_BUS_PIN 2

/*-----( Declare objects )-----*/
// Setup a oneWire instance to communicate with any OneWire devices
OneWire oneWire(ONE_WIRE_BUS_PIN);
// Pass our oneWire reference to Dallas Temperature.p,
DallasTemperature sensors(&oneWire);
int status = WL_IDLE_STATUS;     // the Wifi radio's status
WiFiClient client;

/*-----( Declare Variables )-----*/
DeviceAddress Probe01 = { 0x28, 0xFF, 0xA4, 0xD9, 0x62, 0X16, 0x04, 0x3B };
DeviceAddress Probe02 = { 0x28, 0xFF, 0xA9, 0xD9, 0x62, 0x16, 0x04, 0xD7 };
double temp1,temp2;
String tubi1 = "xx1";
String tubi2 = "xx2";
String token = "tttt";


void setup()   /****** SETUP: RUNS ONCE ******/
{
  // start serial port to show results
  Serial.begin(9600);
  Serial.print("Initializing Temperature Control Library Version ");
  Serial.println(DALLASTEMPLIBVERSION);
 
  // Initialize the Temperature measurement library
  sensors.begin();
 
  // set the resolution to 10 bit (Can be 9 to 12 bits .. lower is faster)
  sensors.setResolution(Probe01, 10);
  sensors.setResolution(Probe02, 10);

  Particle.variable("temp1", temp1);
  Particle.variable("temp2", temp2);
 
  if (Particle.connected() == false)
  {
    Particle.connect();
  }

}//--(end setup )---

void loop()   /****** LOOP: RUNS CONSTANTLY ******/
{
   WiFiClient client;
   if (Particle.connected() == false)
  {
    Particle.connect();
  } if (Particle.connected() == false)
  {
    Particle.connect();
  }
  delay(60000);
   // Command all devices on bus to read temperature 
  sensors.requestTemperatures(); 
 
  Serial.print("Probe 01 temperature is:   ");
  temp1 = sensors.getTempC(Probe01);
  Serial.println(temp1);
  updateUnidots(temp1,tubi1);
 

  Serial.print("Probe 02 temperature is:   ");
  temp2 = sensors.getTempC(Probe02);
  Serial.println(temp2);
  updateUnidots(temp2,tubi2);
 
}//--(end main loop )---

boolean updateUnidots(double value,String idvariable)
{
// if you get a connection, report back via serial:
  int num=0;
  String var = "{\"value\": " + String(value)+"}";
  num = var.length();
  if (client.connect("things.ubidots.com", 80)) {
    delay(100);
    client.println("POST /api/v1.6/variables/"+idvariable+"/values HTTP/1.1");
    client.println("Content-Type: application/json");
    client.println("Content-Length: "+String(num));
    client.println("X-Auth-Token: "+token);
    client.println("Host: things.ubidots.com\n");
    client.print(var);
    }
        }

//*********( THE END )***********


PeterF

  • Hero Member
  • *****
  • Posts: 881
Re: Oak with data dashboards
« Reply #8 on: January 20, 2017, 08:24:22 pm »
Ok, I've had a quick look at the code, and made a few changes (probably just due to smooshing differnt bits of code together)...  I got rid of the WiFiClient client; from loop(), as it's already (properly) declared globally (at the top).

Can I ask why the multiple

Code: [Select]
  if (Particle.connected() == false)
  {
    Particle.connect();
  }

checks... one in setup, and two in loop? It shouldn't really be needed, because unless you have the Oak in SYSTEM_MODE(SEMI_AUTOMATIC) or SYSTEM_MODE(MANUAL), the Oak's firmware will handle that itself in the background. When I've used Particle variables, that is what I have done... used SYSTEM_MODE(SEMI_AUTOMATIC) so that the Particle connection needs to be manually established, so that I can declare the variables and then use that conditional statement to connect to Particle.

Do you want it to delay for 60 seconds and then send the temperature updates, or send the first updates straight away and then wait 60 seconds until the next?

As to why the Oaks stop responding... do they stop responding completely (i.e. offline on Particle) or just stop sending data to ubidots? Do they reboot into safe mode on their own? Nothing is jumping out from the code... it all looks fine. I have essentially this code running on another Oak that has been running for a couple of months now, and it has been stable, but there is one big difference... it isn't running 24x7... it is running, and putting itself to sleep until the next update, at which point it reboots and starts afresh each time. Would that be practical for your intended use? It does mean that you need to put it into config mode to do OTA programming, as it really is asleep during wait... but on the plus side power consumption is virtually nothing.

The only other big difference is that I have the functions for reading the DS18B20 directly in my code (I only include OneWire), but that shouldn't really be the cause of the problem.

If you do want to go down the sleep / reboot route... do a   

Code: [Select]
// power save/sleep for 1 minute
ESP.deepSleep((60 * 1000000), WAKE_RF_DEFAULT);

at the end of your loop, and remove the earlier delay. You'll also need to connect P10 [WAKE] to RST so that the Oak can wake itself up at the end of the deepsleep interval.

Code: [Select]
SYSTEM_MODE(SEMI_AUTOMATIC)
#include <OneWire.h>
#include <DallasTemperature.h>
#include <WiFiClient.h>
#include <ESP8266WiFi.h>

/*-----( Declare Constants and Pin Numbers )-----*/
#define ONE_WIRE_BUS_PIN 2

/*-----( Declare objects )-----*/
// Setup a oneWire instance to communicate with any OneWire devices
OneWire oneWire(ONE_WIRE_BUS_PIN);
// Pass our oneWire reference to Dallas Temperature.p,
DallasTemperature sensors(&oneWire);
WiFiClient client;

/*-----( Declare Variables )-----*/
DeviceAddress Probe01 = { 0x28, 0xFF, 0xA4, 0xD9, 0x62, 0X16, 0x04, 0x3B };
DeviceAddress Probe02 = { 0x28, 0xFF, 0xA9, 0xD9, 0x62, 0x16, 0x04, 0xD7 };
double temp1, temp2;
String tubi1 = "xx1";
String tubi2 = "xx2";
String token = "tttt";

void setup()   /****** SETUP: RUNS ONCE ******/
{
  // start serial port to show results
  Serial.begin(9600);
  Serial.print("Initializing Temperature Control Library Version ");
  Serial.println(DALLASTEMPLIBVERSION);

  // Initialize the Temperature measurement library
  sensors.begin();

  // set the resolution to 10 bit (Can be 9 to 12 bits .. lower is faster)
  sensors.setResolution(Probe01, 10);
  sensors.setResolution(Probe02, 10);

  Particle.variable("temp1", temp1);
  Particle.variable("temp2", temp2);

  if (Particle.connected() == false)
  {
    Particle.connect();
  }

}//--(end setup )---

void loop()   /****** LOOP: RUNS CONSTANTLY ******/
{
//  if (Particle.connected() == false)
//  {
//    Particle.connect();
//  }
 
//  if (Particle.connected() == false)
//  {
//    Particle.connect();
//  }
 
//  delay(60000);
 
  // Command all devices on bus to read temperature
  sensors.requestTemperatures();

  Serial.print("Probe 01 temperature is:   ");
  temp1 = sensors.getTempC(Probe01);
  Serial.println(temp1);
  updateUnidots(temp1, tubi1);

  Serial.print("Probe 02 temperature is:   ");
  temp2 = sensors.getTempC(Probe02);
  Serial.println(temp2);
  updateUnidots(temp2, tubi2);

  // power save/sleep for 1 minute
  ESP.deepSleep((60 * 1000000), WAKE_RF_DEFAULT);
}//--(end main loop )---

void updateUnidots(double value, String idvariable)
{
  // if you get a connection, report back via serial:
  int num = 0;
  String var = "{\"value\": " + String(value) + "}";
  num = var.length();
  if (client.connect("things.ubidots.com", 80)) {
    delay(100);
    client.println("POST /api/v1.6/variables/" + idvariable + "/values HTTP/1.1");
    client.println("Content-Type: application/json");
    client.println("Content-Length: " + String(num));
    client.println("X-Auth-Token: " + token);
    client.println("Host: things.ubidots.com\n");
    client.print(var);
  }
}

//*********( THE END )***********
« Last Edit: January 20, 2017, 08:34:31 pm by PeterF »