Friday, September 11, 2015

Happiness Formula

Many people have tried to express human happiness in a mathematical formula. One of my personal favorites is created by Scott Adams (Dilbert fame). However, after many deep thoughts and a few drinks with my buddies I have concluded that Scott did not get the formula quite correct.

The correct and official Happiness Formula is shown in Figure 1. below
Fig 1. Happiness Formula



While Scott tried to explain happiness as a linear combination of each component he missed a few important points.

Integral over time  - human happiness varies over time. Happiness is a fragile mental state that can easily go up or down. True happiness must be an integral over the observation time period.  The time period could be one fantastic night out with good friends celebrating your promotion or over several months when you are fighting for your life in a cancer treatment center. It could also be over a lifetime when you are on your death bed thinking of your life and all the happy experiences. It can also be over the time period when you fell madly in love, got married  and eventually divorced. When you select a different time horizon, you end up with a different happiness value.

Normalization  - to be able to measure happiness you need to normalize the value by dividing the sum of components with expectations. If you expect the world you might not be happy even with the greatest partner or having billion dollars in your pocket. Your happiness depends on your expectations; winning a million dollars in a lottery when you least expect will boost your happiness for a while. If you expect to win 2 millions but you only get 1 million you will be disappointed. A small kid visiting DisneyWorld for the first time is super happy about the experience; an adult visiting same place for the 5th time gets easily bored and is not very happy.

Individual Coefficient - Ci also known as "Ida's constant" by the Finnish waitress who validated Happiness Formula after our happy group had spent significant effort and had many drinks to formulate happiness. This coefficient scales the happiness value for each individual to comply with International Unit of Happiness, aka  "Anand".

Standardized Unit  -  Anand ( आनन्द ) is a Hindi word for happiness.  One Anand is the unit of happiness, much like Tesla is the unit of magnetic flux density.

So there you have it, a mathematically rigorous formula of Happiness.

In the next post we focus on measurement techniques of Happiness and how to calibrate your measurement system against the International Anand standard held in safety in our Boston based laboratory.

Until next time.

Mauri


Thursday, September 10, 2015

Internet of Things (IoT) - hype vs. reality

Over the last few years the hype around "Internet of Things" (IoT) has been growing rapidly. According to Gartner Hype Cycle 2015 IoT is peaking currently. Assuming IoT follows this cycle this would mean that we are at the peak of inflated expectations and heading towards the through of disillusionment. See figure 1. below to see how IoT concept is tracking on the hype cycle.


Fig 1. "Peak of Expected Inflated Expectations"


























I wanted to learn more about the IoT technology and do some concrete experiments to better understand what IoT can offer. I found the Particle Photon board that is a small $19 Arduino compatible U.S. quarter size board with WiFi enabled Internet connectivity very suitable for prototyping some IoT ideas.  See fig 2. below to get a sense of the size of this tiny board. I ordered two of these just to play a bit and try to build something useful out of these.

Fig 2. Particle Photon board with and without breadboard headers


HUMIDITY CONTROLLER EXPERIMENT

I  already have some previous experience working with Arduino compatible boards such as Arduino Pro Mini that is physically almost the same size of Particle Photon.  In fact I used that board to build a simple humidity controller in our bathroom. This was a quick weekend project where I prototyped on a breadboard a simple circuit with a humidity sensor, a LED indicator and a relay driver to turn the bathroom fan on and off.  I assembled the prototype parts including the breadboard, sensor, relay unit and 12v/5V power supply inside an Apple mouse plastic enclosure. See Fig 3.


Fig 3.  Arduino based humidity controller prototype.



















With a few holes drilled on this plastic enclosure to allow air to flow over the sensor I was able to fit the whole controller inside an existing vent box, see Fig 4. below.


Fig 4.  Humidity controller installed inside the vent box.

























However,  I did have a problem with this simple controller.  The few lines of software that I wrote in winter time when relative humidity is normally quite low worked very well for many months but during summer months when relative humidity is much higher the software didn't work that well. Debugging this kind of embedded software is not that easy.  I disassembled the prototype for 3 times uploading yet another software version but the damn thing kept starting the vent fan in the middle of night or at some random time.


INTERNET ENABLED HUMIDITY CONTROLLER 

I had to find a solution to this problem so when I learned about the Particle Photon board I knew that this might  just be the solution.  After reading some of the documentation I was pretty sure that having Internet connection would not only help me to debug the problem but also saves me a lot of trouble, as Particle Photon allows you to install the new firmware over the air.  So I wouldn't have the get the vent box  open, remove all wires,  flash the Arduino board with new software and assemble everything back together.

After connecting the Particle Photon board to my Wifi and adding the device on Particle.io web IDE, I used Particle.io web based software development environment (see Fig 5. below) to edit and debug the humidity controller software. I could just simply edit, compile new code, press a button and install firmware almost instantly over the Internet using the WiFi connection on this Photon board.

How cool is this?

Fig 5. Web based software development environment























Particle.io provides also excellent API that have simple to use Internet enabled functions that you can incorporate in your own software. In my case I wanted to debug how the humidity sensor behaves when you have a transient increase in relative humidity when taking a shower.  I used the HTU21D sensor from  Sparkfun. Easy way to debug is to publish your sensor data to the Internet using a simple function like  Spark.publish("RH_temp",str,60,PRIVATE); 

You can use the Particle Dashboard to view the sensor data in near real time. This was almost too easy to describe on a blog like this.


Fig 6. Particle Dashboard

















You can use of course use your own web or mobile applications to read and write data as well as control the input/output pins on the Photon board.

I used a simple API command line call to capture the sensor data for plotting:

curl -k https://api.particle.io/v1/devices/<your device id>\/events/?access_token\=<your access token>   >photon_data.txt

Figure 7. below shows the relative humidity transient after taking a shower and then the decline as the vent fan is running.  You can also see the small temperature increase when the hot water is running. When looking at the data I realized that my RH% threshold had been too small. When I increased the threshold value the controller started working much better.  Being able to extract the sensor data and publish it over the Internet made a big difference in debugging the original problem.


Fig 7.  RH% delta and Temperature over time


 

PLOTTING 

In order to collect more data and have a dashboard to plot and review the measurements I signed up for a free account at ThingSpeak. You get an API key and channel number. With these you can plot the values with a simple API call:
ThingSpeak.writeFields(myChannelNumber, myWriteAPIKey);

 Fig 7 and 8 below show the sensor data plot. Relative humidity peaks at 100%  when taking a shower but since the fan is turned on almost instantly the humidity starts to drop quickly back to normal. You can see also a small increase in temperature at the same time. The drop in temperature is due to A/C that turns on at 6:00 AM.

Fig 7. Relative Humidity plot showing a peak

Fig 8. Temperature plot

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

CONCLUSIONS 

My quick foray into the world of "Internet of Things"  took me about 2 hours on a Sunday afternoon. Using the latest  Particle.io Photon board and the web based IDE  I was able to convert my existing Arduino based humidity controller to an Internet enabled controller that is publishing sensor data in near real time and allows me to update the software over the air.

This whole project felt like too easy - I expected that building IoT prototypes would be much harder but at least for this simple use case it took a novice like myself only a short time to solve a real world problem.  Now the bathroom vent works as expected and humidity is under control.


APPENDIX - SOFTWARE 

The current software version is listed below.  As you can see this is not rocket science - a few lines of code and you have an Internet connected sensor / controller.

// This #include statement was automatically added by the Particle IDE.
#include "HTU21D/HTU21D.h"
#include "application.h"
/* 
 HTU21D Humidity Controller
 By: Mauri Niininen (c) Innomore LLC
 Date: Aug 30, 2015


 Uses the HTU21D library to control humidity using a fan.

 Hardware Connections (Breakout board to Photon)
 -VIN = 5.3 V
 -VCC = 3.3 V
 -GND = GND
 -SDA = D0 (use inline 330 ohm resistor if your board is 5V)
 -SCL = D1 (use inline 330 ohm resistor if your board is 5V)

 -RLY = D3   relay board 
 */



#define HOUR  3600/10   // 1 HOUR in seconds - divide by loop delay 10 secs
#define HRS_24 24    // 24 hours of history 

// define class for 24 hr relative humidity 
class RH24 {
private:
  float rh24[HRS_24];  // Keep last 24 hours of humidity 
  int counter;
  int index; 
public:
  void init(float RH);
  void update_h(float RH);  
  float avg(float RH);
};

//Create an instance of the objects
HTU21D mh;
RH24  rh; 

// for time sync
#define ONE_DAY_MILLIS (24 * 60 * 60 * 1000)
unsigned long lastSync = millis();


void setup()
{
  
  
  pinMode(D7, OUTPUT);
  pinMode(D3, OUTPUT);
  
  while (! mh.begin()){
      digitalWrite(D7,HIGH);
      delay(200);
      digitalWrite(D7,LOW);
      delay(200);
  }


  // turn on the fan
  digitalWrite(D3,HIGH);

  // initialize sensor 
  rh.init(mh.readHumidity());  
  delay(5000);
  
  // turn off the fan
  digitalWrite(D3,LOW);
}


// MAIN PROGRAM LOOP 
void loop()
{
  // read sensor humidity and temperature 
  float humd = mh.readHumidity();
  float temp = mh.readTemperature();
  float avg = rh.avg(humd);
  float delta = humd - avg;
  
  // convert data to string
  String h_str = String(humd,2);
  String t_str = String(temp,2);
  String d_str = String(delta,2);
  String avg_str = String(avg,2);
  String tm_str = String(millis());
  String str = String(h_str+":"+t_str+":"+d_str+":"+avg_str+":"+tm_str);
  

  // if relative humidity increases over 12% vs. 24 hour average, turn on the fan 
  if (humd - avg > 12.0) {
    digitalWrite(D7,HIGH);
    digitalWrite(D3,HIGH);
    Spark.publish("RH_temp","ON",60,PRIVATE);
  }
  else {
    digitalWrite(D7,LOW);
    digitalWrite(D3,LOW);
  }


  // time sync over Internet once a day
  if (millis() - lastSync > ONE_DAY_MILLIS) {
    // Request time synchronization from the Particle Cloud
    Spark.syncTime();
    lastSync = millis();
  }
    
  // Send a published string to your devices...
  Spark.publish("RH_temp",str,60,PRIVATE);
  delay(10000);

}


void RH24::init(float RH){
    counter = 0;
    index = 0;
    for (int i = 0; i < HRS_24; i++)
      rh24[i] = RH;
}

void RH24::update_h(float RH) {
    counter += 1;
    if (counter > HOUR) {
      counter = 0; 
      rh24[index] = RH; 
      index += 1;
      if (index >=HRS_24) 
        index = 0;
    }
}  
    
float RH24::avg(float RH) {
    update_h(RH);
    float sum = 0.0;
    for (int i = 0; i < HRS_24; i++)
      sum += rh24[i];
    return (sum/HRS_24);
}