In a Chicago winter it’s way too cold in the garage for woodworking, so I turn to coding to pass the time. In 2014 I built an ATTINY85 Morse Code keyer in an Altoids Small box and in 2015 I expanded that with an Arduino Pro Mini based keyer in a regular Altoids tin. It was a lot of fun and consumed pretty much the whole winter. I’ve written down a few ideas for enhancements and in this year’s model some of those are implemented. The hardware wish list (so far):
Batteries and LCD won’t fit in an Altoids tin. I found a metal Crayola box at Tuesday Morning. It was made by the Tin Box Company, who produce many designs that would make interesting project enclosures. It is 3″ x 5″ x 1.5″, about three times the volume of an Altoids box, the metal is slightly sturdier than Altoids but still flimsy enough to be difficult to work without distortion. I found the inside surface was coated with a thin layer of something which repelled solder unless sanded a bit first. I don’t see this particular box available any more but there is a slightly larger version. My experience indicates that the time to complete a project is inversely proportional to the size of the enclosure (maybe to the fourth power).
These days “Arduinos” come in many shapes and varieties. The latest official 1.6.7 IDE is almost 100 megabytes, expanded to accommodate different versions. I wanted to try processors other than the standard ATMEGA328, so last summer bought a Teensy2.0 (32u4) and a TeensyLC (ARM Cortex M0) made by PJRC. Both promise built in USB client support. The PJ in PJRC is Paul Stoffregan, who has contributed a great deal to the Arduino community. There’s an IDE add-on “Teensyduino” that must be downloaded from the PJRC site to use Teensy boards. Teensyduino installation is dead simple and includes Teensy versions of most familiar Arduino libraries plus a few useful additions from Paul.
Last summer I worked with the Teensy2.0 a bit, wanted to see if the DDS sine wave generation function I used in the 2015 design would work. The port was successful, the 32u4 required only a few minor tweaks, and I even got Fast PWM working as described in Atmel’s documentation. PJRC has a forum where you can brag about your accomplishments so I wrote something on the 32u4 DDS sketch thinking it might be useful to others. Paul Stoffregan replied suggesting I consider a Teensy3.2 as it has an integrated Digital-Analog Converter which would produce a cleaner waveform. I fired up the similar TeensyLC and used Paul’s suggested method. DDS on the TeensyLC was also successful so I built a breadboard version of last years keyer using the LC. Everything worked with PJRC’s libraries including DDS side tone, the PS2 keyboard, and lcd.prints added for the display.
The small module at the upper left of the breadboard is an Adafruit PAM8302 audio amplifier. Last year I struggled with a 1 transistor class A amp for the speaker, gave up on that and built an LM386 design. The PAM8302 amp at only four bucks is clearly a winning choice. The only problem I had was later on I discovered the Output side did not like being grounded and I had to insulate the external speaker jack.
TeensyLC has one serious limitation for my application. Because the ARM chip handles flash differently than the MEGA328, TeensyLC has only 128 bytes of emulated EEPROM. That meant limiting stored button memory to four messages only 30 characters each. At that time I was thinking about adding a Real Time Clock so looked at getting Adafruit’s FRAM breakout and their DS1307 RTC. But for less money than these two modules plus a TeensyLC I could get a Teensy3.2 module with a Cortex-M4, lots of memory, built in RTC, and 5 volt tolerant inputs. I sent off an order to Adafruit (10% off if you watch “Ask An Engineer”).
Teensys have lots of I/O pins, same spacing as the LCD modules, so I elected to mount the Teensy board directly on the LCD. One 3 pin header and one four pin header is needed. In the next photo you can see the headers with two short gray spacers to separate the PC boards. I had to flatten one of the LCD bezel mounting tabs for clearance but the mount is very compact and rigid. Note to self: make sure you don’t need any more connections to the bottom of the board before soldering down the headers.
I had the idea to use a software driven flashing LCD back light to indicate a flat battery. ARM I/O pins are limited to 9 milliamps each, not enough for an LCD back light so a 2n2222 transistor was glued in to act as back light current switch. The trim pot on the right is for adjusting LCD contrast. It is across the back light LED pads, did not work out well, as later in development I am PWMing the 2n2222 to get adjustable back lighting. So the trim pot has been moved up on the LCD board, epoxied in place, and hard wired to ground and +3.3 volts.
The two wires leading off the right end of the Teensy go to a CR2032 backup battery for the Real Time Clock, and you can just see the Adafruit 32KHz crystal added on the bottom of the Teensy. With this minimal configuration I was able to test and experiment with the built in RTC using the example program furnished with the PJRC Time library, modified with LCD prints. Initially setting the clock was a problem, you need to send a “T” followed by Unix time (seconds since 1970) into the serial port. I worked out this Linux incantation to get the proper format for Central Standard Time:
echo T$[`date +%s` – 6 * 3600]
Then copy “T1453151560” and paste into the Arduino serial window. Once the clock has been set it takes care of itself though I’m not sure how. I believe it reads and sets time from code uploaded from the compiler. The Time library is more than a little obscure.
Of course many wires have to be added to interface Teensy with the rest of the keyer. It’s not so neat looking now, I’m using nearly every I/O pin plus power from the built in 3.3 volt regulator. I use mostly 24 gauge wire, solid if connecting to other points on the lid, stranded if routing to points below. I have an old Ungar fine tipped soldering iron plugged into a Variac set to about 70 percent.
There are three auxiliary perf boards in the design, One mounts seven memory switches, another holds volume control, transmit LED, and the Function button, the third has clock battery and an optoisolator for transmitter keying. These boards were carefully laid out on paper, then cut out and marked up so mounting holes could be located. Working with a hinged lid box you have to be careful to leave extra clearance for the lid to close. I did have to file a bit off the button board and the speaker.
The box needs a couple dozen holes to mount parts. Blue tape was applied to all surfaces, a layout drawn on the tape, then all holes center punched. I start with my smallest drill bit in a drill press then enlarge 1/64 at a time to final size. A few holes required fine tuning with a tapered reamer. I made a rectangular cutout for the LCD bezel by using a wooden template screwed to the lid, then cutting with a 3/16 carbide router bit surrounded by a 1/4″ collar. Mounting hardware is mostly 2-56 with a few 4-40 spacers.
I had a pair of paralleled 18650 cells taken from a cell phone charging pack. These are fastened in the box by a strip of tin can metal soldered in, and restrained by an angle bracket soldered at one end. The small speaker was taken from a defunct IPod dock. In the next photo, most of the lid components are mounted. The small audio amp board goes on the two screws at right center of the lid, mounted mezzanine style.
Next is a close up of the batteries with 2 amp fuses soldered in both plus and ground leads. Also see three stereo jacks at the right side for Key/Audio Out, External Speaker, and Paddles In. You can see in the bottom three long #2 screws for mounting the third perf board and Adafruit boost/charger. Most board mounting screws have three nuts; one to secure the screw, one to support the bottom of the board at the proper height, and a third to secure the board against the second. Thank heaven I still have a Heathkit nut starter.
At the right side of the box there is a power switch, PS2 jack, and a micro USB jack breakout. The power switch does not actually switch power, it grounds the Enable pin on the charger board which turns off the boost converter. That allows charging to continue while the rest of the unit is off. Later in debugging the hardware, I added bypass capacitors to that switch and a separate wire to the Enable pin on the audio amplifier which suppresses a weird sequence of sounds from the speaker on powering off. The PS2 jack leads wouldn’t reach the processor board so they route to the third perf board and get jumpered there to stranded wire headed for the Teensy. It’s getting hard to find a real PS2 keyboard but the software works fine with a USB keyboard plugged into a USB/PS2 adaptor.
This is a good place to register a complaint. I bought the Adafruit PowerBoost 500 board to manage the battery. It charges from 5 volt USB in and boosts from the 3 volt battery, seamlessly switching sources when you pull the USB connection. It does NOT however pass through or even break out the two USB data pins from the micro USB input jack. The only way to actually use USB while charging the battery is to wire out the D+ and D- leads outside the board. Adafruit support suggested doing this by cutting up a USB cable. I was able to route the micro USB breakout data leads (Green in the next photo) to the processor and the incoming positive and negative supply leads to the PowerBoost using a plug from an Adafruit micro USB connector (red and black in the photo). An extra $2.50 in parts that wouldn’t have been needed if Adafruit had only provided pads on the PowerBoost for D+ and D- or better, added two traces to route the data signals from the input connector to the output connector.
One more issue with the PowerBoost. It has a nice pair of status LEDs (where it says CHRG) yellow when charging and green when fully charged. These operate from a single pin on the charger chip but that pin is not broken out and you can’t of course, see the LEDs when the box is closed. I added a wire (gray, leading off to the right in the photo) to the common side of the LED dropping resistors so I could have the Teensy display charging status on the LCD. Not difficult but would have been nice to have official access to that chip pin.
The keyer has four monitoring leads between the PowerBoost and the processor. Besides the status signal mentioned above, I wired up the LowBattery pin and USB (power). USB activates the Status signal which is only valid when USB is plugged in and receiving power from the host. LB goes low when the battery is REALLY flat (3.25 volts I think). I also wired the BAT pin to the Teensy A10 analog input through a 10k calibration pot so software can read and display the battery voltage. You can see the calibration pot at the bottom of the board in this photo.
The next photo shows how I insulated the External Speaker jack by opening up the mounting hole and screwing a small piece of Lexan to the box. The plastic had to be counterbored so the jack mounting nuts would fit.
Here is a close up of the box lid interior. You can see the LCD contrast pot which is glued to the LCD, perfboard for the LED, volume control, and Function button. Two screws and a couple of spacers mount the PAM8302 audio amp on top of the LED board.
Here is the completed keyer opened up. Clockwise from top left, I/O stereo jacks, 18650 batteries, memory button board, Teensy3.2 processor on top of 16×2 LCD display, LED board, speaker, on/off switch, PS2 keyboard jack, USB input jack, PowerBoost charger/boost converter, and the transmit interface board.
An Eagle schematic diagram of this project can be downloaded from:
February 25, 2016 MemoryKeyerTeensy3.2_V1.0 Initial sketch
March 9, 2016 MemoryKeyerTeensy3.2_V1.1.0 Rework battery alarm logic, bug fixes.
March 16, 2016 MemoryKeyerTeensy3.2 V1.1.1 Workaround fix LCD does not have backslash in its font.
I posted a link to my previous page on setting up PWM Direct Digital Synthesized sine waves on PJRC’s Teensy 2.0, a 32u4 Arduino. Paul Stoffregen (the PJ in PJRC) commented that I should try porting my DDS demo sketch to a TeensyLC. “You won’t need PWM” he said. “Use the Digital Analog Converter” he said. I was a bit hesitant because TeensyLC has an ARM processor running at 48 Mhz. Quite a bit more power than the Atmel 16 Mhz chips and more I/O capability, so worth a look. PJRC supplies an Arduino IDE add on called Teensyduino which configures support for PJRC boards so simply doing an analogWrite to pin A12 (took me a while to actually find A12) starts the DAC instead of starting PWM. Teensyduino has an included library IntervalTimer which sets a repetitive timer running and attaches that to an Interrupt Service Routine which you supply. So an LC port should be simple as the dirty work of configuring the timer is taken care of.
Arduino PWM based DDS uses a fixed sample rate of 31 or 62 Khz and the interrupt generated sine wave has to fit into that constraint. That means low frequency audio tones are relatively smooth as there are lots of sample periods to go around even with the 256 step tables. High audio frequencies on the other hand, suffer distortion as the shorter period audio wave can’t fit in enough sample periods.
In the TeensyLC, the DAC always gets a fixed number of bits so you change the interrupt frequency to change the frequency of the generated audio tone. For instance, using the 256 step table, to generate a 1000 Hz tone requires 1000 * 256 interrupts per second. That’s about one every four microseconds, which even with the 48 Mhz processor clock, is going to use a LOT of CPU time. The shortest period I could set with IntervalTimer was 5 microseconds, my experiments with the demo program showed a maximum audio frequency of 650 Hz with the 256 step table, the 128 table limited at 1300 Hz, and the 64 step table maxed out at 2600 Hz.
Another down side to the DAC method stems from the fact that the audio frequency granularity is determined by the 1 microsecond granularity of the IntervalTimer function multiplied by the number of steps in the sine table. The demo program shows this while sweeping. Low audio frequencies sweep smoothly but the higher frequencies have very noticeable jumps. Higher sine table sizes show this effect much more.
But the output wave form is much better than PWM. The following photos were shot using the Quarter Wave symmetry version of the demo sketch. Full table version traces were identical. All these were taken at a set audio frequency of 440 Hz. The filter was a single 10K resistor in series with the output pin, and a 0.01 ufd capacitor to ground. You can see the wave period changing a bit with the different table sizes. That is due to the granularity issue.
I will probably use the TeensyLC in my next version of morse keyer. I have to find a 16×2 LCD that will work at 3.3 volts, figure out how to interface a 5 volt PS2 keyboard, and how to charge and connect a 5 volt battery pack. The LC (and the 32u4) have USB serial built in which will make interfacing a terminal window on a logging computer a lot easier.
I found a useful web page showing how you implement quarter wave sine symmetry DDS on an FPGA and I took this opportunity to streamline the quarter wave ISR. You have to be familiar with bit banging to understand it now.
The demo sketches, full table and quarter table versions, and the Libre spreadsheet I used to develop the quarter wave half step offset tables are included in the archive at:
My 2015 winter project will be an expanded version of the Morse Code keyer I built last year. I now have a PJRC Teensy 2.0 controller board (from Sparkfun) to use. The Atmel 32u4 based Teensy 2.0 is even smaller than the Pro Minis I have been using. It is attractive because it has USB built in for program loading and serial transmission. And there’s lots of I/O pins available which will make an LCD easy to connect. I note that everybody making a 32u4 “Arduino” is defining a different pinout from the chip. The Adafruit Feather is quite ambitious, has it’s own IDE addon and can be bought with Bluetooth or WiFi included.
This breadboard photo shows the Teensy 2.0 at top left, Sparkfun Pro Mini at center, Sparkfun RedBoard top right, and a MicroCenter Pro Mini clone at bottom right.
PJRC has ported many of the standard Arduino libraries to their 32u4 Teensy form factor and these are included in your Arduino IDE when you download and install the Teensyduino addon. But my keyer sketch uses Direct Digital Synthesis to form a nice sine wave side tone which requires direct setup of a Pulse Width Modulation timer inside the AVR chip. My implementation is based on code from Jeff Whitlatch, KO7M. I used timer 2 in last winters UNO based keyer as that’s the timer that does tone() in the Arduino UNO and I completely superseded that function. Reading the data sheet on 32u4 shows that it doesn’t even *have* a timer 2. It has timer 0 (8 bit), timers 1 and 3 (16 bit), and timer 4 (10 bit). Digging into the Teensy Arduino libraries shows that PJRC is using timer 3 for tone() so I needed a port that just changed the timer used. Comparing the 32u4 data sheet with the Mega328 data sheet showed that the only difference besides the timer number would be in the Waveform Generation Mode bits. 32u4 has four WGM bits, Mega328 has 3. I used a mode setting that turns the 16 bit 32u4 timer 3 into an 8 bit timer and Success! The port was working in my test program.
Phase Correct PWM in an AVR processor uses the timer in a manner that has it count from 0 to 255 then count back down to zero for each interrupt cycle. The PWM signal goes high on the way up and low on the way down. For an 8 bit counter, that’s 510 counts per cycle (read the data sheet to find out why it skips two) so with no clock scaling the sample rate is 16 MHz/510 or 31.4 KHz. In Fast PWM mode the timer counts from 0 to 255 then rolls over back to zero. A PWM wave on the output pin goes high on the way up and low on overflow. This results in some jitter on the PWM pulses but the sample rate is twice as fast, 16 MHz/256 or 62.5 KHz. I decided to try Fast PWM in the test program. It required only a change in the math that calculates the sample rate, and a slightly different set of WGM bits.
The following images show comparisons of the 31.4 KHz (Phase Correct) and the 62.5 KHz (Fast) rate tone waveforms from the test program. The PWM signal is filtered by a single 10k resistor and a 0.01 ufd capacitor to ground at the scope connection.
There is a clear improvement at the higher sample rate in the amount of “fuzz” on the waveform. The fuzz is at the sample rate and is the result of the 0.01 ufd capacitor integrating the PWM square wave. At twice the rate, the capacitor has half the time to charge or discharge. You can see at 5 KHz, the Fast PWM signal is much closer to a sine wave than Phase Correct. At 10 KHz, both are falling apart. A better output filter that cuts off the sample frequency would help but for morse keyer side tone from a tiny speaker, the average amateur radio operators ear won’t know the difference. I may try a switched capacitor filter some time in the future just to see. Watch this space.
2015/12/08 The photos above are all from the 32u4 port. The program uses quarter wave symmetry to reduce the table size by a factor of 4. Two sketches, one running on UNO or other Mega328 controllers, the other for the PJRC 32u4 Teensy are at:
I also back ported the changes to an earlier sketch that did not take advantage of symmetry. Scope traces were identical to the 32u4 port. Since the complete 360 degree cycle is specified, the code may be modified to generate arbitrary non-sinusoidal waveforms by manipulating the tables. Download at:
Each of these zip archives has a copy of the spreadsheet I used to construct the sine tables.
I’ve done a couple of homemade dual lever paddles but recently I wanted to demonstrate my Tiny85 Arduino based keyer project at a local Maker Faire, so wanted something I could put in my pocket. In a few minutes, I made this. It’s a standard 3.5mm (1/8 inch) stereo plug. You can’t get any more portable than that.
Unscrewing the plastic shell reveals the secret sauce.
This is the dash paddle side. Just a tiny bit of thin copper soldered to the plug terminal. For those readers needing details, the copper came from the band around a Basil Hayden’s whiskey bottle. We recycle!
Here is the dot side.
A bottom view, you can see the two copper strips and how the sleeve (ground) contact was bent to form the common contact. A little careful tweaking left a thick sheet of paper’s worth of space between each copper strip and the common contact.
And the top side.
I was surprised to find it actually works. Could be useful on a QRP mountain top expedition. Have a look at this YouTube video.
This project was done for a Friend Of a Friend. He needs to monitor water flow rate and quantity for his solar heating projects. He is mainly interested in this two inch sensor but also sent along a small plastic hose bib type similar to the Adafruit 828. Both of these sensors are turbine types, water flow spins a plastic wheel which magnetically triggers a pulse output proportional to the speed at which the wheel is turning. There’s lots of these sensors made for irrigation and industrial processes. The display is sometimes called a “Totalizer”.
This photo shows the 228PV sensor connected to the prototype display. I am spinning the turbine with air from a heat gun.
The electrical interface on the small flow meter has 3 wires, power, ground, and pulse output – relatively simple to connect to the microcontroller. But the large device has only 2 wires. It signals a pulse by shunting power to ground through a low resistance. The display must sense a pulse by looking for an increase in supply current. I designed an interface circuit that works with either unit by changing an option jumper. I constructed the interface circuit on a small piece of project board from Radio Shack (RIP). The positive supply feeds through a resistor which produces enough voltage drop when the large sensor is pulsing to trigger a digital low at the Arduino. The series resistor value is low enough that the power feed is still adequate for the small plastic sensor, so the option jumper just selects where to pick off the pulse signal. A series resistor and zener diode make sure the voltage ratings of the Arduino input pin are not exceeded. It’s a bad thing to overvolt an Arduino pin, please Don’t Ask Me How I Know This.
In this photo you can see the interface board soldered down near the front of the Altoids tin. I use “L” shaped bits cut from a paper clip, soldered to the board ground, and to the ground plane. The same technique anchors the Arduino board.
At first I worked up the circuit on a solderless bread board using code from the Adafruit web site. When satisfied with the results, I went ahead with building the Altoids tin prototype. The Arduino variant I used is a Sparkfun Pro Mini 5 Volt. It takes up little space and has a 5 volt regulator with enough capacity to run the 16×2 LCD. An LED and two push buttons protrude through the lid, these are regular 6mm square PCB buttons. I solder one side directly to the lid, the other side of the switch is supported by a bit of PCB material and a piece of paper clip wire.
This photo shows the LED and the Reset button. Note the bit of PC board on the high side of the switch has a groove filed across so the grounded paper clip is isolated from the signal connection.
This photo shows the Function switch. It’s hard to see, but there is a 0.05 ufd surface mount capacitor soldered between the signal side and ground. That capacitor is part of my debounce strategy.
The Liquid Crystal Display itself mounts on four 2-56 screws. The screw heads are soldered directly to the lid. I attached a 10k Pot for contrast adjustment to the back of the LCD and it’s legs are used as tie points for 5v and ground wiring to the rest of the display.
If I have to build another one of these, I might glue the Arduino board to the back of the LCD which will greatly reduce the wiring between lid and box.
There is a power jack for 9 or 12 volt DC input, and a 3 conductor phone jack to connect the turbine sensor. These are epoxyed to the box. Connection to the sensor plug is as follows:
Ground to the plug sleeve
Positive lead to the plug tip
If the sensor is a 3 wire type, the pulse lead connects to the plug ring
The opposite side of the box has a simple on/off slide switch mounted.
Almost all of the turbine type flow sensors I looked at have two calibration factors specified: a “K” factor and an “offset”. During calibration the manufacturer measures the pulse rate outputs for a number of precise flow rates. These are plotted but since the turbine has some friction, the graph will not be linear especially at the low end and a linear regression is done to get a best fit straight line. The “K” factor represents the slope of the fitted line and has a dimension of pulses per unit volume moved. Offset represents the small amount of liquid flow required to start the turbine moving. You can assume that if any pulses are arriving at all, at least the offset volume of liquid is moving. The 228PV manual specifies:
Frequency = (Gallons per Minute / K ) – Offset
We are measuring pulse frequency so turning the equation around:
Gallons per minute = (Frequency + Offset) * K
In general, this formula applies to any measurement unit. It would be possible to convert a gallons display to liters by just scaling the K and offset factors by the constant liters/gallon. The Adafruit example sketch uses this method but measures pulse period in 1 millisecond increments which creates large gaps in the data if the pulse rate is over 100 Hz. At 200 Hz the pulse period will be 5 milliseconds, so a 1 millisecond period change is a 20 percent jump!
The following photo shows the display running Adafruit code:
Adafruit states their sketch is just an example to verify their sensors functionality but I felt higher accuracy at large flow rates was essential. An internet search turned up several sketches using a direct interrupt to count pulses. The sensor pulse train is applied to pin 2 or 3, fires on the rising edge of a pulse and calls an Interrupt Service Routine like:
// Increment the pulse counter
Can’t get much simpler than that. Run this for exactly one second and you have counted pulses per second. Apply to the above formula and get volume units transfered in that second. Accumulate that many units each second to find total volume transferred. So the code to actually calculate rate and volume is easy. I exorcised most of the Adafruit code and added my own formulas. I also added a line in the ISR to blink the LED along with the incoming pulses.
But this display needs to operate with multiple types of flow sensors. So I had to code an arrangement to set and permanently store K and Offset for whatever sensor was plugged in. That turned out to be the most complicated part of the sketch. I use the Function button to do this, taking advantage of the Arduino setup section which is only executed on a reboot. Holding Function down while resetting the processor starts set mode.
Releasing the Function button displays the stored K factor with a cursor flashing over the first character, the sign.
The Function button has three uses in set mode, depending on how long it is held.
A quick click increments the digit under the cursor
A press between 2 and 4 seconds advances the cursor to the next digit
A press greater than 4 seconds completes the setting and moves either to the offset setting or writes the data
To make this a little easier, I added code to blink the LED if the button is held between 2 and 4 seconds, and turn on the LED solid if held more than 4 seconds. I hope this is no more annoying than setting a cheap digital watch.
Note that K factors are always positive but occasionally a negative offset is specified.
This photo is the normal running display entered after exiting set mode, or on a processor reset. The first line records units moved per second, where units is in whatever the given K factor uses. Both the Adafruit sensors have factors specified in Liters/Second. The 228PV I’m working with uses units of Gallons per minute. The water meter on my house here measures in cubic feet. You have to consult the sensor data sheet.
Resetting the processor zeros the cumulative quantity moved.
Finally, holding the Function button down during normal operating mode will cycle the following four displays:
The stored K factor
The stored Offset
Accumulated time since last reset. Note this is subject to the accuracy of the 16 Mhz clock in the Arduino.
A software version number.
I’ve constructed a second unit. This one is built in a nice looking Extruded Aluminum box from Adafruit. I thought the better enclosure would make construction easier. I was wrong. Because it can’t be opened you can’t reach in and solder anything, and you lose the convenience of soldering anything needing a ground directly to the tin box. That means wires have to be attached to every terminal, brought to a common point and spliced. I did try soldering the Pro Mini to the back of the LCD and that works but the contrast pot had to be wired out so the assembly didn’t save much wiring. This photo shows the completed display with K factor set to 1.0 and a 2000 Hz crystal controlled signal applied to the sense input:
The left side has a power switch and also an SPDT switch for 2-wire/3-wire operation that replaces the option block in the prototype.
Sense in and power jacks are mounted on the right panel
Have to open the left side to connect an FTDI Friend
Most of these flow sensors will have specified somewhere in the data sheet, a K factor and offset. What the manufacturer does is plot flow in output pulses per second (frequency) against flow volume through the sensor at a number of flow rates. Then they do a linear regression on the data to get a best fit straight line. An example is Fig 1 in http://www.hofferflow.com/datasheets/miniflow2.pdf.
K factor is the slope of the line, usually given in pulses per unit volume, for example pulses per gallon. Offset accounts for the plot not being non-linear at the low end. Because of friction, it takes some small amount of fluid velocity to get the turbine to start spinning. You can assume that if the turbine is pulsing at all, at least the offset quantity is moving. Less than the offset volume is undefined. In the sketch, interrupt code blinks the LED when pulses are coming in.
There does not seem to be a standard for how K factor is presented. Sensors output a pulse stream at a frequency proportional to the flow volume as calibrated, this can be measured. With some sensors, you multiply the pulse frequency by the K factor to obtain a volume rate. Others however, require you to divide the pulse frequency by K.
In the sketch, I added a way to switch between these two methods by using the first character of the K factor. If this character is a “*”, the incoming pulse rate will be multiplied by the K factor, If the first character is “/” pulse rate will be divided by K. You may see a formula in the sensor data sheet like Freq = (Flowrate * K) – offset. Since we measure Frequency and need to display Flowrate, the formula is rearranged to Flowrate = (Freq + offset) / K and the K factor needs to be set to type “/”. Other sensors present Freq = (Flowrate / K) – offset. Rearranging that formula gives Flowrate = (Freq – offset) * K and you would set the K type to multiply, “*”. If the sensor documentation is not clear, just try it out. If the multiply/divide indicator is wrong, you will probably get totally unreasonable flows displayed. If so try changing the type indicator.
Here is a table from the FMC MNIT001 meter manual:
Note how K factors are presented in Pulses per Unit Volume. So for these meters, set the K factor type to “/”.
Another table, this one from Badger documentation:
Badger presents the flow frequency formula as:
So with these Badger sensors the rearranged equation to find flow rate is GPM = (Freq + Offset) * K and you would chose the multiply type option.
More information on the sketch’s K factor changes is in the file HERE_ARE_THE_DIRECTIONS.pdf included in the V1.10 dropbox download below.
The code can be downloaded from my DropBox account. I am carrying forward the original Adafruit license.
Version 1.oo Oct 08 2015 Initial release
Version 1.01 Oct 17 2015 Correct schematic error
Version 1.10 Oct 25 2015 Change method of applying K factor