Monday 6 July 2015

Rpi2 hysteresis to control temperature with HTML5 and DS18b20 temp sensor

I have not been playing around with the Raspberry Pi due to other commitments. However I have just completed a change that I have been planning for months.

The task is one that is pretty familiar in that I wanted to display temperature, set a temperature to which a 'switch' would go on and off. Oh a thermostat.

The layout, after a hell of a lot of tinker time, is pretty simple.

I will explain a bit about what is actually happening to put the code into context.

We have a HTML5 driven webpage which is built up with a mix of CSS and PHP. The temperture readings are provided via a DS18b20 sensor. The readings are then updating via Server-Sent Events by reading the sensor file. The setting of the set point is simple button events linked to two php functions that open a file called 'setpoint.txt'. The set point file is then polled by a python script. The script then compares the current set point to the temperature from the sensor with some hysteresis built in to reduce the number of 'on' and 'off' events.

Hmm sounds interesting. Lets cut some code and get it on your Pi. For this I have used the Raspberry Pi 2.

First create - index.php and insert the following code.

<?php
//This function opens the setpoint file and increases it by the value of 1 then closes

function uptemp() {

$setpoint = file_get_contents('setpoint.txt');
$myfile = fopen("setpoint.txt", "w") or die("Unable to open file!");
$txt = $setpoint + 1;
fwrite($myfile, $txt);
fclose($myfile);
}

//This function opens the setpoint file and decreases it by the value of 1 then closes

function downtemp(){
$setpoint = file_get_contents('setpoint.txt');
$myfile = fopen("setpoint.txt", "w") or die("Unable to open file!");
$txt = $setpoint - 1;
fwrite($myfile, $txt);
fclose($myfile);
}

?>
<!DOCTYPE HTML>
<html lang="en">
<head>
<link rel="stylesheet" href="css/style.css">
<?php 
if (isset($_POST['RedON']))
{
uptemp();
}

if (isset($_POST['RedOFF']))
{
downtemp();
}

if (isset($_POST['plugon']))
{
exec("/usr/local/bin/tdtool -n 1");
}
if (isset($_POST['plugoff']))
{
exec("/usr/local/bin/tdtool -f 1");
}

?>

  <title>Tell Stick Plug Control</title>
</head>
<body>
<h1 style="text-align: center;">Mawston Mansion</h1>
<div class="container">
    <div class="de">
        <div class="den">
          <div class="dene">
            <div class="denem">
              <div class="deneme">
<script type="text/javascript">
//check for browser support
if(typeof(EventSource)!=="undefined") {
        //create an object, passing it the name and location of the server side script
        var eSource = new EventSource("temp.php");
        //detect message receipt
        eSource.onmessage = function(event) {
                //write the received data to the page
                document.getElementById("serverData").innerHTML = event.data + "&deg;c";
        };
}
else {
        document.getElementById("serverData").innerHTML="Whoops! Your browser doesn't receive server-sent events.";
}

</script><div id="serverData"></div>
              </div>
            </div>
          </div>
        </div>
    </div>
</div>
<br><br>
<div>
<form method="post">
  <table
 style="width: 75%; text-align: left; margin-left: auto; margin-right: auto;"
 border="0" cellpadding="2" cellspacing="2">
    <body>

</div>


<div height: 50%;>
      <tr>
        <td style="text-align: center;"><button class="button" name="RedON">Increase Setpoint</button></td>
<td style="text-align: center;">Current setpoint is: <?
        $f = fopen("setpoint.txt", "r");

        // Read line from the text file and write the contents to the client
        echo fgets($f); 

        fclose($f);
?>&deg;c</td>
        <td style="text-align: center;"><button class="button" name="RedOFF">Decrease Setpoint</button></td>

<tr/>
<tr>
        <td style="text-align: center;"><button class="button" name="plugon">Heat lamp on</button></td>
<td></td>
        <td style="text-align: center;"><button class="button" name="plugoff">Heat lamp Off</button></td>
      </tr>
    </body>
  </table>
</form>

<p>

<?

?>
</p>
</div>

</body>
</html>

Then create a text file called 'setpoint.txt' and put a value of 5 in. No other information at all is needed for this file now.

Next we need our switching for the python script.

#!/usr/bin/env python

from subprocess import call
import time
import datetime

while 1:

file = open('/var/www/setpoint.txt')
tempx = int(file.read(2))
file.close()

with open("/sys/bus/w1/devices/28-000003dcfad1/w1_slave") as f, open("temps.txt", "w") as f1:
ts = time.time()
st =datetime.datetime.fromtimestamp(ts).strftime('%Y-%m-%d %H:%M:%S')
secondline = f.readlines()[1].strip()
temperaturedata = secondline.split()[9]
temperature = float(temperaturedata[2:])
temperature /= 1000
f1.write(str(temperature) + "\n")
time.sleep(1)
if temperature + 0.5 >= tempx:
call(["tdtool", "--off", "1"])
print('The heating will remain off.', tempx, st)
print "The temperature is", temperature, "The setpoint is", tempx;
else:
print('We are switching the heat on.', tempx, st)
call(["tdtool", "--on", "1"])
print "The temperature is", temperature, "The setpoint is", tempx;

time.sleep(1)

Add a folder called 'CSS' to your /var/www folder and create a file called style.css and add the following code.

h1
{
color: white;
}

body
{
background-size:cover;
background: -webkit-radial-gradient(circle, #1a82f7, #2F2727);
color: white;
padding:50px;
margin:0px;
width:100%;
height:50%;
}
div
{
display:block;
}


.button {
   border-top: 1px solid #96d1f8;
   background: #65a9d7;
   background: -webkit-gradient(linear, left top, left bottom, from(#3e779d), to(#65a9d7));
   background: -webkit-linear-gradient(top, #3e779d, #65a9d7);
   background: -moz-linear-gradient(top, #3e779d, #65a9d7);
   background: -ms-linear-gradient(top, #3e779d, #65a9d7);
   background: -o-linear-gradient(top, #3e779d, #65a9d7);
   padding: 5px 10px;
   -webkit-border-radius: 8px;
   -moz-border-radius: 8px;
   border-radius: 8px;
   -webkit-box-shadow: rgba(0,0,0,1) 0 1px 0;
   -moz-box-shadow: rgba(0,0,0,1) 0 1px 0;
   box-shadow: rgba(0,0,0,1) 0 1px 0;
   text-shadow: rgba(0,0,0,.4) 0 1px 0;
   color: white;
   font-size: 14px;
   font-family: Georgia, serif;
   text-decoration: none;
   vertical-align: middle;
   }
.button:hover {
   border-top-color: #28597a;
   background: #28597a;
   color: #ccc;
   }
.button:active {
   border-top-color: #1b435e;
   background: #1b435e;
   }
#content
{
height: auto:
width: auto:
}

h1
{
color: white;
}

body
{
background-size:cover;
background: -webkit-radial-gradient(circle, #1a82f7, #2F2727);
color: white;
padding:50px;
margin:0px;
width:100%;
height:50%;
}
div
{
display:block;
}


.button {
   border-top: 1px solid #96d1f8;
   background: #65a9d7;
   background: -webkit-gradient(linear, left top, left bottom, from(#3e779d), to(#65a9d7));
   background: -webkit-linear-gradient(top, #3e779d, #65a9d7);
   background: -moz-linear-gradient(top, #3e779d, #65a9d7);
   background: -ms-linear-gradient(top, #3e779d, #65a9d7);
   background: -o-linear-gradient(top, #3e779d, #65a9d7);
   padding: 5px 10px;
   -webkit-border-radius: 8px;
   -moz-border-radius: 8px;
   border-radius: 8px;
   -webkit-box-shadow: rgba(0,0,0,1) 0 1px 0;
   -moz-box-shadow: rgba(0,0,0,1) 0 1px 0;
   box-shadow: rgba(0,0,0,1) 0 1px 0;
   text-shadow: rgba(0,0,0,.4) 0 1px 0;
   color: white;
   font-size: 14px;
   font-family: Georgia, serif;
   text-decoration: none;
   vertical-align: middle;
   }
.button:hover {
   border-top-color: #28597a;
   background: #28597a;
   color: #ccc;
   }
.button:active {
   border-top-color: #1b435e;
   background: #1b435e;
   }
#content
{
height: auto:
width: auto:
}

@import url(http://fonts.googleapis.com/css?family=Dosis:200,400,500,600);
html, body { height: 100%; }

.container { width: 300px; margin: 10px auto 0; }
.de .den, .de .dene, .de .denem, .de .deneme { position: absolute;  left: 50%; top: 50%; }
.de {
    position: relative;
    width: 240px;
    height: 240px;
    border-radius: 100%;
    box-shadow: 0 0 10px rgba(0, 0, 0, .1);
    background-color: transparent;
}
.den {
    position: relative;
    width: 210px;
    height: 210px;
    margin: -105px 0 0 -105px;
    border-radius: 100%;
    box-shadow: inset 0 2px 10px rgba(0, 0, 0, .5), 0 2px 20px rgba(255, 255, 255, 1);
    background: #df3341;
    background: -moz-linear-gradient(left, #df3341 0%, #d4f355 50%, #61c0ec 100%);
    background: -webkit-gradient(linear, left top, right top, color-stop(0%,#df3341), color-stop(50%,#d4f355), color-stop(100%,#61c0ec));
    background: -webkit-linear-gradient(left, #df3341 0%,#d4f355 50%,#61c0ec 100%);
    background: linear-gradient(to right, #df3341 0%,#d4f355 50%,#61c0ec 100%);
    position:relative;
}
.dene {
    width: 180px;
    height: 180px;
    margin: -90px 0 0 -90px;
    border-radius: 100%;
    box-shadow: inset 0 2px 2px rgba(255, 255, 255, .4), 0 3px 13px rgba(0, 0, 0, .85);
    background: #f2f6f5;
    background: -moz-linear-gradient(top, #f2f6f5 0%, #cbd5d6 100%);
    background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #f2f6f5), color-stop(100%, #cbd5d6));
    background: -webkit-linear-gradient(top, #f2f6f5 0%, #cbd5d6 100%);
    background: -o-linear-gradient(top, #f2f6f5 0%, #cbd5d6 100%);
}
.denem {
    width: 160px;
    height: 160px;
    margin: -80px 0 0 -80px;
    border-radius: 100%;
    background: #cbd5d6;
    background: -moz-linear-gradient(top, #cbd5d6 0%, #f2f6f5 100%);
    background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #cbd5d6), color-stop(100%, #f2f6f5));
    background: -webkit-linear-gradient(top, #cbd5d6 0%, #f2f6f5 100%);
}

.deneme {
    padding: 35px 10px 0 0px;
    width: 120px;
    height: 137px;
    display: inline-block;
    margin: -60px 0 0 -60px;
    color: #555;
    text-shadow: 1px 1px 1px white;
    font-family: 'Dosis';
    font-size: 40px;
    font-weight: 400;
    text-align: center;
}
.deneme span { position: absolute; left: 1px; top: 27px; font-size: 58px; font-weight: 200; }
.deneme strong { position: absolute; right: 10px; top: 15px; font-size: 28px; }
.setpoint { position: absolute; right: 10px; top: 15px; font-size: 28px; }
.setpoint1 {
  position: fixed; /* or absolute */
  top: 50%;
  left: 50%;
  /* bring your own prefixes */
  transform: translate(-50%, -50%);
}

Its as simple as that.

If you have followed my other videos you will already know how to get your switches working using the Tellstick but please refer to my other blog post on how to get set up.

As always any comments is appreciated and feel free to share.



Friday 10 April 2015

28 DIY Night Vision videos

I had not realised just how many DIY Night Vision videos I had built up over the past couple of years. It seems that I have currently 28, more to follow. All dedicated to how to build your own night vision kits for your scopes.

For those who actually read this blog I won't be stopping the videos any time soon and will no doubt recover them all in the future as to offer suggestions of refinements.

Feel free to watch them all and subscribe to the channel.

Title: DIY Night Vision - How to build Night Vision Scope
Description: Walk through of the basic building blocks of a Night Vision build

Title: DIY Night Vision - Tools to buy
Description: What tools to initially buy.

Title: DIY Night Vision - Board Camera Mounting
Description: If you choose a board camera, e.g not in metal case. This is the video to watch on how to mount it.

Title: DIY Night Vision - Camera mounting Example 1
Description: Example of mounting your camera to fit your scope

Title: DIY Night Vision - Camera mounting example 2
Description: 

Title: DIY Night Vision - Wiring without solder
Description: Soldering the wires is not necessary. You can do it a different way.

Title: DIY Night Vision - Screen Mount
Description: How to mount your screen to the project box

Title: DIY Night Vision - Screen mounting holes
Description: Simple way to attach your screen to your scope if it is 25mm in diameter

Title: DIY Night Vision - Screen weaver rail mount
Description: Mount your screen robustly with a weaver rail scope adapter

Title: DIY Night Vision - Fitting a battery holder
Description: Fitting instructions how to put a battery pack inside your project box.

Title: DIY Night Vision - On board battery pack
Description: Explaination video of where an internal battery pack can sit.

Title: DIY Night Vision - Wiring Camera and Screen Part 1
Description: How to initally wire your camera and screen

Title: DIY Night Vision - Wiring camera and screen part 2
Description: How to initally wire your camera and screen erm… part two.

Title: DIY Night Vision - Focusing the crosshair
Description: How to quickly focus your cross hair by adjusting your 16mm lens.

Title: DIY Night Vision - 12mm vs 16mm Lens
Description: Difference images given from a 12mm lens versus 16mm lens. Personally 16mm lens all the way.

Title: DIY Night Vision - Modifying scope fitment
Description: Tips how to mount your night vision kit for varying scope sizes.

Title: DIY Night Vision - Fitting to scope
Description: Simple video to show how you fit the Night Vision kit to your scope.

Title: DIY Night Vision - Scope with 45mm eye bell
Description: How to fit your night vision if your eyebell is about 45mm.

Title: DIY Night Vision - World Record Build 50 Seconds
Description: A random attempt to set a world record for the fastest Night Vision build.

Title: DIY Night Vision - Duel camera spotter and scope
Description: Exploring the possibility of duel scope/spotter setup

Title: DIY Night Vision - Scope/Spotter prototype
Description: Initial Scope/Spotter prototype

Title: DIY Night Vision - Screen Red or Green filter
Description: Shows the effects of a green filter and red filter on your screen to reduce glare.

Title: DIY Night Vision - Night time footage
Description: Some phone footage of the night vision in action.

Title: DIY Night Vision - Infrared illumination
Description: Types of illumination methords.

Title: DIY Night Vision
Description: My first, very poor attempt, at building night vision - DO NOT FOLLOW THIS EXAMPLE!

Title: DIY Night Vision version 2
Description: My second attempt at night vision in one combined unit.

Title: DIY Night Vision - Raspberry Pi IR Camera
Description: Discussion of the Raspberry Pi camera as an alternative.

Title: DIY Night Vision - Simple Wiring of Angel Eye
Description: How to simply wire the Angel Eye to your camera/screen. 

Sunday 4 January 2015

DIY Night Vision - Full parts list

Well it seems that my DIY Night Vision series of videos are becoming popular but there has always been a missing link...... all the definitive parts list. The small problem with this is, after all my toying around, there has not really been a full off the shelf due to the many combinations that are out there. However I am hoping that this post becomes useful.

So here goes:

3.5 tft screen
Plastic box for screen mounting and battery housing (optional if not opting for external battery source)
Plastic box for camera mount (this is option depending on camera type used)
40mm end cap (this is option depending on camera type used)
2.1mm DC jack (optional if opting for external battery source)
Rocker switch (optional if not opting for external battery source)
40mm straight coupling (suits 42-42mm eyebell)
38-45mm Flexi waste straight coupler (suits 45mm eyebell)
IR Torch mount 25mm to 25mm or 25mm to 30mm depending on your scope tube diameter
Weaver rail 25mm scope mount
IR Camera - several variants can be used depending on preference and your design.
2.1mm female to male DC Y Splitter (optional if opting for external battery source)
18650 battery holder
3 X 1850 batteries

Will update the other links shortly....