Showing posts with label Motion Sensors. Show all posts
Showing posts with label Motion Sensors. Show all posts

Thursday, 6 August 2015

Field Mate Part 2 - Open Your Eyes to an Open Sensorium

A few posts past, I addressed the idea of Field Buddy Field Mate - a portable device for capturing environmental data while in the field. Having had a chance to play with a bit of magnetometry (amongst other toys), and finding that I need to build an intelligent thermostat, I have come to the conclusion that there is something lacking in the world of hobby/amateur electronics - and that is a properly integrated set of devices and software for microcontroller use.

I have decided, therefore, that it is time to formalise the Field Mate concept into a more general project.

To this end, I have decided to commence work on what I am calling The Open Sensorium Project.

The aim is to produce a series of software and hardware modules that can be built up and put together in order to build custom instrumentation. Based around Data Capture using sensors (i.e. a sensorium), the modules will provide both sensing, primary processing and export of data via displays, data streaming and data caching (using SD cards).

It will not only provide an open sensorium, in the sense that the data system's "eyes" are wide open, but will also be an open project - open source software, open source hardware (albeit, using a lot of off-the-shelf modules) and free to use and modify.

Given the relatively low cost of microcontrollers, it would be possible for each major module to be separately intelligent.

I hope that there will be a lot of cross-pollination with various other projects, and between the developers using a range of microcontroller systems including, but not limited to, Microchip's PIC, Parallax Propeller, Atmel AVC / Arduino and Raspberry Pi,

As an open project, the material will be released into the wild with few restrictions, and subject to the Gnu General Public Licence.

The rules will be simple - open source may not form a part of a closed source project unless those portions that are open source remain open source. Derivative works are brilliant. Respect and acknowledge the intellectual rights of those whose work you are building upon - and retain any copyright notices that form a part of the source that you are using.

Finally, there will be standards for various parts of the project - standards for quality of product, for quality of documentation and for communication protocols between modules - and to the outside world.


I hope that others will want to get involved in various ways - even if it is only through an eMail saying that you found it useful.

I look forward to hearing from you. I will pass on the web site address once I have settled upon one. I have set up a project page on Sourceforge at: https://sourceforge.net/p/open-sensorium/



For those who care about these things - the font is Neuropolis, the logos were made in MS Word 2013 and either screen-captured or copied to Inkscape.

Wednesday, 1 July 2015

Eyepiece - expanding the limits of the Raspberry Pi

Make no mistake, the Raspberry Pi is an excellent piece of equipment.

Like any device, it has its limitations, and like any device, there are ways to expand those limitations with clever use of hardware and software.

One of the limitations is the number of communication pins available to the user without using an GPIO expander.

I want to perform a large number of sensor readings and position actuator operations using the Pi. I want to simplify the software that runs those actuators and sensors. Essentially, I want a much more powerful system controlling my microscope.

I can do this in two ways - one is to scrap the idea of using the Raspberry Pi, and to install a big, custom-made control system. The other is to farm out part of the computational load to other, small computers.

The first option sounds expensive, and will require everything to be written as a monolithic system - one that will require a lot of re-writing every time I want to make a change.

The second option, however ...

Enter the Arduino nano. This is a "single chip" solution - it is actually a tiny PCB populated with an AT Mega microcontroller, ancillary circuitry and a set of pins that turns the surface mounted device into a DIP package with a couple of connectors on top.

Programmed in a dedicated version of C, the device is all about sensors and control actuation. It is fast, it is cheap and, above all, can keep track of several stepper-motors, travel limit switches and indicator lamps (LEDs).

Thus, each cluster of stepper motors in this project will be overseen by an Arduino, keeping the workload of the Pi neatly centred on the task of running the microscope.

Of course, this means learning yet another programming language, but at least it is based on one that I have used before, if briefly.

Sunday, 15 February 2015

Eyepiece - absolute position sensing using optical detectors (part 2)

A month ago, I discussed the idea of using an old USB mouse as a motion sensor.

One of the problems that I have been wrestling with is that reading the data stream output by the mouse will hang the process if there is no data (i.e. no changes), until data is presented to the reading program.

Finally, in desperation, I tried splitting the process of reading the mouse data from the process of actually using it. Success in using a system that I'm still not terribly confident with to perform a fairly esoteric job feels good.


The operating system (Raspian Linux) treats the data flow between the OS and devices as file objects, which means that you can simply open the device interface file and read from or write to the device as though it were a binary file.

By opening a text file in another location and writing the appropriate data to it allows the data stream from the mouse to be buffered so that it can be read asynchronously, on demand and the end of file detected - the virtual device file doesn't allow this luxury as there is no EOF marker.

In order to get this to work, I wrote a simple device driver program in python, and set it to work as a background process, a second program can pick up the pre-processed data from the mouse whenever it is required.

The simple proof of concept flushes the file occasionally when the mouse is idling. The mouse driver opens the communication file whenever it is ready to write data and closes it immediately after writing. The reader program simply echoes the mouse data on-screen and occasionally flushes the file in order to ensure that it doesn't become an unwieldy size.

Because of the tendency of SD cards to have a limited operational lifespan, it is important that the data files be on a remote or an external hard drive.

So, the programs:

The Mouse Driver - the original, simple file that needs a bit of work, but essentially works as-is.

#!/usr/bin/python
# Filename: udrv.Mouse.py
# Mouse comms driver program (proof of concept)

# Core logic courtesy of PeterO on the Raspberry Pi forum.
#  http://www.raspberrypi.org/forums/viewtopic.php?f=63&t=80987

import struct
import binhex
import sys

# You'll need to find the name of your particular mouse to put in here...
mFile = open("/dev/input/by-id/usb-05e3_USB_Mouse-event-mouse","rb")

# And this is the communications file
mLog = open("/$.m55.eyepiece.remote/udrv.mouse.comm", "w")
mLog.close()

while True:
    mChunk = mFile.read(16)
    (mType,mCode,mValue) =  struct.unpack_from('hhi', mChunk, offset=8)

    if mType == 1 or mType ==2:
                # These represent button-click and movement messages

        mRes = str(mType) + ", "+str(mCode) + ", " + str(mValue)
       
mRes = mRes + chr(13) + chr(10)
        mLog = open("/$.m55.eyepiece.remote/udrv.mouse.comm", "a")
        mLog.write(mRes)
        mLog.close()
   
This program is launched using a single-line BASH script:

#/bin/bash
# Filename:  script.mousestart.sh
# Simple script to start the mouse driver program
python /$.m55.eyepiece.remote/udrv.mouse.py
quit
And finally, the reader program:

#!/usr/bin/python
# Filename: udrv.MouseComms.py
# Mouse comms reader program (proof of concept)

# Core logic courtesy of PeterO on the Raspberry Pi forum.
#  http://www.raspberrypi.org/forums/viewtopic.php?f=63&t=80987

import struct
import binhex
import sys
import subprocess
import time

mLog = open("/$.m55.eyepiece.remote/udrv.mouse.comm", "r")
mActive = False
mCount = 0
mTime = time.clock()

while True:
    mBuff = mLog.readline()
    if mBuff != "":
        mActive = True
        mTime = time.clock()
        print mTime, mBuff
    else:
        mCount = time.clock() - mTime
        if mActive and mCount > 0.1: # Flush the buffer.
            print "Flushing buffer"
            mLog.close()
            mLog = open("/$.m55.eyepiece.remote/udrv.mouse.comm", "w")
            mLog.close()
            mLog = open("/$.m55.eyepiece.remote/udrv.mouse.comm", "r")
            mActive = False
There is no attempt at locking the file by the during a write operation, so some care is required in operation. This is not a substitute for a GUI mouse driver, after all.

In theory, this system could be used to make precise measurements of the relative motion of mouse and surface, though the need for careful tracking and conversion of mickeys (mouse pixels) to millimetres is fraught with difficulty. Theoretically, this could take the place of a binary scale for sensing the position of the specimen stage for macro focusing.

Note that /$.m55.eyepiece.remote/ is the path to a network shared drive, and is not located on the Raspberry Pi's SD card system drive.



Thursday, 15 January 2015

Eyepiece - absolute position sensing using optical detectors.

There are several ways of locating the relative positions of two mechanical components:

  • Having a datum position (micro-switch, optical interrupter etc.) and calculating the position by measuring the number of pulses (opto-interrupter, motor steps etc.) taken to get somewhere.
  • Using an ultrasonic measuring device (sonar)
  • Using a laser measuring device (laser rangefinder)
  • Using laser interferometry
  • Using an optical scale and a series of sensors.
The first method is simple for the fine focus mechanism on the M55 microscope as this doesn't drift at all.

For the macro focus mechanism, using a datum and calculation doesn't really allow for the possibility of disturbing the set up, either while changing optics, swapping samples or drift due to the heavy sample stage that has to be braked.

Sonar and laser rangefinders are both relatively inaccurate and are both expensive and challenging to implement satisfactorily.

Laser interferometry is an excellent solution for extremely precise positioning, but is unnecessarily complex for this project. Interpolation between the 1mm marks of the scale will be done by counting stepper motor steps.

An optical scale can easily be designed and sensors may be recovered from such devices as old computer mice. This is the route I have settled upon.

Being something of a pack rat, I had half a dozen defunct mice of various types - most of which contained one or more optical interrupters (quadrature encoders for mouse ball position etc). These interrupters comprise an Infra Red LED and a dual Infra Red sensing Phototransistor - as two discrete components.

Unsoldering these is a simple task, yielding about 20 detector pairs.

How does an optical scale work?

Firstly, there are two geometries available - reflective and transmission.

The reflective detector shines a light (usually Infra Red) on a scale and the light level between white (reflective) and black (absorptive) represents a binary one or zero.

The transmissive system simply shines the light through a sheet of paper or plastic. Where the material is opaque, the light is interrupted and where transparent, the light is transmitted - representing the binary value as before.

By printing a grid pattern of black and white representing binary values from, for example, |000000| to |111111| (six bits), a position scale of zero to sixty three positions may be measured. 8 bits give a range of zero to 255. The rectangles on the scale (left) are 0.8mm high on a 1mm pitch, while the ladder on the far left has rectangles 0.25mm high at 1mm intervals - this represents the millimetre datum, and should ensure that the position detection is accurate to ±0.25mm.

Arranging for reliable reflective detection of these small panels is beyond most domestic electronics workshops. On the other hand, transmissive detection is as simple as positioning LEDs and detectors on opposite sides of a piece of paper and getting everything properly aligned. In theory, it should be possible, with the salvaged detectors, to measure down to 0.25mm, though this is rather more precise than the application actually calls for.

Precision - I may test out using a thinner mm scale ladder, or even go to 0.5mm resolution



The Electronics:

Testing the concept (as well as the individual devices) requires a simple circuit to be built. Because the sensitivity may need to be tweaked, I built this using breadboard with a suitable 5V power supply.

Optical position test circuit
The two phototransistors in the package are connected in parallel, giving a degree of redundancy.

The IR LED (D1) illuminates the phototransistors (PH1.1 & PH1.2).

When illuminated, they begin to conduct through R2, pulling the input of U1.n low. U1 is a hex inverter with Schmitt inputs (74LS14), which removes the uncertainty of when the device switches between .true. and .false.

The LED (D2) provides visual confirmation of the output state of U1.n.

The value of R2 alters the sensitivity of the input - values between 82kΩ ind 180kΩ will adjust between insensitivity and extreme sensitivity respectively. 82kΩ is about right for the test IR LED that I was using.

Bit(n) represents the output to the computer.

Choice of material:
Printing the scale using an ink jet printer resulted in a much finer line, but an almost unusable scale due to the relatively low opacity of the ink. Doing the same using a laser printer resulted in an excellent dark/light sensitivity. Both scales were printed on standard photocopier paper.

Colour Scheme:

The scale is actually designed as a white panel = binary zero. This is because a generally dark scale produces less glare (crosstalk) between channels. Because of the way the detector and Schmitt input operate, this translates correctly, resulting in the output being a binary number of millimetres from the datum (maximum elevation of the microscope stage).

Mechanical support:

A paper scale, while easy to produce, is rather too flimsy for this application, thus I will, in the near future, try the transmissive detector using a scale that has been put through a laminator, otherwise, supporting it with a clear acrylic panel will be necessary.

Computer Input:

I have a Quick2Wire interface that will connect to the Raspberry Pi, and, using the port expander, will allow a number of additional interfaces to be connected while providing some protection for the GPIO pins of the Pi.



Sunday, 4 January 2015

Eyepiece - on stepper drivers and motion sensors

I have spent the past couple of days designing the electronics by which to control the stepper motor that will be used to operate the fine focus of the microscope for image stacking.

The mechanism has an extremely free operation and the end stops cause the knobs to continue to rotate through use of a fairy stiff friction clutch.

The output torque of a stepper motor is roughly proportional to the current through the windings, and thus to the voltage of the electrical supply.

The motor that I have has 40Ω windings, and is designed for use at somewhere around 20V - therefore, it would be possible to drive the stepper at a lower voltage, set so that the motor stalls at the end of the focus mechanism's travel.
Preliminary circuit design - stepper controller


Stalling a stepper motor (difficult to do when fully powered) doesn't damage the motor or the drive circuitry (one of the reasons for my choice of stepper rather than a DC servo motor).

I am still refining the design and features of the board which will be used to drive the stepper motor.


_______________________________


While on the subject of the focus mechanism, I wanted to be able to detect when the motor stalled. One way would be to use an optical encoder, either attached to the motor or to the focus knob, but the problem remains that if the knob bounces as the motor state changes, that small motion could well be registered as continued movement.

To prevent this, a quadrature encoder would be required - and thus calling for its own additional circuitry to determine whether the motor was stalled or not.

The alternative would be to use dome form of optical device to detect the net motion of the knurling on the knob.

Now, what device do we all use to detect relative motion?

A clue, most of them are attached to our computers and located alongside the keyboard.

A cheap mouse will do the job, and ten minutes effort with Google provided sufficient information to be able to, theoretically, access a USB mouse directly from software.

Edit:

I have now tested this idea - and, not only does it work, but it detects the three microswitches, too!

Because of the way Plug 'n' Play works, multiple mouse devices are separately enumerated, and their names placed in the appropriate directory
 /dev/input/by-id/ 

The python program that is used as a proof of concept is:

#!/usr/bin/python

# Core logic courtesy of PeterO on the Raspberry Pi forum.
#  http://www.raspberrypi.org/forums/viewtopic.php?f=63&t=80987

import struct
import binhex

# You'll need to find the name of your particular mouse to put in here...
file = open("/dev/input/by-id/usb-192f_USB_Optical_Mouse-event-mouse","rb")


while True:


    byte = file.read(16)
#    h = ":".join("{:02x}".format(ord(c)) for c in byte)
#    print "byte=",h

    (type,code,value) =  struct.unpack_from('hhi', byte, offset=8)

    if type == 1 and value == 1:
        if code == 272:
            print "LEFT PRESS",
        if code == 273:
            print "RIGHT PRESS",
        if code == 274:
            print "CENTRE PRESS",
        print code

    if type == 2:
        if code == 0:
            print "MOVE L/R",value
        if code == 1:
            print "MOVE U/D",value

    if type == 0:
        print "Clear Event", type, code, value

    if (type <> 0) and (type <> 1) and (type <> 2) :
        print "other event", type, code, value


_______________________________


While I like to build my electronics on custom printed circuit boards and, indeed, have the software to do so, it tends to be somewhat expensive - especially should any error be made in the board design.

Since it is unlikely that this electronic design will ever be anything but a one-off, I have decided that I will be building using either proto-board or strip-board.
That is, to say, AFTER testing the design out using breadboard!