Ramblings of a Bayesian (Part I)

“There are three kinds of lies: lies, damned lies and statistics.”

In this first article, I will try to explain the concepts of what we now call probability. You may have heard probabilities used in different contexts; here are three common

examples:

1. There is a 30% chance of rain in Stony Brook, NY, tomorrow,

2. There is a 1 in 292 million chance to win the Powerball Jackpot,

3. There is a 1 in 4 lifetime chance for males to die from cancer.

The question that I would like to pose is - how are these probabilities different from one another? Let’s look at example 2. Here we are dealing with a game of chance, and if we assume that the numbers are drawn fairly (i.e.no bias) then this probability can be calculated as the number of times you can win divided by the numbers of total possibilities. In Powerball, 5 white balls are drawn out of a drum with 69 balls and one red one is drawn out of a drum of 26 balls. So the probability is

$$\frac{5\times4\times3\times2\times1}{69\times68\times67\times66\times65\times26}=\frac{1}{292201338}$$

Here we calculated the number of possible outcomes as 69 possibilites for drawing the first white ball, 68 possibilities for the second white ball(since there is one ball missing), and so on. There are 26 possibilities for the red ball. Similarly, there are 5 ways to pick the first white ball, 4 to pick the second, and so on. All in all, this is a very straightfoward way of thinking about probabilities. This leads us to an interesting question. Let’s assume that the lottery does not give you the rules of how they come up with the numbers; all you can do is play the game every week for one year. Given your experiences over that year, could you give an estimate of the overall likelihood of winning? How long would you have to play in order to find the winning probability? If you’re thinking forever, your instinct is correct – it is probably forever. But this is exactly the position that we scientist are in. We don’t know the rules of the universe, but we are trying to figure out what they are given evidence that we collect by doing experiments (or playing the lottery). That is why we call the rules that we find “theories”, since we can never know exactly how “true” they are. At the same time, we know certain laws of physics pretty accurately, and that is why we rely on them every day. For example, your cellphone contains many technologies that make use of pretty advanced concepts of physics: GPS, radio frequency communication, integrated circuits, and LED display. Can you imagine if any of those “theories” suddenly turn out to be wrong and then our cellphones stop working?

Let’s look at probability example one. This probability is much harder to understand, because global weather is constantly changing. All the variables that describe weather - barometric pressure, humidity, wind speed, and so on - are all continuous, and thus harder to count. Also, the weather is dependent on conditions that have happened in the past and that may have happened far away. The probability in example one sounds more like a degree of belief that it is going to rain given the evidence in the past rather than a rigorous counting of all possibilities.

Example three, on the other hand, is in between the two other examples. People can be counted, and if we know exactly how each person died we can calculate the probability to die from cancer over their lifetime. At the same time, if you are male, you may want to know what “your” chance of developing and dying from cancer is. This personal probability may be very different from 1 in 4,but could vary depending on your genetic makeup, your habits and lifestyle, the environment, and many other factors. Here we are once again drifting into probability as a measure of belief given evidence that relate to you only.

This struggle between understanding probabilities as degree of belief or probabilities as exact measures of frequencies has existed since mathematicians have started thinking about problems associated with uncertain or random events. Interestingly enough, the first mathematicians that thought about these problems: Bernoulli (1700-1782), Bayes (1701-1761) and Laplace (1749-1827), thought that probabilities are measures of belief based on the available evidence. Only later the frequentist interpretation of probability was developed and promoted by Pearson (1857-1936), Fisher (1890-1962) and Neyman (1894-1981).

I wanted to share some experiences with the Beaglebone Green Wireless that I received a few weeks ago.  This board seems ideal for IoT applications but since it is pretty new and since not many people own it yet, there is not much support out there.

Let me first say that I really love how the board is setup.  When you power it up, it becomes a WiFi router which shows up under WiFi networks.  Once you connect to it, it pops up a browser window that lets you connect it to an external WiFi network (only private not cooperate).  Then you can connect via ssh and start playing.

There are a few things that are not working as advertised.  I am working on a project where I want to connect a few sensors (I2C) and I also wanted to connect via Bluetooth LE.  I was also planning to do the whole project in python.

I am using a BNO055 sensor breakout from Adafruit and they have a nice Beaglebone Black library.  Unfortunately, the example program simpletest.py is not working out of the box because the i2c on the BBB and BBGW are not configured the same way.  When I connect the sensor to P9_19 and P9_20, and P9_12 (reset) it shows an IOError.  When I check the i2c connection using i2cdetect -r 2 I can see the sensor under the address 0x28.  But the Adafruit is assuming that the sensor is at i2c-1.  I tried to force the library to use i2c-1 by specifying busnum=2 (btw, the documentation on the Adafruit website is incorrect: it is busnum not bus), but to no avail.  I solved the problem by reinstalling i2c-tools (https://packages.debian.org/jessie/i2c-tools) and also reinstalling py-smbus.  It seems that the py-smbus that you can get through pip does not do the job correctly (install i2c-tools with make, make install and py-smbus using python setup.py install).  Now the script works with busnum=2.

Also, bluepy does not work when installed with pip.  Follow the instructions to install from the github source and it works very nicely.

Good luck

Helmut Strey

Open Hardware Microfluidics Controller Arduino Shield

Finally, I managed to produce our first open hardware project.  The Microfluidics Controller allows us to drive 8 air pressure controllers and 8 air valves.  For this we have two 4-channel Digital-to-Analog chips (MCP4728) that produce voltages from 0-5V as input for our air-pressure controllers.  The air switching valves are driven using a darlington array (ULN2803).  The supply voltage for the valves can be selected either through a barrel jack J1 or by connecting the Arduino supply voltage.  We also added a barrel jack for the air pressure controller supply.  Here is a picture of the assembled shield:

The eagle files for the shield can be found here: https://github.com/hstrey/MicroFluidicsController

You can also order the PCB from OSHPark.com: https://oshpark.com/shared_projects/2HgBiQlS

Above you can see a typical array of pressure controllers that are connected to a common manifold.  As pressure controllers we use the MPV-1-P-FEE015AXL from Proportion-Air in Indiana. This particular pressure controller has an analog input of 0-5V to control the output pressure from 0-15psi.  Similar pressure controllers are available for different pressure ranges (0-0.3psi up to 0-100psi).  Since our DAC produces 0-5V it is important to chose the correct 0-5V command version.  Also, since the flow through these valves is minimal chose the smallest inlet orfice size (0.013'').  For low pressure you may need to adjust the settings of the valve to reduce oscillations (in typical microfluidics applications it is less important to reach the desired pressure quickly than to have constant pressure). The pressure controllers have a resolution of approximately 5000 pressure steps which matches well with the 12 bit DAC on our Arduino board.

The board can also control 8 air switching valves.  We use them for turning on/off the pressure channels when we need quick delivery of pressure for stop and go applications.  We also use them for PDMS valves that were introduced by Quake.  If you need more valves just populate another MicroFluidicsController board with just the Darlington array.  We typically use the Clippard ET-3M-12VDC valves (with exhaust) to drive PDMS control valves (You can also get an array of valves from Clippard that are connected to a pressure manifold EMC-08-12-XX where XX stands for the kind of valve that you need).  For turning on/off we use valves without exhaust.  The 12V supply for the switching valves is connected to the MicroControllerBoard through a designated barrel jack.

Gelman bioassay without MCMC

I am currently teaching a class on Advanced Numerical Methods in Biomedical Engineering (BME 502) at Stony Brook University and I wanted to include some basic Bayesian Analysis.  I chose to go through some of the examples in "Bayesian Data Analysis" by A. Gelman, J.B. Carlin, H.S. Stern, D.B. Dunson, A.Vehtari and D.B. Rubin.  Since my class is taught in Python/Numpy/Scipy/Matplotlib, I translated his examples into an iPython notebook.

1000 draws from the posterior LD50 distribution for the bioassay data set from Gelman's "Bayesian Data Analysis" book.

Mathjax in Squarespace 6

Finally, I managed to get Mathjax working in Squarespace 6.  This is how it works:

1. Under Settings -> Code injection insert the following in the header:

<script type="text/javascript"   src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>

then insert the following in a code block as HTML and you will see the Mathjax rendered equation below:

When $$a \ne 0$$, there are two solutions to $$ax^2 + bx + c = 0$$ and they are$$x = {-b \pm \sqrt{b^2-4ac} \over 2a}.$$
When $$a \ne 0$$, there are two solutions to $$ax^2 + bx + c = 0$$ and they are $$x = {-b \pm \sqrt{b^2-4ac} \over 2a}.$$

Squarespace will only render the equation if you are viewing the website without being in editing or administration mode.  This is a little frustrating but you can have a separate window open to view what a visitor will see.

Syntax highlighting in Squarespace 6

I held off switching to Squarespace 6 because of its lack of support for javascript-based syntax highlighters that I have used in Squarespace 5. I finally found a solution that may not be ideal but works. I am using Textmate 2 on the OS X that provides very nice syntax highlighting for most languages. Use the menu Bundels -> Textmate -> Create HTML from Document. Enter the HTML into a code block in Squarespace 6 and you have nice looking code. There is also the option of including line numbers.

Continuous Bluetooth LE data transfer to iPhone using the RedBear BLE shield

This is an update on our work on creating a bluetooth home health monitor in my class BME 440/441 "Senior Design in Biomedical Engineering".  The idea is to create an iPhone app that can connect to several Bluetooth LE sensors (ECG, EEG, Galvanic Skin response) and then display and record the data.  There will also be a data analysis component to actively monitor the health of the subject.

This post will describe a simple Arduino sketch that measures an analog signal at regular time intervals and then sends it through the Bluetooth connection of the RedBear BLE Shield. The sketch uses a timer to set the frequency at which analog pin 5 is measured and writes it into a buffer that is then sent through the BLE shield. I had to add a flag analog_enabled to make sure that the BLE shield only receives data when connected to the iPhone app. Unfortunately, there is a bug in the RedBear BLE shield software that makes it necessary to first receive data before it can send (I used BLE_Shield_Library 1.0). I could not get this project to work without the iPhone first sending at least one byte of data. In our case, when the iPhone sends "I" then the BLE shield starts sending. When the iPhone sends "0" then the BLE shield stops sending. I also included the parameters for 100Hz and 2Hz data transmissions.  Here is the sketch:

untitled
#include <SPI.h>
#include <ble.h>

#define ANALOG_IN_PIN      A5

boolean analog_enabled = false;

void setup()
{
SPI.setDataMode(SPI_MODE0);
SPI.setBitOrder(LSBFIRST);
SPI.setClockDivider(SPI_CLOCK_DIV16);
SPI.begin();
ble_begin();

// initialize timer1
noInterrupts();           // disable all interrupts
TCCR1A = 0;
TCCR1B = 0;
TCNT1  = 0;

//100 hz timer setup
OCR1A = 2500;            // compare match register 16MHz/64/100Hz
TCCR1B |= (1 << CS11) | (1 << CS10);    // 64 prescaler
TIMSK1 |= (1 << OCIE1A);  // enable timer compare interrupt
TCCR1B |= (1 << WGM12);   // CTC mode

/*
//2 Hz Timer Setup
OCR1A = 31250;            // compare match register 16MHz/256/2Hz
TCCR1B |= (1 << CS12);    // 256 prescaler
TIMSK1 |= (1 << OCIE1A);  // enable timer compare interrupt
TCCR1B |= (1 << WGM12);   // CTC mode
*/
interrupts();             // enable all interrupts
}

ISR(TIMER1_COMPA_vect)          // timer compare interrupt service routine
{
if (analog_enabled)  // if connected
{
ble_write(value >> 8);
ble_write(value);
}
}

void loop()
{
while(ble_available())
{
// read out command and data
// if data is "I" then turn on transmission
// if data is "0" then turn off transmission
if (data0==0x49) {
analog_enabled = true;
}
else if (data0==0x30) {
analog_enabled = false;
}
}
// Allow BLE Shield to send/receive data
ble_do_events();
if (!ble_connected()) {
analog_enabled = false;
}
}


Now to the iPhone app. It can be found here: http://github.com/hstrey/BLEShieldConnect

The entry screen is a table view that scans for BLE devices and add them to the table. I used the new iOS6 pull down to refresh method that is really neat. When you select any of the available BLE shields, a Bluetooth LE connection is established and a new screen appears that displays the RSSI, analog value, and number of bytes send.  The number of bytes send is a measure for how often the BLE shield sends the data that is accumulating in the arduino buffer.

A few remarks about the BLE SDK 0.4 that RedBear provides.  I was not very happy about the object design.  The sdk provides a ble object that has a method to scan for Bluetooth devices but then you can only connect to one of those devices.  That did not really make sense in terms of object oriented design.  There should be a more general class that is used to scan and then there should be individual BLE devices that you can connect to and those will provide protocols to receive and send data.

The iPhone program is quite simple but there was one aspect of its design that I struggled with for a while.  When switching views I had to transfer the ble object between view controllers.  In the table view I use the ble object to find all BLE shields in the area.  When I select one, I need to connect and then define all the protocols in the next view which all happens in the ble object.  Because the data protocols of the ble object are needed in the data view controller I need to pass the ble object to the data view controller in the prepareForSeque method as such:

untitled
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:@"Show Bluetooth Data"]) {
NSIndexPath *path = [self.tableView indexPathForSelectedRow];
BSCViewController *s = segue.destinationViewController;
s.ble=self.ble;
s.path=path;
}
}

In the data view controller I need to set myself as delegate and connect to the BLE device in viewDidLoad. When I return to the table view I need to disconnect and tell the Arduino to stop sending data. At first, I tried to set the ble delegate to nil but that was not necessary.

untitled
- (void)viewDidLoad
{
self.ble.delegate=self;
[self.ble connectPeripheral:[self.ble.peripherals objectAtIndex:self.path.row]];
}

- (void) viewWillDisappear:(BOOL)animated
{
NSLog(@"ViewController will disappear");
if (self.ble.activePeripheral)
if(self.ble.activePeripheral.isConnected)
{
//send BLE shield "0" to turn off transmission
UInt8 buf[1] = {0x30};

NSData *data = [[NSData alloc] initWithBytes:buf length:1];
[self.ble write:data];
// after that cancel connection
[[self.ble CM] cancelPeripheralConnection:[self.ble activePeripheral]];
}
}

Back in the table view controller I simply reconnect the ble.delegate to self. This is necessary since viewDidLoad will only be called once.

untitled
-(void)viewWillAppear:(BOOL)animated
{
//reconnect delegate when coming back to table view
self.ble.delegate = self;
}

Now lets talk about the performance. With this setup, I was able to send 100 data points (2 bytes each) per second easily to the iPhone. At 200 data points per second the buffer overflows and the BLE arduino sketch crashes. Believe it or not, the RedBear BLE Arduino library does not protect from buffer overflows. I am planning to do a similar test with Dr. Kroll's BLE Shield because for our project we need 200 data points per second per sensor.

Let me know if you have any questions.

MatPlotLib running in Cocoa under Xcode

I have always been frustrated that python does not have a nice GUI builder similar to what XCode provides.  Since I am a scientist and engineer, I am really fond of the combination matplotlib/scipy/numpy.  Here I will give an example of how to combine the two using the python cocoa bridge that is build into the python that comes with the operating system (in my case Mountain Lion OS X 10.8).  The only thing that you need to install for this example to work is the SciPySuperpack.

Here is the link to my example: github.com/hstrey/ShowMatPlotLib

Here is how it's done. The basic idea is that the python code creates a png file of the graph and that this graph is sent to the Cocoa program via a NSData object. I then convert NSData into a png image and display it. To show how fast this happens, I added a slider to change the frequency of the sine function that is being displayed. Every time you change the setting a new graph is created and displayed. This technique is not suitable for graphs that need to change dynamically at a high frame rate but for most applications it should work.

First the Cocoa part:
untitled
//
//  SMPLAppDelegate.m
//  ShowMatPlotLib
//
//  Created by Helmut Strey on 4/23/12.
//

#import "SMPLAppDelegate.h"
#include "Python/Python.h"

// Global pointer to app delegate
SMPLAppDelegate* myprogram;

// sendGraph function for sending graph through NSData
PyObject* sendGraph(PyObject* self, PyObject* pArgs)
{
char* GraphStr = NULL;
int length;
if (!PyArg_ParseTuple(pArgs, "s#", &GraphStr,&length)) return NULL;

NSLog(@"%i",length);
[myprogram pythonOut: [NSData dataWithBytes: GraphStr length:length]];

Py_INCREF(Py_None);
return Py_None;
}

static PyMethodDef sendGraphMethods[] = {
{"SendGraph", sendGraph, METH_VARARGS, "submit string"},
{NULL, NULL, 0, NULL}
};

@implementation SMPLAppDelegate

@synthesize window = _window;
@synthesize matplotlibView = _matplotlibView;
@synthesize freq=_freq;

- (void)setFreq:(double)freq
{
_freq=freq;
NSString *mystring = [[NSString alloc] initWithFormat:@"drawplot(%f)\n" , freq];
PyRun_SimpleString([mystring UTF8String]);
}

{
myprogram=self;
Py_Initialize();

Py_InitModule("MPL", sendGraphMethods);
NSString *scriptPath = [[NSBundle mainBundle] pathForResource:@"init" ofType:@"py"];

// load the main script into the python runtime
FILE *mainFile = fopen([scriptPath UTF8String], "r");
PyRun_SimpleFile(mainFile, (char *)[[scriptPath lastPathComponent] UTF8String]);

self.freq=50;

}

- (void)pythonOut: (NSData*)pngimage
{
NSImage *matplotlibGraph = [[NSImage alloc] initWithData:pngimage];
[self.matplotlibView setImage:matplotlibGraph];
[self.matplotlibView setNeedsDisplay:YES];
}

@end

And here is the python part (MPL is a module that I inserted from the Cocoa side):

untitled
import MPL
import numpy as np
import StringIO
from pylab import *

time=linspace(0,6.3,500)

def drawplot(freq):
f=StringIO.StringIO()
figure(num=None, figsize=(9,7),dpi=60)
a=np.sin(freq*time)
plot(time,a)
savefig(f,format='png')
out=f.getvalue()
f.close()
MPL.SendGraph(out)

Sending Humidity and Temperature data with ZigBee

This is the solution that I posed to my senior design in Biomedical Engineering class (BME 440).  Over the last few weeks we covered basic Arduino programming (e.g. debounced toggle, DHT sensor), we did some basic ZigBee communication (AT mode).  The final project was to build a wireless Humidity, Temperature sensor that can transmit the data to a central computer. Above you can see the wiring to connect the humidity sensor DHT22 (see Adafruit's tutorial) to the Arduino/Xbee Shield.  For this solution we configured the XBee S2's to "ZigBee End Device API" with AP = 2 (escape enabled).  The central computer is connected to the Network coordinator XBee ("ZigBee Coordinator API AP=1).  The Arduino code uses the XBee-Arduino library and the Adafruit DHT library.  The python code is using the python-Xbee library.

untitled
/**
*
* This is an Arduino sketch that reads the humidity and temperature
* from a DHT 22 sensor and transmits it using a ZigBee RF module.
* It combines two example sketches that came from the XBee-Arduino library: Series2_Tx
* and DHTtester from the adafruit DHT arduino library.
* *
* HumindityTempZigBee is free software: you can redistribute it and/or modify
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program.  If not, see http://www.gnu.org/licenses
*/

#include "XBee.h"
#include "DHT.h"

#define DHTPIN 2     // data pin of the DHT sensor

// Uncomment whatever type you're using!
//#define DHTTYPE DHT11   // DHT 11
#define DHTTYPE DHT22   // DHT 22  (AM2302)
//#define DHTTYPE DHT21   // DHT 21 (AM2301)

// Connect pin 1 (on the left) of the sensor to +5V
// Connect pin 2 of the sensor to whatever your DHTPIN is
// Connect pin 4 (on the right) of the sensor to GROUND
// Connect a 10K resistor from pin 2 (data) to pin 1 (power) of the sensor

DHT dht(DHTPIN, DHTTYPE);

/*
This example is for Series 2 XBee
Sends a ZB TX request with the value of analogRead(pin5) and checks the status response for success
*/

// create the XBee object
XBee xbee = XBee();

// we are going to send two floats of 4 bytes each
uint8_t payload[8] = { 0, 0, 0, 0, 0, 0, 0, 0};

// union to convery float to byte string
union u_tag {
uint8_t b[4];
float fval;
} u;

// SH + SL Address of receiving XBee
ZBTxStatusResponse txStatus = ZBTxStatusResponse();

int statusLed = 13;
int errorLed = 13;

void flashLed(int pin, int times, int wait) {

for (int i = 0; i < times; i++) {
digitalWrite(pin, HIGH);
delay(wait);
digitalWrite(pin, LOW);

if (i + 1 < times) {
delay(wait);
}
}
}

void setup() {
pinMode(statusLed, OUTPUT);
pinMode(errorLed, OUTPUT);
dht.begin();
xbee.begin(9600);
}

void loop() {
// Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)

// check if returns are valid, if they are NaN (not a number) then something went wrong!
if (!isnan(t) && !isnan(h)) {

// convert humidity into a byte array and copy it into the payload array
u.fval = h;
for (int i=0;i<4;i++){
}

// same for the temperature
u.fval = t;
for (int i=0;i<4;i++){
}

xbee.send(zbTx);

// flash TX indicator
flashLed(statusLed, 1, 100);

// after sending a tx request, we expect a status response
// wait up to half second for the status response
// got a response!

// should be a znet tx status
if (xbee.getResponse().getApiId() == ZB_TX_STATUS_RESPONSE) {
xbee.getResponse().getZBTxStatusResponse(txStatus);

// get the delivery status, the fifth byte
if (txStatus.getDeliveryStatus() == SUCCESS) {
// success.  time to celebrate
flashLed(statusLed, 5, 50);
} else {
// the remote XBee did not receive our packet. is it powered on?
flashLed(errorLed, 3, 500);
}
}
} else if (xbee.getResponse().isError()) {
//nss.print("Error reading packet.  Error code: ");
//nss.println(xbee.getResponse().getErrorCode());
} else {
// local XBee did not provide a timely TX Status Response -- should not happen
flashLed(errorLed, 2, 50);
}
}
delay(1000);
}

Below is my python script that I used to receive the data.

untitled
#! /usr/bin/python

"""
HumidityTempZigBee.py

This is a python script that receives and outputs the humidity and temperature
that was wirelessly transmitted from a DHT 22 / ZigBee RF module.

HumindityTempZigBee is free software: you can redistribute it and/or modify
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see http://www.gnu.org/licenses/.

"""

from xbee import ZigBee
import serial
import struct

PORT = '/dev/tty.usbserial-AE01CQ5N'
BAUD_RATE = 9600

def hex(bindata):
return ''.join('%02x' % ord(byte) for byte in bindata)

# Open serial port
ser = serial.Serial(PORT, BAUD_RATE)

# Create API object
xbee = ZigBee(ser,escaped=True)

# Continuously read and print packets
while True:
try:
rf = hex(response['rf_data'])
datalength=len(rf)
# if datalength is compatible with two floats
# then unpack the 4 byte chunks into floats
if datalength==16:
h=struct.unpack('f',response['rf_data'][0:4])[0]
t=struct.unpack('f',response['rf_data'][4:])[0]
print sa,' ',rf,' t=',t,'h=',h
# if it is not two floats show me what I received
else:
print sa,' ',rf
except KeyboardInterrupt:
break

ser.close()

Arduino debounced toggle

I posed the following problem to my senior design class:  create an arduino sketch that toggles an LED with a button push ( similar to turning on/off a TV with one button).  The students quickly realized that they had to include a deboucing algorithm otherwise the boucing would result in a random on/off state.  Here is my solution that is an extension of Ladyada's "better debouncer" http://learn.adafruit.com/tilt-sensor/using-a-tilt-sensor.

untitled
/* Better Debouncer Toggle
*
* Helmut Strey 9/21/2012
*
* this sketch senses debouced edges (high-low) (low-high) and toggles at (high-low)
*
* This debouncing toggle circuit is modified from Ladyada's better debounceer that can be found below
*
*/

int inPin = 2;         // the number of the input pin
int outPin = 13;       // the number of the output pin

int LEDstate = HIGH;      // the current state of the output pin
int previous = LOW;    // the previous reading from the input pin
int switchprevious = LOW;

// the follow variables are long's because the time, measured in miliseconds,
// will quickly become a bigger number than can be stored in an int.
long time = 0;         // the last time the output pin was toggled
long debounce = 50;   // the debounce time, increase if the output flickers

void setup()
{
pinMode(inPin, INPUT);
digitalWrite(inPin, HIGH);   // turn on the built in pull-up resistor
pinMode(outPin, OUTPUT);
}

void loop()
{
int switchstate;

// If the switch changed, due to bounce or pressing...
// reset the debouncing timer
time = millis();
}

if ((millis() - time) > debounce) {
// whatever the switch is at, its been there for a long time
// so lets settle on it!

// Now toggle the LEDstate when button is pressed
if (switchstate == HIGH && switchprevious == LOW) {
switchprevious = HIGH;
if (LEDstate == HIGH) { LEDstate = LOW;} else { LEDstate = HIGH;}
}
if (switchstate == LOW && switchprevious == HIGH) {
switchprevious = LOW;
}

}
digitalWrite(outPin, LEDstate);

// Save the last reading so we keep a running tally
}

MOSFET LED Driver

In the past few months we switched all our microscopy illumination to LEDs.  LEDs have many advantages: 1) they are cheap ( few dollars a for high powered LED ); 2) they come in pretty colors; 3) they can switch very fast.  This post will explore how you can control and switch LEDs fast.  Specifically, we will build a setup that allows us to trigger a camera and then send a short (microsecond) LED pulse to illuminate the CCD camera chip.  This is important for applications for fast moving objects in microfluidic channels.  We also use this technique to measure the speed of droplets in channels.  In this case we send a trigger signal and then two LED pulses during the same exposure time.  That results in a double exposure image.  The distance between the two objects divided by the time difference is the speed of the droplet.  The trigger timing can be achieved by a microcontroller or a FPGA (I will write about this later).

But now I would like to describe our TTL driven MOSFET switch.  I was looking around on the web for solution but I could not find much detail on how to design such a switch.  Most designs on the web did not work for me or did not perform well in terms of switching speeds.  So here is my solution.  The basic idea is to use a MOSFET that is designed for low voltage gate switching (IRF520).  The other is to limit the supply voltage to around TTL level by a resistor that is in series with the LED (has to be 10W or so).  In this case we are using a high powered LED that can take 700mA.  In this configuration, we achieve 700mA at 5.6V supply voltage.  The rest is simple.  I included a pulldown resistor of 10k and a small resistor between the TTL in and gate.  It turns out that 300 Ohm is best for fastest switching times.

I also experimented with LED power supplies that control the current (Buckpack).  Unfortunately, these power supplies produce pretty high frequency oscillations that interfere with high speed switching.  We simply use cheap variable voltage power supplies for driving our LEDs.  This has the advantage that we can regulate the intensity of the LEDs.

Here is our oscilloscopes output for a 10µs TTL pulse.  The circuit switches the LED on at about a microsecond after the pulse arrives and turns it off about a microsecond after the pulse ends.  I have no clue where these oscillations at the end come from.  The LED visibly blinks down to about 1µs pulse width.

The whole circuit, including the LED, can be build for about 15 Dollars.  This is much much less than what companies charge for LED illumination.  Some of the cheapest LED solutions are on the order of 300-2000 Dollars.  In order to replace your standard microscopy illumination (usually a halogen lamp) with an LED you have to place the LED exactly at the same position as the halogen bulb.  In some cases we added a small x-y stage to optimize the placement.  Thorlabs sells collimation adaptors for most microscopes.  In our case we use a collimator for Zeiss Axioscope (COP4-A) and a coupler (SM2T2). The inside diameter of the coupler is a little less than 5cms and we simply mounted our LED in the middle of a 5cm circular heat sink and wedged it into the coupler.  The coupler screws into the collimation adaptor and allows us to optimize the distance between LED and the lens.

This is how the final assembly for our Zeiss microscope looks like.

How to setup pyobjc with enthought python

In my first blog post ever, I will describe how I got pyobjc running using the enthought python distribution.  For a while I have been trying to learn Cocoa programming but I find coding in C (or objective C for that matter) very unproductive.  Coding in C just takes forever.  My favorite programming language for quite some time now is python.  It is a wonderful language and ideally suited for my needs especially with the numpy, scipy and matplotlib modules.

So recently, I have been trying pyobjc again.  I had given up several years back because it was just too hard to get everything running. pyobjc is a Cocoa-python bridge that should allow you to code Cocoa in python.  Unfortunately, pyobjc has almost no documentation.

So here is how you do it

1. Install XCode (I have Version 3.2)

2. Open the terminal application and type:

sudo easy_install -U setuptoolssudo easy_install virtualenv

create a directory for virtual environment.  All my virtual environment live in "/Users/hstrey/programming".

virtualenv pyobjc23cd pyobjc23source bin/activateeasy_install pyobjc-coreeasy_install pyobjc

virtualenv establishes a safe installation that does not interfere with the standard installation. Every time you want to use pyobjc go to your virtualenv folder and activate it by source bin/activate

Now we need to install the XCode pyobjc templates.  Mount http://svn.red-bean.com/pyobjc/trunk/pyobjc/pyobjc-xcode/ using "Connect to server" from the Finder.  Copy the "File Templates" folder into "/Library/Application Support/Developer/Shared/Xcode" (create this path if necessary). Copy "Project Templates" to the Desktop and follow the instructions in the README.txt file to install everything.

Open Xcode and create a new XCode project.  Under User Templates/AA Testing you will find the pyobjc templates.  Choose Cocoa-Python Application.  Call the project test for right now.

Open main.py.  Add the following two lines before the import statements:

activate_this = '/Users/hstrey/programming/pyobjc23/bin/activate_this.py'execfile(activate_this, dict(__file__=activate_this))

Before compiling the project we need to replace the Python framework that is used for linking with the enthought python framework.  Right-click on Python.framework and Show Info.  Now change the path to "/Library/Frameworks/Python.Framework".  We also need to adjust the project settings to adjust for the fact that enthought python is intel-only and 32-bit (at least my academic version is).  Go into Project - Edit Project Settings and select the Build tab.  Here delete all valid architectures except for i386 and select Build Active Architecture only.

Now you can click on Build and run and voila - the program should compile and an empty window will appear. Your first pyobjc application is running!