Thursday, July 17, 2014

Arduino Pulse Counter

Today I decided to create a computer interface for the geiger counter I repaired several years ago. It is a Black Cat Systems GM-45 that takes in 12V and outputs 12V pulses for each incident detection. It uses a russian mica window pancake tube, which is very sensitive. There were some issues with the HV inverter circuit when I bought it second hand, and they were easily fixed by simple component swaps. It was originally designed for RS232 communication, but this unit did not have a DB9 or DB25 connector on it, just flying leads. Likewise, it did not have the window exposed from the housing. I did the housing modifications when I first got it, but I'm debating remounting the board into a better enclosure and leaving the excessively fragile window enclosed and protected.

The hardware is simple, a 100nF dc blocking cap to block the ~2.4V DC bias on the output and a 10K:10K voltage divider to step down the ~9.6V to <5V suitable for TTL/USB communication. Corrected output is fed into the Arduino's pin3 and a ground/return wire is run between the arduino and GM detector for continuity.

The software was relatively straight forward for the counter. It simply increments a variable each time a pulse is detected and sends the total to the serial monitor at a set interval. Note that no delay command was used since it needs to count pulses while timing. I also programmed in an indicator LED to pin13 which had a built in led on the Uno. I had to code in hysteresis, which took me several hours, for this LED as the ~<10mS pulses are too short for our eyes to see well. This involved an entirely separate timer routine and some creative coding to toggle states efficiently.

Here's the links to download the .txt files with the arduino code.
General Purpose Pulse Counter

Note that the LED will appear continuous above about 30Hz. You can set the time period and make adjustments to better suit your needs, but remember that I'm only transmitting data from the arduino via the serial port, not to it, so you'll need to push new code for each change.

As well as this works I may look into picking up a cheap USB-RS232 converter and DC-DC converter to step up the 5V from USB to 12V so that I have a more compact all in one, always on radiation monitor. I don't want to tie up my only arduino, and as is this is taking my best breadboard and bench supply to power!

7/20/14 UPDATE: I noticed that when used for a geiger counter scaler that the readings were a bit high. When I was writing the program I was concerned that the entire loop might be executed so fast as to have multiple triggers for the same pulse. This was confirmed with single pulse testing. I revised the code to include a delay line that prevents multiple triggering. There is now a user changeable variable that sets a dead time before the arduino will count an additional pulse. This is set to 100uS by default but easily changed to suit your needs. For non square pulses keep in mind that the arduino's digitalRead triggers on about 2.0V, so just have it for as long as the waveform is above 2V. I've also revised the serial output code for better visuals when used as a geiger counter and added in the function of dose rate conversion. Simply put in the counts per microRem into the GMsensitivity variable and it will do the math for you. To not clutter things there are now two .txt files, one for generic counter, and one for geiger counter. Enjoy!

Wednesday, July 16, 2014

DIY Arduino Stepper Motor XY Laser Scanner

I've recently worked on a project that I had the parts for for quite some time, but never got started on. I salvaged this XY stepper head from a cheap chinese "laser show" which had no programmable inputs and a nonfunctional "auto sound" mode that would only repeat the same three patterns over and over again. The laser that was built into it had its pump diode die a thermal death a long time ago so I shelved it and planned on modifying it eventually.

I decided to look into stepper motors and their control schemes and found that it would be rather simple to code the subroutines for single coil per step movements on an arduino. Once I realized this, it was time to start work.

Now, steppers aren't particularly fast or accurate, especially at the upper limits of their speed, as they start to miss steps. I can get these cheap ones to about 2.75mS/step and no further without losing steps, but that's good enough for me.

Instead of driving the motors with an intermediary IC (or even an entire dedicated board) designed for stepper control I decided to just go discrete electronics with NPN bipolar transistors and small signal fast diodes for flyback recovery. I'm only driving one coil at a time since I don't have the pinout for the motor coils and it is a 5pin unipolar motor with common ground. It doesn't appear that it is two center tapped coils with common CT., but rather it looks to be four individual coils with tied ends. I know there are ICs that can use the two center tapped coils in a bipolar drive method to allow microstepping and such but I don't think that is possible with these steppers. The reason for the NPN BJTs is that the arduino can only sink or source 40mA maximum per I/O line and these steppers draw about 90mA @ 9V (and they're 12V steppers, but run down to 5V min).

I experimented with increasing the motor voltage in hopes of gaining speed, but no increase in accuracy or speed was measured between 5.7V and 12V. I found that I got the best results with a 2.75mS ontime and 250uS offtime.

Unfortunately the mechanical issues of rotor inertia, jitter, and flicker could not be eliminated. Only the simplest of designs could be reproduced without a large degree of error. Attempting to reproduce a number 8 results in two vertically stacked squares with a space in between them, tethered in the center. (see video #3).

For the amount of work it takes to get this poor result it isn't worth continuing further. It was a good exercise and a fun experiment if you ignore the 12hours or so of coding. I wrote nearly 2500 lines of code for this, and while most were just edited copy/paste, it was still a nightmare of a job. There are 64 subroutines written for motor advancement: 1 to 16 steps forward, 1 to 16 steps backward, each for two axes.

The code is straight forward; manually pulse each coil for a set time in grouped ordered bunches to produce movement. The Achilles heel is that this is completely open loop. There is no way to detect or remember what the last coil used was so when you go back to the same axis you have to manually insert code to bridge the gaps to ensure it doesn't inadvertently reverse steps or miss steps entirely.

For example:

void loop(){
  xplus4();
  xminus4();
}

Thus pulses coils as such: 1 2 3 4 4 3 2 1. Notice the double pulse of coil 4? This means the rotor will sometimes make 4 positive movements and then three negative ones, and other times it will make three positive and three negative, depending on where the rotor was when the first pulse to coil 1 hit.

If we wanted to fix this we would have to do as so:

void loop(){
  xplus4();
  digitalWrite(1, HIGH);
  delayMicroseconds(tON);
  digitalWrite(1, LOW);
  delayMicroseconds(tOFF);
  xminus4();
}

This pulses as such: 1 2 3 4 1 4 3 2 1. Now we'll always get four positive and four negative steps, but occasionally we'll get five positive initially, again depending on rotor position.

Consequently, the subroutine for xplus5 looks just like 1 2 3 4 1, so I would have just used it instead, but I wanted to illustrate the process more precisely. This example has a pre-written subroutine that fits in as a correction, but most transitions do not.

The hardware circuitry is simple, as this schematic and picture show:



Here's a link to the arduino code: 
https://app.box.com/s/mtae49elczo39468myul