Wednesday, March 21, 2012

Nose Poke Circuit

Just finished my nose poke circuit.  It consists of a beam break that triggers an notification LED to come on and toggles output state.

UPDATE:

Turns out that the transistor for the Poke Notify LED sucked current away from the output, reducing the "high" signal voltage sometimes to below TTL levels.  Replacing the transistor with a mosfet (in this case an AND gate) solved the issue.  Here is the new circuit which uses the AND gate to drive both the TTL output and the Poke Notify LED.


Dual Teflon Rodent Odor Port

In my new rat behavior box, I am putting in a dual odor port.  This lets me do comparisons between two independent odor lines.  I just assembled the new odor ports with beam break detectors that will activate when the rat pokes its nose into the port.  The ports are designed to be small so that odor onset is fast. Here is a picture of the new ports:

 In the middle there are some LTE 302 emitters facing out and on the sides there are LTR-301 receivers.  There are several ports on the back for odor injection.  On the top is a vacuum suction.

I am now making a controller for these ports with an Arduino Nano.

Tuesday, March 20, 2012

Hacking Agama V-1325R IR Camera

As part of my research, I do experiments with rodents (rats).  I train rats to do a number of tasks that allow me to ask them how they perceive odors.  Rats like to work in the dark and I monitor them with an IR camera.  As a cheap IR camera, I bought an Agama V-135R cam with built-in IR LEDs.  However, one annoying thing about this camera is that the IR LEDs must be turned on via software and are programmed to shut off every 45 mins.  I just want them to be on all the time!  So I opened up the camera and found a way to keep those guys glowing!  The LEDs were wired as two garlands of 2 leds plus a 50 Ohm resistor.  This makes sense:

USB Vcc = +5VDC
IR LEDs drop = ~1.75 V Each
Leaving 1.5 V dropping over R=50 Ohms --> I = 30 mA

The two garlands go to ground through a transistor.  I simply shorted the transistor with a fine copper wire!

There are 4 LEDs on the Agama 1325R connected as two garlands.  They receive power from a 5V Regulator and go to ground through a transistor switch (right top).  I shorted this transistor with a fine copper wire.

Monday, March 19, 2012

MFC Control Complete

Today I finished implementing control over my mass flow controllers from Alicat.  I now have the capacity to drive two MFCs via analog voltage or serial from our custom Arduino shield.  Everything works directly from MATLAB.

This is our Arduino-based olfactometer control module connected to two Alicat MFCs.
The output works at high frequencies with the MFCs being able to follow up to 3 Hz well.  I doubt that this performance will be maintained with long downstream tubing, but I hope to be able to do at least 1 Hz at output.

I had to work out a kink to get switching between serial and analog control to work.  The Alicat documentation says that A$$W20=16384 should enable analog set point. However, I found that this does not work.  Reading register 20 after setting analog set point from the front panel, however, showed that the correct value is actually 17408.

The Arduino will start by default in analog control mode. To switch modes:

[mode] = {0: SERIAL_OUT, 1: ANALOG_OUT}
olf.funcALIMode([mode]);

I tested the whole setup using my handy dandy flowmeter and things work very well so far.  Here is the code I used for my current test setup:


olf = OlfactometerDriver_SerialInterface('COM10'); pause(12);


% proportional control var
olf.funcALIMessage('A$$W21=500')
% differential control var
olf.funcALIMessage('A$$W22=10')


olf.funcALISin(1,1,0.5);
olf.funcALISin(0,1,0.5);


Next step: connect the MFCs to the olfactometer, determine the right parameters for sinusoids, and verify output via PID.


Saturday, March 17, 2012

Arduino Timer Configuration for 10bit Analog Output

Two things matter for PWM analog output:

1. PWM Frequency
2. PWM Resolution

The Atmega1280 comes with a couple of timers that control PWM on specific pins.  These timers are, by default, set for 8bit operation and a prescale value of 64.  That means that the timer resets every 256 ticks and each tick is 64 clock cycles.  The Atmega1280 runs at 16 MHz so, by default the timer frequency is 1/64th of that, or 250 KHz and the timer cycle is 1/256th of that, or ~977 Hz.

This is fine so long as you want fairly crude signals, but I wanted signals good to the millisecond and better bit depth.

The manual for the Atmega1280 is fairly clear:  http://www.atmel.com/Images/doc2549.pdf

PWM frequency can be increased by setting the prescale value to 1 (i.e. the 16 MHz clock).  PWM resolution can be increased by increasing the number of timer ticks in the cycle from 256 (8 bit) to 1024 (10 bit).  This produces a PWM of 16 MHz / 1 / 1024 = 15.6 KHz.  Much better!

Since I am interested in signals << 1KHz, I can simply run the PWM output through an RC circuit with a time constant of 1 msec  (e.g. 1 uF capacitor and 1K resistor).  This produces a reasonable sine function for frequencies up to ~50 Hz.

This code, which runs in setup(), applies the aforementioned settings for Timer 1, which controls pins 11 to 13 on the Arduino Mega.  To understand it, one has to dig through the manual for the descriptions of registers TCCR1A and TCCR1B.


  // set Timer1 (pins 13 and 12 and 11)
  TCCR1B = 0x09;  // set Control Register to no prescaling 
                  // WGM02 = 1


  TCCR1A = 0x03;  // set WGM01 and WGM00 to 1 (10 bit resolution)

Friday, March 16, 2012

Arduino as Analog Function Generator

I realized that outputting functions over the serial port is a little too much overhead.  However, my MFCs can be controlled by analog signals on input pin 4 in the miniDIN.  So I decided to see if the Arduino can output reasonable signals by PWM.

I generated a sin using PWM and filtered the signal using a simple RC circuit (tau = 1 msec).  It took a little fiddling with the Control Register of the appropriate timer (I had to remove prescaling) to get good output PWM frequency, but it looks pretty good.

This is my test code:


unsigned long t0;


void setup() {
    pinMode(9, OUTPUT); 
    t0 = millis();
    
    TCCR1B = 0x01;
}


void loop() {
    analogWrite(9, (int) (255.0 * 0.5 *(1.0 + sin( (float) ((millis()-t0) % 1000) * 2.0 * 3.14 * 5.0 / 1000))));    
}

UPDATE: click here for explanation of my choice of RC filter

Along the way, I found this useful blog with info about the Arduino:
http://softsolder.com
http://softsolder.com/2010/09/05/arduino-mega-1280-pwm-to-timer-assignment/
http://softsolder.com/2009/02/21/changing-the-arduino-pwm-frequency/ 

Mass Flow Sensor: ~$100



Just a note, to measure the air flow through my MFC, I was using an independent mass flow sensor.  I bought it directly from a Honeywell sensor distributor for ~$100:

AWM5101
http://sensing.honeywell.com/honeywell%20sensing%20and%20control%20product%20search?sid=1361C81FF163&Ne=3025&N=3468

The sensor is very easy to use, but I just added on some ports for power in and a BNC.  If you already have a scope or a PC with a DAQ, this let's you measure flow and for much less than $1000.

Alicat Control Registers: 21, 22, & 23

So I got a reply back from Alicat about what those control registers mean.  Turns out the documentation is spotty for a reason, the algorithm they use to control the valve is proprietary so they cannot reveal the details.  However, they could describe things roughly by an analogy:

"Address 21 (or the P value) can be considered as the gas pedal in a car, the harder you push it (raise its value) the faster the valve will operate. 

Address 22 (the D value) can be considered the brakes, the more the brakes are applied (raise its value) the faster the valve will stop at its set point. 

Finding a balance between these two values is crucial when trying to achieve an optimal response and accuracy from the valve. 

Address 23 ( the integral value) is a bit undefined…and rarely used.  It’s a value completely unique to the valve on the device, I guess to keep the analogy alive you can say that the I value is like the gear ratios within a gear box. The farther spread out the ratios are, (the larger the I value) the overall stability is increased, but the acceleration suffers. Conversely, the closer together the ratios become (the smaller the I value) acceleration is increased but overshoot and instability can become a major issue. 

Keep in mind that too high a value in any of these categories can and will cause overshoot/undershoot/oscillation, so when tuning start at a base number, write those base values down and increase and decrease in small increments."

I guess I will just play with the settings to get the performance that I need!  Thanks Alicat!

Thursday, March 15, 2012

Speedy MFC!

So it turns out there was a setting on the device that adjusts the speed with which the MFC operates.  Here I demo both the nice speed of the MFC and how it follows a 2 Hz sinusoid put out by my Arduino.

In order to do this, I had to change the "Proportional Control Variable" from the default value 100 to 500.  The documentation is not clear on what this variable is, but changing it sure does speed things up.  Here's how I did it all from MATLAB:

>> ret = olf.funcALIMessage('A $$W21=500'),

ret = 

    funcName: 'funcALIMessage'
         str: 'A   021 = 00500
                                                '


ret = olf.funcALISin(2,1,0.5),

ret = 

    funcName: 'funcALISin'
       state: 0



 And here's the flow output:


Alicat Response Times

I started measuring the performance of Alicat MFCs.  To do this, I set up an independent mass flow sensor at the output and connected it to an oscilloscope.  Alicat posted a rather impressive video on their website:

http://www.alicatscientific.com/documents/movies/alicat_response_time.avi

However, my performance so far is far less impressive:



And here's the video:


My Awesome Test Setup

Here's a picture of my setup.  On top of the Arduino is our custom valve driver shield.  Attached to the shield DB9 port is my hastily soldered inverter.  That connects to the Alicat MFC.  The Arduino is also connected to the PC by its USB port.

PC (MATLAB) --> Arduino --> MFC


Below is what interacting with the MFC looks like from MATLAB.


Outputting Functions to MFC

One of the thing I want to be able to do is to output arbitrary odor waveforms with my MFCs.  As a start, I implemented a Sin function to be output to the MFC (i.e. changing the flow rate at some set frequency).  I am hoping to put my MFCs into the setup to verify that they are working properly.

What I did was put a function that gets called on each loop of the Arduino which updates the flow rate at 100 msec intervals.

void loop()                     
{
  ...
  ALI.makeSin(); // ALI is my AlicatMFC object
}


void AlicatMFC::makeSin()

{
  float flow;
  unsigned int uiflow, flow_out;
  
  if (!_on) return;
  if ((millis()-_tL)<100) return;
  
  _tL = millis();
  
  flow = _mean + _ampl / 2.0 * sin( (float) (_tL - _t0) * 2.0 * 3.1415926536 * _freq / 1000.0 );


  if (flow > 1.0) flow = 1.0;
  if (flow < 0.0) flow = 0.0;
  
  uiflow = (unsigned int) ((float) ALI_MULTIPLIER * flow);
  
  setFlow('A',uiflow,&flow_out);  
}



Wednesday, March 14, 2012

Why is RS232 so Backwards??

Ah the beauty of old conventions.  I could not understand why RS232 treated -ive voltages as 1s and +ive voltages as 0s.  But, I got a bit of an explanation from a tech support person and then wikipedia:

http://en.wikipedia.org/wiki/RS-232

Turns out RS232 was created in the days of teletype machines (YEAH!).  In those days trasmitted data was stored as holes punched onto moving tape. These holes were then read as 1s and no holes were read as zeros. So the translation was that a hole (i.e. lack of paper and bit value 1) makes sense as a -ive voltage and no hole (i.e. still paper and bit value 0) makes sense as a +ive voltage.

This all reminds me of that story as to how the wheel spacing of Roman chariots set constraints for getting rocket ships onto the launch pad.

http://www.astrodigital.org/space/stshorse.html

Makes perfect sense now!
Just resolved sending also and I got my first serial port comm between Arduino and the MFC.  In the end, I simply inverted both the transmit and receive signals.

In the light of the morning

In the light of the morning, answers come:
http://www.sparkfun.com/tutorials/215

It looks like the MFC is using an RS232 standard but the Arduino is using TTL serial standard.  These two protocols differ in two main ways:

1. TTL is high for 1 and low for 0, whereas RS232 is the opposite
2. The voltages on TTL and RS232 can be wildly different

However, I happen to know that the voltages one the two devices are ok, so for me its just a matter of inverting the signal.  I can in principle just get a signal inverter, however, I will also order a RS232 to Serial converter:

RS232 Shifter SMD
http://www.sparkfun.com/products/449

Update, I added a simple voltage inverter circuit in front of the receive on the Arduino and MAGIC, it now reads the signals from the MFC just fine!  Now all that is left is sending...

Tuesday, March 13, 2012

RS 232 Voltages

I managed to get some serial input from the MFC to the Arduino, however, the input was garbled!  One cause of this could be that the RS 232 voltage levels sent by the Alicat MFCs are inappropriate for the Arduino to handle directly.  I will call tech support tomorrow to determine their exact specs to see if all could be fixed with a simple resistor or if I will need some more serious circuitry.

However, I measured the output signal on my oscilloscope and I see that it indeed is 0-5V, which should be fine as far as the Arduino is concerned.  Strange behavior.

Setting Up Serial Comm with MFC via Arduino

I am now working on linking our Arduino to the Alicat MFCs.  I am connecting Serial port 3 on the arduino to the Alicat via a DB9 on our custom made Arduino shield.  As far as the software goes, I am first just forwarding strings sent to the Arduino from MATLAB on the PC to the Alicat and strings sent from the Alicat back to MATLAB.

One of the things I want to be able to do is to produce different odor concentration waveforms by manipulating the MFCs.  For example sine curves.

To do this more interesting and faster control, I will implement direct functions in the Arduino that will manipulate the MFC flow rate in real time.

Monday, March 12, 2012

MFC Online

First successful communication with the Alicat MFC. The device takes a line feed and new line as command terminators.

The device returns data as strings, however, so I will need to write a parser on the Arduino side.

Never Trust a Cable Just Because It Has The Right Connectors

I got some DB9 to mini DIN cables to connect to my Alicat MFC and... no luck.  After 1/2 hour of making sure I connected to the right PC serial port, I realized that the cables I got were designed for some other use.  They connected the wrong pins (only 3) from the DB9 to the DIN.  However, lucky for me, the DB9 connector on the cable was easily open-able and the cable had all the strands I needed!

The necessary connector layout is as follows:

DB9 --------------> 8 Pin Mini-DIN
5 ----- Ground ---- 8                                                             
3 ------ TX ------- 3
2 ------ RX ------- 5

Serial Port Support

Our Arduino powered valve driver makes control of solenoid valves from the PC easy.  We gave one of our valve drivers to a neighboring lab that is setting up some basic olfactometry.  They are trying to integrate it with existing software.  However, I realized that I wrote the whole library for our Arduino to specifically communicate with MATLAB through a custom object.  To make the system compatible with their software, I added simple serial port text parsing so now the Arduino can be controlled by several methods!

It should now be possible to turn on valve 0 by typing:

S valve 0 1

Our Home Made Olfactometer

In the lab, we are doing both human and rodent olfactometry.  What does that mean?  Well, to study olfaction we need to present controlled odor concentrations.  This is achieved via a device called an olfactometer.  Instead of buying one, we decided to make our own.  This device is a teflon/glass olfactometer controlled by an Arduino running custom code controlling solenoid valves.  This device lets us present steady odor concentrations to our subjects and rapidly switch between odors.  The olfactometer air delivery is currently controlled by simple flow meters.  However, we are now switching to mass flow controllers to enable rapid alterations in odor flow.  My next technical part will be to write a control interface for the Alicat MFCs we got in the mail last week.

Getting Started

This is the first post to my new blog where I will attempt to chronicle my various adventures in setting up and running a small neuroscience laboratory studying olfaction.  I will be making some posts about technical and scientific issues that I encounter along the way.