For soldering electronic components I use a Tenma 21-10130 rework station, this is a rebadged Chinese model sold by Farnells under their own brand name it has a soldering iron and hot air station combined in the same box, for me it works well, does the job and is considerably cheaper than those from Hakko or Weller.
Tenma 21-10130 Rework Station
The only real problem are the controls, five small fiddly buttons on the front panel, something that appears to be common on all these ‘budget’ stations, while the temperature on the soldering iron only needs changing infrequently, the hot air temperature and flow need to be adjusted more regularly. I guess the manufacturers preference for buttons is to make the machine cheaper to produce.
Under The Cover
Removing the lid reveals the air pump, sundry tubes, a large control board and a fantastic selection of wires to discourage taking the whole thing properly to bits.
Inside the Rework Station
The onboard microcontroller is a PIC16F916, this is a 28 pin 8-bit 20MHz controller with 14Kb of program memory, 24 I/O pins and an integrated LCD driver.
PIC16F916 pinout
Fortunately the connections for the front panel buttons can be just about reached with multimeter probes, and with the mains power disconnected, I was able to buzz out each switch and find where it went to on the PIC controller.
Button Connections
26
RB5
Set Button
25
RB4
Soldering Iron Power
24
RB3
Hot Air Rework Power
23
RB2
Down Button
22
RB1
Up Button
21
RB0
no connection
20
Vdd
5 volts
19
Vss
Ground
Breakout
To improve access to the microcontroller connections I built a breakout board to give me access to all the micro-controller pins via standard pin headers. On the side that plugs into the existing socket I mounted a load of 90 degree pin headers and on the other a standard DIP socket with the legs splayed out so I could surface mount it. The pin headers are little on the large side for plugging into a DIP socket so you need to check its fully engaged with the onboard socket when you push it in.
Breakout board in placeshowing the header pinsthe PIC controller in the breakout board
Rotary Controller
Circuit Diagram
The rotary encoder I used is the SparkFun COM-10982 mainly because it is easy to panel mount, at this stage I have not used the builtin LED’s to add effects. This connects back to the controller board which has an ATtiny84 microcontroller to convert the encoder pulses into suitable button responses. There is also an opto-isolator for the button controls and a small DC-DC 3.3 volt power supply as I don’t know the power characteristics of the rework station. I took the 5v power for the controller from the same supply as for the PIC.
The controller board with an ATtiny84
I programmed the controller so that pressing the encoder emulates the set button and cycles through the available settings; the temperatures for the iron and hot air as well as the air speed. Rotating the encoder adjusts whichever setting has been selected. In the code, the Soldering Iron Power button is shown (RW_IRN) as connected; it is not used, the LED flashes when the rotary encoder is turned, its a bit pointless as it can’t be seen once the cover is back on. I wrote this in the Arduino IDE.
There is not much free space available on the front panel of the station, the encoder can only be mounted between the connection for the soldering iron and the mains switch. I have mounted the controller circuit board on the rear panel.
Rotary Encoder in place on the front panel
Limitations
One of the problems with this rotary encoder is when its turned too quickly it gets confused and can skip pulses or operate in reverse.
Also, the speed of change is limited, the PIC controller will only see so many pulses per second, I got this down to 14ms anything lower and it was unreliable, probably this is part of some code to detect button bounce, so a fairly long pause between each button press needs to be made.
Improvements
A few improvements could be made to the rework station that could mostly be implemented in the PIC software. Those that have occurred to me are; the control for the air speed only needs to go from one to eleven, slow, medium and fast, the speed currently goes between 20 and 100 and changing the speed can be rather slow. Some sort of velocity control on the rotary encoder so the faster its is turned the greater the amount of change in the temperature. An auto-off function for the iron, so when its back in the cradle it cools down and preserves the life of the soldering tip and, most importantly, a volume control for the annoying buzzer.
I have written more extensively about the main board hardware in this teardown.
With one of my electronics projects I am wanting to add a couple of phototransistors to make a crude movement sensor and to do this I first need to discover the best way of using them. A phototransistor is sensitive to the amount of light falling upon it, as this increases higher current is allowed through the device. This in turn can be used provide a variable voltage to an analogue input on your microcontroller.
For this posting I am using two different phototransistors, the SFH3710 is a surface mount device smaller than a red lentil and the TEPT4400 is through hole and looks like small white LED and is easier to prototype with, they are both NPN transistors made to respond to visible light at wavelengths around 570nm.
left TEPT4400, right the SFH3710 mounted in stripboard for prototyping
Connecting
A bias, or load, resistor is required to produce an output (VOUT). This can be above or below the phototransistor. Common Emitter
The resistor RC acts to pull-up the voltage, as light increases the output voltage drops.
Common Emitter
Common Collector (Common follower)
In this case the resistor RE acts to pull-down the voltage, as light increases the output voltage increases.
Common Collector
Phototransistor Modes
The Fairchild Semiconductors application notes describe the two modes that phototransistors can be used in; switch and active. The mode is set by the value of the load resistor RL:
Switch Mode: VCC < RL x ICC
Active Mode: VCC > RL x ICC
Where :
VCC = Supply Voltage
RL = Load Resistor (Rc or Re)
ICC = Maximum anticipated current
In switch mode the transistor is either on or off, this ‘digital’ output is useful for object sensing or object detection, typically a resistor value greater than 5kΩ is adequate, the output in the ‘high’ state should equal the supply voltage, and for ‘low’ the output should be below 0.8V.
In active mode the output is variable, giving a value related to the amount of light. To use this a low value resistor is required to prevent VOUT exceeding the supply voltage, using Ohms Law you can find the maximum resistance, the value above which the transistor may respond in switched mode: Rmax = VCC / ICC, so: 5v / 4mA = 1.2kΩ. Connected up as Common Emitter, selecting a resistor value 30% below this to ensure a margin of error a 875Ω should give 4.5V at the output when completely dark, dropping to below one volt when saturated with light.
The drawback with active mode is that phototransistors have a non-linear response to light, as light increases beyond a certain level their output will suddenly jump and then flatten out, other factors, such as the ambient temperature and the type of light (daylight, fluorescent tubes, LED’s, etc) also affect the value of the output.
Practical Experiments
I want to test that the above is actually true, this circuit uses a white LED pointed at a TEPT4400 along a short piece of black straw to act as a stray light shield. The LED brightness is set using PWM on the Arduino. The phototransistor is setup for Common Emitter output, so the output voltage will drop as the light increases. For active mode RC was set to 220Ω and for switched mode this was 10kΩ.
Phototransistor Test Circuit
The code below uses PWM to fade the white LED up to full brightness, the reading taken from the analog port is a majority candidate reading, where from the ten readings made the one that occurs most often is used as the phototransistor output bounces around, I think this is caused by the PWM, the results are output on the serial port for use in a spreadsheet.
From the output, I was able to produce these graphs, remember that for the Common Emitter setup being used the voltage drops as the light increases, not quite getting the smooth response to light/time I was expecting. With 10k resistor
With 220R resistor
I am not sure why I got these results, they were consistent and I suspect my test setup. Some more experimentation is needed, but for now I have run out of time.
In this post I am looking to discuss setting up a Trinocular Microscope for use with photography and video, covering my own experiences in getting the thing working and aspects that are not covered in the fairly useless manual. The type I am using is sold as an Industrial Inspection Microscope giving a magnification range of 3.5X to 90X depending on the installed optics. These look to come from a single factory in China and are distributed under various different brands by a variety of shops on the internet and in places such as ebay and Amazon.
In my electronics work I have been moving across to SMD (Surface Mount Devices) components, these can be rather small and fiddly for which a microscope is just the business. I chose a stereo microscope over the cheaper monocular microscope camera as this gives me a binocular depth of field view so when micro-soldering components I can make out the distance of the iron tip in relation to the board and component. In the past I have tried similar with a camera and monitor setup and this did not work for me.
Parts of the Microscope
Parts of a Trinocular Microscope
Clockwise from the top:
Eyepieces, to look through, with rubber cups – these make the scope easier to use. The eyepieces fitted here are WF10X/20, I’ll talk about the magnifications later
Ocular Tubes, the eyepieces mount into these and are used to set the dioptre – fine tune the focusing
Interpupillary Adjusters – to set the distance between the eyepieces
Objective Lenses – there are two of these
Focusing Knob – as you change magnification, you will need to re-focus.
Magnification Knob – for zooming in and out of your object
Trinocular Lever – pull this out to enable the camera view, when enabled the left eyepiece is blacked out. Simul-Focal microscopes do not have this.
Trinocular Port – camera mounting – the microscope shown comes with a C-mount adapter, here I have attached a C-mount to Fuji X-Mount adapter.
Objective Lenses on a Stereo Microscope
Other Parts
An essential addition to the microscope is some kind of illumination, an LED ring light is an excellent place to start, this mounts onto a slot on the barlow lens or a screw in adapter. You will be wanting one thats both adjustable, really bright and gives and even spread of light, look for those with at least 144 bright white LED’s.
LED Ring light
Barlow Lenses fit below the objective lenses, they are used to either reduce the magnification slightly to increase the working distance, or to add additional magnification.
Barlow Lenses
With the 0.5X barlow fitted the working distance can be raised from 9cm to around 15cm, I have not yet found any real use for the 2X barlow.
I have also fitted a 48mm UV (plain glass) filter from a camera shop, this is to simplify cleaning up the various emissions created when soldering, to this I have added a 48-52mm stepping adapter ring to give a place for the LED ring light to attach to as the 0.5X barlow lens does not have a suitable slot.
The objective lenses Magnification is shown on the right hand magnification knob, from 0.7X to 4.5X, the eyepieces are 10X and the barlow is at 0.5X the zoom is calculated by multiplying all the magnifications:
Generally I am more concerned about the image size being appropriate for the work I am doing, but when specifying a scope you need to know what it can do, these inspection microscopes are excellent for electronics but completely useless for extreme closeups such as seeing the cells from a layer of onion.
The Field of View is shown on the eyepieces, it is the second part of the code: WF10X/20 this field number is the diameter of your objective view in millimeters at 1X magnification, the formula is:
Types of Stereo/Trinocular Microscope
These trinocular microscopes have two main types, those that are simul-focal and those that are not. As mentioned before, the standard (for want of a better name) have a lever on the left side which needs to be pulled to enable a view for the camera, this in turn disables the left eyepiece, this becomes a problem if you wish to video while you are working, for photography is is less so. These standard microscopes are a bit cheaper, around £80 – £100 than the simul-focus ones and the image quality from the optics is just the same.
I first started with a standard microscope, in the photo at the top of this page, the small stand makes it very stable for photography, and although it does not have a reducing barlow lens I have successfully used it for a few electronics projects. I have now moved onto a simul-focal microscope with a long boom arm, this is the AmScope SM-4TPZ, this type of microscope is popular among the independent repair shops on YouTube (see the links below), the boom arm and barlow lens makes it more flexible to use.
Microscope on Dual Boom Arm
Setup and Focusing
Setting up for eye focus or for camera focus is relatively straight forward, but getting the camera and the eyes to be working in the same focus can be tricky. The eyes are much more tolerant and have a greater depth of field than the camera, the following steps should give you the results you are looking for (with a 0.5X Barlow Lens, knock 5cm off the height if you don’t have one):
With the focus knob turned so that the scope support (the bit that goes up and down when focus is turned) is flush with the part attached to the support upright hold the microscope and loosen the upright knob at the rear, set the height of the scope so that the objective lens is around 15cm above your work surface.
Set the interpupillary distance to something comfortable, with your eyes hovering above the rubber cups, not in them, I use the bridge of my nose to fix the distance you should see a whole clean circle, and black shading around the sides means you are off centre.
Rotate the ocular tubes, dioptre, so that they are just above halfway distance in their range. Set the magnification to its lowest, 0.7X (I’m not including the magnifications of the other lenses).
With a specimen like a coin or ruler under the objectives, close your left eye and adjust the dioptre on the ocular tube for your right until the focus is sharp.
Repeat with your left eye, closing the right and adjust the left diopter. Its not unusual for your eyes to have different focal distances.
Now zoom in, as you increase magnification adjust the focus knob to suit, micro-adjust the dioptres as required. Once correctly set up, adjusting the focus should be minimal while zooming through the range.
Now that the eyes have been setup, its time for the camera. The smaller the cameras sensor the further away it needs to be:
Zoom back out to 0.7X and set the focus back to its central position, as you started with before
Mount the camera on the Trinocular Port and adjust the height so you see an in focus image.
Now as before, increase the magnification in steps 1X, 2X etc. and check the focus of the camera and eyes, put the camera into focus with the focus knob and adjust the diopters for the eyes, these should be micro-adjustments.
With everything in place, you should have a stable in focus range of around 3cm from your work surface where for a particular magnification nothing but the focus knob needs to be changed.
Photography
When taking photographs using the microscope my camera of choice is a Fuji X-Pro2. This is a mirrorless camera with an APS-C sensor, the reasons for this are: its lighter than most DSLR’s, an old fashioned mechanical plunger type cable release can be used, because the sensor size is smaller it crops out much of the tunnel effect caused by looking down a long tube, and the live view has a manual focus assist which can be used to zoom the live view display and help take a nice sharp image.
Camera attached to Microscope
The camera sensor size makes a huge difference, to illustrate this here are two photos, one with the Fuji and another with a Canon DSLR full-frame both uncropped:
Fuji APS-C sensorCanon Full Frame Sensor
Normally I would crop to a square inside the image.
The depth of field is rather shallow and there is no aperture to change. To get around this I have used Image Stacking/Focus Merge, where you take a series of photos starting at the top of your object and focusing slightly further down, each image being a slice, I then use Affinity Photo to create a fully focused image.
Image Stacked Daisy
I set for a low ISO, around 100-400 and being lazy I use auto-exposure. Despite the bright LED light exposure times are generally quite long, 40th-60th of a second and bumping up the ISO to grainy makes little difference, cropping in post can make high ISO grain more apparent. I have made a suitable mount for a macro flash from the lid of an old spray can, a resize ring, small bits of wood and plenty of epoxy (I should have documented this).
One thing you may see in your images is a white dot in the centre of the photo, this is most obvious when fully zoomed in and is caused by light bouncing around the trinocular tube leading to the camera:
With the dreaded White Dot, and fixed
this is simply fixed by inserting a tube of matte black card running the length of the camera mount, in this case 40mm:
Cardboard inserted into trinocular mount
Video
I use a dedicated microscope camera for video, the photo cameras while I am sure they would work well have a built in time limit for recording and need attention, I also want to record directly on computer. The camera I use is a generic nameless blue box bought of ebay, on the computer it has the name “H1400 USB Camera” and I have it on a USB 2.0 port outputting 1080p at 30fps in to Open Broadcaster without any problems, it can also do HDMI and can take still images at 14 megapixels (apparently).
Video Camera for the Microscope with a 0.5X reduction lens
The big drawback with the camera is that the sensor used is tiny compared to those used for photography, this appears to be common among almost all video cameras designed for microscopes. To partly fix this a reduction lens can be fitted to the Trinocular Port, I use an AmScope FMA050 (aka RU050) 0.5X reduction lens which I got of ebay. You can see the cameras view in the sketch drawn on 5mm graph paper below, with the magnification set to 0.7X the outer circle is what I see through the eyepieces, the rectangle is what the video camera supplies to the computer:
Microscope limited video camera view
These cameras would also benefit from being able to provide an image in the old 4:3 aspect ratio as that is much more square than the 16:9 widescreen. The view to your eyes in the microscope will always be substantially better than that presented by the camera.
To Conclude
For a trinocular microscope suitable for micro-soldering I would recommend a simul-focus, its only little extra money for the functionality with the 0.5X barlow lens. AmScope do cheat the magnification a bit, not pointing out the need to swap barlow lenses round to get the advertised 3.5X to 90X range, but with the 0.5X barlow attached it goes upto 22.5X or without it is 45X, on the electronics for most of the time I work at around 15X only zooming in close for inspecting bad soldering and showing off.
As I live in the UK, buying through Amazon UK has the advantage that import duty is paid at checkout, AmScope ship from the USA (a well traveled Microscope, made in China) using UPS, this prevents holdups in customs and UPS’s hefty tax collection fee, ebay have a similar Global Shipping Programme.
Using the microscope for the first time is an odd experience, its interesting how your fingers adjust to the micro-distances, finding the occasional need to wave the soldering iron about until it appears in your field of view and looking at dead insects under the microscope, while eating, is probably best avoided.
Crows Feather
Links and References
Microscope Suppliers
AmScope – USA, also available on Amazon UK and ebay
Bluetooth Low Energy – BLE – Bluetooth 4.0 is an industry-standard wireless protocol built for the Internet of Things – IoT, it is designed to provide connectivity for devices operating from low capacity power sources such as coin cell batteries.
Raspberry Pi2 with ASUS USB-BT400 Bluetooth 4.0 Dongle
In this introduction to BLE I’ll be configuring a Raspberry Pi2 computer to talk to a smart watch. We will be installing the latest version of BlueZ from source, enabling BLE support. This is not a tutorial on decoding the data from the watch I am just using it as an example, although I may write about decoding it in a future posting.
I am using a ASUS USB-BT400 Bluetooth 4.0 Dongle on a Raspberry Pi2 but this will work on any computer with a Debian based distribution. Your dongle must be BLE/Bluetooth 4.0 capable otherwise this won’t work. I am using an ID107HR activity tracker with pedometer and heart rate monitor, randomly chosen from the list of cheap ones available on Amazon. While using the Pi to talk to the the watch make sure Bluetooth on the phone is off as it can only connect to one device at a time.
The current distribution of Raspbian – jessie on the Raspberry Pi comes with version 5.23 of the BlueZ Bluetooth stack that’s rather old, dating from September 2014 which lacks many of the features we will be needing. The current version 5.44 of the BlueZ has many changes in the package with many familiar components such as hcitool and gatttool being depreciated, so I will be ignoring those and using the available commands, bluetoothctl, on the terminal.
Installing BlueZ
With Raspbian – jessie installed we will need to update the Pi make sure some packages are installed and then installing the latest version of BlueZ. But first, remove the installed version 5.23 of BlueZ:
removing the installed bluez
1
2
$sudo apt-get--purge remove bluez
$sudo apt-get autoremove
Next, perform the traditional housekeeping updates then install the build tools and USB libraries. Those parts that are installed already will be automatically skipped.
Inside the BlueZ directory, configure, make (this takes a while), and install. The experimental option adds BLE support and enabling the library allows for python use later on:
installing bluez
1
2
3
$./configure--enable-experimental--enable-library
$make
$sudo make install
Configuring and Starting BlueZ
At this stage we will need to check that the installation worked and that we can see your bluetooth dongle. With your bluetooth dongle in a USB port you should see it on your list of USB devices, here you see mine as device ID: 0b05:17cb ASUSTek Computer, Inc.:
dongle view
1
2
3
4
5
6
$lsusb
Bus001Device006:ID0b05:17cbASUSTek Computer,Inc.
Bus001Device004:ID046d:c52e Logitech,Inc.
Bus001Device003:ID0424:ec00 Standard Microsystems Corp.SMSC9512/9514Fast Ethernet Adapter
You will also need to enable the experimental services, edit the file /lib/systemd/system/bluetooth.service and in the [Service] section change the ExecStart line to end with –experimental:
for first time use, try scanning to find your watch, if it doesn’t appear it is out of range, its battery is flat, or your dongle does not support BLE, here you can see it as ID107 HR:
bluetoothctl remembers your devices, so when you next use the program the watch appears on the list at the start. The controller has a number of options, these can be seen with help command. You can use show to view the status of your dongle:
UUID:A/VRemote Control Target(0000110c-0000-1000-8000-00805f9b34fb)
Modalias:usb:v1D6Bp0246d052C
Discovering:no
The list of UUID’s show the services supported by the Dongle. Now we can power the dongle on, set the agent – this manages the connection, and then connect to the watch on which the bluetooth symbol will appear. Once connected there will be a pause then you will see a list of attributes supported by the watch, it is advertising the services available:
These UUID’s are used to describe the sevices available on the device, some are pre-defined and can be found in the a href=”https://www.bluetooth.com/specifications/gatt/characteristics” target=”_blank” rel=”noopener noreferrer”>GATT schema, others are vendor specific and unless they publicly release these, decoding can become rather difficult. There are four types of attribute:
Services – collections of characteristics and relationships to other services that encapsulate the behavior of part of a device
Characteristics – attribute types that contain a single logical value
Descriptors – defined attributes that describe a characteristic value
Declarations – defined GATT profile attribute types
Each attribute is identified by a 128 bit ID, for example, one of the characteristics from the list above: 00002902-0000-1000-8000-00805f9b34fb, the first eight bits are used as an unique identifier: 00002902 and are shown as UUID’s: 0x2902. Data is contained in services, each service has a number of characteristics that may contain further descriptions depending on the requirement of the characteristic. You can see how the data is mapped out in this chart:
Service Containers
A spreadsheet with the watch data reformatted and tastefully coloured to illustrates this. Observe the Service URL column, it looks a lot like a directory structure:
Here we see two services /service0008 and /service000c looking further into the second service: /service000c we see that it has four characteristics, and to of those have descriptors. We can interrogate the characteristics and descriptors to glean further information by selecting the attribute and reading, like so:
Which is all very nice, but not particularly helpful as the manufacturer has chosen to use custom, proprietary, UUID’s for the watch. We don’t know the instructions to send to have the watch realease its data.
Those Scripting BlueZ
Inevitably, you’ll be wanting to automate connections. This becomes easy with the automation scripting language expect. Install, then make a script file:
install expect
1
2
3
4
$sudo apt-get install expect
$cd~
$nano bttest
$chmod+xbttest
In this example the script forgets the watch, finds the watch, connects to the watch, gets some info and then disconnects:
expect
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#!/usr/bin/expect -f
set timeout10
set prompt".*#"
set usrpasswd""
set address"C5:E8:FB:BF:F2:6C"
## execute blutetoothctl
spawn sudo bluetoothctl
expect-re".*password.*"
send"$usrpasswd\r"
## forget about the device - if connected previously
expect-re$prompt
send"remove $address\r"
expect-re$prompt
sleep3
## switch on the dongle
send"power on\r"
expect"Changing power on succeeded"
expect-re$prompt
## scan for devices
send"scan on\r"
expect-re$prompt
sleep5
send"scan off\r"
expect-re$prompt
## set the agent
send"agent on\r"
expect"Agent registered"
send"default-agent\r"
expect-re$prompt
sleep2
## connect to watch
send"connect $address\r"
expect-re$prompt
## get some info
send"info $address\r"
expect-re$prompt
## disconnect
send"disconnect $address\r"
sleep2
expect-re"\[bluetooth\]#"
## bye
send"exit\r"
in the script, send sends a command, don’t forget to add the carriage return – \r and expect is used to wait for a response within the timeout period, here it is set to 10 seconds. expect -re is using regex when looking for a reply, otherwise it uses a literal string. So much more can be done with expect and there are many tutorials, such as this one written by FluidBank.
More Bluetooth Data
For analysing bluetooth data a couple of very useful tools are available, Wireshark and Android data logging. I will go through the installation but not look at the data in any detail, this posting is getting a bit long. This Section is in two parts, installing Wireshark and Android Debug Bridge.
Sniffing with the Shark
Wireshark is a network and bluetooth packet sniffer, it shows you network and bluetooth traffic occurring on your Pi. Here is a quick installation method for a reasonably new version of Wireshark (v2.2.4) from the backports, answer yes to the question “Should non-superusers be able to capture packets?”:
and if you get a message about permissions, reconfigure the package and answer yes:
wireshark install
1
$sudo dpkg-reconfigure wireshark-common
Start Wireshark and double click your bluetooth device on the list, in my case bluetooth0. There is not much to see as Wireshark will only see traffic between the watch and the Pi:
Wireshark Data Capture
Android Debug Bridge – ADB
For Anroid 4.2.2 and above, activate developer mode on the phone, go to Settings, tap About Phone and at the bottom of the list tap Build Number three times. Back in the main settings page Developer Options has appeared, tap developer and turn USB debugging On. With the phone plugged into a USB port a little Android head should appear in the information bar at the top-left of the screen. To begin we will need to install some udev rules written by Nicolas Bernaerts:
At this point on the phone an allow USB debugging dialog will appear, give permission and always trust to authorise it. ADB will now show the device as a device:
android tools install
1
2
3
$adb devices
List of devices attached
064be417008eef9fdevice
If the device list is empty, with everything plugged in good and proper and the phone setup in developer mode, start your diagnosis by checking udev; open another terminal window and view logging with udevadm monitor –environment and reload with sudo udevadm control –reload I’m not entirely sure what I did to get it from ‘not working’ to ‘working’. If all else fails elevate yourself to root.
Data Capture
With ADB now setup we can capture the Bluetooth data being exchanged. With bluetooth off, in the Developer Settings find Enable Bluetooth HCI snoop log and turn it On. In the smartwatch app synchronise with your watch, once complete turn Bluetooth off manually – this is to minimise the amount of captured data. Don’t forget to turn logging off on the phone when done. To find where the log file has been stored and copy the file from the phone to the Pi use:
This wasn’t quite the posting I originally had in mind, I wanted to decode the data from the watch for my own use, making something more useful, impressive graphs and charts, than that provided by the Android App VeryFit 2.0 but as the manufacturer has chosen to use proprietary GATT codes it makes the job that much harder. It may be much simpler to just buy an expensive FitBit and download the data from them. But with writing this I now know a few things that were previously unknown, and I hope that this has provided some light to your BlueZ (a pun!, right at the end!).
In Part One I covered the byte codes sent by the Zoom Remote Controller RC1 and decoded data sent over the wire to the remote from the Zoom H2n Recorder.
In this post I will be covering the use of an Arduino style micro-controller to decode the signals sent by the remote, then control the recorder. I have used a Tennsy 3.1 Arduino clone as this is a small controller with two additional hardware serial ports, works with 3.3volt logic, and a with the addition of a crystal and button battery a real-time clock.
Arduino control of the Zoom H2n
Setup and Connections
The connections on the remotes four pin 2.5mm jack, with pin one being the tip:
Remote Receive – RX
Remote Transmit – TX
Ground
3.1V – Power
On the Teensy there are two hardware serial UARTs available in addition to that used by the USB port, UART2: Pin 9 (RX2), Pin 10 (TX2) and UART3: Pin 7 (RX3), Pin 8 (TX3). Serial data is sent at 2400 baud, 8 bits, no parity, 1 stop (8n1). The response data shown is for when the recorder is in XY Stereo mode (0x20, 0x21), different codes are returned when other recording modes are used, see the end of Part One for details.
Serial Monitor
This first chunk of code is for monitoring the outputs of the remote control and recorder. Connect Remote Receive – RX on the remote to RX2 – Pin 9 on the Teensy and Remote Transmit – TX to RX3 – Pin 7 and Ground to Ground on the Teensy. This program will output data received to the Arduino IDE’s serial monitor.
The output is in four columns; the UART seeing activity, current milliseconds and the received data in hexadecimal and decimal values.
Taking Control – But Not Listening
Sending the command to the recorder blindly is quite straight forward, just send the bytes to the Remote Transmit – TX pin on the recorder (Zoom RX). This can be seen in the following, when run it starts the recorder recording for ten seconds. Connect: Remote TX to TX2 on the Teensy, Remote RX to RX2 and Ground to Ground.
Zoom H2n Serial Transmit
Arduino
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
//written for a Teensy 3.x
#define MONITOR_LED 13
// bytes to start and stop the recorder, a negative number is used as a delay
intrecord[5]={0x81,0x0,-100,0x80,0x0};
voidzoomTX(intd[],intlen){
// show what is going to be done
for(inti=0;i<len;i++){
charout[40];
if(d[i]<0){
sprintf(out,"TX2: delay(%d)",abs(d[i]));
Serial.println(out);
}
else{
sprintf(out,"TX2: %d\t0x%x",i,d[i]);
Serial.println(out);
}
}
// do the command
for(inti=0;i<len;i++){
if(d[i]<0){
delay(abs(d[i]));
}
else{
Serial2.write(d[i]);
}
}
}
voidsetup(){
delay(1000);
Serial.begin(9600);
Serial.println("ready");
Serial2.begin(2400,SERIAL_8N1);// connection to Zoom.
pinMode(MONITOR_LED,OUTPUT);
digitalWrite(MONITOR_LED,LOW);
delay(2000);
Serial.println("REC: start");
zoomTX(record,sizeof(record)/sizeof(int));
digitalWrite(MONITOR_LED,HIGH);
Serial.println("-----------------");
delay(10000);// wait ten seconds
Serial.println("REC: stop");
zoomTX(record,sizeof(record)/sizeof(int));
digitalWrite(MONITOR_LED,LOW);
Serial.println("-end-");
}
voidloop(){
// nothing to loop
}
Taking Control – And Listening for a Reply
The next stage is to have the Teensy control the Zoom and listen for a response from the recorder. Again, as before connect: Remote TX to TX2 on the Teensy, Remote RX to RX2 and Ground to Ground. For the demonstration I have added three buttons to act as the controller.
Zoom Control with three buttons
The following code needs more development work, I ran out of time, but I think gives a good starting point for further investigation. I have placed the commands for the remote in a structure, each command; record, pause and mark has four components, the command to transmit to the Zoom, the expected responses when starting and stopping and a flag to store the status.
Zoom H2n Transmit and Reply
Arduino
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
//written for a Teensy 3.x
#define MONITOR_LED 13
#define RED_BTN 2
#define GRN_BTN 3
#define BLU_BTN 4
unsignedlongnowMillis=0;
unsignedlongprevMillis=0;
unsignedlongbuttonPressDelay=400;
unsignedlongserialTimeout=8000;// it can take a few seconds for the zoom to start recording
structZOOMTX{
intrecord[4][5]={{0x81,0x0,-100,0x80,0x0},// Transmit command data - a minus number is used as a delay(xxx)
{0x20,0x20,0x21},// Expected Response - Start (in XY Stereo mode)
{0x21,0x21,0x20},// Response - Stop
{0}};// status: record[3][0] = 1: recording, 0: not recording
intpause[4][5]={{0x80,0x2,-100,0x80,0x0},
{0x21,0x21,0x20},
{0x20,0x21},
{0}};
intmark[4][5]={{0x80,0x1,-100,0x80,0x0},
{0x20,0x20},
{0x20,0x20},
{0}};
intnoAction[2]={0x20,0x20};// this happens when pause is pressed while not recording. Response in XY Stereo mode
Serial.println("PAUSE COMMAND FAILED!");// probably not recording, or not recording in XY Stereo
}
prevMillis=nowMillis;
}
// blink the LED while paused
if(ZoomTX.pause[3][0]==1){
digitalWrite(MONITOR_LED,LEDmonitor.state);
toggleMoitorLEDstate(nowMillis);
}
}
There is a problem when resuming from pause, because the Zoom sends codes to flash the LED on the remote this can pick up the wrong pair of bytes; such as 0x21 0x21 instead of the expected 0x20 0x21.
I expect to be revisiting this, adding a timer function plus external battery for long running. I’m not sure how useful listening for a response is, sending the record command toggle on its own seems fairly robust without the need to check.
The Zoom H2n is a portable sound recorder looking like an old fashioned microphone it is a handheld device that provides an assortment of stereo and surround recording modes, it records onto an SD card in MP3 or WAV format with options for various bitrates and frequencies. The unit is powered internally by two AA batteries and can also be powered from the USB port. The recorder I am experimenting on has firmware version 2.00 installed.
A not at all contrived image of the Zoom H2n Portable Recorder
The Zoom Remote Controller RC2 is a wired four pin 2.5mm jack plug connection, this remote has three buttons: record, mark, and pause there is also an LED to show when the H2n is recording. It is purchased separately from the recorder and only appears to be available bundled in an accessory pack. It looks difficult to take apart without leaving some damage, and this may not be necessary for decoding.
Zoom Remote and breadboard for testing
In this post I am looking to see how the remote works and find what control method it employs so in Part Two I can use an Arduino style micro-controller to provide an external trigger such as for timed recordings.
Setup for Testing
For testing I have made a breakout lead, this is essentially an extension cable split in half with a couple of molex style connectors allowing me to plug it into a breadboard. With this I have found the cable has the following connections, with pin one being the tip of the 2.5mm jack plug:
Remote Receive – RX
Remote Transmit – TX
Ground
3.1V – Power
When checking with a multimeter I found continuity from the negative of the left battery (on the Mic Gain side) to pin three, ground, of the jack, there is also a connection between the positive of the right-hand battery to pin one of the jack but on the multimeter in diode mode there looks to be a capacitor, the voltage rises until no apparent connection is indicated. With no activity on the recorder the RX and TX pins show ~2.7 volts.
Determining the RX and TX pins turned out to be straightforward. When you press the record button after a moment the recording LED lights up, on the oscilloscope I can see three different square wave patterns for the three different buttons on the TX pin and a single type of square wave on RX to light the LED. The following images show the signal for the record button then that sent in response to to light the LED.
Signal sent by the remote when Record pressedSignal sent by the Zoom recorder to light the LED in the remote
Also when buttons are pressed on the recorder data is seen on the RX line. For a more detailed examination I will need to break out the logic analyser.
Signal Analysis
Following some research where the remote for a Zoom H4n was examined, I set both channels being used on the logic analyser to the following:
Protocol: UART
2400 baud, 8 bits, no parity, 1 stop (8n1)
Bit Order: LSB first, inverted logic: No
Decoding of the first part of the stop recording command
First I decoded the buttons on the remote with the trigger on the logic analyser set to falling edge on the Remote TX line. On TX there is a pause between the two pairs of command bytes which appears to be the length of time the button was pressed, around 350-500ms, there is also a pause between bytes in the RX response, the value of the response changes depending on which recording mode you are in, those shown below are when the recorder is in XY Stereo:
Record Start
TX:
0x81 0x0
~
0x80 0x0
RX:
0x20
1.85s
0x20 0x21
record LED on
Record Stop
TX:
0x81 0x0
~
0x80 0x0
RX:
0x21 0x21 0x20
1.9s
0x20 0x20
record LED off
Pause (while recording)
TX:
0x80 0x2
~
0x80 0x0
RX:
0x21
51ms
0x21 0x20
then this repeats
492ms
0x20 0x21
to flash the LED
492ms
0x21 0x20
until pause is pressed again
Resume from Pause
TX:
0x80 0x2
~
0x80 0x0
RX:
0x21 0x21
LED on
Mark
TX:
0x80 0x1
~
0x80 0x0
RX:
0x21
492ms
0x20 0x21
LED on
I was also able to capture the following activity sent to the remote when various buttons were pressed on the recorder itself with the recorder in XY Stereo mode. Other models of the recorders made by Zoom have more advanced remotes, such as the RC4 as featured in this hack of the H4n. I suspect they would work on this machine too. This time I set the logic analyser to trigger with a falling edge on Remote RX. I think the 0x20 code is used to indicate the display illumination has been turned off. I saw activity on all buttons except the Mic Gain knob.
Power On – Without remote attached
TX:
Lots of random activity
RX:
0x10
400ms
0x80 0x81
1.2s
0x10 0x0 0x80 0x0
140ms
0x0 0x0 0x80 0x80 0x0
~2ms
0x0 0x80 0x0 0x0 0x80 0x0
Power On – With remote attached
TX:
0x0
five pulses 30ms apart
30ms
0x0 0xA1 0x80 0x0 0xA1
RX:
following pulses on TX
0x80 0x81 0x80 0x10
1.2s
0x10 0x0
148ms
0x0 0x0
~4ms
0x0 0x0 0x0
Record Start
RX:
0x20
20ms
0x20 0x21
LED on
Record Stop
RX:
0x21 0x21 0x21 0x20
~
0x20
~283ms
0x20 0x20
LED off
Menu \ Home – Into Menu
RX:
0x20 0x20 0x0
Exit from Menu
RX:
0x20
45ms
0x20
Play Switch: Up/Down/Press
RX:
0x20
55ms
0x20
Clipping detect (tapping the microphone with a pen)
RX:
0x10 0x2
56ms
0x2
59ms
0x10
60ms
0x10
354ms
0x10
Volume: Up and Down
RX:
0x20
Recording Mode Change: 4 channel surround
RX:
0x10 0x10 0x30
14ms
0x30 0x30
122ms
0x34
60ms
0x30
60ms
0x30
Recording Mode Change: XY Stereo
RX:
0x30 0x30 0x20
216ms
0x20
Recording Mode Change: 2 channel surround
RX:
0x20 0x20 0x30 0x30
18ms
0x30
148ms
0x30
164ms
0x30 0x6
56ms
0x14 0x30
477ms
0x30
Recording Mode Change: MS Stereo
RX:
0x30 0x30 0x10
170ms
0x10
50ms
0x12
I think these response codes are to light up various LED’s on the more advanced Zoom RC4 remote, this suggests that other remotes would work in this recorder.
The following table shows the response codes given with different microphone configurations when record is clicked to start recording:
TX:
0x81 0x0 ~100ms delay 0x80 0x0
XY Stereo:
0x20 750ms delay 0x20 0x21
2 Channel Surround:
0x30 750ms delay 0x30 0x31
MS Stereo:
0x10 750ms delay 0x10 0x11
4 Channel Surround:
0x30 750ms delay 0x30 0x31
In Part Two I will be covering the use of a Arduino style micro-controller as an alternative remote control.
Interrupts are a handy way of having the micro-controller listen for triggers and respond to them, instead of polling, constantly checking, the controller listens while getting on with other things, this is analogous to when the door bell rings you interrupt what you are doing to answer the door rather than repeatedly going and checking the door every few minutes to see if anyone is there. The interrupt is handled by micro-controller hardware and reacts very quickly and efficiently to a detected event, different micro-controllers have different interrupt pins available, for example the one used in the original Uno only has two digital pins available but on more recent models such as the Genuino 101 or the Teensy 3.2 all digital pins can be used.
In your program when an interrupt is triggered the action performed by your function – the Interrupt Service Routine (ISR) should be kept simple so as not to keep the controller occupied and possibly miss other trigger events, interrupts are for listening and monitoring to tell your main program that something has happened. The micro-controller can react to four different types of trigger:
LOW – trigger whenever the pin is low
CHANGE – trigger whenever the pin changes value
RISING – trigger when the pin goes from low to high
FALLING – when the pin goes from high to low
Square Wave Edges
On the oscilloscope screen above we can see these conditions on a square wave, the change trigger can be said to be all the corners. If your input is being pulled high and goes low when triggered (as shown), then choose Falling or Low, it is better to detect a falling or rising edge as using low can cause the interrupt to trigger multiple times for the duration of the low state.
Hardware
To illustrate the use of interrupts I have written a program to find the rotation and wind speeds of a 30cm Desk Fan. To do this I added a hall effect switch and magnet to find the rotation speed of the blades and bought a cheap Anemometer to find the speed of air being pushed out by the fan. Circuitry for the Hall Effect Switch, Anemometer and monitor LED’s
To monitor the speed of the fan I have used a A1120EUA-T Hall Effect Switch and 10K pull-up resistor and glued this to the body of the fan near the motor shaft and on the shaft itself glued a small magnet.
Glued to the fan is a Hall Effect Switch with pull-up resistor and magnet on fan shaft.
The Anemometer is not particularly robust and could be seriously damaged by a pigeon. Taking the cap off you will find a bearing to allow the top to rotate freely as well as a magnet, inside there is a small reed switch that closes every time the magnet passes over it. I have connected this to the Teensy in the same way as would a button switch with a pull-down resistor.
The cheap AnemometerReed Switch inside the Anemometer
The the reed switch in the anemometer creates a bit of noise when it closes as you can see on the oscilloscope below, these are picked up as false positives by the micro-controller and will give you bad readings. Fortunately this can be fixed in software by having the interrupt handler ignore further events for a few milliseconds.
Reed switch noise, after the first rise when the switch closes, the contacts bounce about for a short time before settling.
A thing I found useful when testing this was to have the multimeter set to its frequency counter (Hz) and check that roughly the same cycles per second were displayed on the meter and on the Arduino serial out.
Software
The Arduino commands to look out for are attachInterrupt and digitalPinToInterrupt to convert the named digital pin as you see on the board/piece of card to the interrupt name used by the controller. There are a few rules to remember when using interrupts:
Keep it simple – the function – Interrupt Service Routine (ISR) called by your interrupt should be short and simple, any extra data processing should be done in the main program.
Delay() won’t work, and don’t use Serial.print()
Make variables shared with the main code volatile – this tells the complier that the variable can change at any time, so it must be reloaded every time its referenced.
fan speed and anemometer monitoring using interrupts
Arduino
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
#include <math.h>
#define FAN_PIN 14
#define FAN_LED 23
#define ANEMOMETER_PIN 15
#define ANEMOMETER_LED 22
// all global variables used in a interrupt function need to set as volatile
volatileintfanCount=0;
volatilebytefanState=LOW;
volatilebyteanemometerState=LOW;
volatileintanemometerCount=0;
volatileunsignedlonglastAnemometerMillis=0;
// reed switch debounce time, keep this as low as possible
// set long enough not to give you false readings
volatileunsignedlonganemometerTimeoutMillis=10;
booleanisrMonitorON=true;
intfanRPM=0;
intanemometerRPM=0;
unsignedlonglastMillis=0;
constintanemometerRadius=70;// in mm, the distance from the centre of the anemometer to the middle of a cup
// fan Interrupt Service Routine (ISR)
voidrpmFan(){
if(isrMonitorON==false){
return;
}
fanCount++;
fanState=!(fanState);
}
// anemometer Interrupt Service Routine (ISR)
voidrpmAnemometer(){
if(isrMonitorON==false){
return;
}
// the reed switch in the anemometer makes a fairly rough signal, so we ignore further interrupts
// for the next anemometerTimeoutMillis - switch bounce fix in software
isrMonitorON=false;// stop updating the counters while calculating and displaying
fanRPM=fanCount*60;// convert frequency to RPM.
anemometerRPM=anemometerCount*60;
Serial.print("fan: ");
Serial.print(fanRPM);
Serial.print("rpm\t");
Serial.print(fanCount);// if your multimeter has a frequecy counter, use this number to check against when testing
Serial.print("Hz\t anemometer RPM: ");
Serial.print(anemometerRPM);
Serial.print("rpm\t wind speed: ");
Serial.print(calcMetersPerSecond(anemometerRPM));
Serial.print("m/s\t");
Serial.print(anemometerCount);
Serial.println("Hz");
fanCount=0;
anemometerCount=0;
lastMillis=millis();
isrMonitorON=true;// start updating the counters again
}
}
Data
Here is a chart of the information gathered, it might even be interesting for someone with an interest in aerodynamics, anemology or something. The fan is a three speed SFC-300BP 12″/30cm Air Circulator and the Anemometer was placed one meter away from the fan positioned to capture the strongest wind.
fan
anemometer
setting
RPM
Hz
RPM
Hz
m/s
1.
1045
17
150
2.5
1.10
2.
1223
20
201
3.35
1.47
3.
1366
22.7
214
3.5
1.5
I took 60 readings for each fan speed then averaged them, in my program I used the following formula to work out the wind speed from the Anemometer in meters per second:
where:
v = velocity in meters per second
r = radius in meters – distance from the centre to the middle of the cup
N = Revolutions Per Minute (RPM)
I have a had a few requests on how to add more than one MCP23017 port expander to the Arduino via the i2c bus, this chip is a very useful and easy to use component that adds up to 16 digital I/O ports to the Arduino. This demonstration uses two MCP23017’s with three LEDs for output, one RGB LED to loop through a selection of colours, a single colour that blinks on and off, and another RGB LED that is controlled by a four button keypad. I have written the program using the millis() timer rather than the delay() function to maintain the illusion of multi-tasking. Two MCP23017s and a Teensy
Addressing the MCP23017
The port expander has a three pins, A0, A1, and A2 for which an address can be set, each MCP23017 on your i2c bus must be set to have its own address, this is a three bit address and up to eight expanders can be used. Although I suspect things may noticeably slow down as you add more expansion. There is an SPI version available, the MCP23S07, that may be better for use with larger setups.
The address connections are shown the chart below, where zero is a connection to ground and one is a connection to 5V (or 3.3 volts). The MCP Address column refers to the address used by the Adafruit driver as you will see later.
chip
address
hardwired address
i2c
address
MCP
address
A2
A1
A0
000
GND
GND
GND
0x20
0
001
GND
GND
5v
0x21
1
010
GND
5v
GND
0x22
2
011
GND
5v
5v
0x23
3
100
5v
GND
GND
0x24
4
101
5v
GND
5v
0x25
5
110
5v
5v
GND
0x26
6
111
5v
5v
5v
0x27
7
In my circuit I have assigned the first expander address 0x20 and the second 0x21.
Powering the Expanders
The port expander has been designed to run on a supply of 2.5v to 5.5v, so using a 5v supply from the USB port should be OK for a modest number of LED’s, you will need to calculate what your power requirements will be, approx 20mA per LED, so in this demonstration: 7 LED’s x 20mA = 140mA, plus whatever the chip itself is using. Bear in mind that each GPIO pin on the expander can only handle a maximum of current 25mA, and that the maximum total power dissipated must not exceed 700mW (after which point it’ll let the magic smoke out).
A Teensy 3.2 has a 3.3V supply but this is rated at 250mA maximum, the Ardunio UNO looks to be around 450mA on the 5V and only 50mA on the 3.3V output. For running from a battery I would look to use a 6v supply and a buck converter such as this Pololu step-down regulator.
The Hardware
On the left we see the Arduino UNO with the two i2c wires coming from pins A4 – SDA and A5 – SCL, two 4.7K ohm resistors are used for pullup, the port expanders are daisy chained along this bus, using pins 12 – SCL and 13 – SDA. See how the addresses are set on pins 15, 16 and 17, and note the 1K ohm resistor on the reset pin (18), without this resistor the circuit will work for a while then stop. The GPIO pins are connected as appropriate and the button switches do not need pull-up resistors as the port expanders internal pull-ups are turned on in the software. Connecting two MCP23017 port expanders (click to enlarge)
Also if you are using RGB LED’s you will want to adjust the values I have given here, different colours have different power requirements so different resistor values are required to get a properly balanced colour LED. The RGB LEDs I have used are common anode, 5v is applied to the common and the path to ground to through the expander, this inverts the logic so setting the pin HIGH turns the LED off, and LOW turns it on.
The Software
The Adafruit MCP23017 library assigns each GPIO pin a number as you can see in the following diagram:
On both expanders the RGB LEDs are on ports 8,9 and 10 (to save me writing separate code for each RGB LED), the blink LED on port 7 of the first expander, and the buttons occupy ports 4, 5, 6, and 7 of the second. The first three buttons are used to toggle the red, green and blue in the second RGB LED while the fourth turns them all off. The other two LEDs are just doing things to show that they can do stuff.
A quick captive nut how-to, for when you are making a wooden box that has a lid you need to remove on an irregular basis. Wood screws tend to maul the wood after a while and then the lid falls off, these captive nuts are easy to do and just work.
You will need:
Nut and bolt
two part expoy adhesive
drill bit as large as the nut and a drill
Vaseline or any other petroleum jelly
parts needed
In this example I am using an M4 nut and bolt and an 8mm drill bit. You may need to cut your bolt to length.
1. Drill your hole
in this case about 1 cm, deep enough so when you insert the nut and bolt the expoy will cover the nut. Clean it up, removing wood shavings and other debris.
Hole Drilled
2. Grease Up
To prevent the expoy sicking to the bolt smear some Vaseline onto your bolt, only a small amount is required, but you should get it into the thread, make sure you keep the nut clean. Thread the nut back onto the bolt, leaving 4-5mm of bolt protruding, as shown:
grease your bolt
3. Mix up the Expoy
Mix a blob about the size of a marrowfat pea, enough to fill half of the hole. Drizzle this into the hole.
drizzle the expoy
4. Plunge the nut and bolt into the hole
Wiggle it about a bit to make sure the expoy is well distributed. Position the bolt how you would like and leave to set. If you see the bolt moving use some sticky tape to hold it in place.
plunged bolt
5. Remove the bolt
After about 10 to 15 minutes, the expoy will have set (unless you got that weird stuff). Use a screwdriver for at least the first turn as there will be a little adhesion, but it’ll come out cleanly.
If you have any excess expoy protruding it’s still quite soft at this time so cut it way with a Stanley knife as I have done in the example. Once fully cured expoy makes a hard plastic that can be difficult to cut.
the nut is captured
The amount to cut off your bolt is the length of your bolt less the thickness of your lid less a bit of wiggle room, I use a cutting disc on a Dremel, and file the cut edge smooth. You need to ensure its long enough to go through the nut once cut as the expoy has a thread that gives a misleading nutness (technical term!) that soon wears away.
I hope you enjoy your captive nuts, I am sure they will give you many years of service. The same principle can also be applied to making captive bolts, especially if you wanted to use Wing Nuts for easier access.
Here are some notes on using the Sparkfun Thumb Slide Joystick on an Ardunio. This is a small two way X-Y variable resistor based controller that uses two analogue pins on the Arduino and works with both the 5 volt logic of the Uno as well as the 3.3 volts of the Teensy.
Thumb Sliding Joystick
I found that this joystick works well for giving the eight positions found at the stick limits crosswise and diagonally but it doesn’t seem sensitive enough for reporting accurate positions.
Connecting
On the underside of the joystick there are four solder pads, looking from above with the screw holes pointing towards you, the connections are:
X-Axis
+5 volts
Y-Axis
GND
Connections, looking from above and circuit diagram
Should you take one to bits, you will find two sliders with small metal contacts and a circuit board with carbon tracks acting as a variable resistor. The sliders move in a parallel configuration, and the joystick control has a spring to return it to centre when released.
Inside the Joystick showing the contactsCarbon tracks on the circuit board, solder pads top left
These can be tricky to put back together afterwards.
Underside of the joystick, with some wires soldered to the connections
The pads on the base are spaced at 2mm but with some bending it is possible to attach standard 2.54mm (0.1inch) header pins, solder the inside two first before attaching the outers.
Thumb Joystick test setup with a Teensy,
When mounting in a case or panel you will need to drill a 18mm hole for the controller and the thumb pad is raised about 3mm above the surface of the body. I would secure the controller in place with a couple of blobs of hot glue rather than use the small screw holes.
Programming
For my setup I am using the Teensy’s 3.3 volt output to power the joystick and the X-Axis connected to Analog pin 0, and Y-Axis to Analog pin 1,
This test program shows the position of the joystick through the serial port, it attempts to calibrate itself and set the values for the chosen direction, if this is not always successful when returning to the centre position try experimenting with the tolerance and maxRange values.
thumb_slide_test.ino
Arduino
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
#define XAXIS A0
#define YAXIS A1
#define MONITOR_LED 13
intxVal=0;
intyVal=0;
intlastX=0;
intlastY=0;
constinttolerance=4;
intcentreXY[2]={0,0};// x,y
// highest reading on an analog pin is 1023, but the resistors in the thumb slider
// limit this to around 900
constintmaxVal=900;
// set this too low and detecting diagonals is difficult, too high and detecting
// the centre position becomes difficult
constintmaxRange=50;
// output the joystick position, left, right, etc to the serial port
voidaxisPosition(intx,inty){
charxpos[7]="";
charypos[7]="";
// calculate how far the joystick has to be moved
// before the direction is established
intleft=centreXY[0]-(tolerance-1);// x
intright=centreXY[0]+(tolerance+1);// x
inttop=centreXY[1]-(tolerance-1);// y
intbottom=centreXY[1]+(tolerance+1);// y
if(abs(x-centreXY[0])<tolerance){
strcat(xpos,"centre");
}
elseif(x<=left){
strcat(xpos,"left");
}
elseif(x>=right){
strcat(xpos,"right");
}
else{
strcat(xpos,"unknown");
}
if(abs(y-centreXY[1])<tolerance){
strcat(ypos,"centre");
}
elseif(y<=top){
strcat(ypos,"top");
}
elseif(y>=bottom){
strcat(ypos,"bottom");
}
else{
strcat(ypos,"unknown");
}
Serial.print("x: ");
Serial.print(xpos);
Serial.print("\ty: ");
Serial.print(ypos);
}
// see if the joystick has moved outside the set tolerance
booleanaxisChange(intx,inty){
// abs always returns a positive number, even when the result is negative