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