Last minute: Oscilloscope workshop 17 maart (morgen!)

Een last minute aankondiging van een workshop die ik ga geven:

Tkkrlab: Meten is zweten; Oscilloscope basics
za, mrt 17, 2012, 14:00 – 17:00
TkkrLab, Kloosterstraat 1, Enschede
Met een oscilloscope kan je zien hoe signalen er uit zien in een elektrische schakeling. Maar hoe werkt zo’n ding nou?
In deze workshop wordt aan de hand van een beetje theorie en veel (voor)doen uitgelegd wat de functies zijn die je op een oscilloscope kunt bedienen, hoe je signalen goed kunt bekijken en wat de verschillen zijn tussen een digitale en een analoge scope.
Het eerste deel is presentatie, het tweede deel ‘hands-on’.
Wanneer je zelf een scope hebt is het leuk die mee te nemen; je kan dan oefenen op je eigen scope, en het is interessant om de scopes onderling te vergelijken!

Follow-up

Voor deze bijeenkomst een poster met uitleg over oscilloscope bediening gemaakt, en hieronder een plaatje van alle scopes bijelkaar!

Scopes van 1960(?) tot 2006

Treindraaiklok

Summary

This is a summary of a clock I built. Some years ago I bought some digits from an old NS (Dutch Railways) clock. These resided in a cardboard box for a long time waiting to be changed into a working clock. The digits consist of two cylinders transporting a plastic coated cloth with printed digits. On top of each digit a gear is placed that converts the plane of rotation, and provides the mechanical interface to the old host, the railway sign.
I wanted to make a clock, with as little modifications to the original as possible. Also, I liked the idea of being able to place the digits in free order, not necessarily HH:MM, or at equal distances from each other. Just to make it easy to change their place in my interior, or to make the readout more interesting.
In previous projects, I used MSP430 or AVR xMega processors with the GCC compiler. For this project, I decided to use an Arduino. I heard so many good stories about it (as member of Hackerspace Tkkrlab)that I thought it would be good to try some Arduino programming myself. I’ll write my experience down below.

Drive Train

Gears

Broken...

Method to drive out wedge

Grinded down spike as tool

All four unmodded digits

The original gearing provided a big toothed wheel on the outside of the digit to the drive shaft of the complete sign. I wanted to mount a small motor on top of the digit, with as little new parts as possible. The gearing as present on the digit provided one big advantage: one rotation of the drive axle meant moving the roll one digit further / back!
To interface with the drive axle, I wanted to use the original gears, but driving the main axle (on back side) from another angle. To do this, I had to remove the lateral axle. All gears were fixed with cotters / wedges which were pretty much stuck. Other members of Tkkrlab helped me by creating a beatiful but simple tool to remove the cotters: a nail which was ground down! It provided the right diameter, and a good interface to a hammer! With aid of this tool I was able to remove 3 out of 4 axles without damage, the fourth was broken, unfortunately.

Servo’s

To rotate the digits I wanted to have a simple motor construction. Years ago I looked into driving the digits with rubber tracks and a huge motor with gearing, but it became too bulky to be nice. When looking for a simple, small solution I found the ‘continuous rotational servo’ from Parallax. I ordered one to try it, but the first test immediately showed that it was way too sensitive for input PWM change, there was a minimal range over which the speed could be changed, and the ‘center’ trimming was also VERY sensitive. This might be OK for an R/C vehicle, but not for a clock that should be able to run unattended for a long time. A second issue I had with this servo is that it is VERY noisy. The sound resembles the screaming of a young pig, which is not the sound I’d like my clock to have.

First test continuous rotational servo

When taking a look in the parallax servo there’s just a normal servo controller, without potmeter to determine the position of the end axle, and no end stop on the (plastic) gears. I decided to buy servo’s with metal gears and ended up (budget servo with good ratings) with the MG995 servo from DealExtreme. These servos have metal gears, and I found them very easy to modify. See end pin modification below:

MG995 Tower Pro

Servo electronics + motor

End pin in gears

End pin removed

The bevel gear I removed from one of the axles had to be mounted to the servo. The hole in the bevel gear was a bit larger than the radius of the output axle of the servo. I found a bit of aluminium tubing in the local R/C store, which fit loosely over the output axle, and snug in the bevel gear. Using some bison glue I was able to join these parts together. I used the original cotters to secure the bevel gear to the aluminium tube.

Driving the servos

With a ‘normal’ servo hack (removing end pin, replacing potmeter with fixed resistor divider) there is very little room for speed control. I wanted to have some form of speed control, as I already found out with the parallax servo that slower speed equals less noise from the gears. Normally you’d use an H-bridge driver for something like this, but I didn’t feel like doing that for several reasons:

  • I wanted to try the Arduino environment, and Arduino ‘AnalogWrite’ means PWM of circa 490Hz. I didn’t want a ‘singing’ tone from my motors, and 490Hz lies well within hearing range.
  • The motor is supposed to run in two directions, and I had very little room to cramp a full bridge driver
  • Digital control would mean a PWM and a direction line. I had some very nice old telephone cable lying around with 4 conductors, of which I wanted to use GND, Power, PositionDetection (sense when complete digit is transported), and 1 line for motor control

In the end I came up with this schematic (click for readable version):

Explanation: R1&R2 form a divider to half the supply voltage. A1B buffers this voltage. When the input is disconnected, the motor will halt, as R4 keeps the input of A1A (also buffering) on the same half-supply-voltage. R3&C1 form a lowpass filter for the PWM signal. If an input is connected, the difference between M1&M2 motor connections can only get as large as plus or minus half the supply voltage. Result: 5V in gives full throttle forward (+2.5 V over motor), 0V in is full throttle reverse (-2.5V over motor), 50% PWM will make the motor stop as there will be (almost) no difference between the input voltage and the divider voltage. THe opamp I used for this circuit is a TCA0372 because of its high current rating and single supply operation. The input and output are not completely rail-to-rail, thus limiting the control range a bit further, but it still functions as wished for.
Using the circuit above I was able to fit the new driver into the housing of the servo’s; this made me very happy since I didn’t like the idea of dangling motor drivers and / or bunches of wires all around the digits. See the ‘layout’ of the board below.

mounting of electronix (ex wires) in servo housing

mounting of electronix (ex wires) in servo housing

Servo motor driver, component side

Servo motor driver, solder side

Servo mounting

To mount the servos to the digits I used a piece of angled aluminium. Slits were sawn in the places where the servos needed to be mounted, and I was able to mount the servo holder to the original screws on top of the digits. The gears were glued on a piece of aluminium tube that fit snug over the output wheel of the servo and into the plastic gear. I used some 2-component glue to fix the tube to the servo output shaft.

Position feedback

Now I was able to drive the digits from the arduino board, I had to know when to start / stop driving the digits. One of the first things I noticed when looking at these digits with the intention of making a clock was that one turn of the cogged wheels / axles converges to moving a digit one step forward or back. So what I needed was a way to detect when the axle had made one full turn. Several ways sprang to mind here; use reed switches, hall sensors, optical sensors (ripped from an old mouse?), microswitch,….
I chose to use a small neodynium magnet, orderable at Farnell in combination with reed switches. The Atmega pins of the Arduino can provide a pullup, I just needed a switch to pull these pins down. I must admit I first bought some Hall sensors, but the look of these just couldn’t please me, and adjusting there position to get a good readout would mean fiddling / bending their pins, not something to yield a nice result to look at. Reed switches might bounce a bit, but that’s no problem in this clock. The ‘pro’ of the reed switches was that they look vintage (matching the clock), and through the glass tube you have an immediate look at the effect of magnet position on your contacts.
To mount the magnets I made a small pocket in each gear wheel glued to the servos. The tricky part here, is that the metal gears in the servos attract the magnets, so they tend to fly out of their pocket while the glue is curing. I prevented this using cocktail sticks and matches (see pictures below). The magnets are really great,for some servos the magnet-to-reed distance is >3mm, and still they manage to reliably trigger the reed. I fiddled quite a lot with the reed’s position, finding out that the end of the reed switch is more sensitive than the middle.

Magnets

Pocket for magnet

Match stick holding the pressure

Match stick holding the pressure

Top view of gluing setup

Result: glued magnet

Magnet and reed switch, final assembly

Arduino & Proto Shield

Until now I used the Arduino by sticking wires into the sockets of the Arduino, I found the time had come to make a more permanent solution. I wanted to use a real time clock (RTC) to not have to set the time after power outages or maintenance, and to and minimize clock drift. My first solution was to use a piece of proto board, but as many have found out the pitch between two of the four connectors of the Arduino is NOT 2.54mm….. Also, I found my own protoboard a bit clumsy-looking and it was mechanically unstable so I decided to go Arduino-solution-style all the way and bought the Olimex Arduino Proto Shield.

Side by side, old and new

Hand soldered board

?Que Pasa?

Olimex proto shield

Detail; switch and small power vias

Protoshield

The protoshield was a great benefit for this project. It has several features really helping out; 2 buttons, a LEDs and several places to connect wires for GND and… 3V3! This made me wonder a bit; I designed everything for 5V, thought the voltage most used in projects was 5V and now I find out that this board is using 3V3 as standard? Interesting…. One of the features of this board is that it has small vias between the proto grid that provide GND and 3V3 connectivity all over the board. Very handy most of the time (also for decoupling), but selection of ‘VCC’ between 3V3 or 5V would have been appreciated…..
Something else that surprised me is that two pins protruded from the board and touched the electrolytic caps from the Uno. I clipped them 😉

Arduino

I never used an Arduino before, always wrote my own code from scratch. I heard a lot of people being enthousiastic about the Arduino, and thought this project would be a great test case; no strict millisecond timing requests, simple IO, a few PWM lines. So I started out on the Arduino, and found out it does not suit my needs in a complete project. For prototyping this is a great product, and for starters in electronics this is also quite a good start, but before I’ll write my positive experience I have to point out some drawbacks:

  • Documentation is quite good for starters, but not if you’d like to know what is REALLY happening; what is the I2C bitrate? Is the SerialWrite function interrupt based, or blocking? This info is probably around somewhere on the web, but not in the reference
  • The IDE does not provide code completion
  • Why do I have to call two functions that write AVR registers to make a pin tristate with pullup? I’d think that that should have been an good addition to the language
  • To unlock the power of the ATMEGA you’d be writing your good old programs; PWM (incorrectly named analog output) is ‘around’ 490 Hz and frequency is not settable by standard Arduino functions, which would have been an improvement both in functionality as in programmability
  • I’m afraid the ‘simpleness’ of the Arduino environment lets people create solutions that waste processor (peripheral) power. It’s a bit like writing LabView code: it’s very easy to get a simple thing going, but for a GOOD program that gets a bit more complex you have to be able to use programming techniques, something not really developed by using Arduino

I guess I’d start a new project writing code from scratch, IF it is to be used for a permanent solution. The big benefits of Arduino I see in:

  • Easy implementation of external IC’s. I did NOT have to look into the DS1307 datasheet except for the pinout when soldering. That’s cool! Chip demo’s can easily be made
  • Debugging by sending messages is really easy. Although I still wonder if sending a long string blocks all my other code
  • Making simple projects that are allowed to be completely messy is wonderful using the Arduino.
  • Using the results of other people’s projects to get something working fast!

The clock works by letting the user run all rolls to start position at startup. After that, one digit is turned at a time to the position needed as dictated by the DS1307. Several time limits are used to ensure the roll is moving, and is not broken by continuous pulling; when a magnet is not detected in several seconds, the clock just stops. Not elegant, but better safe than sorry. Programming / change of time is done by programming the Arduino. Time adjustment by using the buttons is on my whish / to do list.

First test run

First test run. Can you spot this was at the end of the year 😉 ?

Noise!

Now, after the first test run the clock ran for several days in my living room. It really looks great, but it was quite noisy, especially when one of the rolls needs to roll all the way back. I thought something like a bell jar would solve this, and started looking around for these items. I found most of them were quite expensive ( > EUR 50 each), and buying four of them would ruin my budget and fun.
Looking around in the post-christmas sale at the Intratuin (gardening warehouse) I found a vase that had just the right dimensions to fit over a digit. I took 4 of them home for a total of EUR 16! The vase had the right diameter, but was a bit high. I used PVC end caps for sewage pipes to raise the digits. To let the cable exit I bought a glass engraving Dremel bit, and ground away an opening. Exciting to do!

Cable exit

Grinded cable slot

Preparation and grinded cable slot

The vases do a wonderful job muffling the servo sound!

Housing Electronics

At last, the end is near….. I made a small housing for the electronics, using ugly DIN connectors to get a good retro feeling.

Internal cabling, protoshield, Arduino

Housing with connectors and switch

Finished digits

Side

Front

back

Evaluation

One of the things that cost me some time is to use speed control; in the end I didn’t use it, I just go ‘full throttle’ back or forward. Full throttle means the servo motor is driven by circa 2,5 Volts, which is slow enough for not making a lot of noise. But at least I’ve got the opportunity to scale the speed, maybe someone else can use the circuit with all its capabillities…..
The clock has been running for a week or so by now, and its a pleasure to the eye, and a real conversation starter!

Arduino code

Available for download here

#include <Wire.h>
#include "RTClib.h"

#define BUT_SET         6
#define BUT_OK          7

#define SPEED_STOP 127
#define SPEED_FWD  255
#define SPEED_BACK 0

#define MIN_UNITS_SPEED 3
#define MIN_TENS__SPEED 5
#define HRS_UNITS_SPEED 9
#define HRS_TENS__SPEED 10
#define MIN_UNITS_POS   2
#define MIN_TENS__POS   4
#define HRS_UNITS_POS   8
#define HRS_TENS__POS   12

RTC_DS1307 RTC;
unsigned char min_units = 0;
unsigned char min_tens  = 0;
unsigned char hrs_units = 0;
unsigned char hrs_tens  = 0;

void FindStartPos(char speedpin, char positionpin)
{
  while(digitalRead(BUT_OK) == HIGH);
  while(digitalRead(BUT_OK)  == LOW);
  while(digitalRead(BUT_OK) == HIGH)  
  {
    analogWrite(speedpin, SPEED_BACK);
    delay(100);
  }  
  analogWrite(speedpin, SPEED_FWD);
  while(digitalRead(positionpin) == HIGH);
  analogWrite(speedpin, SPEED_STOP);
}

struct roll
{
  unsigned char numbers[10];
  unsigned char length;
};

struct roll min_units_roll = {{1,2,3,4,5,6,7,8,9,0},10};
struct roll min_tens__roll = {{0,9,8,7,6,5,4,3,2,1},10};
struct roll hrs_units_roll = {{0,9,8,7,6,5,4,3,2,1},10};
struct roll hrs_tens__roll = {{1,2,0},3};

unsigned char search_roll(char to_be_number, unsigned char *current_number , struct roll *roll_p)
{
  char count;
  char number_current_index;
  Serial.print("|SR. To be number: ");
  Serial.print(to_be_number, DEC);
  Serial.print(";");
  Serial.print("|SR. current number: ");
  Serial.print(*current_number, DEC);
  Serial.print(";");
  //stop if nothing has to be done
  if( *current_number == to_be_number )
    return SPEED_STOP;
  //find current position on roll
  for(count = 0; count < (roll_p->length) ; count++)
  {
    number_current_index = count;
    Serial.print(number_current_index,DEC);
    if(roll_p->numbers[count] == *current_number)
      break;
  }
  //min_units_current_index gives index to value of current position
  Serial.print(number_current_index, DEC);
  //See if new digit is placed before old digit on roll
  for(count = 0 ; count < number_current_index ; count++ )
  {
    //if so, update min_units (in advance!) and give direction to turn
    if(roll_p->numbers[count] == to_be_number)
    {
      *current_number = roll_p->numbers[--number_current_index];
      Serial.print("; back, min_units: ");
      Serial.print(*current_number, DEC);
      return SPEED_BACK;
    }
  }
  //otherwise, turn other way
  *current_number = roll_p->numbers[++number_current_index];
  Serial.print("; forward, min_units: ");
  Serial.print(*current_number, DEC);
  return SPEED_FWD;
}

char movestep( unsigned char speed, char speedpin, char positionpin)
{
  int loopcounter;
  analogWrite(speedpin, speed);
  for(loopcounter = 0; loopcounter < 3   ; loopcounter++)
  {
     delay(300);
     if(digitalRead(positionpin) == HIGH)
       break;         
  }
  for(loopcounter = 0; loopcounter < 300 ; loopcounter++)
  {
    delay(50);
    if(digitalRead(positionpin) == LOW)
      break;  
  }
  analogWrite(speedpin, SPEED_STOP);
  if(loopcounter > 250)
    return(1);
  else
    return(0);
 }
 
void setup()
{
  pinMode(HRS_UNITS_SPEED,OUTPUT);
  pinMode(HRS_TENS__SPEED,OUTPUT);
  pinMode(MIN_UNITS_SPEED,OUTPUT);
  pinMode(MIN_TENS__SPEED,OUTPUT);
  analogWrite(HRS_UNITS_SPEED,SPEED_STOP);
  analogWrite(HRS_TENS__SPEED,SPEED_STOP);
  analogWrite(MIN_UNITS_SPEED,SPEED_STOP);
  analogWrite(MIN_TENS__SPEED,SPEED_STOP);
  pinMode(HRS_UNITS_POS,INPUT);
  pinMode(HRS_TENS__POS,INPUT);
  pinMode(MIN_UNITS_POS,INPUT);
  pinMode(MIN_TENS__POS,INPUT);
  digitalWrite(HRS_UNITS_POS, HIGH);
  digitalWrite(HRS_TENS__POS, HIGH);
  digitalWrite(MIN_UNITS_POS, HIGH);
  digitalWrite(MIN_TENS__POS, HIGH);
  pinMode(BUT_SET,INPUT);
  pinMode(BUT_OK ,INPUT);
  Serial.begin(57600);
  Wire.begin();
  RTC.begin();
  if(!RTC.isrunning())
  {
    Serial.println("RTC is not running!");
    RTC.adjust(DateTime(__DATE__, __TIME__));
  }
  FindStartPos(HRS_TENS__SPEED, HRS_TENS__POS);
  FindStartPos(HRS_UNITS_SPEED, HRS_UNITS_POS);
  hrs_units = hrs_units_roll.numbers[0];
  hrs_tens  = hrs_tens__roll.numbers[0];
  FindStartPos(MIN_TENS__SPEED, MIN_TENS__POS);
  FindStartPos(MIN_UNITS_SPEED, MIN_UNITS_POS);
  min_units = min_units_roll.numbers[0];
  min_tens  = min_tens__roll.numbers[0];
}


void loop()
{
  int incoming;
  char minuteunits,minutetens,hrstens,hrsunits;
  char error;
  DateTime now = RTC.now();
  Serial.print("|main. now:");
  Serial.print(now.minute(), DEC);
  Serial.println();
  delay(1000);
  minuteunits = now.minute() % 10;
  minutetens  = now.minute() / 10;
  hrsunits    = now.hour() % 10;
  hrstens     = now.hour() / 10;

  Serial.print("|main. min_units:");
  Serial.print(min_units, DEC);
  if( minuteunits != min_units)
  {
    error = movestep(search_roll( minuteunits, &amp;amp;amp;amp;min_units, &amp;amp;amp;amp;min_units_roll), MIN_UNITS_SPEED, MIN_UNITS_POS);
    if(error)
      setup();
  }
  if( minutetens != min_tens)
  {
    error = movestep(search_roll( minutetens, &amp;amp;amp;amp;min_tens, &amp;amp;amp;amp;min_tens__roll), MIN_TENS__SPEED, MIN_TENS__POS);
    if(error)
      setup();
  }
  if( hrsunits != hrs_units)
  {
    error = movestep(search_roll( hrsunits, &amp;amp;amp;amp;hrs_units, &amp;amp;amp;amp;hrs_units_roll), HRS_UNITS_SPEED, HRS_UNITS_POS);
    if(error)
      setup();
  }
  if( hrstens != hrs_tens)
  {
    error = movestep(search_roll( hrstens, &amp;amp;amp;amp;hrs_tens, &amp;amp;amp;amp;hrs_tens__roll), HRS_TENS__SPEED, HRS_TENS__POS);
    if(error)
      setup();
  }
}

Adding a middle mouse button to a Kensington Orbit

To Orbit or not to orbit

As a christmas gift from my employer I got a very nice mouse, the Kensington Orbit. I really liked having a trackball mouse again, in the past I’ve had several Logitech trackball / mice that helped me solve RSI problems. The reason I liked having one now is that I’m frequently drawing in Google Sketchup and / or Solidworks. I liked the idea of rotating a physical object (the ball in the mouse) to manipulate the object on the screen.

Middle mouse button!

The Kensington Orbit has a ‘scrolling ring’ and two mouse buttons, but lacks a third mouse button. That last button is extremely comfortable when using 3D CAD programs as it allows you to orbit your object while performing another task at the same time. Confusing enough, the Kensington Orbit cannot be used to orbit by mouse….

..have..to…press..middle…mouse…button….

OK. This one might have gone too far, but I REALLY wanted that middle mouse button. To go short, I added a Konig mini USB hub, and the controller of another mouse inside the original housing to add the functionality I wanted.
Description:

  • Konig Mini USB hub, removed housing and desoldered the USB connectors to make space available
  • Cypress CP6238 controller desoldered from a logitech mouse, only to use the USB lines and the middle mouse line.
  • Original mouse electronics and USB cable, but removed connector from incoming USB cable and soldered the lines directly to the USB hub. One of the USB hub ports now feeds the original electronics

What did I try that did not work?

I had several other options in mind before I used the one described above:

  • Remove original electronics and use only donor mouse parts.
    • Pro: USB hub not needed
    • Con: the Orbit uses a Allegro A505 optical chip, the donor mice I had lying around were all using other (less sophisticated) optical chips. Interfacing would be very hard.
  • Use original microcontroller
    • Pro: no other hardware needed
    • Con: The original microcontroller (also Cypress, but now the CY7C63813) can probably be flashed, but I didn’t feel like finding out what compiler to use, creating a build environment, etc. I also tried checking unused pins for pull-ups by touching them with 10k to GND (first checked voltage level on left & right mouse button to see what could be expected), but could not find an unused ‘middle mouse button’ pin.

Pictures

Terminal Proof

user@t61 ~ $ lsusb
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 002 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 003 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 004 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 005 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 006 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 007 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 003 Device 003: ID 0483:2016 SGS Thomson Microelectronics Fingerprint Reader
user@t61 ~ $ lsusb
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 002 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 003 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 004 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 005 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 006 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 007 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 003 Device 003: ID 0483:2016 SGS Thomson Microelectronics Fingerprint Reader
Bus 001 Device 011: ID 058f:6254 Alcor Micro Corp. USB Hub
Bus 001 Device 012: ID 047d:2048 Kensington 
Bus 001 Device 013: ID 046d:c03f Logitech, Inc. M-BT85 [UltraX Optical Mouse]
user@t61 ~ $ 

Modify Trust Mila 2.0 USB speakers / Deadbug QFN

Edited:see ‘update’ below for bonus features!

Recently I got a present for Sinterklaas, a USB audio set. I asked for this as I like watching movies from my laptop, but hate the hassle of cables that surround my previous set. Also, my 3,5 year old son popped the tweeters of the old setup by pushing the nice shiny conus….

So I got the….

Trust Mila 2.0

Trust Mila 2.0 speakers

This system is really easy in use: just use USB for power and the audio jack for the sound. Although I was glad to have a working audio setup again I had a few nuisances with this product:

  • No audio-> lots of noise. The volume control controls input volume, but all the noise on the speaker is apparently coming from the output stage, as it’s VERY noisy.
  • Overall sound quality is flaky. It sounds very thin. I got the impression that better performance might be possible
  • VERY bright blue LED

Other power amp

I opened up the speaker containing the amplifier, and found the PCB shown in the image.

Original Electronics


I couldn’t find the datasheet of the amplifier, and thought little improvement could be made to this circuit. I went looking for a replacement amp. The criteria were:

  • 4.5 to 5.5 V supply voltage
  • More than 1.5W audio power
  • Minimal external parts count
  • Able to drive 4 Ohm
  • Easy to obtain

On the site of maxim I found the MAX9759. It matched my requirements, and I could sample it. Hooray!

Soldering

The MAX9759 is a 16-lead TQFN, which means it has no legs like a DIL or TQFP IC. I took a deep breath, and soldered it ‘deadbug style’:

Dead bug QFN 'right'

Dead bug soldering QFN 'left'

Dead bug soldering QFN 'left'

This took about 2 hours a piece, I used a normal soldering station, and yes, you can debate if it would have been faster to etch my own PCB. I used the circuit as described on page 9 of the datasheet with maximum gain (G1 and G2 both grounded). The result is a major improvement:

  • The speakers sound LOTS better, with less noise. I included a video (shot with a normal still camera) in this post which gives a hint of the difference in sound quality.
  • The amplifier IC’s do not get noticeably warm
  • Removing the original PCB also removes the irritating blue LED

Finally, when everything was working I added a BIG blob of epoxy glue to fix all wires. When mounting all components I shortened the wires to match the size of my laptop.

Ready to fix circuit

Final considerations

USB soundcard

I thought about using a USB soundcard I purchased for $2 at DealExtreme some time ago. That way, I’d only have a USB connection to my speakers. I decided not to do that, as that would mean switching soundcards every time I’d plug in speakers. Also, I can use them to play other sources now.

Quality

How, ON EARTH can it be cheaper / better for Trust to use this crappy amplifier board with lots of components whereas the budgetary price of the Maxim IC is USD 0.75 at 1000 pieces? I know Trust is known for making decisions based on cost, but this is quite baffling for me. Is can’t be that much cheaper to place and purchase so many through hole components. This does not make sense to me….

Demo video

http://vimeo.com/33724857

Update


After using the modified speakers for some weeks I still found the wires too messy. Also, the sound output from my laptop gives a bit of a buzz when my harddisk is busy. Bad design Acer! I had a $2,80 usb soundcard lying around and decided to build that into the speaker housing. Now I’ve got true USB speakers, with power AND sound over USB. They’ve been in use for some weeks, and I’m very happy with the result.

Yes, it's a mess on my desk. Glue gun warming up.

PCB of soundcard visible on the left

Hein Hacks

Hein Hack One – Xenon Flash
Hein Hack Two – Halloween / Birthday special
Hein Hack One AND Two – Video

At my job, an anatomical model of a skeleton stands in front of the window facing the corridor. The Dutch name for Grim Death is “Magere Hein”, so the skeleton was aptly named “Hein” (also a common Dutch name). Since a skeleton standing alone on its pedestral is deadly boring (pun inteded), Hein was given a birthday (Halloween), and is dressed up occasionally to reflect the current season, his birthday, or dressed in orange to support the Dutch soccer team. He’s even got something I haven’t got: a Facebook page!

Hein Hack One

View to Hein from the corridor


The first hack is something created to celebrate summer / holidays! Hein had been standing watching the corridors for some months, and we thought we saw a twinkle in his eye socket when the first summer sun rays entered our office. What better occasion to give him a real summer outfit?
With a really cool Hawaii shirt, flipflops and the coolest sunglasses ever Hein was ready for the summer… Wasn’t he? What he really needed was something to remember these beautiful days, put it in his memoires. He needs a point and shoot camera!

Flash!

For quite some time I had the idea of making something interactive with Hein, reacting on the people passing by. Our corridor is a busy traffic route, and due to the dressing up many people keep an eye out for Hein.
When Tkkrlab, the local hacker/makerspace was moving I could confiscate one of the old infrared movement sensors from the -soon to be destructed- building. I thought it would be quite a joke to make Hein flash a disposable camera when someone would be passing him by from a small distance. I set out buying a 4€ disposable camera and tried to figure out how to connect that to the PIR sensor.

PIR Sensor

The PIR sensor I got was a very old type, but had very simple connections: power supply should be in the 12V range, detection of movement was indicated by opening a relay connection. The normally closed relay contacts were both available on a terminal block.

Camera

Now to the hairy work: getting the camera triggered. The camera I had bought works as follows: when you would like to make a picture with flash, you need to press a button on the front of the camera until a small (neon) light starts flashing. When you trigger the camera, the flash is turned on. I had been searching on how the circuit was working for some time when I found this marvelous site on xenon flash circuits in disposable cameras. The first schematic on the site is equal to what I found in my camera. The circumstances for the trigger circuit were:

  • The PIR sensor gives pulses between 1 and ….(?) seconds, as long as movement is present
  • The PIR sensor relay is not able to switch the normal ‘trigger’ connections since the voltage across the terminals is circa 300VDC
  • The flash circuit is quite sensitive to changes. As it is a resonant circuit, adding components in the circuit changes the frequency of pulsing, resulting in lower output voltages or very irritating audible whining. Hein is standing in my office, so whining should be minimised 😉
  • This is one of the dirtiest hacks I’ve done, circuit wise. All values are based on availability in my shelves, all component choices as well

Modified Xenon Flash Circuit

Modified camera circuit. Click for PDF


See the PDF linked to by the image on the left to see the camera schematic with the added components. All components that are not original to the camera itself are colored red. A small description:

  • An SCR (12TTS08) was used to trigger the flash. I also tried using a TRIAC, but could not get it to work reliably.
  • The trigger signal is tied to GND when noone is ‘seen’ by the sensor, and is 5V with 100 Ohms in series when the sensor does see movement

  • To limit the length of the trigger pulse (prevent continuous turn on after first trigger) the diode / capacitor circuit was used.
  • The FET in the lower left corner was a start on making the unit stop charging when -300V was built up on the main capacitor (eliminate whining). I intended using (a multiple of) zeners for this. As it turned out, adding the FET changed the efficiency of the charging circuit, and resonance frequency shot over the audible range. A bit good is good enough in this case….

Pictures of modification

Pictures were made during disassembly, so do this in reverse if you’d like to make the same thing 😉

Practical issues

PIR sensor mounting, cardboard flap limits view angle


At home, I finished the complete project, working satisfactory. I planned on placing the camera in Heins hands, and placing the sensor on a cabinet next to him, viewing the corridor. Unfortunately, this did NOT work. Glass blocks the infrared radiation which is used by the PIR sensor! With the help of colleagues we mounted the sensor between the piping in the corridor. A cardboard flap was used to limit the viewing angle of the sensor, so people who already know this gadget have the choice to walk by unblinded. 

Pictures of Hein

Reactions

  • I think about 50% of passers by don’t notice what happens / does not register flash as a strange thing
  • Those who do register start laughing 3 meters past the office, very funny to see this reaction time
  • Some people wonder what we do with the pictures. Since the camera is emptied out to make room for electronics, no pictures are taken. This generally ends up in a discussion on how to make use of a webcam, and/or a discussion on privacy

Hein Hack Two

Hein’s birthday was pinpointed to be on the 31st of october, aka Halloween. It seemed very nice to me to change Heins camera for something more appropriate.

Pressurize!

What belongs to a birthday? A blowout whistle! Inspired by this T-shirt cannon I thought I could make something comparable on a smaller scale. Although pressurized air generally is a very weak solution for pneumatics (CO2 cartridges keep pressurized longer because part of the CO2 is still in liquid phase) a blowout whistle does not need much air to inflate, and using a bicycle pump would make this a simple solution!

I used standard PVC piping which is NOT meant to be pressurized, so replicate at own risk…. To pressurize, I inserted a standard bike valve from a punctured inner tube which I glued with generous amounts of Bison
Kombi Power
. End caps were also glued on, in one of the endcaps I placed a 1/2″ adapter on which I screwed a cheap valve. I drilled out the orifice to 2.4mm to allow a bit more air to pass per unit time.
The other end of the valve was fitted with a 1/2″ adapter that was modified to a Pneufit connection for a standard pneumatic tube.


Hein with blowout whistle

Control

The completed pressure tank with valve was working as intended. Only a very short pulse to the valve would inflate the whistle (the flow is too small to let it actually sound a whistle, which is OK by me). The PIR sensor used gives longer pulses, and sometimes more after each other. I thought it would be nice if the pulse duration could be fixed, and some fixed time of inactivity / insensitivity of Hein could be devised.
Recently, I ordered an TI MSP430 Launchpad, and this would be a nice starter project. I installed the linux build environment, used pin interrupts and the 16-bit timer and got a very nice 16 whistle blows on 6 times pumping 😉

setup

– Bicycle pump to pressure tank
– MSP430 board is fed by 5V supply (coming from PIR sensor) regulated to 3V3 by TS1117
– Trigger signal is pulls down P1.3 (also connected to onboard switch) throught NPN transistor
– Valve is supplied by external supply, P1.0 from the MSP430 (also connected to LED) is switching the supply on or off through a power BJT (TIP120)
– Diode is placed over valve connections to prevent coil voltage damaging other circuitry.
– Blowout whistle is connected to tube with glue-lined shrink tubing

Silent video of effects

Sorry, I just didn’t have time to make something really flashy in a movie editor. I just wanted to show the effects.

Sourcecode for MSP430

#include <io.h>
#include <signal.h>
#include <stdlib.h>
#include <inttypes.h>

#define SW_PIN     BIT3
#define VALVE_PIN  BIT0
//delay in ms to keep relay open
#define DELAY_MS   50
//minimum amount of cycles to run before new trigger is processed
#define MIN_DELAY_CYCLES 100
#define MAX_DELAY_CYCLES 255

#define DELAY_CTR  (DELAY_MS/1000.0)*12000.0


volatile uint16_t delaycounter;

int main(void) {
// Stop WDT
  WDTCTL = WDTPW + WDTHOLD;	
//Enable LED / valve output
  P1DIR |=   VALVE_PIN;
  delaycounter = 0;
//SW is input
  P1DIR &amp;amp;amp;= ~(SW_PIN);
//SW pull up
  P1OUT |=   SW_PIN ;
//EN pullup
  P1REN |=   SW_PIN ;
//configure pin interrupt
  P1IES |=   SW_PIN ; //low-to-high transition
  P1IE  |=   SW_PIN ; //enable pin change interrupt
  BCSCTL3 |= LFXT1S_2;	//Set ACLK to use internal VLO (12 kHz clock)

  TACTL = TASSEL__ACLK | MC__UP;	//Set TimerA to use auxiliary clock in UP mode
  TACCTL0 = CCIE;	//Enable the interrupt for TACCR0 match

  WRITE_SR(GIE);	//Enable global interrupts

  while(1) {
	//Loop forever, interrupts take care of the rest
  }
}

interrupt(TIMERA0_VECTOR) TIMERA0_ISR(void) {
  //Clear Valve Pin
  P1OUT &amp;amp;amp;=  ~(VALVE_PIN);
  delaycounter --;
  if(delaycounter == 0)
  {
    //Stop counter
    TACCR0   =     0;
    //Clear interrupt flag for pin
    P1IFG &amp;amp;amp;= ~(SW_PIN) ;
    //enable interrupt on pin
    P1IE  |=   SW_PIN ;
  }
}

interrupt(PORT1_VECTOR) PORT1_ISR(void)
{
  uint16_t randomnumber;
//clear interrupt flag
  P1IFG &amp;amp;amp;= ~(SW_PIN) ;
//disable pin change interrupt
  P1IE  &amp;amp;amp;= ~(SW_PIN) ;
//clear LED
  P1OUT |=   VALVE_PIN  ;
//Let counter run 200ms
  TACCR0   = DELAY_CTR;
  randomnumber = rand();
  delaycounter =  MIN_DELAY_CYCLES + (randomnumber % (MAX_DELAY_CYCLES-MIN_DELAY_CYCLES));
}