phatduinoa personal home automation technology arduino




Automate!

Who's there? (Processing door lock data) • Blinded by the... night?! (Processing light sensor data) • Get out of my bed! (FSR data processing) • The real heart of it (Automating light switches)

Welcome to the very core of Phatduino. Automation is the essence of making this project useful. To automate my home I am using a couple of functions as shown in the diagram in the software section. It can be used as simple navigation! The functions are processed one by one, in a specified loop interval (see reference for loop() function for further explanations).

Now we will go through all automation functions. For me it was a great pleasure to finally arrive at my goal and start brainstorming about how the sensor values are really related to each other and how they could serve the goals I wanted to achieve (see idea). To understand which kind of sensors we are using I want you to read the previous sections. However I will try to write an intuitive description of the automation process.

The structure of the automation process works mainly modular. There is a function for each thing to be checked (e.g. whether there is someone lying in bed, whether it is night) and a function that switches lights depending upon the reports of the check functions. You could see this as a further input/output stream in the diagram, leading from the sensors via Arduino directly to the user and its environment. The first function I want to introduce is the "door check".

Who's there?

Can that really be one of Phatduino's questions? No, because for switching off lights to save power and provide safety when noone is at home it is not necessary to know "who's there", but if there is somebody. And as my life works I always unlock the door when I am in my room and I lock it when I go out of my home. So whenever I am not at home, that means, whenever my door is locked, I do not want any lights to be turned on and I do not want hackers to hack the web interface and switch on the lights on and off as they wish. This is why I need a function called door_check(). This function works with the following variables that you do not know yet:

  • int access_last_checked This variable stores the access state - if access to the room is possible (door is not locked) it is 1, if access is not possible it equals 0. It is the working variable for the door status in Phatduino, all automation functions use it.
  • int access_var This variable is pretty much the same as access_last_checked but it is always the current status determined by the measurement in the measure functions. It is necessary to have two values to prevent errors in automation (that could happen e.g. if the door is locked/unlocked while an automation cycle is performed).
void door_check() {
  
  // Shut down all light when door is closed
    if((access_last_checked != access_var) && access_var == 0){
        for (int i = 1;i <= 4; i++){
          if(SL[i] == 1){
            SLC[i] = 1;
          }
        }
        Serial << F("Door is closed!");
        access_last_checked = 0;  
      }
      if(access_var == 1){
        Serial << F("Door is opened!");
        access_last_checked = 1;
      }
}

So you see, if the door is locked and was unlocked before the lights are getting a "switch off" marker via int SLC[] in case they are on and will be switched off later by the function change_light_status(). In case the door is not locked access_last_checked is set to 1.

∧ back_to_top()

Blinded by the... night?!

Exactly! There has to be a specific threshold value for Phatduino to decide whether it is dark (and therefore night) outside or not. It is just a matter of experience, I found out that I think it is night when the voltage value at my photocell pin is lower than 250. However this is not the only purpose the function night_check() serves, it also counts the nights for a special purpose: When I am going to bed I am used to read some newspaper or listen to some music. So the light should be turned on for some minutes. But when I step out my bed to pay a visit to the lavatory at night I do not want the light to stay on for this long time. This is why I implemented a function (we will talk about that later) that checks if it is the first time I went to bed this night. This function uses the counter implemented in the function we are going to talk about now: night_check().

Now let me explain the variables this function uses:

  • nights_counted, nights_running The counters I just talked about.
  • int light_darkness_threshold This is the threshold value for Phatduino to decide that it is night/day.
  • int light This is the light level light_darkness_threshold is compared to.
  • boolean last_night_went_to_bed, is_night Self-explanatory, I guess.
void night_check(){  
        int light_darkness_threshold = 250; // Threshold for light sensor to sense night
              
        Serial << F("Night check!\n");  
        
       // Check for night
       if(light <= light_darkness_threshold){
         
         is_night = true;
         
         if(nights_running == nights_counted){
           nights_counted++;
      
           Serial << F("It's night number ") << nights_counted << "\n";
        }

       }else{
          is_night = false;
          if(nights_counted != nights_running){  
            nights_running++;
      
            Serial << F("I am running so many nights: ") << nights_running << F(" It is day 
¬now!\n"
);           }           last_night_went_to_bed = false;         } }        

As the light level is lower than the threshold value Phatduino decides that it is night. int nights_counted has to be greater by one than int nights_running. Just as the sun rises in the morning int nights_running is set equal to int nights_counted. Finally a new day has come and a new night will arrive... and we know that boolean last_night_went_to_bed for the coming night has to be false for now.

∧ back_to_top()

Get out of my bed!

For sure: We do not want any wires lying beside us while we are sleeping. That's not romantic! This is why Phatduino holds all equipment for measuring whether you are in your bed far away from where you are sleeping. Good! But to check whether there is any need to dim the light it is absolutely inevitable to do a check on the weight that stresses the slatted bed frame. This is realized by the function bed_check(). This check has a special way of finding out if someone entered or left the bed. There are two mathematical ways of interpreting the values given by the voltage measurement. One is to check whether a certain threshold has been reached, meaning that there is at least a specified weight on the bed frame. The other is to check how much the value has changed since the last check. If it has changed a lot, then we can be sure of that somebody moved his body out of the bed. I do not want to deny that this mechanism has its problems. Just imagine somebody is entering the bed very slowly, so that the value change between two measuring cycles is smaller than the threshold value. Or imagine I just lost a lot of weight: The mechanism will not even realize I am inside the bed. From the measurements I can already tell that the chance of missing the sensor with your weight center is close to zero. Because the sensor measures the weight on a central bar of the slattered bed frame you can hardly imagine that a person sleeping in the bed will miss that bar.

As we talked about the problems now, let us face the facts. The mechanism works and is highly customizable. Again we find two values of sensor data, one "working value" and one value delivered freshly from the measuring routine. Just have a look:

  • int bed This is the freshly measured value!
  • int bed_last_checked The working value for "int bed".
  • int entered_bed_time The archived loop no. from the point of time someone went to bed.
  • boolean someone_in_bed, int bed_change_threshold, bed_value_threshold Definitely self-explanatory.
void bed_check(){    
        
   // Threshold values
        int bed_change_threshold  = 20;
        int bed_value_threshold  = 440;
      
      
        Serial << F("Ich check das Bett!\n");
      
        if((bed_last_checked - bed) > bed_change_threshold && bed < bed_value_threshold){  
          someone_in_bed = false;
          Serial << F("Keiner im Bett!\n");
        }
    
        if((bed - bed_last_checked) > bed_change_threshold && bed > bed_value_threshold){      
          someone_in_bed = true;
          entered_bed_time = loop_no;
          Serial << F("Es ist jemand ins Bett gegangen!\n");
        }
     
        bed_last_checked = bed;
        Serial << F("Letzter Wert: ") << bed_last_checked << "\n";
}

∧ back_to_top()

The real heart of it

After all we are left with the light_automation() function. This is where all variables and sensor data we talk about in Phatduino comes together. By a series of if statements we check various values and decide which light should be switched on or off. But see for yourself:

void light_automation(){
    
    if(someone_in_bed == false && is_night == true && lcm[1] == 0 && SL[1] == 0  && 
¬access_var == 1){         SLC[1] = 1;         change_light_status();         Serial << F("Nobody in bed, but I'll turn the lights on because it is night!!\n");     }            // Turn off lights if someone in bed after bed_lights_off_interval and is going to bed
¬ for the first time this night
      if((loop_no - entered_bed_time) > bed_lights_off_interval && last_night_went_to_bed
¬== false && nights_counted != nights_running && is_night == true && someone_in_bed == true
¬ && access_var == 1){         for (int j; j <= 4; j++){           if(SL[j] == 1 && lcm[j] == 0){             SLC[j] = 1;             change_light_status(); // Delete this if there is a memory overflow           }         }        Serial << F("Someone is in bed sice a couple of minutes!");        last_night_went_to_bed = true;       }            // Turn off light 3 if someone is going to bed at some point in time at night,
¬ but not for the first time
      if((loop_no - entered_bed_time) > bed_lights_off_interval_short &&
¬last_night_went_to_bed == true && is_night == true && someone_in_bed == true &&
¬ access_var == 1){         for (int j; j <= 4; j++){           if(SL[j] == 1 && lcm[j] == 0){             Serial << F("Switch off lights... somebody went to bed not for the first time this
¬ night!"
);             SLC[j] = 1;             change_light_status(); // Delete this if there is a memory overflow           }         }       }             if(is_night == false){           if(SL[1] == 1 && lcm[1] == 0){             SLC[1] = 1;             change_light_status(); // Delete this if there is a memory overflow           }       }     }

I guess there is no need to explain the function further, as the variables have clear names and there are proper debugging notes included. If you are looking for a definition of int SL[], SLC[], lcm[] check this.

∧ back_to_top()