SPOT Hack

Deconstructing SPOT 
via  Sparfun

The SPOT Connect is a pretty awesome device. Basically, with a clear view of the sky, you can transmit small amounts of data (like text messages or short tweets) across a low-orbit satellite network from nearly anywhere on earth. You can control the SPOT Connect messenger with simple serial commands. This is a great device if you find yourself stranded in the forest and your "Man vs. Wild"skills aren't up to snuff.

They are a bit pricey ($150 for the hardware, $100 a year for the service, $20 for the breakout board, $0.10 per message) but that didn't stop SparkFun CEO Nate from taking one and completely dismantling it. Which brings us to today's post.


The guts that make SPOT go.

Nate created a great writeup all about his SPOT Connect teardown. In this tutorial, Nate takes the SPOT Connect and does a hefty bit of investigating. He breaks it into two parts:  Part 1 covers the serial interface requirements while Part 2 covers the tear down and reverse engineering aspect of this project. Check out the tutorial to see what Nate discovered!

Controlling an oscilloscope Python


Controlling a Rigol oscilloscope using Linux and Python

Rigol DS1052E Oscilloscope





After many frustrated nights trying to debug electronics projects blindly (the analog scope is wayyyy too much work to pull off the shelf and use), I decided it was time to spring for a digital storage oscilloscope. Since I had read many good things about them, I chose theRigol DS1052E, which is a two channel 50 MHz scope that can be easily modded to work at 100 MHz. The scope is way smaller and lighter than I expected, and has a nice set of buttons that give it the feel of a quality instrument. It works perfectly well as a standalone device, however since it has a USB slave port that implements the usbtmc interface, it turned out to be pretty easy to control using Linux. After a night of coding (most of which involved re-learning Python), I was able to grab data from the device and plot it:

Controlling the scope from Linux








This is all well and good, and should be particularly useful for my engineering pursuits, however it has me thinking about the artistic possibilities of a high-speed data acquisition device. I’m not sure exactly what I will do with it yet, but I’m thinking scope+processing or scope+pd could lead to some interesting possibilities. Any suggestions?

Source code for the current, boring use after the break.First, a rudimentary library for accessing the usbtmc driver. After I become more familiar with what I want from the device, I may turn this into an actual interface- for now, it just exposes the devices programming interface. Name it instrument.py:

import os
 
class usbtmc:
    """Simple implementation of a USBTMC device driver, in the style of visa.h"""
 
    def __init__(self, device):
        self.device = device
        self.FILE = os.open(device, os.O_RDWR)
 
        # TODO: Test that the file opened
 
    def write(self, command):
        os.write(self.FILE, command);
 
    def read(self, length = 4000):
        return os.read(self.FILE, length)
 
    def getName(self):
        self.write("*IDN?")
        return self.read(300)
 
    def sendReset(self):
        self.write("*RST")
 
 
class RigolScope:
    """Class to control a Rigol DS1000 series oscilloscope"""
    def __init__(self, device):
        self.meas = usbtmc(device)
 
        self.name = self.meas.getName()
 
        print self.name
 
    def write(self, command):
        """Send an arbitrary command directly to the scope"""
        self.meas.write(command)
 
    def read(self, command):
        """Read an arbitrary amount of data directly from the scope"""
        return self.meas.read(command)
 
    def reset(self):
        """Reset the instrument"""
        self.meas.sendReset()
And here is an example program that uses the library to grab the waveform from Channel 1 and graph it:

#!/usr/bin/python
import numpy
import matplotlib.pyplot as plot
 
import instrument
 
""" Example program to plot the Y-T data from Channel 1"""
 
# Initialize our scope
test = instrument.RigolScope("/dev/usbtmc0")
 
# Stop data acquisition
test.write(":STOP")
 
# Grab the data from channel 1
test.write(":WAV:POIN:MODE NOR")
 
test.write(":WAV:DATA? CHAN1")
rawdata = test.read(9000)
data = numpy.frombuffer(rawdata, 'B')
 
# Get the voltage scale
test.write(":CHAN1:SCAL?")
voltscale = float(test.read(20))
 
# And the voltage offset
test.write(":CHAN1:OFFS?")
voltoffset = float(test.read(20))
 
# Walk through the data, and map it to actual voltages
# First invert the data (ya rly)
data = data * -1 + 255
 
# Now, we know from experimentation that the scope display range is actually
# 30-229.  So shift by 130 - the voltage offset in counts, then scale to
# get the actual voltage.
data = (data - 130.0 - voltoffset/voltscale*25) / 25 * voltscale
 
# Get the timescale
test.write(":TIM:SCAL?")
timescale = float(test.read(20))
 
# Get the timescale offset
test.write(":TIM:OFFS?")
timeoffset = float(test.read(20))
 
# Now, generate a time axis.  The scope display range is 0-600, with 300 being
# time zero.
time = numpy.arange(-300.0/50*timescale, 300.0/50*timescale, timescale/50.0)
 
# If we generated too many points due to overflow, crop the length of time.
if (time.size > data.size):
    time = time[0:600:1]
 
# See if we should use a different time axis
if (time[599] < 1e-3):
    time = time * 1e6
    tUnit = "uS"
elif (time[599] < 1):
    time = time * 1e3
    tUnit = "mS"
else:
    tUnit = "S"
 
# Start data acquisition again, and put the scope back in local mode
test.write(":RUN")
test.write(":KEY:FORC")
 
# Plot the data
plot.plot(time, data)
plot.title("Oscilloscope Channel 1")
plot.ylabel("Voltage (V)")
plot.xlabel("Time (" + tUnit + ")")
plot.xlim(time[0], time[599])
plot.show()