Saturday, May 26, 2012

8Kb is not a lot

...but it just has to do.

The Arduino with the Atmega chip has only 8Kb bytes of RAM.  In writing my Arduino-MATLAB interface I came up hard against that limit.  My interface works by allowing a user to upload a small program to the Arduino that uses a locally defined function library.  I realized something was funny when programs will too many instructions failed.  This was because when program upload size exceeded a certain value, the Arduino would crash because it could no longer allocate memory for the incoming data.  By being more careful with memory, I was able to extend the amount I could send.

Also I found some nice ways to check the amount of memory available to malloc.  In the following code, x is there just to test that this function is working properly (i.e. detecting a prior malloc usage):


void funcFreeMem(IN_FREE_MEM_FUNC *in,OUT_FREE_MEM_FUNC *out)
{
  int sz = 0; 
  
  byte* x = (byte*) malloc(in->in * sizeof(byte));
  
  byte *buf;
  while ( (buf = (byte*) malloc (sz * sizeof(byte))) != NULL ) {
    sz++; // if allocation was successful, then up the count for the next try
    free(buf); // free memory after allocating it
  }
  
  free(buf);
  free(x);
  out->mem = sz;
}

Thursday, May 24, 2012

Beware Logic Levels

I had a very annoying time tracking down a problem with my poke detector circuit.  For some reason, it recently started acting up.  Now, the circuit is basically just a phototransistor feeding into an AND logic gate.  The weird behavior was that occasionally the output of the logic would get lots of noise on it and there would be strong crosstalk between different channels, i.e. different pokes.

After poking around with a scope for a while and re-reading documentation on the AND gate, I figured out the problem:  the phototransistor did not activate fully in the "no poke" condition and this caused a small voltage drop across the transistor.  This voltage drop was right about 0.8 volts, the TTL low level (TTL levels are 0.8V-=LOW and 2V+=HIGH).  Apparently if the voltage is between LOW and HIGH, strange things happen.

I fixed the problem by installing a higher value resistor prior to the phototransistor.  This served to drop more volts before the phototransistor.  Now the reading is only 0.3 volts when there is no poke and the system is working just fine.

Wednesday, May 23, 2012

Circuit Simulation

My electronics projects have gotten complicated enough to give me a headache.  To surrender to this complexity I started using a circuit simulator application.  The one I downloaded is FREE and seems pretty good.  It is called LTspice (spice stands for Simulation Program with Integrated Circuit Emphasis).  The program is available for download by anyone at: http://www.linear.com/designtools/software/.

I also found a Java-based program available as a web applet here for very simple things: http://www.falstad.com/circuit/

Saturday, May 12, 2012

Arduino PWM Filter

To get nice analog signals from the Arduino PWM pins it is necessary to filter the output.  Arduino PWM is somewhat slow, frequency of 15.6 kHz at 10 bit timer resolution (see this post on configuring the timer).  Luckily this is fine if you do not care about signals faster than 1 kHz.  Indeed I find that the Arduino can't really generate sine curves faster than about 0.1 kHz.  So it makes sense to just filter signals to maximally attenuate the PWM noise while retaining signals slower than 0.1 kHz.

This requires us to design a low-pass filter.  Now, doing some research, it is easy to find recipes for all kinds of analog filter designs, however, a simple RC filter does just fine for our needs.  I found a nice tutorial online explaining how the RC filter works.  The main formula needed is that the time constant of the RC circuit is related to the cutoff frequency as:  Tau = RC = 1/(2*pi*f)

So we have PWM at 15.6 kHz and we want to pass signals of 1 kHz, which means we should put our cutoff frequency at just a little above 1 kHz, say f = 2 kHz.  We get Tau = 1/(2*pi*2 kHz) = 8e-5 sec.  For a resistor of 1 kOhm, that gives a capacitor of 0.08 uF.  However, the attenuation of an RC filter is rather poor with only a -20 dB decrease per decade.  This means that for this cutoff we will be attenuating the PWM signal by only ~20 dB or ~10 times.  So a 5 V pwm will still show up as a ~500 mV signal on our output.  

To improve our results, I sometimes use a combination of a 1 kOhm resistor and a 1 uF capacitor with Tau = 1 msec.  This gives a cutoff frequency of 159 Hz, acceptable given that the Arduino has trouble with signals faster than 100 Hz and attenuates the PWM frequency significantly more (~-40dB) or only ~50 mV left of our 5 V PWM signal.

Open-Source Arduino-Based Olfactometer Shields

We just put together a set of shields to allow Arduino-based olfactometer control.  I am including the linked schematics here.  To make these shields, we are using a program called ExpressPCB, which is linked to a printing service.  I will not go through the details of what component goes where on the PCB, but I assume anyone with some electronics know-how should be able to figure them out.

ArduinoShieldBasic.pcb - Template we use for designing shields for Arduino Mega

rs232shield2.pcb - A module we use to communicate with Alicat MFCs

This module converts from Arduino's TTL serial to RS232 serial.  It also has a pwm signal filter and unity gain to allow analog output from two channels on the Arduino for control using an analog voltage.

valvedriver3.pcb - The valve-driver module for controlling odor valves

The module has optocouplers to switch solenoids on or off and status LEDs to view valve state.

valvedriverSMT.pcb - Another valve driver module with ribbon cable breakout (below)
ValveBreakout.pcb - the breakout with indicator LEDs


Valve - breakout












Valve - driver