Posts with «uncategorized» label

**********Stereo Audio VU meter on Arduino**********

This blog is a sequel of “Tears of Rainbow”.  Using the same hardware set-up of Gigantic RGB LED display, I decided to re-work software a little bit, in order to display the true RMS amplitude of musical content. Video clip on youtube:                       VU_Meter   640×480                                      VU_Meter_HD

Objective:

  • Stereo input, process both channel;
  • Full audio band, 40 Hz – 20 kHz;
  • Fast update rate of visual output.
  • Precision Full-Wave  measurements. 

To process stereo input, this time arduino is switching ADC multiplexer every time when it finish sampling input data array (size=128). Two channels “interleaved” with frame rate 78 Hz, so during each frame only one channel sampled / processed, and update rate per channel is equals to 78 / 2 = 39 Hz, which is more than enough for most audio applications.

 I’m using FFT Radix-4  to extract RMS magnitude of audio waveform, and this is why:

1.  Sampling rate in this application is 10 kHz. How I achieved  20 kHz stated in objective section, doing sampling only 10 ksps?  >>>Aliasing!<<<   What is considered to be nightmare when we need spectral information from FFT output, aliasing in this project is really helpful, reflecting all spectral components around  axis – 10 kHz back “to the field”. As all bins going to be sum-up there is no issue, only benefits. Due aliasing, I’m able to use low sampling rate, and reduce CPU workload down to 52%.

2.  In order to get accurate magnitude calculation of RMS,  which is defined as square root of the sum of squares divided by number of samples per specified period of time:    V(rms) = √ ( ∑ Vi ^2 ) / N) DC offset  must be subtracted from the input raw data of each sample    Vi = Vac + Vdc   (if you remember, AtMega328 ADC needs DC offset to read AC negative half-wave).  The problem here, DC offset value is never known with high accuracy due bunch of reason, like voltage stability of PSU,  thermal effects, resistors tolerance (+/- 1 or 5 %), ADC internal non-linearity etc. Cure for this, which works quite well for monitoring electrical grid power, high pass filter (HPF). Only instead of single 50/60 Hz frequency of power line,  I have a wide frequency range, starting from 20 Hz and ending at 20 kHz. When I feed specification of the HPF:

  • Sample Rate (Hz) ? [0 to 20000]                     ? 10000
  • Desired stop-band attenuation (dB) [10 to 200] ? 40
  • Stop-band edge frequency Fa [0 to 5000]         ? 0
  • Pass-band edge frequency Fp [0 to 5000]        ? 40

to  Parks-McClellan FIR filter design algorithm (one of the most popular, and probably, the best) it provides the result:

  • …filter length: 551 …beta: 3.395321

551 coefficient to be multiplied and sum up (MAC-ed) every 100 usec! No way. I’m not sure, if it could be done on 32-bits 100 MHz platform with build-in MAC hardware, but there is no way for 8-bit 16 MHz Arduino.

IIR filter wouldn’t make much difference here. It has lower quantity of multiplications, but more sensitive for truncation and rounding error, so I’d have to use longer (32-bits?) variables, which is not desirable on 8-bit microprocessor at all.

And here comes FFT Radix-4, which easily fulfill this extra-tough requirements in the most efficient and elegant way. All I have to do, is just NOT include bin[0] in final sum, and all DONE!. TOP-FLAT  linear frequency response  40 Hz – 20 kHz  ( -3 dB ), with complete suppression of DC, and low frequency rumble below 20 Hz attenuation.  Linearity is better than +-1 dB between 80 – 9960 Hz.

Last things, audio front-end. As VU meter was designed in stereo version, I’ve build another “line-in”  pre-amplifier based on this kit: Super Ear Amplifier Kit

Link to Download a sketch:  Stereo_VU_Meter.

 

Modified Stereo VU meter, Logarithmic scale, 8 bars per channel, spacing 6 dB.

Dynamic range: 8 x 6 = 48 dB.  Stereo_VU_Meter(Log10).
 Next blog:   Extending dynamic range to 72 dB! 

Audio Input to Arduino

The easiest way to connect audio signal to your arduino, is build a simple 3 components (2 resistors plus cap) circuitry shown on the first drawings on right side. Disadvantage: as there is no amplifier, sensitivity would be low, hardly enough to work with headphones jack output.  For low level signals, like electret microphone, amplifier is necessary. Here is the kit, which included board, electronic components and NE5532 Operational Amplifier IC:

  Super Ear Amplifier Kit

Other option, from SparkFun Electronics:

  Breakout Board for Electret Microphone

Note: I don’t recommend to replace NE5532 OPA with popular  LM358 or LM324 due their pure frequency response above > 10 kHz.

Configuring AtMega328 ADC to take input samples faster:

void setup() {

   ADCSRA = 0×87; // freq = 1/128, 125 kHz. 13 cycles x 8     usec =  104 usec.
// ADCSRA = 0×86; // freq = 1/64,   250 kHz. 13 cycles x 4     usec =   52 usec.
// ADCSRA = 0×85; // freq = 1/32,   500 kHz. 13 cycles x 2     usec =   26 usec.
// ADCSRA = 0×84; // freq = 1/16 ,    1 MHz. 13 cycles x 1      usec =   13 usec.
// ADCSRA = 0×83; // freq = 1/8,       2 MHz. 13 cycles x 0.5   usec =  6.5 usec.
// ADCSRA = 0×82; // freq = 1/4,       4 MHz. 13 cycles x 0.25 usec = 3.25 usec.

ADMUX    = 0×40;                          // Select  Analog Input 0

ADCSRA |= (1<<ADSC);                 // Start Conversion

Timer1.initialize(T_PERIOD);           // Sampling with TimerOne library
Timer1.attachInterrupt(iProcess);

}

Reading and storing samples to array via ISR ( Timer Interrupt Subroutine ), Timer1 in this example:

void iProcess()
{
static uint8_t n_sampl;
if (ADCSRA & 0×10)
{
int16_t temp = ADCL;
         temp += (ADCH << 8);
          temp -= sdvigDC;    
    ADCSRA |= (1<<ADSC);
xin[n_sampl] = temp;
}

if (++n_sampl >= FFT_SIZE )
{
n_sampl = 0;
process = 1;
}

}

Don’t like to solder all this components from the drawings above? Here is easy way around, if you, by chance, have a spare USB speakers around. Something like this:

Note: Speakers should use USB port as a power source, not AC power outlet!

1.  Open box up, and look  what kind of chip (IC) Power Amplifier inside, on the PCB board:

2.  TEA2025 in this example, but could be different in yours. Not big deal, just write down the name, than go on-line and try to find a data sheet for your particular chip. My favorite links:  1   and   2.  From the data sheet you will find pin numbers of two outputs, for left and right channels. Just solder couple of wires to ground and to one of the output and that’s it!

3. If printing on the IC body is unreadable, or couldn’t find a data sheet, it is possible to trace two wires from the speaker to IC. Most likely, there would be an electrolytic cap installed in series, between chip output and speaker. Solder a signal wire on the chip’s side of the cap, or near IC. There is a slim chance, of course, that IC configured in bridge configuration, and wouldn’t be any caps. It’s even better, just use ether of two speaker’s wires as a signal line, and ground as ??? a ground.

Be careful, use different color of wires for ground line and signal line. There would be no protection, and wrong polarity could damage an analog input of the arduino board, and in some occasions Power Amplifier IC. To prevent this, I’d strongly advise to install 10 kOHm resistor in series with signal wire.


Tears of Rainbow.

Video clips on youtube, arduino is running simple demo application.

Tears of Rainbow                             BarGraph HD movie                                    " href="//www.youtube.com/watch?v=30ELYwyy4JQ&feature=youtu.be]" target="_blank">BarGraph movie.

 

It’s time to release new updates for my first (ever) project with Arduino, “Color Light Music”.  From artistic perspective, VU BarGraph style (IMHO) is the best one for spectral dynamic representation, and not much could be improved on this side. But this time, it cross my mind an another idea “Tears of Rainbow”. This blog about how successively (or awfully) the idea was brought to life. And of course, VU visual effects still there, updated with nice peak indicators, color adjustment flexibility (this time triple color LEDs), and PWM-ed brightness settings luxury.  So, this is design requirements, I was following:

  •   make it as big as possible, GIGANTIC size !;
  •   Lego style, or many blocks / modules, which could be re-arranged in different pattern;
  •   extend-able,  easy to add up more blocks later on;
  •   low price on hardware, no special display driver IC.
To simplify assembly work, I decided to buy RGB Led Strip. I had known, from my first project, that design would be composed with straight lines, and the longer lines means the more LED’s ( and consequently, soldering work). For comparison, one line on this display consist of 6 RGB leds, or 24 soldering connections. Using RGB strip, I reduce a workload 24 to 4, or 6 times. I envy to people,  who have a patience to build  8x8x8 RGB led cube (or even 10^3 !).   Addressable RGB strip would make life even easier,   but  I couldn’t find local re-seller,  and was not going to wait shipment / customs. It’s summer time!
 In order to easy reconfigure a style, for example, from  3 BarGraphs, needed in Color Music exposition, to just  1 GIGANTIC VU meter (*),  RGB led strip is chopped-up and attached to 3 rectangular shape plates. I find out, that for some reason strip isn’t “sticky” enough, and to keep its perfectly align on a plate, I used a tire-ups at both ends. Luckily, it was quite easy to punch a holes in the plates for tire-ups just using kitchen knife.
 It wouldn’t be so, if I use a glass as a back-plate
(I had such idea initially). Something to think, if you plan to work with a strip in your design. The same also true for wiring (32 wires per plate). Tin “cookie” plates just was made to be part of this project!  And I even did not mention the heat dissipation,  1/3 of 5 meters strip consume around 12 W of power,  it’s almost like my soldering iron!
 One more things before I forget, I installed 1 cm paper pads to insulate contacts from the metal plate in the middle and on one side. Heat shrink tube takes care of the other end.
 LED’s use 12V as power source, and as I need a lot of  PWM channels to control their brightness , here comes 74HC595 buffered by ULN2803 at the outputs. Nothing special, 9 shift registers daisy chained to produce 72 PWM outputs. Two IC in a pair installed in reverse on a prototype board, to minimize a number of interconnections. As you can see from the  picture, there is only 1! yellow jumper brought from pin 15 of the shift register to pin 8 of the Darlington array. Why they don’t make a shift register in DIP-16 package? There wouldn’t be any jumpers at all!  Other alternative is using TPIC6B595.
        * For clarity, schematic diagram shows only two pairs of chip, and half length of the strip lines.

Now software part.

There are on-line libraries available, to drive 74HC595 by arduino. Only some of them not using hardware “build-in”  SPI interface , and really slow in communication with peripheral IC’s (don’t forget, that LED display only second part of the project, the first one, FFT, is very time consuming). The others libraries, nicely written and perfectly optimized for speed, have too much functionality, that I don’t need in my project, plus they are memory demanding. On the other hand, I need low resolution animation function – sliding down colorful tears, that I have to create on my own.  Now I ‘d like to represent a code, very fast SPI subroutines, completely written in C !  Function shift out 9 bytes ( for 9 shift registers in this project ) approximately in less than 36 usec, or 0.5 usec per one PWM channel. One bit-set in the unrolled loop is about 4.5 cycles.

static uint8_t brightn;

brightn++;
 if(( brightn % QUANTUMS ) == 0)
{
bitClear(PORTB,LATCH_PB);
SPDR = 0;

uint8_t * srP = &brightns[PIN_NBRS];
uint8_t cmp_level = brightn;

for (int8_t iSR = 0, curBt = 0; iSR < IC_COUNT ; iSR++, curBt = 0){

if ((* –srP) > cmp_level)
curBt |= 0b00000001;
if ((* –srP) > cmp_level)
curBt |= 0b00000010;
if ((* –srP) > cmp_level)
curBt |= 0b00000100;
if ((* –srP) > cmp_level)
curBt |= 0b00001000;
if ((* –srP) > cmp_level)
curBt |= 0b00010000;
if ((* –srP) > cmp_level)
curBt |= 0b00100000;
if ((* –srP) > cmp_level)
curBt |= 0b01000000;
if ((* –srP) > cmp_level)
curBt |= 0b10000000;

loop_until_bit_is_set(SPSR, SPIF);
SPDR = curBt; // Start the transmission
}
loop_until_bit_is_set(SPSR, SPIF);
bitSet(PORTB,LATCH_PB);
}

FFT part of the code completely “copy / pasted” form my “Radix-4″ blog. Here an advise, if you wish to explore the code, look there for “pure” form of function. What is new in this publication, is magnitude calculation subroutine, without slow SQRT.

Bar Graphs “set position” sub-function, or mapping height of lighted area of a plate to integral sum of the bins, brought into this project with mild modification from first project.

Continue moving from LED’s display to audio input, I should say couple words on a sampling. There are two functions in the project, that have to be triggered periodically with a timer, “display refresh” posted above and “take ADC sample”. It looks logically, instead of having two timers and have a lot of troubles with collision / racing between them, to scale both function to the same time frame, and execute them at once. “Display refresh” rate equals to minimum rate just to avoid flickering (60/70 Hz) multiplied by the numbers of brightness level. For example, setting brightness step number to 256 ( which provides excellent 256 x 256 x 256 = 16 M colors ) would require periodicity 60 x 256 = 15360 Hz.  See, where I’m driving at? Exactly, 15 kHz is nice frequency to sample audio input!. Well, it’s not 44.1 kHz as default settings Hi-Fi audio standard would recommend, but I ‘m not using all sound data in this project, as I only interested in lower 2 kHz part of the spectrum. And BTW, it’s almost 4x times higher than bear minimum prescribed by sampling theorem (Whittaker–Shannon–Kotelnikov).  I’ve made my choice at 15.625 kHz, to simplify math of binary compare to 64. ( 1/64 usec = 15.6 kHz) If there is no big difference, why not pick up “lucky” binary number, and help a Timer to do his job?

Initially, I thought that I would just re-use sampling sub-function  from “Pitch Shifting” project, slightly adjusting it from 8.0  to 15.6 kHz. I was surprised to discover, that TIMER2 and SPI don’t want to work together! Have I missed something in a data sheet? Could be, sometimes it’s so hard to comprehend, that I’d be still experimenting with “Blinking Led”, if not help from this (must to have) masterpiece:

AVR Microcontroller and Embedded Systems: Using Assembly and C (Pearson Custom Electronics Technology)

O’K, there is TIMER1 available. As project already have been heavily “over-loaded” on software side, I decided to take TimerOne library and not bother myself this time with a bunch of registers, interruptions, masks, etc, leaving this out of the scope, as not related to subject.

FFT size =128 provides extra fine resolution for Color Music performance. BTW, may be it not obvious, but bigger size of FFT has LOWER CPU workload per sample. And last, after everything was melted in one  (BIG) sketch nothing happened. No, my arduino can’t catch up at 15.6 kHz. Shifting 9 bytes via SPI, as I mention earlier, takes 36 microseconds. It’s leaving 64 – 36 = 28 microseconds per sample for everything else, or 28 x 128 = 3 584 per frame.  Radix-4 (size = 128) takes 4.2 milliseconds, as I posted here.  Alright, hell with it, who need 16 M colors  on 8 x 3 led display, by the way?  So, I bring quantity of brightness steps down to:             256 / 4 = 64, which is more than enough -> 262 144 color combinations!  QUANTUMS definition sets coefficient 4 in SPI sub-function.  The same time frame rate equals to  122 Hz, which is 2x times higher, than 60 Hz I started my calculation with.

Default color map, or bin’s assignment to a specific plate, is shown above. This time I implemented a command in CLI to make adjustment in this map on the fly, according to music style, equalizing all three bars more or less proportionally. Automatic Gain Control loop implemented in first project, doesn’t work so great with bigger display size ( first project uses 4  lines per color ). Plus, AGC bringing noise in the visual performance in  pauses between  two songs and in quite fragments of the music.  Starting bin position for each RGB plate could not be changed using CLI  ( you still can do this modifying the scetch), but quantity of bins accumulated per plate could be adjusted simply sending “dr” for red, “dg” – for green, and “db” - for blue, where  d is a digit 0..9.  Bands could over-lap, which is not desirable, in this case red is limited too 0..3, green 0..6, and blue 0..9.

More on the audio input hardware and sampling software subroutine, I post in separate blog, as this part follows w/o much modification thorough a few previous blogs, and doesn’t need to be re-stated here.

*Note: in software G.VU is not implemented yet.

Link to download a sketch:  Tears_of_Rainbow.


More musings on circuits course: temperature lab

I’ve decided to do a lot of my musing about the course design on my blog, so that others could contribute to the course design (or at least participate vicariously).  I think that having an open log of our thinking on the course design will be useful to grad students or new faculty who are having to do their own course designs, to show how us old farts do it (whether they wish to copy our methods or avoid using them).

The relevant posts so far are

Changing teaching plans
More on electronics course design
Yet another project idea
Another way to think about course design

I’ve got my son working on Arduino software to act as a data logger, so that students can have an easy-to-use tool that requires no programming, but which is easily modified if they want to do their own programming.  He has Arduino code for alpha testing already, and I think he’ll have a user interface ready for beta testing by the end of the week, but he’ll only have tested it on a Mac—we’ll need to get him access to a Windows machine to do testing there, because there are some operating system dependencies in talking to USB devices like the Arduino from a Python program. He’s been consulting with me on desired specs for the data logger, but doing all the coding himself. It is good practice for him both in interrupt handling and in user-interface design. He’s also having to think about portability for the first time, as the data logger has to run on Windows and Mac OS X (I think that Linux users should have no trouble with the version that works on Mac OS X, but we probably won’t be testing it). He’ll have to write user documentation and installation instructions also. Some of the packages he likes to use (like PyGUI) are enough of a pain to install that he’ll probably provide a stripped-down interface without a GUI for those who want to do minimal installation (Arduino software, Python, and PySerial are only essentials).

The first lab I’ve been thinking about is for temperature measurements. For the small temperature ranges normally needed in biosensor applications, the sensitivity, low thermal mass, and low cost of thermistors make them probably the best approach, and I think that they are what are used in the cheap digital oral thermometers sold in drug stores.  I wonder what techniques the manufacturers use to get medically acceptable calibration for those devices.

I’ve been thinking about the thermistor lab—it seems like we could do that in stages: first just reading resistance with a meter, then adding a series resistor to make a voltage output, then adding a parallel resistor to try to linearize the exponential curve a bit, finally adding larger series resistors and an amplifier to avoid self-heating currents through the thermistor and to allow nearly the full range of the ADC to be used.  This series of lab exercises could be spread out over the quarter, as students learn more about circuits.

For them to calibrate the thermistor, we could use hot and cold water baths, if the thermistor was in a waterproof package. From what I can see, that raises the price of a thermistor with leads from about 25¢ (for something like the NTCLE100E3333JB0 by Vishay BC Components) to $1.55 (for USP10982 from US Sensor) or $3 (for USP10973RA from US Sensor).  [Prices from DigiKey 10-unit price.]

I think that having the students do their own waterproofing is probably not a good idea.  Potting components gets to be a mess, and adding a large blob around the thermistor will slow its response time a lot.  I wonder whether using 5¢ disposable thermometer probe covers would work, or whether they tear too easily.  I probably need to look at some at the drug store, to see whether there is thicker one on the market that the cheap thermistors would fit into.

If waterproofing a cheap thermistor turns out to be too difficult, we need to think about whether to use the more expensive parts or work out some cheap, measurable temperature sources that are not wet.  We could make something like is used in PCR machines, with a couple of blocks of aluminum and a Peltier device, but I don’t think that the price is worth it—better to use the sort-of waterproof probes, a cup of water, and a thermometer.

I’ve noticed that for some applications, people are choosing voltage-output temperature sensors that rely on the thermal
coefficient of a transistor, rather than on a thermistor, like the MCP9700-E/TO from Microchip Technology (25 cents).  They have a fairly linear 10mv/degree C output, but their absolute accuracy is even worse than thermistors. These may be a better choice than thermistors in many applications, but would not provide the same teaching opportunities for a circuits class.

Using a thin-film platinum resistor temperature sensor (RTD) like the US Sensor PPG102C1RD would allow more accurate temperature measurement without calibration. With calibration, RTDs can be the most precise electronic temperature sensors, though I don’t know if the high precision is available in thin-film resistors, or only in the more expensive wire-wound ones. I suspect that repeatability from part to part is higher in the wire-wound RTDs, but that the thermal coefficients are the same, so that calibrating at one temperature should give about equal accuracy either way.

The naturally linear response of RTDs (100Ω at 0°C and 138.5Ω at 100°C in a very straight line) does not lend itself to as much circuit design as thermistors. On second thought, converting the 3850 ppm/°C resistance change into a voltage range readable by the Arduino ADC is not a bad circuit exercise, particularly if self-heating is to be avoided, though it is not as difficult as flattening the highly nonlinear response of a thermistor.  The biggest problem with RTDs is their price: at over $10 for a bare sensor they may be too expensive for class use.

Another possible temperature sensor is a thermocouple, which generates a voltage based on the temperature difference of two electrically connected junctions of dissimilar metals. One article in the engineering toolbox claims that thermocouples are cheap and RTDs expensive, and I think that is true if you are looking for high-temperature devices (like thermocouples for detecting pilot lights in furnaces), but not so true if you are looking for careful measurement in corrosive wet materials (like most biosensing applications). See Choosing and using a temperature sensor for more info comparing RTDs and thermocouples. Thermocouples have relatively low precision and sensitivity, and they measure only the difference in temperature between two points, and so are probably not very interesting for biosensing.

Action plan for testing out a temperature measurement lab:

  • Get some thermistors and some thermometer probe sheaths and see if I can make adequate temporary waterproofing for pennies per student.  I’ll probably have to solder on wires to lengthen the leads.
  • Try calibrating thermistors using a multimeter, cups of hot and cold water, and an accurate thermometer.
  • Try reading the thermistor using a voltage divider and the Arduino ADC.  Plot the temperature and Arduino reading over a wide temperature range (say, as a cup of boiling water cools).
  • Try linearizing the thermistor readings  using a parallel resistor and voltage divider.
  • Try designing an amplifier to read the thermistor with much lower current through it (and so less self-heating).

 

 


Filed under: Uncategorized Tagged: Arduino, bioengineering, circuits, course design, teaching, temperature measurement, thermistor

Another way to think about course design

Continuing the series about designing an applied electronic circuits course for our bioengineering majors (with more project ideas and another project idea), I want to talk about another lab-oriented view of what we want the course to teach—what lab skills they should have by the end of the course. Eventually, I’ll get around to textbook-concept view of the course, but I’m trying to stay away from that for a while, since the course we are trying to replace was faulted for being far too theoretical.  I want to start with the practical goals first, and work out form there what are the most important theory topics and what order they should go in.

Again, this is all very preliminary brainstorming—I have to talk with my co-instructor about what lab skills are feasible to teach in the class, which ones he sees as essential, and which are beyond the scope of the class.  Here is a tentative list of technician-level skills that every engineer should have:

  • Reading voltage, current, and resistance with a multimeter.
  • Using an oscilloscope to view time-varying signals:
    • Matching scope probe to input of scope.
    • Adjusting time-base.
    • Adjusting voltage scale.
    • Using triggering.
    • Reading approximate frequency from display.
    • Measuring time (either pulse width or time between edges on different channels)
  • Using a bench power supply.
  • Using a signal generator to generate sine waves and square waves.  Hmm, only the salinity conductance meter uses an AC signal so far—I may have to think of some other project-like labs that need the signal generator.  Perhaps we should have them do some capacitance measurements with a bridge circuit before building a capacitance touch sensor.
  • Using a microprocessor with A/D conversion to record data from sensors.
  • Handling ICs without frying them through static electricity.
  • Using a breadboard to prototype circuits.
  • Soldering through-hole components to a PC board.  (I think that surface-mount components are beyond the scope of the class, and freeform soldering without a board is too “arty” for an engineering class.)

There are probably a lot more skills to add to this list, which I haven’t thought about yet, and details within these skills that I’ve not thought about.  Luckily, my co-instructor has been teaching beginning students how to use electronic lab equipment for over 15 years, so I’m sure he knows what needs to be covered.

The bigger problem here is motivating students to want to develop these skills quickly—the EE and computer engineering students see the skills as directly related to their chosen profession, but the bioengineers will need to know why anyone would care about resistance, voltage, or current.  Getting a simple biosensor in right from the beginning would probably help.  I wonder if we should start with a thermistor lab for resistance, voltage, and current measurement.  How soon can we cover voltage dividers, so that they can design a resistance-to-voltage converter for interfacing to the ADC on an Arduino? Can we do that in the first lab?

 


Filed under: Uncategorized Tagged: Arduino, bioengineering, circuits, course design, teaching

Yet another project idea

I wrote earlier this week about an applied electronic circuits course for our bioengineering majors  and added some more project ideas in another post.  This weekend, while in southern California for my niece’s wedding, I was given another idea for a project by my sister: a pulse oximeter.

I knew that a pulse oximeter worked by looking at ratios of two different wavelengths of light shining through a finger or earlobe, which have different absorption by oxyhemoglobin and deoxyhemoglobin, but I had never thought about the details.  The first thing that concerned me was how a single ratio of two light intensities could be used—there must be huge variations in how much absorption there is that have nothing to do with oxygenation of hemoglobin.  Rather than puzzle through this on my own, I looked up the Wikipedia article on pulse oximetry.

It turns out that different techniques have been used over the decades.  Some of the early methods used more than two wavelengths of light including some that did not distinguish between the two states of the hemoglobin, in an attempt to quantify the total amount of hemoglobin as well as the ratio of oxy- to deoxy-.  The modern approach, though, is much simpler and more elegant.  The ratio measurements are made repeatedly, and only the fluctuating part of the readings is used.  The arterial blood flow shows a strong pulse signal (at around 0.5–3 Hz), while contaminating signals (hemoglobin in veins, absorption due to tissue other than hemoglobin, fingernail polish, …) are constant. By ignoring the DC signal and using only the fluctuating signal, the oxygen ratios are fairly easily measured.  Note that a pulse is essential to this measurement—continuous flow would not work—hence the name “pulse oximetry”.

There is at least one homebrew pulse oximeter on the web (like this one done by some Polish students and described in Polish, with a Google translation).  As far as I can tell, they used a PWM output from the microprocessor to provide signals alternately to the two LEDs, and to demultiplex the signals from the sensor and do separate analog filtering of the two signals.  It would probably make more sense to reduce the sampling rate to about 100Hz and do all the processing digitally. One thing they did that might be a bit trickier on the Arduino was to adjust the current to the LEDs to keep the DC signal level roughly constant, despite differences in the thickness and opacity of the fingers they were shining the light through.  The Arduino provides PWM outputs, but not real digital-to-analog channels.

They also do not seem to have thought about how to calibrate the device, which could be a problem for our lab also. Since commercial pulse oximeters only cost about $30 these days, we could simply have a couple in the lab for students to compare their results to, making a calibration chart of their reading vs the commercial reading.  (The hard part would be finding variation in oxygenation, since every one in the lab will likely be in the normal range of 95–99% oxygenated.)

The pulse oximeter would be a nice step up from the simple one-channel pulse sensor.  Unfortunately, most of  the design work seems to be on the digital side, rather than the analog side, which may make it a poor fit for the circuits course.


Filed under: Uncategorized Tagged: Arduino, bioengineering, circuits, course design, teaching

More on electronics course design

I wrote earlier this week about an applied electronic circuits course for our bioengineering majors that Steve P. and I will be designing over the summer, and how it will be designed backwards from the labs we plan to have them do.  That wasn’t quite an accurate description of our design process though, as the selection of the labs is based on more fundamental curricular goals.  I think that Steve and I have similar goals for the course, based on our discussions of it, but we’ve not tried to write them down formally yet.  I believe that we’ll need to do this for ABET, if the bioengineering program goes for full engineering accreditation.

I know that the EE Department wants the course to have a wider appeal than just to bioengineering majors taking it because it is (well, will be) required, as fluctuations in the cohort size for engineering majors has been large (biggest in computer science, which has been on a roller-coaster ride nationwide for the past couple of decades). The BME department chair, who is also the bioengineering undergrad director and main adviser, estimates a class size of 30–50 students if the course is offered this coming winter, and expects growth to 50–60 over the next few years.  The labs have room for about 20 students at a time, so this means 2 lab sections this year, growing to 3.  If we had a wider appeal, we might be able to pick up some computer science students, some game design students, or some Digital Arts and New Media (DANM) students, who are currently avoiding EE courses despite some interest in electronics because of the highly theoretical EE 101 course that is prereq to everything.  One problem with this broadening is that most of the potentially larger audience will not have been required to take the physics electricity and magnetism class, which I think is going to be an essential prereq.

Trying to put these two ideas, the need for more explicit goals for choosing labs and a wider potential market for the course, together, I came up with a possible theme for the class to guide lab selection and topics for the course:

Students completing this course will be able to design and build simple biosensors  for measuring chemical, electrical, or physical properties of biological systems (especially humans) and recording the measurements for computer analysis or interaction.

I still have to run this idea by Steve, and we’ll almost certainly need to tweak it a bit before we’re happy with it.  I’m particularly interested in two words in the goal (which I think Steve will agree with): design and build.  I don’t want this class to be a theoretical circuits course, in which students learn to formulate and solve large systems of linear equations, with no connection in their minds to any design problems.  I also want the students to learn to make things that they can take home, not just breadboard prototypes, though I may have to compromise a bit on this one, with most labs being breadboard only, and only one or two getting them to the next stage: a soldered prototype. Designing PC boards is probably beyond the scope of the class.

The labs I talked about in the previous post all fit within this theme:

  • Skin conductance meter.
  • Electrical field measurements in an electrophoresis gel.  This one is a bit of a stretch for the new theme, as electrophoresis gels are a standard lab tool, but not a biological system.
  • Conductivity of saline solutions. Used for measuring ecosystems (like rivers).
  • Do-it-yourself EKG
  • Optical pulse detector
  • Breathalyzer
  • Thermistor-based temperature measurement.

Since that post I’ve come up with a couple of other ideas:

  • Capacitance touch sensor (nice intro in Microchip application note AN1101).  This one is more ambitious than the EKG even, in that it involves a capacitance-sensitive oscillator design, but the oscillator is low frequency and the frequency sensing can be done by a microprocessor. They could use the same Arduino that they use for recording voltage data in other labs, but we’d have to provide them with a different program, since we are planning on having no programming required in the class or as prereqs to the class.  If the oscillator is a low enough frequency (say around 1kHz), then the program could be almost identical to the interrupt-driven data logger that my son wrote for the homemade super pulley, but interpreting the interrupt times differently.
  • Potentiometer-based goniometer for measuring joint angles.  Like the thermistor lab, this one is mainly a voltage-divider lab. The design problems are more mechanical than electrical, but it would be useful for students in understanding noise problems in sensors, since potentiometers are notorious for the noise in the signals.  It would also prepare students well for later work (outside this class) using servos, since most servo motors use a potentiometer-based angle measurements in their feedback loop.  I wonder whether the guts of a servo circuit are within the scope of this class—probably not, as much of it is concerned with handling the power demands and voltage spikes of the inductive load of the motor.

There have been a few ideas that I’ve had to reject as being overly ambitious for a first circuits course or too expensive to implement:  anything involving a microscope or micromanipulator setup is too expensive (eliminating most of the nanopipette work done in Pourmand’s lab), anything requiring weeks of practice to set up is also out (eliminating much of the nanopore work in Akeson’s lab, since forming the bilayers is still an art that few master quickly, also eliminating most work that would require growing neural cell cultures).  The nanopipettes and nanopores also require measuring currents in the picoamp range, which requires very sensitive electronics and extreme attention to noise control (including doing everything in a Faraday cage), which is probably beyond the scope of a first circuits class.  A subsequent bioelectronics class could cover patch-clamp amplifiers and other specialized measuring circuitry.

We probably do want some lab that measures ionic current, though, as that is fundamental to both the nanopipette and nanopore work.  I wonder whether we can do a scale model of the nanopore (with pin-prick size holes in plastic or Teflon), so that the students can measure the currents without the picoamp scale problems.

I suspect that when we try out the labs, we’ll find that only about half of them work well for us, and that several of them rely on the same basic circuit ideas (like voltage dividers to convert resistance into voltage).  In the latter case, we may give students the choice of several different labs to do.  I’ve always liked the approach of giving students a number of different design problems (of roughly comparable difficulty and covering the same fundamental concepts) and letting them choose which ones to work on.  I’ve never implemented this approach in any of my classes, though, as I’ve either been faced with a pre-designed set of lab exercises that I didn’t have the authority or time to redesign or I’ve gone for quarter-long independent projects which are not even attempting equivalence between projects.

Whether we end up rejecting some of these labs or merging some into alternative choices for a single lab, we’re obviously going to need more lab ideas.  Does anyone have any?


Filed under: Uncategorized Tagged: Arduino, bioengineering, circuits, course design, teaching

Changing teaching plans

It turns out that I won’t be teaching an introduction to programming for biologists, as I announced in February.  Funding was found for that class to be taught by the instructor who has been teaching it, freeing me up to take on a different class as overload.  (I already pretty much committed myself to teaching an overload this year.)

I decided that the most pressing need was for an applied electronic circuits course for our bioengineering majors (the current EE circuits class is way too theoretical).  The School of Engineering’s best EE instructor (Steve P.) and I had discussed doing such a course before I went on sabbatical, and our respective department chairs were enthusiastic, but funding was not found for it.  Everyone was even more enthusiastic this time around, so Steve and I are going to design the course this summer and try teaching it together in Winter (at least, if all the enthusiasm converts into a secure position for him—otherwise he’s going to have to pick up another couple of courses from a different department and not teach the new one).  We probably won’t know for sure about the funding until November, so we’re going to go ahead and design the course on spec, hoping that we get to teach it.

If Steve becomes unavailable, I don’t think I have the confidence to teach circuits by myself, since I’ve never taken a circuits course, being almost entirely self taught (my Dad taught me a little, including a German joke about a Wien bridge, when I was in high school).  After we co-teach it once, I think either of us could do the course alone, though co-teaching with a master teacher like Steve is fun.  (If the applied circuits course falls through for this year, I’ll probably try to cobble together a graduate genome assembly and annotation course, based in part on the Banana Slug Genomics class but adding a bunch of new material, so I’ll end up with a teaching overload and working on a new course this year no matter what happens.)

I’m looking forward to designing a course with Steve. We’ve both designed many courses before, and co-taught senior design project courses, but we’ve not designed a course together before. I’ve lost track of how many I’ve designed—something like 15–20, depending how you count the courses that someone else started but I extensively modified.

The approach that Steve and I are taking to the course design is to start by looking for lab projects for the students to do.  We need 10 labs (one a week for 10 weeks) ranging from very basic getting-to-know-the-equipment labs up to real (but small) design challenges.  We will try out the labs ourselves separately, then compare notes on how things went before writing up the lab handouts.  After we have the labs figured out, we’ll make sure that we cover the theory needed to understand the labs and do the designs, pacing the lectures to stay just a little ahead of the labs.  At least, that is how we both envision the process currently.

Here are a few labs that I’ve been thinking about—I’d appreciate a lot more suggestions.

  • Skin conductance meter.  There are a lot of do-it-yourself lie detector circuits for measuring skin resistance (“electrodermal response” if you want to sound medical).  I like the “Lego” sensor that just uses the inputs of a Lego RCX brick to read the resistance between two fingers. But getting RCX bricks for the lab just to measure resistance is silly.
    I wonder if we should give them something that reads and records voltage (like an Arduino or other microprocessor with an A/D converter) and have them make a voltage divider to read resistance.  This could be a good first lab, with them making a single measurement with a multimeter, choosing an appropriate resistor for the voltage divider, then recording a few minutes of skin resistance, perhaps on the inside of the wrist.  We could have them use fancy silver chloride gel electrodes at 500/$80, rather than Al foil and velcro—it’d probably end up cheaper.
  • When I told my son that we wanted to design the labs so that they could be done by the students without hand holding, he suggested the experiment where you pass a (small) current through a chain of people holding hands.  This might not be a bad idea also for a lecture demo.
  • Electrical field measurements in an electrophoresis gel.  The students would cast a gel (possibly agarose, but maybe just agar, to make it cheaper) with a standard buffer, apply a small voltage (much less than usually used in electrophoresis, since we’ll be working without the safety shield of a closed electrophoresis box), then use a handheld voltmeter to measure the voltage at different points in the gel.  We would also have them measure voltage and current.  We might even have them time the movement of a loading dye at different voltages, but I think that would take too long.
    One problem with this lab is that it requires using the wet lab, and neither Steve nor I are really wet-lab people.  I wonder if we could borrow a TA for a week from another course.  Perhaps a bioengineering senior undergrad could be hired, as many of them have some experience at casting gels.
  • Conductivity of saline solutions.  It is standard to measure the ionic content of fresh water and even sea water by measuring its conductivity—Wikipedia has a decent article on the theory of electrolyte conductivity.  A conductivity calculator gives an equivalence of 1 ppm total dissolved solids as 1.56 µS/cm, though they don’t specify the temperature or include a temperature correction.  The City of Santa Cruz 2011 Consumer Confidence Report lists the drinking water in town as 280–760 µS/cm (though they use the charming older name: µmhos/cm), while a 2004 San Lorenzo River Watershed Management Plan gives the conductivity in the estuary as 260–44,860 µS/cm, depending when and where the sample is taken (though they label their table wrong)
    The tricky part here is that the conductivity testing has to be done with an AC signal, not a DC one, to avoid problems at the electrodes. If we trust the students not to spill salt water into the equipment, we could probably do this lab in the electronics lab, and use the bench oscillator and meters.  Later in the quarter we might have them design their own rectifier circuit to communicate with a microprocessor, but I suspect that doing an oscillator may be beyond the scope of the class.
    We may also want to get silver/silver chloride electrodes (or fine silver wire at $0.90/foot and soak it in bleach).    Using thin wires as the electrodes may cause problems with the resistance being very high.  I wonder if we should try doing something cheaper first, like using a pair of pennies cleaned in vinegar and rinsed.  They wouldn’t last long in salt water, but even demonstrating the problem might be instructive.
  • A good project for late in the quarter would be a do-it-yourself EKG, which requires a simple amplifier (and gets another use for the silver/silver-chloride gel electrodes).
  • We could also do an optical pulse detector, using an LED and a light sensor, though we’d probably end up making our own, rather than buying one for $20.
  • Breathalyzer.  A resistance-output sensor for alcohol on the breath looks like it only costs about $5.  This may be too simple.
  • [Added 14 June 2012, after first publishing this post] Thermistors. A different application of voltage dividers, and one that would be relevant for both EE and BIOE students is thermistors.  The intro at http://www.mstarlabs.com/sensors/thermistor-calibration.htmlgives a nice overview of the subject for students. This would be a cheaper lab than the gel electrophoresis, with less cleanup needed.It would be easy to do three temperatures in water baths (ice water, room temperature water, hot water) and do 3-point calibration.  The design exercise of figuring out the best resistance to get fairly linear voltage vs. temperature plot is a useful one, and not too hard (I think).

Several of these labs look like they would be most interesting if they involved hooking up to an Arduino or other cheap microprocessor that can record time-course data.  Since programming is outside the scope of the circuits course, we could have the students buy an Arduino for about $20–30 online and give them a simple recording program (perhaps I can get my son to write them a versatile one, based on the one he wrote for our super pulley recording).  The students could sell the Arduino used if they weren’t interested in doing anything with it (the Digital Arts and New Media students use them and probably would be glad of cheap ones).

Obviously, we’re going to need more lab ideas.  Does anyone have any?


Filed under: Uncategorized Tagged: Arduino, bioengineering, circuits, teaching

Journalism #2 Typewriter: generative stories about killed journalists

“On Journalism #2 Typewriter” is a typewriter installation of Julian Koschwitz, which purpouse is to remember journalists who got killed in the past 20 years. The installation writes generative stories about all journalist who have been killed worldwide between 1992 and today based on the existing data on their life as well as their published work. The individual stories are connected through common fields of coverage, places, professions and the story is written endlessly on one endless piece of paper.Besides the text the typewriter creates flags which are distorted the more journalists got killed in that particular country.
The installation makes use of Arduino Nano, Arduino and Processing software, 32 solenoids and shift-registers.

For more information: http://koschwitz.org/studio/?page_id=627

Embedded programming gap

It seems that there is a shortage of programmers who can do embedded systems (which is what computer engineering is mostly about these days).

Critics lay much of the blame for the embedded programming gap at the doorstep of university computer science departments that have tended to migrate curricula toward trendy programming languages like Java at the expense of unglamorous tasks such as how to design and analyze algorithms and data structures.
Struggle continues to plug embedded programming gap | EE Times (by George Leopold)

I’m not so sure that Java is at fault here. It seems to me to be perfectly fine second programming language (after a simpler one like Python that does not require all data structures to be declared before any code is written).  The problem is more that the instruction focuses entirely on designing huge complex data structures and using large libraries of complex software components, rather than on fundamentals:

The problems start early in the curriculum. Too often an introductory Computer Science course will fall into one of two extremes: either focusing on the syntactic details of the programming language that is being used—“where the semicolons go”—or else treating programming as a matter of choosing components and plugging them into a GUI.

The basics—how to design and analyze algorithms and data structures—are covered summarily if at all. Software methodologies such as Object Orientation that are best approached in the context of the development life cycle for large applications, are introduced through trivial examples before their benefits can be appreciated: the proverbial cannon that is used to shoot a fly.

The education of embedded systems software engineers: failures and fixes | EE Times (by Robert Dewar)

I’m not so sure that I believe in Robert Dewar’s proposed solution, though, as he suggests having students do more high-level design (software architecture, rather than nuts-and-bolts programming), which is in direct opposition to his claim that students should be getting more training in low-level languages like C.

Robert Dewar also makes an argument for group work at the university level—something that is common in computer engineering programs, but apparently rare in computer science programs.  At UCSC, I know that all computer engineers, electrical engineers, and game design majors are expected to do group senior projects, and some of their other classes (such as mechatronics) are also group projects.

I think that the lack of group projects in many CS courses is not so much tied to Dewar’s idea “a perhaps regrettable staple of the educational process is the need to assess a student’s progress through a grade, and a team project makes this difficult” as it is to the problem of scale—a group project is only reasonable when the project is too big to be done more efficiently by a single person.  Creating and managing such big projects in lower-level classes would be a major undertaking, particularly in the short time frame of a quarter or semester, when a lot of things other than group dynamics need to be learned. Pasting a group structure onto tiny project would make things worse, not better, in terms of training students to be effective in groups (see Group work).

Some entrepreneurs have addressed the problem by starting up “initiatives like Barr’s week-long, hands-on Embedded Software Boot Camp.”  The idea is to take programmers who already have degrees and supposedly know C and train them specifically in the skills needed to do real-time programming. The cost is not small ($3000 for 4.5 days, if you register early).

Some computer scientists have been pointing out problems in the standard CS curriculum for a while:

I started saying this over a decade ago. I even did embedded stuff in my 3rd year data architecture course—my department was uninterested, and the students had a real hard time wrapping their heads around the thought that there are places where resources are limited.

The department fought me when I said that students needed to learn more than one language (Java). The department disagreed when I said that students should learn how to program for environments where bloated OO methods might not work (… But, the ARE no places where efficiency matters!!! It’s all about “Software Engineering”!).

The students had NO idea what it meant to program for a machine that had no disk, only memory.

Part of the reason CS departments are seen as being so out of touch is BECAUSE THEY ARE!!!

University should not be about job training, BUT it is also NOT about teaching only those things the faculty find interesting.

Struggle continues to plug embedded programming gap | The Becker Blog.

I know that there have been struggles between the computer science and computer engineering departments at UCSC about what programming language to teach first, with the computer scientists arguing for Java and the computer engineers arguing for C and assembly language.  Eventually they reached a compromise (which has been stable for about a decade), with the computer science students taught Java first and the computer engineering students taught C first, then both making transitions to the other language.

I think that both approaches work, but the strengths of the resulting programmers are somewhat different.  For device drivers and small embedded systems, I’d bet on the computer engineers, who have a better grasp of low-level details, interrupts, and hardware/software interactions.  For more complicated projects, I’d want one of the computer scientists doing the high-level programming, teamed with computer engineers to do the detail work.

I actually don’t like either C or Java as a first programming language.  I think that students would be better off starting with Scratch, which gets them quickly into multi-threaded code, real time operation, and race conditions, without burdening them with a lot of syntax.  Then they can switch to Python to learn about code syntax, types, and objects, without the burden (or support) of compile-time type checking.  After that they can switch to Java to learn about declaring all their data structures and having very rigid type rules (useful for bigger projects to make interfaces between different design groups more explicit).  In parallel with learning Python and Java, they should learn C and C++ in the context of the Arduino microprocessor (or similar small microprocessor) to control real-time physical systems.

The computer engineers could even skip Java, and learn their rigid type systems strictly in C++ (which they are more likely to use later), though Java is cleaner and makes the learning somewhat easier.

Computer scientists should not stop with this handful of languages, though, as they are essentially all Algol derivatives.  The CS students should also learn a couple of languages that come from different lineages (LISP or Haskell, for example).


Filed under: Uncategorized Tagged: Arduino, C++, computer science, education, higher education, Java, programming, Python, Scratch