OWFS, OWSERVER, OWHTTP, OWPYTHON, and a little 1wire pi

1Wire

I’ve been using 1wire devices forever. An equipment designer and engineer I hold in high regard introduced me back in grad school and I’ve never turned back. For the 95+% of my applications where the resolution, range and poll speed limitations of 1Wire devices are acceptable, their cost, ease of use, rugged stability, and bus flexibility make them a great choice for sensing and sensor networks.

I started off using 1Wire devices on Windows machines, specifically using LabVIEW and a good old DS9490R, a USB interface that comes with some built-in applications for device location and troubleshooting. Building in device manipulation and reads turned out to be a bit more complicated, and in fact we wrote a package for LabVIEW to deal with these issues and handle some of the more complicated logging devices such as the DS1923. But that’s besides the point of this post, so I digress.

OneWire networks and *nix : OWFS

When I decided I wanted my 1wire devices on my linux boxes for homebrewing, and on my Raspberry Pi for fun projects, I discovered per usual that someone had put together a nice little package. OneWire File System (OWFS) lets me access my 1wire devices as a virtual filesystem. In its simplest implementation, you can have it bind to your physical interface and create an abstraction that is a readable filesystem. So the command

 owfs -u /var/1wire

would happily bind your USB adapter (-u) to the directory /var/1wire. There are implementations for a number of the 1wire family interfaces, so for an i2c devices like the DS2483, you could issue:

 owfs  --i2c=/dev/i2c-1:ALL /var/1wire

and with a directory listing you’d see something like:

pi@cupid ~ $ sudo ls /var/1wire
28.9E4FA8040000  alarm  settings      statistics  system
28.B3CDA7040000  bus.0  simultaneous  structure   uncached

Each of the 28.* listings is a directory containing all of your device data. The interface autodetects, so when you attach devices, they pop up. Run a cat on any of the temperature files within a sensor directory and you get your temp read back to you. Better yet, each resolution option offered by, say, a DS18B20, is represented by a file:

pi@cupid ~ $ sudo ls /var/1wire/28.9E4FA8040000
address  errata    id       r_address  scratchpad     temperature11  temphigh
alias    family    locator  r_id       temperature    temperature12  templow
crc8     fasttemp  power    r_locator  temperature10  temperature9   type

Want 9-bit resolution?

 sudo cat /var/1wire/28.9E4FA8040000/temperature9
13

12-bit?

 sudo cat /var/1wire/28.9E4FA8040000/temperature12
12.8125

Anyhow, you get the point. Very neat implementation that results in data accessible by any sort of code you might write on top of it. But wait, there’s more!

OWserver, OWhttpd, and OWPython

I’ve been using owfs for quite a while, and it just works. I knew that there were additional features. I just didn’t need them. I knew you could set it up to serve your 1wire data, either locally or via a lightweight webserver. I was, however, content to just read and parse the stuff into my applications.

At some point, however, I discovered there was an owfs python library, aptly named owpython. Lo and behold, it was already built into my owfs installation (2.9p1 here). I was going to start using a more diverse set of 1Wire devices, and I really liked the idea of an object-oriented approach to discovery, aliasing, and databasing. Enough of this text-parsing stuff.

owfs, owhttpd, owpython, OR owserver can bind to the physical 1wire interface

After reading the owpython docs, I realized that could not (or at least should not) bind owpython to the 1Wire interface using the ow.init() call. The same was true of owhttpd. We needed an arbitrator. Enter owserver. Now, if this conclusion was obvious from the documentation, I truly apologize for my density, but this concept eluded me despite all the reading I’d done. Let me repeat this: owfs, owhttpd, owpython, OR owserver can bind to the physical 1wire interface. If you initialize with and bind to the interface using owserver, you may then instruct owfs, owhttp, and owpython to talk to owserver. It will be the air traffic controller. Let me illustrate below with a functional diagram and the commands issued:

Methods of attaching to your 1Wire network: directly, or through owserver.
Methods of attaching to your 1Wire network: directly, or through owserver.

The final commands list for my DS2483 on i2c, which I locate in /etc/rc.local, is:

/opt/owfs/bin/owserver --i2c=/dev/i2c-1:ALL -p 4304
/opt/owfs/bin/owfs -s 4304 /var/1wire/
/opt/owfs/bin/owhttpd -s 4304 -p 4305

Piece of cake. I can use owpython as I please, and check on connected sensors in raw output form at http://my.ip.add.ress:4305.

There are many other advantages of owserver, such as caching, negotiation, statistics, documented here. We’ll get to that later, along with some python examples.

 

Class-based database UI rendering with jQuery – Update ALL the things!

Basic UI Rendering/Updating

Javascript and jQuery offer the UI designer the tools necessary to update page text, select, and other form elements based on user interaction, as well as other conditions defined at either page load or at specified intervals. The basic tools for this in javascript are the document.getElementById() and document.getElementsByClassName() functions. What these functions do is retrieve objects that match the criteria specified. Depending on what sort of object is returned, appropriate properties and methods are available. The first will retrieve the first object that has the id specified, and the second will return an array of objects with the class specified. Remember that id elements are unique in a given document (or should be), and classes may describe multiple elements. Additionally, an element may only have one id, while you can assign it a slew of classes if you see fit. Although there are situations where a unique element is very useful, for example identifying exactly which element a user clicked, classes tend to be more flexible for most UI applications.

While the above vanilla javascript is plenty functional, jQuery wraps up these functions in their own library functions, adding a great deal of error-checking, including cross-browser functionality and fallbacks. They also tend to make the calls easier to use, shorter to code, and designed with the coder in mind. For all of these reasons, we almost exclusively use jQuery around here. The analogous class and id calls are both wrapped into the $() selector, which you would call as $(".myclassname") and $("#myidname"). Now, as opposed to the vanilla javascript, which returns pure DOM elements, these return a jQuery object, which can hold one or many DOM elements inside of it. This has repercussions when we want to access a single element inside a returned array, but we can use built-in methods to deal with this. More on that later.

The basic methods we’ll be using are the following:

Set text of all class elements:

DOM element examples:

<div class="mydatafield">Default Value</div>
<span class="mydatafield">Default Value</span>

How to render data:

$('.mydatafield').html('text or numeric data')
Set value of select with class:

DOM element examples:

<select class="mydatafieldselect">
  <option value="value 1">value 1</option>
  <option value="value 2">value 2</option>
  <option value="value 3">value 3</option>
</select>

How to render data:

$('.mydatafieldselect').val('value 2')
Set checkbox with class:

DOM element examples:

<input type="checkbox" class="mydatafieldcheckbox">

How to render data:

$('.mydatafieldcheckbox').attr("checked",true);

Standard Class Naming

You can see in the above examples how it is convenient to adopt a standard naming convention for the different types of widgets. There are many more you may want to use, such as toggles, sliders, and other custom elements. By using a standard naming practice, if we have a value ‘mydataname’, we know that a selector for this value will be at ‘mydatanameselector’. This comes in handy when we want to batch process ui elements.

So if we want to render ‘mydataname’ with value ‘value’, we can use the following piece of code every time. You can see I’ve included a helper function to assign true/false values to binary elements.

function setWidgetValues(baseclass,valuearg) {
    var value = valuearg || 0;

    $(baseclass).html(value);
    $(baseclass + 'select').val(value);
    $(baseclass + 'checkbox').attr("checked",booleanBinaryToTrueFalse(value));
}

The second piece of adopting naming standards is more application specific, but relates to the data source. As the next section will demonstrate, we can render an entire database table, as long as we predictably name our class widget elements.

Batch Rendering from a Database

Let’s assume for instance that we are operating out of a single database with a number of tables. Each table has  a single row with columns that describe the data. We adopt a class naming convention where classname=table + columnname. So if we have a table named  controls  and fields polltime, pollfreq, pollstatus,  we get classes controlspolltime, controlspollfreq, and controlspollstatus.

Now say we have retrieved a data table named superspecialdata, for example using an ajax database query, as we showed previously. Our data is a json object or array of json objects, where the properties are the columnnames, and the values are the row values. If we return, for example, a multirow database table as tabledata, to get the value of the third row in the column pollfreq, we’d use tabledata[2].pollfreq. It’s that easy. Typically, if know the table only has one row, we’d return the data as a single object. We’ll call that onerowdata, i.e. onerowdata=tabledata[0]. Since we know the name of the table and the standard for naming classes, we can just go for it:

function setWidgetValues(baseclass,valuearg) {
    var value = valuearg || 0;
    $(baseclass).html(value);
    $(baseclass + 'select').val(value);
    $(baseclass + 'checkbox').attr("checked",booleanBinaryToTrueFalse(value));
}
function renderWidgets(tablename,dataarg) {
  var data = dataarg || {};
  $.each(data,function(key,value){
          var baseclass='.' + tablename + key;
          setWidgetValues(baseclass,value);
  });
}
renderWidgets('superspecialdata',onerowdata);

See how easy that is? To create a user interface, just name your classes after your data, retrieve your data, time it up right, and render it to your classes automagically!

Creating a responsive user interface – Updating browser data in real time using jQuery and ajax

The Application

Any sort of User Interface (UI) that displays data that changes in real time needs two main components: a request from the browser (client) to a server, and a response from the server with (hopefully) some data. Examples of this are ubiquitous, but good ones are things like device control panels with indicators as well as interactive widgets.  Core functionality:

  • The browser should be able to update itself based on predetermined conditions such as timeouts
  • The user should be able to interact with the interface by supplying or requesting data when they choose
  • Data is updated selectively, not requiring a browser refresh event

Below are a few examples we have kicking around here:

Control panel application with indicators and controls
Control panel application with indicators and controls
jqm_controlpanel
Mobile control panel application with neat widgets
reflow temperature profile
Real time data plotting

Why Asynchronous?

Getting data into your web page is simple. If you want to dynamically create a web page, you can use anything that will generate text: perl, python, php … the list is endless. Tell your web server how to interpret it, and it will happily serve it up for you. This doesn’t, however, give you content that updates itself. You have to refresh. Very web 1.0.

In most languages, the interpreter executes the command and resumes on the next line when the command is complete. To read a file in python, for example, you might do something like:

f = open('workfile', 'w')
mytext = f.read()
print('here is the entire file')
print(mytext)

Because the program stops until the command is complete, it is blocking, or synchronous. This creates problems with interfaces, and especially if you were to use synchronous commands in a web interface. What if it takes 2 seconds for the server to respond and deliver your data? What if it is unavailable and times out? What if you have ten files you want to parse and update? What if you are retrieving 4,000 data points? Bad Things.

All of these situations will lead to at best sluggish response and a poor user experience. In the worst case, the browser will simply lock up and cease responding. These scenarios point to the need for asynchronous data requests. Enter Ajax. While the acronym stands for Asynchronous Javascript And XML, it’s very useful if we use Javascript Object Notation (JSON) to send data back and forth. While strictly speaking this is AJAJ, most still refer to this as Ajax, along with any interface code that facilitates sending data between client and server. It’s also possible to force it to be synchronous, but we won’t discuss that here.

The jQuery AJAX call

So how do we do this magic Ajax? Well, as the name implies, we need some javascript. Now, it is worth noting that it is possible to do your ajax using vanilla javascript, i.e. without jQuery, but why would you? jQuery takes the pain out of most javascript and just makes things better. If you need a primer on how to set it up and use it, take a look here. It’s as simple as a line in the head of your html documents to import the library and you are ready to start using the wonderful library of functions. I won’t spend time here explaining what jQuery is shortcutting  when it comes to ajax.

The docs for the jQuery.ajax() tell us what we need to know – send in a url and optionally some settings as a plain object and it will perform an asynchronous (override with async=false) http request. Here is a boiler-plate example, with explanations below the break. Remember that $ is a shortcut for jQuery function, so $.ajax() is the same as jQuery.ajax().

function showMeData(data) {
    console.log(data);
}
$.ajax({
    var callback=showMeData;
    url: "/wsgisqlitequery",
    type: "post",
    datatype:"json",        
    data: {'database':'/data/database.db','table':'mytable'},
    success: function(response){
    // Execute our callback function
        callback(response);
    }
});

Now what does each of the options do?

url tells the query where to go for the data. In this case, ‘/wsgisqlitequery’ refers to the link wsgisqlitequery at the site root. In the site configuration, we’ve got an alias that tells our server where this actually goes. We’re using wsgi with an apache directive in our site definition:

WSGIScriptAlias /wsgisqlitequery /usr/lib/iicontrollibs/wsgi/wsgisqlitequery.wsgi

You could also use standard cgi-bin, in which case your url would be something like /cgi-bin/myscriptname with a directive like:

ScriptAlias /cgi-bin/ /usr/local/apache2/cgi-bin/

We’ll discuss the differences between these two approaches later.

type specifies whether we are issuing a POST or GET request. GET is the default, and here we choose POST for compatibility with our wsgi script server-side.

datatype specifies what datatype we are expecting back from the server. This will direct the client (browser) to parse the data as it is returned. We specify json here, which works beautifully for our wsgi script. We send our data back as a python dictionary (through a json dump), and it pops out as json objects, with keys as property names and the values as property values. In other words, if we return data and assign it to ‘myfundata’, and it’s a dictionary with key ‘myproperty’ and ‘mypropertyvalue’ as its value, if we were to follow our ajax query with:

alert(myfundata.myproperty)

We’d be greeted with an pop-up with ‘mypropertyvalue’. Magic!

callback specifies a function name that will be executed after the data is returned. Herein lies the beauty of the ajax request. We send it off, and when it’s completed successfully we do what we want with it. No interruption! We can even add additional parameters to the original request to feed into the callback. Say, for example, we want to see how long each query takes. We can send that on to the callback:

function showMeData(data,time) {
    console.log('Here is our data. It was returned in ' + time + ' ms')
    console.log(data);
}
function myajaxfunction(database,table,callback){
    var inittime=new Date();
    $.ajax({
        url: "/wsgisqlitequery",
        type: "post",
        datatype:"json",        
        data: {'database':database,'table':table},
        success: function(response){
        // Execute our callback function
            var finishtime=new Date();
            timediff=finishtime.getTime()-inittime.getTime();
            callback(response,timediff);
        }
    });
});
myajaxfunction('/data/mydatabase.db','mytable',showMeData)

Even better, what if we want to send a set of parameters into the callback, depending on what we’re doing? We can make this as flexible as we want:

function doStuffWithData(data,options) {
    // Here is the data
    console.log(data);

    // Here are all the options: how we got it,
    // and maybe what to do with it
    console.log(options);
}

function myajaxfunction(options){
    $.ajax({
        url: "/wsgisqlitequery",
        type: "post",
        datatype:"json",        
        data: {'database':options.database,'table':options.table},
        success: function(response){
        // Execute our callback function
            options.callback(response,options);
        }
    });
});
var options = {'database':'/data/mydatabase.db','table':'mytable','callback':doStuffWithData}
myajaxfunction(options)

Server-side response

Ok, now that we’ve sent our formatted request and are eagerly awaiting data, how do we process it on the server side? Here is some base code that will make this work. Now remember that wsgi is python-specific (it’s what django uses, for example), so the following is in python. This is the wsgi file that has been aliased as mentioned above in the apache site definition:

def application(environ, start_response):
    import cgi, json

    from mylib import myspecialfunction

    post_env = environ.copy()
    post_env['QUERY_STRING'] = ''
    post = cgi.FieldStorage(
        fp=environ['wsgi.input'],
        environ=post_env,
        keep_blank_values=True
    )

    # Get the form data
    formname=post.getvalue('name')
    data={}
    d={}
    for k in post.keys():
        d[k] = post.getvalue(k)

    status = '200 OK'

    # Run stuff as requested
    if 'runspecialfunction' in d and 'myvariable' in d:
        data['result']=myspecialfunction(d['myvariable'])
        if data['result']:
            data['status']='success!'
        else:
            data['status']='fail!'
    else:
        data=['empty']

    output = json.dumps(data,indent=1)
    response_headers = [('Content-type', 'application/json')]
    start_response(status,response_headers)
    return [output]

Now, without getting into too much detail, the main components of the script are pretty clear. We set the environment, retrieve the post form data, convert it to a dictionary, and process it as we see fit. When we’re done, we send it back to the client as a json dump! Pretty simple!

More on wsgi vs. cgi and processing your json on the client side when I return… in the meantime, check out how to get your ajax timing right.

Why CuPID? Because your Pi can do more.

So what are we doing? We’re making the most flexible general purpose controller. It’s a PLC. It’s a home automation controller. It’s a sensor gateway. It’s a home energy management system. It’s a homebrewer’s time and beer saver. It’s a hacker’s start at web-enabled IO. It’s many more.  What makes it able to do all of these things (and well) is a pretty typical combination of the hardware to do the job and the software to interface with the humans.

The Hardware

With all of the applications we’ve just described, there are a lot of things that need to be included. Below is what we consider the core of essential functionality, and how things stack up. What we’ve done is taken the beauty, simplicity, and raw potential of the Raspberry Pi, added a few goodies, and made everything simply accessible inside a pretty protective box. What we haven’t done is throw in a whole bunch of stuff you might or might not need, like relays or hardware switches. Nice and simple, so you can plug in whatever modules and functionality you may need.

Core Hardware

Raspberry Pi CuPID
Runs *nix X X
ModBus TCP/IP X X
Powered USB X
WiFi X
I2C X X
SPI X X
UART X X
1Wire X
Programmable Indicators X
IO on standard cabling X
Replaceable Fuse X
Durable Enclosure X
NEMA-rated Enclosure Option X
Remote Sensor Options X**
Camera Option X**

**In development

The software

The special sauce is the interface. It’s not always about doing things people can’t do. It’s about not reinventing the wheel. A lot of us could, for example, write static or dynamic html that produces the page you’re looking at. But we have bigger ideas to focus on. The CuPID is designed around this principle. Produce an API and interface for the IO that allows flexible control, logging, and databasing of what you want, when you want. Put it all in an HTML5-compliant, device-agnostic interface that allows the hacker and system developer alike to build powerful control systems.  Here are the basics, and you can see a little more detail here: http://interfaceinnovations.org/ccsoftware.html

OS raspbian wheezy
control languages Python 2.7, 3.0 compliant
databasing sqlite
interface html/js/jquery, jquerymobile
controller/model wsgi/python
web service apache

Turn on the (SPI) lights : SPI output, shift registers, and LEDs

Save your GPIO

If you have any sort of microcomputer and use it as an IO device or controller, you are always in the business of budgeting connection points. With a pint-size device like the Raspberry Pi, this is especially important. If you use all of your dedicated I2C, SPI, and UART IO, you are left with 8 GPIO. Certainly manageable, but if you want a bunch of indicator LEDs or buzzers (like I do), you have to get smart, and you certainly can’t tie up a GPIO for each one.

Protect your Pi

An additional consideration is sourcing current and directly connecting your GPIO to devices. While sourcing current through a diode is fairly safe, stranger things than short-circuits and current reversals have happened, and the GPIO on the Pi are not protected from this sort of error. A great way to blow $35. It’s also possible with the cumulative current of many LEDs to exceed the current sourcing capability of the Pi. What happens when you do this? Well, best case is that your LEDs don’t light up. In reality, because there isn’t current-limiting built into the Pi, you’ll probably attempt to light all your lights and the Pi will reboot. Good stuff.

SPI and shift registers to the rescue

All of the above lead us to an interface that won’t occupy our GPIO, and can isolate our logic output from the current source. SPI is great for this. We can take a single serial output on GPIO and use a handful of cascaded shift registers to turn eight devices on per shift register, and realistically as many as you like once you cascade them.

What’s a shift register? Pretty simple. Send in serial data, in this case one byte, and put each bit of that byte on an output pin. Eight bits high low –> eight pins, each at high or low. Even better, if you send in a second byte, it will push out the first byte to the shift register’s serial output pin. If you have another shift register connected to the output, the second will display the serial data in the same way as the first was before it was pushed out, and the first register will now show the data on the byte that was sent in.

Wire it up

While the shift registers I mention here (74HC595) will only source 70mA total (8.75 per output), this is enough to light most LEDs even with eight lit, you can easily get around the current limitations by using the shift register to drive a BJT or FET. You can run them on the high or low side, since you can sink or source from the shift register. Let’s get to the wiring. The connections are as follows:

  • Serial data in (DS, pin 14) – SPI MOSI or from previous shift register
  • Serial clock (SHCP, pin 11) – SPI SCLK
  • Master reset (MR, pin 10) – 5V
  • Storage Clock – (STCP, pin 12) SPI CE (0 or 1)
  • Output Enable (OE, pin 13)- GND
  • Ground (GND, pin 8) – GND
  • Voltage supply (Vcc, pin 16) – 5V
  • Serial data out (Q7S, pin 9) – Serial out to next register (optional)
  • Parallel (single IO) output (Q0-7, pins 15, 1-7) – to output devices

Here’s a handy pic:

Wiring schematic for multiple shift registers with a single SPI output. Note that MOSI and CE connections at the top refer to a single SPI output. Note current limitations of register outputs compared to LEDs used and include transistors if necessary to power adequately.
Wiring schematic for multiple shift registers with a single SPI output. Note that MOSI and CE connections at the top refer to a single SPI output. Note current limitations of register outputs compared to LEDs used and include transistors if necessary to power adequately.

Fire up the python

Alright, so now to control the things. The easiest way to do this is by setting up spidev. A few modules need to be enabled if you’re using a Pi, and you’ll need a couple packages, notably spidev. Good instructions are here: http://tightdev.net/SpiDev_Doc.pdf .

After you’ve got all that set up, the code is pretty simple. The basic command to send a byte is:

import spidev
spi = spidev.SpiDev()
spi.open(0,1)    # Port 0, Chip Select 1 (CE1)
spi.xfer2([spisendbyte])

Now if we want to add some usability, we can use an array to translate to our assign bytes. The following is a good base raw write function. It is written for output low (the shift register is connected to the cathode of the LEDs) and it sinks current. For output high you would simply remove the bit inversion line.

def spirawwrite(enabledlists):
    import spidev
    spi = spidev.SpiDev()
    spi.xfer2([spisendbyte])
    spi.open(0,1)    # Port 0, Chip Select 1 (CE1)

    # If we have two registers, we set two bytes
    # They are set in order. First in goes 
    # to the farthest register
    spiassignments=[]
    for enabledlist in enabledlists:
        bytesum=0
        for index,bit in enumerate(enabledlist):
            bytesum+=bit*(2**index)

        # We are output low
        spiassign=255-bytesum

        spiassignments.append(spiassign)
    #transfer bytes
    resp = spi.xfer2(spiassignments)
    return resp

With a bit more fancy code calling this function (and a board as created here), you can do something like this:

Home reflow soldering (on a budget)

These days, you just can’t get around Surface Mount Devices (SMDs). The times when you could get all your chips in DIP configurations and plug them into nice little sockets are, well, gone. Unfortunately, this means if you are inclined to release magic smoke, your board-mounted chips are a bit harder to replace. The good parts are that chips are cheaper, and occupy much less space. You can jam more neat stuff in tiny spaces, as I’ll show shortly.

The tough part is that many of today’s small outline packages (TSOP, SOIC, etc.) are nearly impossible to hand-solder, and certainly not quickly and repeatably. Ideally, a good reflow soldering technique not only allows us to use these new devices, but potentially even speeds assembly.

With the magic of the china/ebay connection a functional reflow oven can be had for $300-1000. If you’re not sure you want to pull that trigger yet (or will eventually spring for off-site assembly), you can get away with a toaster oven, a temperature controller, some calibration and patience. Your market-variety toaster oven will set you back <$50, will get to 450F (ballpark maximum reflow temp), and perform reasonably well. We’ll show you how to do it here, and you can apply more or less everything to the same process with a professional oven. (We may even re-edit when we get ours in the mail).

Step 1. Prepare your board with paste

The idea is simple: apply solder paste to the pads on your bare board. When the paste reaches a high enough temperature, the organic binders will combust/evaporate and leave nice, clean solder joints. The components will also be hot enough at this temperature to wet with solder, and due to surface tension will tend to shift around to the centers of pads. Bonus.

Depending on the pitch of your devices, this step requires various degrees of precision. If you’ve got SMD resistors, caps, fuses, etc., you can really just glob on a dot and call it good, as long as you don’t get so generous that you bridge contacts. This is fairly hard to do, as the solder does not wet non-metallic surfaces (yay soldermask). However, if you have fine-pitch devices (such as the shift registers in the board shown), you want to be careful to not overapply, or you will potentially bridge contacts. You then get the extra-fun task of going back in with a rework tool or needle-point soldering iron to disconnect them. Remember: it is always easier to add solder than remove it, especially from SMDs, and even more so for devices with hidden pads. For this step, I use either a needle tip from the tube of solder paste, or dispense a small amount on something disposable and use a toothpick. This avoids the difficult task of controlling dispense rate from the tube. When you get a PCB design you like, you can get a screen for this step and save much time.

Solder paste and application tools with board
Solder paste and application tools with board

Shown below is an LED indicator board before and after paste application. While it appears a truly ugly application of paste, the bases are covered: each pad has paste, and not too much of it. The paste will melt and coat each one of the pads. Stray paste will either migrate to the pad or can be easily wiped off after reflow, as it will not stick to the solder mask – it will ball up.

Board before paste application
Board before paste application
Board with paste
Board with paste. Ugly, but as we’ll see, highly effective.

Step 2. Apply your devices

Of course making sure you get your orientation right, stick the little guys on there. Do what you can to get them as close to the board as possible by pushing them down with your tweezers.

Board after component application
Board after component application

Step 3. Determine your temperature profile

Typically, you want a profile something like the one shown here for Kester Solder Paste in Figure 1.

Standard Kester Solder Paste reflow profile
Standard Kester Solder Paste reflow profile

Although I’ve seen elsewhere that the earlier stages are not critical and that you can just cook at reflow temperature for four minutes or so, we chose to attempt to recreate this profile as closely as possible, because we like to read directions. Just kidding. In any case, we wanted to be able to replicate and tweak the process if we needed to. So we took some liberties with temperature conversion and rounding and ended up with the planned profile steps shown below. This was set up to run on one of our beta CuPID Controllers laying around the shop with an SPI thermocouple. This setup and temperature profile have served us rather well, after a bit of said tweaking.

temperature profile recipe steps
Set temperature profile recipe steps
reflow temperature profile
Visual reflow temperature profile

Step 4. Place and bake

I really wanted to say Shake and Bake, but that would not have made any sense. Place your board in the oven, and set your recipe running. You can see that we ended up with a pretty reasonable actual profile, considering we’re using on/off control, a completely uninsulated chamber and, well, a $35 toaster oven.

reflow temperature profile
Actual reflow temperature profile

Here below we have the board in the oven. Pretty impressive what a Target special will do for you.

We cooks the board. Thermocouple is visible at left.
We cooks the board. Thermocouple is visible at left.

Step 5. Test your results

When it’s done, let it cool! The solder paste needs a while to solidify, and the last thing you want on a well-placed board is to see them drift when they come out of the oven. Not to mention the potential for burns here. Shown below is the final product, before any cleaning of stray solder has been done.

Board with components after reflow.
Board with components after reflow.

This board, despite the ugly job I did applying the paste, came out 100% for one-to-one connections and continuity. Mission accomplished. What does this board do? Shown below is the board mounted in a basic CuPID Control unit connected to a Raspberry Pi. Below you can see rotation through all of the LEDs. Four RGBs and four single color for a total of 16 pixels. I’ll show how this is done through some Python and SPI in another post.

Interface Jquery ajax queries and timeouts — get the timing right

So you’ve got a nice web UI that interfaces with something else on your server – a database is a pretty common example. You’re using jQuery, so you set yourself up an ajax call to get your data, something simple like:

function wsgiCallbackTableData (database,table,callback,callbackoptions) {
    callbackoptions=callbackoptions || {}
    $.ajax({
        url: "/wsgisqlitequery",
        type: "post",
        datatype:"json",                
        data: {'database':database,'table':table},
        success: function(response){
            // Execute our callback function
           callback(response,callbackoptions);  
        }
    });    
}

This means you have wsgi configured on your server and a script aliased to ‘/wgisqlitequery’ that interprets the object you’ve passed to it as a command to grab the specified table from the specified database, in this case an sqlite database. Send in some options in callbackoptions and send them on to your callback function. Pretty vanilla stuff, as described here.

The tricky part is the timing. Because this call is asynchronous, a setInterval() or setTimeout() will not take into account the time it takes to execute and process the data. At best, you end up with erratic and unpredictable intervals depending on client and server-side load. At worst, you can end up stacking functions indefinitely and crashing your users browsers and bogging down your server. For example, if you set an interval of 500ms and your queries are taking 2s, you will just continue to stack concurrent requests. As simultaneous queries stack, each slows down, and they stack indefinitely until the browser gives up. No bueno.

If you set an interval of 500ms and your queries are taking 2s, you will just continue to stack concurrent requests until the browser gives up.

The key thing is remembering that the ajax call is asynchronous. This is a good thing — you don’t want your slow query to block execution of the remainder of the page. We send the data request into the sunset, and when it’s done we get the answers we were searching for. What we want is for the next timeout to begin when the asynchronous function ends.

Here’s how we do it. The concept is common and I personally learned it here (a very good read by Paul Irish on jquery). We set up a self-executing function in the callback. For synchronous calls, it would look something like this:

(function myFun(){
    doStuff();
    setTimeout(function(){myFun(),timeout})
})()

We run doStuff(), then reexecute the function only once the stuff is done. If we set it up as self-executing as we have here, it runs immediately and indefinitely at the timeout period specified. Let’s add two things. First, the option to run not on timeout:

function myFun(myoptions){
    doStuff();
    myoptions=myoptions || {}
    if (myoptions.timeout > 0){
        setTimeout(function(){myFun(),myoptions.timeout})
    }
}

Now we can run the function with or without timeout. This is useful if you need an updater running in the background, but also need to call it on, say, an updating button click.

Next we add the ajax. This is pretty simple. We just put the invocation of the function in the callback. This way it doesn’t execute until data (or error) is returned. Most important, it will not execute again until it has successfully completed. Dead query? No problem. Fail once. Something to keep in mind, however, if you know you’ll only succeed some of the time.

function updateStuff(myoptions){
    myoptions=myoptions || {}
    wsgiCallbackTableData ('/my/dbpath','mytable',myCallbackFunction,myoptions)
} 

function myCallbackFunction(response,myoptions){
    doStuff(response);
    if (myoptions.timeout > 0){
        setTimeout(function()
        {updateStuff(),myoptions.timeout})
    }
}

Now, if you really need to nail down timing, you could quite easily determine how each query takes, pass the value in the callbackoptions and adjust your timeouts in real-time to predictively attempt regularity, Ultimately, however, with the asynchronous call it’s just going to take how long it’s going to take.

Another neat thing you can do using this basic method is to allow updates of your timeouts. Sounds unimportant unless you need to do it! What if a user wants to set the update time of the interface on the fly without a refresh? We can do that. Just grab your timeout value in each self-executing function, for example:

myoptions.timeout=someGlobalVariable

OR

myoptions.timeout=$('#someControlWidget').val()

Then carry on. See here for a simple example. All the meat is here:

<script>
  $(document).ready(function(){
    (function ticktock(){
      console.log($('#ticker').val())
      if ($('#ticker').val()=='tick') {
          $('#ticker').val('tock')
      }
      else {
          $('#ticker').val('tick')
      }
      $('#ticker').slider('refresh')
      console.log('running at ' + $('#timeoutslider').val() + ' second intervals')
      setTimeout(function(){ticktock()},$('#timeoutslider').val()*1000) 
    })()
  })
</script>

Until next time.
~C

Hello there.

Good day!

So much fun stuff has been going on here at CuPID Controls that I thought we should talk about it. So many great forums and knowledge articles have been created by tech lovers such as myself. I have learned so much and been so inspired to create by all of the wonderful little microcontroller, microcomputer, sensor, network, javscript (and more) projects strewn across the interwebs. I felt I needed to give back, to update on what we are doing here to hopefully bring a little something extra to the scene, and in the end bring some projects, products, and knowledge to spice things up.

We’ll start with some bits and pieces of the projects we’ve been working on, and hopefully send on some videos of some stuff we like.

To set the stage, I’ll outline what we are interested in .. in broad strokes. We like linux, microcomputers, sensors, monitoring, databasing, networked control and instrumentation, mesh networks, smart energy and home controls, and everything in between. We are huge fans and proponents of the Raspberry Pi, and often use it as a platform to build cheap and fun projects. We play with 1Wire, SPI, I2C, MODBUS TCP/IP and CAN. We want to see if we can’t just make an RPi-based platform an everything device. So far, so good.

Anyhow, please chirp in and tell us what interests you, if you see fit. Otherwise we’ll just continue to babble about our little geek projects.

Cheers! ~C