Difference between revisions of "Projects in process"

From Wiki2
Line 1: Line 1:


==[[water control project]]==
==[[water control project]]==
 
{{:water control project}}
==[[online heating system control project]]==
==[[online heating system control project]]==
{{:online heating system control project}}

Revision as of 14:20, 31 May 2013

water control project

little app to communicate between browser/app and microcontroller to run a small waterfall

We have two little ponds in the yard fed by the rainwater from the roof. They are at the base of a big outcropping of roxbury pudding stone. Water is pumped from the lower pond to the upper pond and from the upper pond up the side of the ledge.

There is an app, "cascada" that starts the pumps and energizes the circuits to turn on the waterfall and control the level of the lower pond.

If it hasn't rained in a while, over time water evaporates and leaks out. The level of the pond is controlled using a $10 lawn sprinkler valve to inject water into the pond when the falls below a certain level. Water gets added while the pumps are on until it reaches the max level then it goes off. If you turn on the pumps again it doesn't continue filling but waits to inject water til the water falls to the low water sensor.

The water level control is independent of the pond timer, is located in its own circuit box on the porch and is activated whenever the waterfall is on.

The other circuit is connected to the house ethernet and contains a server, relays and timers to turn the system on and off. Its microcontroller is connected to an Enc28j60 chip that implements a server capable of delivering GET string variables to the microcontroller.

The app is written in HTML5/javascript, resides on http://cascada.sitebuilt.net and uses $.get to send a string to a php script on the that server which transfers it by curl to the external Enc28j60 server located in the house. It does this via a http://www.noip.com/ since the home network's IP can change. It tells the controller which circuit it wants on and for how long. more info casc {"user":"tim","token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJuYW1lIjoidGltIn0.LmoK1Nr8uA4hrGr25L2AlKXs6U832Z_lE6JGznHJfFs"}
back to electronics projects in process

Your apikey for stuff2get is: Ricuhiqozarulerofekuqepa

controlling the water level

water-control_circuit.JPG

comparators - LM324N quad op amp
flip flop - 74HC74AP dual D flip flop pin-out

The water level sensors are just thermostat wire. When immersed the resistance decreases to about 50K. Each sensor goes to a comparator. Comparators work in this setup by outputing LO if the minus input is a lower voltage than the +input and HI if the + input is higher.

For the bottom sensor, the -input was hard wired with an even voltage divider that gave it 1/2 VCC. The +input had an uneven divider of 47K to VCC and 57K to GND when the sensor was out of water. More of the voltage dropped across the 57K than the 47K so the +input was higher than the -input and the output was HI. Submerging the sensor put approx 50K in parallel with the 57K so then the equiv resistance wasless than 47K so the -input is at a higher voltage and wins. The hi water sensor had a similar comparison.

The low level comparator goes HI when out of water and the high water sensor goes HI when immersed. The output of the low level comparator goes to the D input and the output of the high level comparator drives the clock. When the D flip flop output Q is HI the pump goes on.


D-flipflop74HC74AP_truth.PNG

how the flip flop works

The flip flop was setup with pre set to HI. Then, whenever a clock pulse goes HI, whatever is on the D input gets transferred to 'memory' and shows up on the Q output, EXCEPT, if pre goes LO, it forces Q HI no matter what.

water-control_TRUTH.JPG

how this circuit works

loop

set is always HI
The bottom sensor comparator(out1) is wired to the D and through a NOT gate to reset. out1 is HI when dry and reset is LO forcing !Q HI which only happens when the water level is below the low sensor. The HI turns the pump on.
rising water
Once the water reaches the lower sensor and forces it LO that LO on D just hangs there waiting to be transferred by a rising clock pulse. That doesn't happen until the water rises sufficiently so the high sensor is immersed. Then it sends a rising pulse to the clock which puts what's on the D input on the Q output. In this case that is a LO. So the output goes LO and the pump goes off.
falling water
When the water falls below the high limit it goes LO, sending a falling pulse into clk which doesn't change Q. So the pump stays off until it falls past the lower sensor. LOOP

loop


revision

After using for awhile I decide to change the function a bit.

As designed, when the switch was thrown to run the circulation pumps if the state of things was between high and low water then D saw a LO & pre saw HI, and Clk saw a LO. When you flipped the switch that state caused the pump to come on, ie be HI. I decided I didn't like that, I'd be filling the pond when I didn't really need to and end up wasting water.

So I had to change what happened on power up. If I could force a rising pulse on the clock I could drive it HI and since the lower sensor was LO it would transfer that LO from D to Q and keep the water relay off. Putting a capacitor between ground and the -input of the upper sensor comparator drove that pin to ground when the power came on (as the capacitor momentarily looked like a short) which sent a rising pulse to the CLK which transferred the LO on D to Q turning off the pump. When the capacitor charged then the -input went back to winning the comparison and sent the CLK LO which as we know has no effect on the Q output.

the app

Normally, the server serves up the webpages by loading the html and javascript to the client browser/app and responding to user input sent up from the client browser/app. A server running on a microcontroller can do that for very small and simple apps. Even loading images and script resources from somewhere else, microcontroller servers could quickly run out of memory and choke.

system design with microcontrollers

version2 -pi

gpio
     import RPi.GPIO as GPIO
     GPIO.setmode(GPIO.BCM)
     GPIO.setup(int(pin), GPIO.OUT)
     GPIO.output(int(pin), 1)

pi can't drive a relay like the arduino can so it needs this

NPN Relay Switch Circuit

A typical relay switch circuit has the coil driven by a NPN transistor switch, TR1 as shown depending on the input voltage level. When the Base voltage of the transistor is zero (or negative), the transistor is cut-off and acts as an open switch. In this condition no Collector current flows and the relay coil is de-energised because being current devices, if no current flows into the Base, then no current will flow through the relay coil.

If a large enough positive current is now driven into the Base to saturate the NPN transistor, the current flowing from Base to Emitter (B to E) controls the larger relay coil current flowing through the transistor from the Collector to Emitter.

For most bipolar switching transistors, the amount of relay coil current flowing into the Collector would be somewhere between 50 to 800 times that of the required Base current to drive the transistor into saturation. The current gain, or beta value ( β ) of the general purpose BC109 shown is typically about 290 at 2mA (Datasheet).

NPN Relay Switch Circuit

switch1.gif


Note that the relay coil is not only an electromagnet but it is also an inductor. When power is applied to the coil due to the switching action of the transistor, a maximum current will flow as a result of the DC resistance of the coil as defined by Ohms Law, (I = V/R). Some of this electrical energy is stored within the relay coil’s magnetic field.

When the transistor switches “OFF”, the current flowing through the relay coil decreases and the magnetic field collapses. However the stored energy within the magnetic field has to go some where and a reverse voltage is developed across the coil as it tries to maintain the current in the relay coil. This action produces a high voltage spike across the relays coil that can damage the switching NPN transistor if allowed to build up.

So in order to prevent damage to the semiconductor transistor, a “flywheel diode”, also known as a freewheeling diode, is connected across the relay coil. This flywheel diode clamps the reverse voltage across the coil to about 0.7V dissipating the stored energy and protecting the switching transistor. Flywheel diodes are only applicable when the supply is a polarized DC voltage. An AC coil requires a different protection method, and for this an RC snubber circuit is used.

version1 -arduino

microSERVER <- CURLonLAMPserver <-> CLIENTbrowser/app

Creating and interacting with the user interface happens from a regular LAMPserver which communicates with the microSERVER with some simple string (GET or JSON). But since the microSERVER is on a home network that likely has a dynamic IP that might change anytime then you need to go through http://www.noip.com/

microSERVER <- no-ip.com <- CURLonLAMPserver <-> CLIENTbrowser/app

This application needs to switch on the chosen waterfall for a user-determined amount of time. The relays and the timers reside on the microSERVER. ?status=ON&relay=0&til=1 would turn ON relay 0 for 1 minute. Relay 0 is the waterfall.

The server can also run and time two other relays. They are connected to other water valves in the yard. If you wanted to programmatically control a system to water your garden, for instance you could use the same microSERVER unchanged. The application would do all the calculations on which days and times the sprinklers should come on and just send a string to the microserver at the appropriate intervals.

the microcontroller code

The microcontroller endlessly loops. Each time it checks whether new packets have arrived and whether timers have expired. If they have, their relays are turned off. <syntaxhighlight lang='cpp'> void loop() {

 word len = ether.packetReceive();
 word pos = ether.packetLoop(len);
if (millis() > timer[0]) {
  digitalWrite(repin[0], reoff[0]);
} 
 if (millis() > timer[1]) {
  digitalWrite(repin[1], reoff[1]);
} 
 if (millis() > timer[2]) {
  digitalWrite(repin[2], reoff[2]);
} 

</syntaxhighlight>

If a packet has arrived then the get string is read using the ether.findKeyVal() function of ethercard library. First it reads which 'relay' is to be controlled and then if it is to be turned ON then ether.findKeyVal() grabs the 'til' value. <syntaxhighlight lang="cpp">

 if(pos) {
   char* data = (char *) Ethernet::buffer + pos;
   Serial.println(data); 
   ether.findKeyVal(data + 6, rel , sizeof rel , "relay");
   byte rela = atoi(rel);   
   Serial.println(rel); 
   if(strstr(data, "GET /?status=ON") != 0) {
     ether.findKeyVal(data + 6, til , sizeof til , "til");

</syntaxhighlight>

code on LAMP server

Nothing much to this. The get string produced by the app and sent by jQuery is forwarded to the microcontroller by CURL via no-ip.com. <syntaxhighlight lang="javascript"> from casc.js:

  $.get("../../services/curl.php", { status: state, relay: "0",til: til } );

from curl.php:

  $data = $_SERVER['QUERY_STRING'];
  //http://cascada.sitebuilt.net/services/curl.php?status=ON&relay=0&til=1                           
  $ch = curl_init('sitebuilt.no-ip.biz/?'.$data);                              
  curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "GET");  

</syntaxhighlight>

development log

cascada 2.0

but actually the board has errors, my mind has errors

The bottom sensor comparator(out1) is wired to the D and through a NOT gate to set. out1 is HI when dry and set is LO forcing !Q HI which only happens when the water level is below the low sensor. The HI turns the pump on.

if reset is always HI (proposed pcb hack)

when completely dry, out1 HI D2 ON

set would be LO D would be HI(doesn't matter) CLK would be LO, !Q wouldand pump would be ON

once low sensor is covered out1 LO D2 OFF, (pump should stay ON)

set would be HI, rest HI, D would be LO, CLK would be LO, no change !Q stays LO so ON (now reset is actually LO oops)

once water reaches upper sensor ^ D3 ON

set would be HI, reset HI, CLK ^ so D LO would be Q so !Q would be HI and pum would go OFF

once water falls below upper sensor | D3 OFF

set would be HI, reset HI, CLK | so D LO(doesn't matter) no change !Q stays HI so OFF

once water falls below lower sensor out1 HI

set would be LO, reset HI, D would be HI(doesn't matter) CLK would be LO, !Q would and pump would be ON

What happens when power comes on with the pond partly filled??? (pump off would be good)

once low sensor is covered out1 LO D2 OFF, upper sensor uncovered out7 LO, Clk LO

set would be HI, rest HI, D would be LO, CLK would be LO, no change from ???

you would like Q to be LO (!Q HI, pump OFF)

since D would be LO, if LO could be forced on Q, !Q would be hi and the pump would stay off. That could happen if we could get clock to issue a rising pulse.

The only time clock issues a rising pulse is when j2 shorts or its resistance is lower than 5.1M. or when the voltage on pin 5 is greater than the voltage on 6. How can you make that happen for a minute?? charge a capacitor somewhere, maybe inline with some resistor. which one??

you could short out r8 5.1M Once the cap is charged it would look open and back to just the 5.1. But at first it would(oops no current path to ground)

with no current flowing through the 5.1, the voltage on pin6- should be 5v (it is 3.6 vs 2.5 on pin5-) so - wins . + could win if the upper r6 was temporarily shorted

redesign ideas

circuit, pcboard, microcontroller program, server and client understanding-24vac-sprinkler-valves

Redesign to eliminate powering normally closed valves for garden watering. So only one valve near porch for pond, another in center of garden, maybe another facing out from the porch or in kitchen garden. Each will need 24vac to power the valve and 5vdc to p0wer the relay and microcontroller. In the same cable?

If you start with four insulated wires, the + and- for one signal and the + and - for another signal, and run them parallel to each other in that order and as close as possible (so insulation touching) , then youi have a ribbon cable and a signal on any of them couples inductively and capacitively to all of the others. If you then twist the two signal pairs together you have very littel effect on the capacitive properties between the wires in a pair since theystay pretty much the same distance from each other. You will reduce the capacitance between wires in different pairs, but probably not by more than a factor of two or so. However, you greatly reduce the inductive coupling, particularly if the twist pitch is different between the two pairs, because whatever is induced by one loop of the twist is largely cancelled out by another. https://forum.allaboutcircuits.com/threads/why-does-twisting-two-wires-create-capacitance.83777/

To reduce power in transformer, power it on whenever (or right before) any microcontroller wants to be on. How? Maybe use the pond microcontroller to act on mqtt commands to activate the (120v side of the )24v relay when any of the devices is calling. Then, an additional relay will be needed to activate the pond (on the 24 side)

tests

op amp tests

  1. connect power to opamp
  2. ground the inputs output should be zero
  3. + to 5v, output should be 5
  4. - to 5v, output should be 0
  5. jumper 1 shorted -> D1 led should go out (brings pin 3+ to zero so 2- wins(out1 goes lo))
  6. jumper 2 shorted -> D3 led should come on (bring pin 6- to ground so pin 5+ wins(out7 goes hi))

not gate test

  1. jumper 1 open, out1 hi -> not gate 2,3in hi 1out low and visa versa

D flip flop tests

  • 4 - set = !out1
  • 2 - data = out1
  • 3 - clock = out7
  • 1 - reset =
  • 5 - Q1
  • 6 - !Q1


D flip flop truth table

set clk data out
L x x H
H x x L


suggested tests

  1. check the 8 input nor gate to see if having th signal on A(2) and all the other 7 grounded give a not signal on X(13) with vcc(14) and ground(7)
  2. test an op amp and its voltage dividers on the bottom and top pond sensors to see if the output is right
  3. test relays
  4. test a transistor circuit to see if the collector is hi when its conducting (seems not)

refs

voltage drop

So power will run to the location of sprinkler in 18 gauge thermostat cable, voltage drop for 24vac at 1.8 amp for 100 ft is 2.3v volts 10% is OK.

for a 5 volt in that same wire drawin .3A over 100 ft, the voltage drop is .38V (7.6%


cascada 0.2 - http://10.0.1.186/?status=ON&relay=0&til=60 pond

next:

alanesq.com uses findKeyVal <syntaxhighlight lang="cpp">

 if(pos) {
   char* data = (char *) Ethernet::buffer + pos;
 Serial.println(data);    
 if(strstr(data, "GET /?status=ON") != 0) {
   ether.findKeyVal(data + 6, til , sizeof til , "til");
   Serial.print("Will stay on for ");
   Serial.print(til);
   Serial.println( " minutes.\n");
   int until = atoi(til);
   //Serial.println(until);    
   timer = millis() + until*60000;

... </syntaxhighlight>

cascada 0.1 - Enc28j60, timer

  • simple timer
    • setup
    • loop
      turn of ligth after 5 seconds

<syntaxhighlight lang="cpp"> ...

 pinMode(RELAY_PIN, OUTPUT);
 digitalWrite(RELAY_PIN, HIGH);  
 timer = millis() + 5000;

} void loop() {

   if (millis() > timer) {
     digitalWrite(RELAY_PIN, false);
   } 		

} </syntaxhighlight>

cascada 0

Click the button pump goes on in pond.

  • send '1' to arduino, to tun on relay
  • send '0' to arduino to turn off device

Arduino-Ethernet-Shield-Tutorial

version 1

todo

Pick up my phone, go to a web site, have there be a series of buttons on, off, 10, 20, 30, 60.

The idea was to automatically control the level of the pond by using a (cheap) lawn sprinkler relay to inject water into the pond when it falls below a critical level. Water gets added while the pumps are on until it reaches the max level then it goes off. If you turn on the pumps again it doesn't continue filling but waits to inject water til the water falls to the low water sensor.

The buttons could be from a client side jquery-mobile page. Timing would seem suited to the server. Server would send an on message and start a timer. After the time elapsed it would send an off message. Client would poll server to see what the status is and the time remaining.

Basic control is working in an outdoor circuit box mounted on the bridge next to the lawn sprinkler relay.

online heating system control project

back to electronics

the pitch

Hi, I used run a company that built houses. I have prototyped a device that replaces all the thermostats in your house with temperature sensors. Data from those sensors streams to the cloud every 20 seconds. Your interface to your heating and cooling system is any device, smartphone, tablet of laptop. You can use the data collected to monitor your energy use and to optimize system performance or to help you decide on a system upgrade. A multiple-zone HVAC system can be controlled and monitored for less than the cost of one nest thermostat.

I plan on producing small run of hand assembled devices by the fall and I want to get them into the homes of people who could help get this product to market. My name is Tim Mckenna. The company is Site-Built Systems.

description

The most advanced and easy to use user interface these days is probably the one contained in your smartphone or tablet. Apps are easy to use, interactive and readily update-able. The interface on your programmable thermostat probably wouldn't be high on that list. And if you have more than one heating zone then the difficulty is multiplied.

Replace those thermostats with temperature sensors and control the whole house from one interface. Slip a microcontroller device between the thermostat connections and the heating/cooling system. Connect it to the home network and you are ready to go. From 1 zone to 8 zones, it will monitor and control them all.

Start collecting data on your energy use. Which zone calls for heat the most? Which takes longest to heat up? How much would it cost to be a little warmer? How much is setting back the thermostat saving me in my house? Optimize your hydronic system by running the boiler at a lower temperature on a warmer day.

Overriding any zones program is easy and can be done remotely from any connected device, phone tablet or browser.

An Avr microcontroller takes in temperature readings from multiple locations. At the control room the AVR hub polls temperature and for each zone knows the set temperature, the default temperature and whether or not a zone is ON and how long it has been on. If it doesn't hear from the (linux) scheduler then it falls back to act as a multi-zone thermostat set at the default temperatures.

The scheduler would take temperature data from the AVR client and would know the schedule. Whenever a schedule change point would come up, it would notify the AVR and instruct it to change the set point.

The controller would on the client probably an HTML5/javascript client. Here you can read the temperatures and view the schedule. You can override or change the schedule.

online heating system control project

table

documentation

Small articles

  • communication with arduino through the get string
  • offloading computation to server and javascript

Do I have the fire in the belly to create a product out of this?

hvac.sitebuilt.net

Control all your hvac zones online.

  1. replace thermostats with temperature sensors
  2. install system microcontroller
  3. connect to internet

Control all your hvac zones online

replace thermostats with temperature sensors

install system microcontroller

connect to internet

troubleshooting

sql

curl

development log

12/18/13

  • re holds:
    hold on master puts hold on tv_display & hold on tv puts hold on master_display and shuts off
    hold on TVroom for 67 when is 64 puts system on in TVroom but displays 67ON at Master
    hold on TVroom for 62 when is 64 puts system on in TVroom since Master reads 60 which is over 62
    hold on TVroom for 59 when is 64 puts system OFF in TVroom since Master reads 60 which is over 59

conclusion for holds: TVroom reads temp of Master, displays setting/state in Master, state is controlled by temp of Master.

  • hold on Master for 67 when Master reads 60 and TV reads 64 -> puts 67On inTV and turns on zoneMaster
    hold on Master for 63 when Master reads 60 and TV reads 64 -> puts 63Off inTV and turns off zoneMaster

conclusion for holds: for TV and Master

  • upper right display is switched
  • temp of one controls state of other


http://homecontrol.sitebuilt.net jquery-mobile app

deployment - sensors for 7 zones live

One wire sensors are known to be weird when connected in a star network of varying lengths < 100ft. See...

on one wire problems
guidelines for relaiable 1 wire networks

In general if they can be found on search then they will work for reporting temperatures. So I unplugged sensors until I got a configuration that worked then put the rest in a second OneWire network ds1(26). and then modified the code to read the first network then the second. You can tell how a particular configuration does by running setup. Screwing the wires in sucks. Plugging them in is good.

TODO:

  • get rid of swipe right/swipe left
  • fix sort ordering
  • refresh on home
  • fix so not always LR
  • fix save program so it looks like something happenede (get rid of checks)

beta 0.1 - cleaned up colors, some testing on multiple devices

TODO: back to electronics. Build working relays. on relaysS

version I:

on callback functions from things like $.get(... this.something doesn't refer back to the object method but must be explicitly referred to by like sys.somethhing

version H: titeObj -time temp array: display, sort, clear, edit

TODO:create a datObj. Arrays/objects push/slice/delete

All the functions and data are encapsulated. A coulple of 'this' problems were solved by replacing this. with titeObj.

My kind of oops: http://www.javascriptkit.com/javatutors/oopjs.shtml

version G: tempA -time temp array: display, sort, clear, edit

(TODO: flesh out the program data structure) OK now I know at least about the tempA array

   0: Object
   temp: "69"
   time: "00:45"
   __proto__: Object
   1: Object
   temp: "69"
   time: "09:45"
   __proto__: Object
   2: Object
   temp: "69"
   time: "12:45"
   __proto__: Object

andthere a boatload of functions to manipulate it and its display. Strong candidate for an Object with member functions.

Moved away from using JQuery and delved further into CSS3 for creating buttons and widgets. Everything works better.

Javascript
nth children

<syntaxhighlight>

   $(".prog-tes li").click(function() {
       time=$(':nth-child(2)', $(this)).html();
       temp=($(':nth-child(3)', $(this)).html()).substring(0,2);
       alert(temp+"clicked it "+time);
   });	

</syntaxhighlight>

javascript array.push(newval);
$(this)[0];//same as getElementById
dataset data-mydata
 ddd=$(this)[0];//same as getElementById
 dow = ddd.dataset.dow;
$(document).on('pageshow', '#aroom', function (e) {

Use when you have programmatically changed page and now need to do somethin on that page

scroll to anchor

<syntaxhighlight>

   if(anc.length>0){
       $('html, body').animate({
           scrollTop: $(anc).offset().top-95
       }, 1000);  
       anc=""; 	
   }

</syntaxhighlight>

CSS

If styling isn't getting picked up specify the hell out of the selector. - .prog-day div.day2 li, .prog-time div.prog-time-box li{

version F: CSS3 and media queries

col1, col2, col3 do wahht they should
just cloumn 1a is working in terms of element layout

version E: write schedule progs to database

PUT request to /prog/80302/ver/ multiple ckts and multiple days for those ckts
PUT request to /prog/80302/ver/99/5, multiple ckts for day 5
PUT request to /prog/80302/ver/4/, multiple days for ckt 4
PUT request to /prog/80302/ver/4/5, day4 for ckt 5

remembering the flow from the case:put case:feed arduino loop is

  • getTodayLTEnow()
  • ckHolds($db, $req); //(calls updateSetptArr())
  • $se = getSetptArr($db, $path);
  • echo $se; //sends it to arduino
  • zeroSetptArr($db, $path);

Work on, from app end, routines and interface for writing programs

The structure of prog data is {"feed":"80302","ckts":[[{"time":"9:30","setpt":"147"},null,null,null,null,null,{"time":"9:30","setpt":"147"}],null,null,null,null,null,null,null,null,null,null,[{"time":"9:30","setpt":"147"},null,null,null,null,null,{"time":"9:30","setpt":"147"}]]} and it is roughed out in comments at bottom of ha.js


version-D prog data and hold data

ACTUALLY: didn't touch getTodayLTEnow()

  • added a RewriteRule boho /var/www/hsc/index.php?id=$1 in defauls sites
  • worked on hold.php driven from .button-boost and .button.setpt (data structures are the same {"feed":"80302","ckt":4,"start":1363707975,"finish":1363688100,"setpt":167})
  • worked on release as DELETErequest inhad deleteHold.php wcase:delete:case:boho callinging existing method in index.php called delHold()

PLANNED: Will be combining dialog for boost and hold. Working to have /feed do the following extra tasks

   getTodayLTEnow(); //(calls updateSetptArr())
   ckHolds($db, $req); //(calls updateSetptArr())
   $se = getSetptArr($db, $path);
   echo $se; //sends it to arduino
   zeroSetptArr($db, $path);	

Have been using the dialog pages as test pages for moving prog data and hold data through system.

post of new program data (was getting tested boost-yes button )

<syntaxhighlight> //{"feed":"80302","ckts":[[{"time":"9:30","setpt":"147"},null,null,null,null,null,{"time":"9:30","setpt":"147"}],null,null,null,null,null,null,null,null,null,null,[{"time":"9:30","setpt":"147"},null,null,null,null,null,{"time":"9:30","setpt":"147"}]]}

   schedJ =JSON.stringify(sched);
   console.log(schedJ);
   console.log(ckt.length);
   console.log(sched.ckts[11]==null);
   console.log(sched.ckts[11][7]==null);
   $.post("../services/newProg.php", {data: schedJ}).done(function(data){
           alert("Data Loaded: " + data);

</syntaxhighlight>

this data tracks through newProg.php and then to http://198.23.156.78/hsc/prog/80302 as a a JSON post string
post of new hold/boost entry (was getting tested in hold-yes button)

<syntaxhighlight>

   $(".hold-yes").click(function() {	
       console.log("clicked hold-yes");		
       holdS='{"feed":"80302","ckt":99,"start":1363707975,"finish":1364000000,"setpt":140}';
       holdArr = JSON.parse(holdS);
       holdStr =JSON.stringify(holdArr);
       console.log(holdArr);
       $.post("../services/hold.php", {data: holdStr}).done(function(data){
           alert("Data Loaded: " + data);
       });
       return false;
   });		

</syntaxhighlight>

header-menu

If you want menus in your header use this code, just don't let any class in the data-role="page"

mess with your formatting

<syntaxhighlight>

<a href="#popupMenu" data-rel="popup" data-role="button" data-inline="true">Menu</a> <a href="#popupNested" data-rel="popup" data-role="button" data-inline="true">Nested menu</a>

Dog

  • Popup API
  • <a href="options.html">Options</a>
  • <a href="methods.html">Methods</a>
  • <a href="events.html">Events</a>

Farm animals

  • <a href="../dialog.html" data-rel="dialog">Chicken</a>
  • <a href="../dialog.html" data-rel="dialog">Cow</a>
  • <a href="../dialog.html" data-rel="dialog">Duck</a>
  • <a href="../dialog.html" data-rel="dialog">Sheep</a>

Pets

  • <a href="../dialog.html" data-rel="dialog">Cat</a>
  • <a href="../dialog.html" data-rel="dialog">Dog</a>
  • <a href="../dialog.html" data-rel="dialog">Iguana</a>
  • <a href="../dialog.html" data-rel="dialog">Mouse</a>

Ocean Creatures

  • <a href="../dialog.html" data-rel="dialog">Fish</a>
  • <a href="../dialog.html" data-rel="dialog">Octopus</a>
  • <a href="../dialog.html" data-rel="dialog">Shark</a>
  • <a href="../dialog.html" data-rel="dialog">Starfish</a>

Wild Animals

  • <a href="../dialog.html" data-rel="dialog">Lion</a>
  • <a href="../dialog.html" data-rel="dialog">Monkey</a>
  • <a href="../dialog.html" data-rel="dialog">Tiger</a>
  • <a href="../dialog.html" data-rel="dialog">Zebra</a>

</syntaxhighlight>

system versions -arduino+server code

version C - /hsc/index.php /services/putSetptArr.php

Cron calls have to build the data into the URL so they will look like:

http://homecontrol.sitebuilt.net/services/putSetpt.php?feed=80302&type=prog&sensor=6&setpt=167

Not a PUT but in Curl it gets converted for the rest api as a PUT with data encoded

$bdata=json_encode($data);   
curl_setopt($ch, CURLOPT_POSTFIELDS,$bdata);
http://198.23.156.78/hsc/prog/80302/4
$req = RestUtils::processRequest()- index.php starts with this. The request object has...
$path =$req->getPathArr()- path[0]=hsc(the db name), path[1]=80303=2(the feed id), path[3]=sensor#
$data=$req->getData() - rest.api finds the data depending on PUT GET POST etc setpt=167

Index.php looks at PUT||GET||POST, feed||prog, and sensor||noSensor to determine what to do.

updateSetptArr($db, $path, $data); - appends to setPtArr one value

when PUT/feed/ fires it first grabs any new setpts from the db, then echo's it back to the Arduino and then zero's it out.

$se = getSetptArr($db, $path);
echo $se;
zeroSetptArr($db, $path);

getHttpHeaders() holds hidden stuff like apikey and that stuff gets set here:

curl_setopt($ch, CURLOPT_HTTPHEADER, array( 
  "Accept: json",
  "HTTP/1.1 Host: api.cosm.com",
  "X-ApiKey:  xxxxxxjxjndjjxn",
  "User-Agent: sitebuilt Arduino Example (83080)" ));  
       
version C - hsc-run: C code - no more String class, everything indexed on MAXCKTS, new setpts in (simple)<JSONarray>
setup() starts the serial monitor and ethernet then reads from memory an array of sensor id's (char lu[MAXCKTS][9]), the numckts and an array of setpts[MAXCKTS] where 12 is MAXCKTS. It then assigns an array of pins as outputs (to relays not yet arrived from China)
The main loop() begins zipping along taking in a character of incoming data on each loop and printing it to the serial monitor while grabbing characters if they come between < and > and storing them in a character array cdata[]
updateSetpts() then kicks in, first reading current setpt[] data from memory, and, as long as some data has come (strlen(cdata)-2>4) it loads up ps[] from cdata[] with everything inside <[]>. This incoming dat must be in the form <[0,0,0,0,0,0,0,0,0,167,0,0]> with MAXCKTS entries.
strtok then breaks up that ps[] character array on the ',' and puts each setpt in an array of char arrays *strings[pslen] which gets indexed for each of the MAXCKTS setpt values coming in. Each is then atoi'd into an integer newVal which is compared with curVal and if(curVal != newVal && newVal > 0){ //not equal to each other and newVal isn't 0, then the newVal is written to memory and replaces the curVal.
   cdata[0]='\0';
   getSensorIds();
   readTemps();
   orderTemps();    
   setRelays(); 
   assembleData();
   sendData(); 
   lastConnectionTime = millis();  

Next: only record to db if temp changes

in c://Users/tim/Documents/tech/electronics/Arduino/hsc_run.ino
in c://Users/tim/Documents/tech/electronics/Arduino/hsc_setup.ino
in c://Users/tim/Documents/tech/electronics/Arduino/hsc_readSetup.ino
version B - no more String class, missing readings retain order
version A - mega as server sending to ReSt API and client receiving new setpts

in c://Users/tim/Documents/tech/electronics/Arduino/thermoc.ino

bits and pieces

version 6

Moving things to 10.0.1.101 but first set up api framework there
Added rewrite rules in /etc/apache2/sites-available/default by following beginner link <syntaxhighlight> <Directory /var/www/hsc>

   RewriteEngine On
   RewriteRule feed/([0-9]+) /var/www/hsc/index.php?id=$1
   RewriteRule feeds /var/www/hsc/index.php
   RewriteRule datastreams /var/www/hsc/index.php?id=$1	
   RewriteRule prog /var/www/hsc/index.php?id=$1		
   RewriteRule progs /var/www/hsc/index.php?id=$1		

</Directory> </syntaxhighlight> Test code to parse url <syntaxhighlight> <?php echo("hi dog
"); print_r($_SERVER['REQUEST_URI']); echo "
"; $urlarr = (parse_url($_SERVER['REQUEST_URI'])); echo "
"; print_r($_GET); echo "
"; print_r($urlarr); echo "
"; $pathstr=($urlarr["path"]); echo $pathstr; echo "
"; print_r(explode("/", $pathstr)); ?> </syntaxhighlight>

version 3
php www-data program that creates a crontab and calls a C program that executes root commands to copy it into crontabs and install it
write a php file that PUTS some light on on the AVR
collect data from AVR and store it in mysql
view the saved data on a client using javascript

code working on arduino

versions now use both arduino and php code so new versions sill be listed under #system versions -arduino+server code
version 5
raw DS18B20 to server, convert and send back to serial monitor

Uploaded to Arduino is hsc_tempJSONphp.ino Raw data is sent by arduino to /var/www/feeds/getnoise.php which puts it in an object and then creates another object containing F converted sensor readings for data coming off ONEWIRE connected sensors. Then it sends that data back.

Trying to convert to float on the Arduino wasn't working. Why push it? I've got unlimited power on LAMP server.

version 4 - temp readings beyond serial monitor
version 4a - DS18B20 readings to JSON
version 4b - JSON from arduino to PHP server
a) separate out a function to provide a reading to send to cosm for pin 0(14) and 1(15)
1 one possibility - send to cosm. This is better than having a webclient like thermometer.ino. Get it to Cosm and then later set up an api like cosm
version 3 - onewire demo

Put sample code in function getTemp(). Subsequent calls of the function don't reset the device counter. this is good.

DS18B20wiring.PNG

On serial monitor running DS18x20_Temperature.ino ala the library here. Of note: How it polls each device: <syntaxhighlight>

 if ( !ds.search(addr)) {//this is where it loops to the next address
   Serial.println("No more addresses.");
   Serial.println();
   ds.reset_search();//if there are no more devices go back to start of list
   delay(250);
   return;
 }

</syntaxhighlight>

version 2
Online thermometer creating web page in which you call for the data by clicking a button. Uses design from Practical Arduino in /tim/Documents/electronics/arduino/thermometerthermometer.ino and it runs at http://10.0.1.79
version 1
Take random readings from analog pins start an etehrnet client that sends them out to http://cosm.com (mcktimo 6j) every ten seconds :comtest.ino

final narrative

An Avr takes in temperature readings from multiple locations. At the control room the AVR hub polls temperature and for each zone knows the set temperature, the default temperature and whether or not a zone is ON and how long it has been on. If it doesn't hear from the (linux) scheduler then it falls back to act as a multi-zone thermostat set at the default temperatures. Through a rudimentary display it would allow you to set temperatures for each zone.

The scheduler would take temperature data from the AVR client and would know the schedule. Whenever a schedule change point would come up, it would notify the AVR and instruct it to change the set point. It would do this via chrontab maybe.

The controller would on the client probably an HTML5/javascript client. Here you can read the temperatures and view the schedule. You can override or change the schedule.

possible routes

A cheap circuit like http://www.craig.copperleife.com/tech/thermo/ or more complicated http://www.rentron.com/project01.htm using http://datasheets.maximintegrated.com/en/ds/DS1620.pdf which can be overridden by server program that controls multiple thermostats.

ReST

Angular and PHP

Apache setup
Add rewrite rules

so a restful path /hsc/feeds/1234 (which doesn't really exist) sends you to the API which processes the request using the /feeds/12345 information from the path.

In /etc/apache2/sites-available/default add rules like <syntaxhighlight lang="html5"> <Directory /var/www/hsc> RewriteEngine On RewriteRule feed/([0-9]+) /var/www/hsc/index.php?id=$1 RewriteRule feeds /var/www/hsc/index.php RewriteRule datastreams /var/www/hsc/index.php?id=$1 RewriteRule prog /var/www/hsc/index.php?id=$1 RewriteRule progs /var/www/hsc/index.php?id=$1 </Directory> remember to restart apache /usr/sbin/apache2ctl restart </syntaxhighlight> The API processing code resides in /hsc in this case.

when to GET PUT POST
GET when you want some data
PUT when you've got data to put in the API
POST when you want to setup something new
DELETE duh

In the case of home_system_control (hsc):


  • GET request to /api/users – List all users
  • GET request to /api/users/1 – List info for user with ID of 1
  • POST request to /api/users – Create a new user
  • PUT request to /api/users/1 – Update user with ID of 1
  • DELETE request to /api/users/1 – Delete user with ID of 1
refs
cosm curl helper
http://api.cosm.com/v2/feeds/83080/datastreams/noise.csv?start=2013-01-11T19:30:00Z&end=2013-01-11T21:00:00Z&interval=0 doesn't work
http://cosm.github.com/cosm-js/tutorial/
accessing-incoming-put-data-from-php
create-a-rest-api-with-php
http://rest.elkstein.org/2008/02/using-rest-in-php.html
http://blog.garethj.com/2009/02/17/building-a-restful-web-application-with-php/
get for my feed
making-reliable-connections-with-arduino

Cron Jobs

Hudsonvalley#cron_and_backups
http://net.tutsplus.com/tutorials/php/managing-cron-jobs-with-php-2/
http://stackoverflow.com/questions/4421020/use-php-to-create-edit-and-delete-crontab-jobs

parts

on one wire problems

guidelines for relaiable 1 wire networks

DS1620 Digital Thermometer and Thermostat

In a thermostat circuit $2.20 for dip

DS18B20 Maxim 1-wire temperature sensors
DS18B20 datasheet$1.00 each for chip, $3.00 each for waterproof sensor
one-wire protocol
https://arduino-info.wikispaces.com/Brick-Temperature-DS18B20 multiple
OneWire tutorial another better library
color code for encased DS18B20 sensor red=vcc,black=gnd,yellow=data

DS18B20-pinout.jpg