Gas station without pumps

2017 January 8

Applying for Mini Maker Faire 2017

Filed under: Uncategorized — gasstationwithoutpumps @ 17:41
Tags: , , , ,

I’m submitting an application for the Santa Cruz Mini Maker Faire 2017 (2017 April 29), since last year’s Mini-Maker Faire went well (see Santa Cruz Mini Maker Faire went well).  This year I’m getting my application in early, rather than dithering about it for months as I did last year.  I have less free time to prepare the display this year, but I have a better notion what I want to do, so it should not take long to get ready.

Last year's banner, which I can reuse this year. I might also make a shorter one that will fit on the front of the table.

Last year’s banner, which I can reuse this year. I might also make a shorter one that will fit on the front of the table.

The “non-public” description of my display is straightforward:

I’ll bring a tabletop full of electronics projects, as last year (see https://gasstationwithoutpumps.wordpress.com/2016/04/16/santa-cruz-mini-maker-faire-went-well/ ).

Laptops demonstrating free software to turn cheap microprocessor boards into data-acquisition systems suitable for home labs and science-fair projects.
Homemade LED desk lamp and stroboscope.

Several of the projects will be interactive (an optical pulse-rate monitor, oscillators that can be adjusted to change Lissajous figures on an oscilloscope, …).

A few changes from last year: a more reliable pulse-monitor design and a new USB oscilloscope.

The public blurb is similar to last year’s:

See your pulse on a home-made optical pulse monitor!
Record air pressure waveforms using free PteroDAQ data acquisition software!
Play with a bright custom-design LED stroboscope!
Control fancy Lissajous patterns on an oscilloscope!

I removed mention of an EKG, because I decided that it was too much trouble to tether myself with EKG leads all day.

My “Maker bio” is a bit boring, :

Kevin Karplus has been an engineering faculty member at UCSC since 1986, but has done hobbyist electronics on-and-off since the 1960s. For the past few years he has been working on a low-cost textbook to make hands-on analog electronics accessible to a wider range of students.  Several of the projects on display are from the textbook.

2016 April 16

Santa Cruz Mini Maker Faire went well

The first Santa Cruz Mini Maker Faire seemed to go well.  I did not get to see much of it, since I was busy at my booth most of the day, though I did get a break for lunch while my assistant Henry manned the booth, and I made a quick tour of the exhibits during that break, to see what was there, though with no time to chat with other exhibitors.

I understand that about 1800 people bought tickets to the Mini Maker Faire, which probably means there were over 2000 people on-site, including volunteers and makers.  I hope the food vendors did OK—I ate at the Ate3One truck, since I never have before, but my opinion afterwards was that CruzNGourmet and Zameen have better food (both of those trucks are frequently on campus, and I’ve eat at each several times).

My day went pretty well, though I had one annoying problem, having to do with my pulse monitor display. When I set up the booth Friday evening, the pulse monitor was not working, and I thought that the phototransistor had somehow been broken in the rough ride in the bike trailer, so I brought the pulse monitor home, replaced the phototransistor and tested in thoroughly.  Everything worked great, so I packed it more carefully for transport in the morning.

When I got everything set up Saturday morning, I found I had no electricity, though the electricity had worked fine the night before.  After I finally tracked down a staff member with the authority to do anything about it, he suggested unplugging the other stuff plugged in and switching outlets.  I turned out that the only problem was that the outlets were so old and worn out that they no longer gripped plugs properly—taping the extension cord to the outlet box so that the weight of the cord didn’t pull out the plug fixed the power problem.

Once I had power, I tested the pulse monitor, and it failed again!  I used the oscilloscope to debug the problem, and found that the first stage transimpedance amplifier was saturating—there was too much light in the room, and even shading the pulse monitor didn’t help. By then, my assistant for the day (and my group tutor for the class on campus), Henry, had arrived and gotten the parking permit on his car, so I raced home on my bike to get resistors, capacitors, op amp chips, multimeters, hookup wire,and clip leads to try to rebuild the pulse monitor from scratch on the bread board.

When I got back to Gateway School, I tried a simple fix before rebuilding everything—I added a pair of clip leads to the board so that I could add a smaller resistor in parallel with the feedback resistor in the transimpedance amplifier, reducing the gain by a factor of about 30.  This reduced gain kept the first stage from saturating, and the pulse monitor worked fine.  Rather than rebuild the amplifier, I just left the pair of clip leads and the resistor in place all day—they caused no problem despite many people trying out the pulse monitor.

I think that I want to redesign the pulse monitor with a logarithmic first stage, so that it will be insensitive to ambient light over several decades of light.  That should be an easy fix, but I’ll have to test it to make sure it works. I don’t think I’ll have time this weekend or next to do that, but I’ll add it to my to-do list.

I’ll need to think about whether to include having a logarithmic response in the textbook—that is certainly more advanced than what I currently include (just a transimpedance amplifier), which is already pushing students a bit.  A transimpedance amplifier is a pretty common component in bioelectronics, so I really want to leave one in the course.  I’m not sure a logarithmic amplifier is important enough or simple enough to include at this level (I don’t currently cover the non-linearity of diodes).

 

Here is the booth display with my assistant, Henry. I was permitted to use painter's tape to attach the banner to the whiteboard.

Here is the booth display with my assistant, Henry. I was permitted to use painter’s tape to attach the banner to the whiteboard.

The magenta laptop on right (which my family refers to as the “Barbie laptop”) was a used Windows laptop that I bought for testing out PteroDAQ installation on Windows. It was set up with PteroDAQ running all day, recording a voltage from a pressure sensor and a frequency from a hysteresis oscillator (as a capacitance touch center).

Just to the left of that was a fairly bright stroboscope, using 20 of my constant-current LED boards. To its left is my laptop, displaying the current draft of my book. Behind (and above) the laptop is my desk lamp, which uses the same electronic hardware as the stroboscope, though with only 6 LED boards, not 20.

In front of the laptop is the pulse monitor, which includes a TFT display in an improvised foamcore stand. I used just a half block for the pulse sensor, relying on ambient light (sunlight and the desk lamp) for illuminating the finger.

To the left of the pulse monitor was a stack of business cards for my book and sheets of paper with my email address and URLs for this blog and the book.  I should have included the PteroDAQ URL as well, but I had forgotten to do so. I did tell a lot of people how to find PteroDAQ from the navigation bar of my blog, but putting it on the handout would have been better. Ah well, something to fix next year (if Gateway is crazy enough to do another Mini Maker Faire, which I hope they are).

I also had all my bare PC boards that I had designed and not populated, plus my two Hexmotor H-bridge boards, behind the business cards. One of the amplifier prototyping boards was displaying in the Panavise that I use for soldering.

On the far left of the table is my Kikusui oscilloscope and two function generators, set up to generate Lissajous figures.  I let kids play with the frequencies of the function generators, take their pulse with the pulse monitor, and play with the pressure sensor and the capacitive touch sensor.

My booth was not the most popular of the Faire by any means (certainly the R2 Makers Club in the next booth was more popular), but I was kept busy all day and I talked with a lot of people who seemed genuinely interested in what I was doing, both with the UCSC course and as a hobbyist.

2016 April 4

Banner blooper

Filed under: Uncategorized — gasstationwithoutpumps @ 22:48
Tags: , ,

My table banner for the Santa Cruz Mini Maker Faire arrived today from Spoonflower, and it looked really good, until I tried to put it on the table.  I had foolishly ordered a design that was a yard of fabric 56″ wide. The 56″ wide part was reasonable, but the table is most likely only 25–27″ high, so the yard-high pattern is about 50% too big!

I should have thought of that before sending off the order!

Oh, well, perhaps I’ll have a wall behind me that I can blue-tape the banner to.  Or I can put the top foot of it on the table top, though that will make stuff on the table less accessible.

2016 March 27

Pulse monitor with display

Filed under: Uncategorized — gasstationwithoutpumps @ 15:10
Tags: , , ,

For the Mini Maker Faire, I put together the pulse monitor board with a 240×320 full-color TFT display, to make a self-contained pulse monitor (no laptop for display or power):

The display showing my pulse (which was a bit higher than my usual resting pulse). The trace is drawn left-to-right taking 5.33 seconds for each pass. The gap in the middle shows where the new trace is currently being drawn. The heart blinks with the pulse.

The display showing my pulse (which was a bit higher than my usual resting pulse). The trace is drawn left-to-right taking 5.33 seconds for each pass. The gap in the middle shows where the new trace is currently being drawn. The heart blinks with the pulse.

The block diagram shows the components I assembled for the monitor. I deliberately am not showing the pulse-monitor amplifier board, since that is a design exercise in my applied electronic course.

The block diagram shows the components I assembled for the monitor. I deliberately am not showing the pulse-monitor amplifier board, since that is a design exercise in my applied electronic course.

I need to redesign the finger block to be easier for kids to use—perhaps a more open design with the phototransistor not so deep.  I tried doing a back-scattering design (with the LED and phototransistor adjacent on a board), and I got a usable signal, but it seemed to be even touchier and more sensitive to motion artifacts than this block.  The motion artifacts mainly come from varying the amount of pressure with which the finger is pressing against the hole in the block for the phototransistors.

Real pulse monitors clip onto a fingertip or earlobe, so that the person does not have to keep their hand relaxed and still, but I’ve not yet come up with an easy-to-make design that works (mechanical design had never been my strength).

 

Here is the rather crude source code for the pulse monitor:

// code for pulse monitor on Teensy 3./3.2 board
// Using ILI9341 TFT 240x320 TFT display
// Sun 20 March 2016 Kevin Karplus

#define MONITOR_PIN	(A0)

#include "SPI.h"
#include "ILI9341_t3.h"
#include "font_GeorgiaBold.h"

// Use pins 9 and 10 for the DC and chip-select inputs of the TFT SPI interface
#define TFT_DC  9
#define TFT_CS 10

// Use hardware SPI (#13=SCK, #12=MISO, #11=MOSI) and the above for CS/DC
ILI9341_t3 tft = ILI9341_t3(TFT_CS, TFT_DC);

static const unsigned char heart_data[] = {
/* Glyph 0: size=25x22, offset=0,-2, delta=25
	      **         **      
	  ********     *******   
	 *********** *********** 
	 *********************** 
	*************************
	*************************
	*************************
	*************************
	*************************
	 *********************** 
	 *********************** 
	  *********************  
	   *******************   
	    *****************    
	     ***************     
	      *************      
	       ***********       
	        *********        
	         *******         
	          *****          
	           ***           
	            *            
*/
0x19,0xB0,0xEC,0x80,0xC0,0x18,0x03,0xFC,0x1F,0xC1,
0xFF,0xDF,0xFC,0x7F,0xFF,0xFF,0x5F,0xFF,0xFF,0xFE,
0x1F,0xFF,0xFF,0xC3,0xFF,0xFF,0xE0,0x7F,0xFF,0xF0,
0x0F,0xFF,0xF8,0x01,0xFF,0xFC,0x00,0x3F,0xFE,0x00,
0x07,0xFF,0x00,0x00,0xFF,0x80,0x00,0x1F,0xC0,0x00,
0x03,0xE0,0x00,0x00,0x70,0x00,0x00,0x08,0x00,0x00,
};

static const unsigned char heart_index[] = {
0x00,0x00,
};
/* font index size: 2 bytes */

/*
typedef struct {
	const unsigned char *index;
	const unsigned char *unicode;
	const unsigned char *data;
	unsigned char version;
	unsigned char reserved;
	unsigned char index1_first;
	unsigned char index1_last;
	unsigned char index2_first;
	unsigned char index2_last;
	unsigned char bits_index;
	unsigned char bits_width;
	unsigned char bits_height;
	unsigned char bits_xoffset;
	unsigned char bits_yoffset;
	unsigned char bits_delta;
	unsigned char line_space;
	unsigned char cap_height;
} ILI9341_t3_font_t;
*/
const ILI9341_t3_font_t heart_font = {
	heart_index,
	0,
	heart_data,
	1,
	0,
	0,
	0,
	0,
	0,
	13,
	5,
	5,
	3,
	4,
	5,
	24,
	22
};

#define HYSTERESIS_THRESH	(1000)
	// filtered signal is turned to square wave with 
	// hysteresis with thresholds +-HYSTERESIS_THRESH

#define DEFAULT_PERIOD	((int32_t) (60e6/70.)) // period for 70bpm

static volatile     int32_t x_0, x_1, x_2;
static volatile     int32_t y_0, y_1, y_2;

// filter parameters for biquad bandpass filter

// selected for approx 0.66--6Hz with 60Hz sampling
#define SAMPLE_FREQ	(60)	// sampling frequency in Hz
#define a0  (256)
#define a1  (-388)  
#define a2  (141) 


#define SAMPLE_PERIOD_USEC (1.e6/SAMPLE_FREQ)



#define gain (1)
 // b0= - b2= gain*a0
  // b1=0

#define DELAY_XY (x_2=x_1, x_1=x_0, y_2=y_1, y_1=y_0)
#define GENERAL_BANDPASS (y_0 =  ((gain*a0)*(x_0-x_2) -a1*y_1 -a2*y_2)/a0, DELAY_XY)

#define NUM_TIMESTAMPS (8)
volatile int32_t time_falling[NUM_TIMESTAMPS];	
	// time (from micros()) of last NUM_TIMESTAMPS falling edges
	// (may want to replace with circular buffer)

volatile int32_t num_edges_since_pulse_found=0;

volatile bool reported_edge=0;	// most recent edge has been reported in loop()

IntervalTimer sampler;

volatile uint16_t xloc;	// location of trace in x dimension
uint16_t old_xloc;    // old value of xloc, to detect change outside interrupt routine

volatile bool squared_pulse=0;	// square wave made from pulse signal
bool heart_displayed;  // current state of heart display

void one_sample(void)
{
    x_0=analogRead(MONITOR_PIN);
    GENERAL_BANDPASS;
    xloc++;
    if (xloc>=320) {xloc=0;}
    if (squared_pulse && y_0< -HYSTERESIS_THRESH) { squared_pulse =0; for (int i=NUM_TIMESTAMPS-1; i>0; i--)
	    {    time_falling[i]= time_falling[i-1];
	    }
	    time_falling[0]=micros();
	    reported_edge=0;  // new edge not reported yet
    }
    else if (!squared_pulse && y_0 > HYSTERESIS_THRESH)
    {   
        squared_pulse =1;
    }
}

// convert the timestamps in time_falling 
//	to periods and report the median of the
//	NUM_TIMESTAMPS-1 periods
int32_t median_period(void)
{
    int32_t periods[NUM_TIMESTAMPS-1];	// sorted array of periods 
    	// (increasing)
    
    for (int i=0; i<NUM_TIMESTAMPS-1; i++) { int32_t p=time_falling[i]-time_falling[i+1]; int j; // do a crude insertion sort, since list is so short for (j=i; j>0 && periods[j-1]>p; j--)
	{   periods[j] = periods[j-1];
	}
	periods[j] = p;
    }
    return (NUM_TIMESTAMPS%2)? 
    	(periods[NUM_TIMESTAMPS/2-1] +periods[NUM_TIMESTAMPS/2])/2:
	periods[NUM_TIMESTAMPS/2-1] ;
}

void draw_heart(bool red)
{   tft.setFont(heart_font);
    tft.setTextColor(red? ILI9341_RED: ILI9341_WHITE);
    tft.setCursor(5,5);
    tft.drawFontChar(0);
}

void clear_text(uint16_t x_start=40, uint16_t y_start=0, 
                uint16_t x_stop=319, uint16_t y_stop=60)
{
    tft.fillRect(x_start,y_start,x_stop,y_stop,ILI9341_WHITE);
    tft.setCursor(x_start,y_start+5);
    tft.setFont(Georgia_14_Bold);
    tft.setTextColor(ILI9341_BLACK);
}

void setup(void)
{
    tft.begin();
    tft.fillScreen(ILI9341_WHITE);
    tft.setTextSize(2);
    tft.setRotation(1); // Header pins are on the right.

    pinMode(MONITOR_PIN, INPUT);
    analogReadRes(16);
    analogReadAveraging(32);
    Serial.begin(115200);
    squared_pulse=0;
    for (int i=NUM_TIMESTAMPS-1; i>0; i--)
    {    time_falling[i]= 0;
    }
    num_edges_since_pulse_found=0;
    sampler.begin(one_sample, SAMPLE_PERIOD_USEC);
    
    heart_displayed=0;
    draw_heart(heart_displayed);
    old_xloc=xloc=0; 
}

void loop(void)
{
    if (Serial.available())
    {   char c= Serial.read();
    	if (c=='r')
	    {    setup();
	    }
    }

#define scale (512)

    if (xloc!=old_xloc)
    {   tft.drawFastVLine(xloc,75,240,ILI9341_WHITE);
    	int32_t low_y,height;
        if (y_0<y_2)
        {   low_y=(y_0/scale)+170;
            height = (y_2-y_0)/scale; 
        }
        else
        {   low_y=(y_2/scale)+170;
            height = (y_0-y_2)/scale; 
        }
        if (low_y<80) { height -= (80-low_y); low_y=80; } if (height>=0)
        {   tft.fillRect(xloc-1,low_y-1, 3, height+3, ILI9341_BLACK);
        }
        old_xloc=xloc;
        if (squared_pulse==heart_displayed)
        {   // update heart display
            heart_displayed = !squared_pulse;
        	draw_heart(heart_displayed);
        }
    }

    if (reported_edge) return;	// nothing new to report
    reported_edge=1;
    int32_t period = time_falling[0]-time_falling[1];
    
    if (period < 250000 || period > 3000000)
    {   clear_text();
        tft.setTextColor(ILI9341_RED);
        tft.println("PULSE LOST");
        tft.setCursor(40,25);
        tft.print("period=");
		tft.println(period);
	    num_edges_since_pulse_found = 0;
	    return;	// bogus short or long pulse (maybe should adjust hysteresis?)
    }

    num_edges_since_pulse_found ++;
    if (num_edges_since_pulse_found<=0)
    	num_edges_since_pulse_found=NUM_TIMESTAMPS;	// handle rare overflow
    if (num_edges_since_pulse_found<NUM_TIMESTAMPS)
    {	// report number more pulses needed
        clear_text();
        tft.setTextColor(ILI9341_RED);
        tft.println("PULSE LOST");
        tft.setCursor(40,25);
        tft.print(NUM_TIMESTAMPS-num_edges_since_pulse_found);
        tft.println(" pulses needed");
    	return;
    }
	
    int32_t mid_period = median_period();
    clear_text();
    tft.print(60e6/period,1); tft.println(" bpm");
    tft.setCursor(40,25);
    tft.print(60e6/mid_period,1); tft.println(" bpm (median)");
    
}

2016 March 25

Accepted for Mini Maker Faire

Filed under: Uncategorized — gasstationwithoutpumps @ 00:02
Tags: , , , ,

My application for the Santa Cruz Mini Maker Faire (mentioned in Santa Cruz Mini Maker Faire 2016Applying for Mini Maker FaireApplying for Mini Maker Faire round 2, and Applying for Mini Maker Faire round 3), was accepted this week.  I’ll have a 30″×72″ table to display on.

I’ve ordered a yard of 56″-wide “Performance Piqué” fabric, which is costing me $33, because I’m paying an extra $12 for faster processing (having dithered so long about the design).  That is, I’ve changed the design again, to something less busy:

 

Dr_K_banner_try2_622x400

The 150dpi image that I sent to Spoonflower was 7.7MB as a PNG file, which is not too large.  I’m curious to see how bad the gradient looks when printed on fabric.

I’ll have to spend some time once my son has gone back to college setting up the table in his room as the display table, to see how much stuff I can reasonably put in the display.  Here is what I’m currently thinking of:

  • A pulse monitor with a 2.8″ TFT display driven by a Teensy 3.1 board and using the op-amp protoboard with a transimpedance amplifier on it to amplify the phototransistor signal.  I got that working this week (not written up yet for the blog), but I’m still playing with other ways of mounting the LED and phototransistor, since the two ways I’ve tried so far are both subject to severe motion artifacts.  I need a way to immobilize the LED and phototransistor, but still move it quickly from person to person.
  • An analog oscilloscope with a pair of function generators, to show Lissajous figures (kids can adjust the frequency and amplitude of one of the function generators).
  • PteroDAQ running on my laptop and a Teensy LC board, with EKG and pressure-sensor input.  I’ll have to wear the EKG electrodes, but the blood pressure cuff can be set up separately.  I’m a little worried about being tethered to the EKG, and about the blood pressure cuff readings being a bit too hard to read in the raw PteroDAQ output—I normally have to bandpass filter to get the fluctuations and low-pass filter to get the corresponding pressure.  I may want to think about other things I could show with PteroDAQ.
  • Bitscope and microphone preamplifier?
  • Desk lamp using LED boards
  • Strobe using LED boards  (which reminds me—I wanted to put together a program which could switch between dimmer and strobe functions with a single shorting jumper).
  • Tool display? (soldering iron, board holder, multimeter, flush cutters, …)
  • Business cards for my book (designed, but not ordered yet)
  • Handout with book and blog information (not designed yet—probably will be quarter-page to keep printing costs down)

If anyone has other ideas for stuff I should do, I still have a little time to put something together, but classes start next week and I’ll be putting in full time on the Applied Electronics course, so it can’t be anything complicated (unless I already have it soldered up on a board).  I’ve also dedicated both my Teensy boards (for the pulse monitor and PteroDAQ), so I’d have to do things with either an Arduino or the FRDM KL25Z board.

 

Next Page »

Blog at WordPress.com.

%d bloggers like this: