Author Archives: myadmin

1-wire Power Injector

One way that I get reliable 1-wire communication is to use a power injector. This means that the along with the 1-wire signals, I inject a supply voltage into additional cable pairs.  Since  the most readily available commodity cable currently is 8 conductor Cat-5 cable, chances are that you also use this cable for 1-wire cabling and have spare wires going unused. Dallas called the 1-wire bus a MicroLAN, so I will continue to use their terminology here.

For short runs, where the total length of the MicroLAN is < 30 meters and the network only has maybe 6 to 10 slave devices on it, cable selection for use on the MicroLAN is reasonably simple, as even flat modular phone cable can work with a small numbers of 1-Wire slave devices. However, the longer the MicroLAN, the more important cable properties and therefore cable selection becomes more critical.  However, since I’m dealing with 30M or less, I’ll focus on that here and leave the research for  better cable techniques for when I run into a problem.

One of the remaining issues with using 1-wire driven from an Arduino pin directly is the fact that it is also providing power to all of the devices on the the 1-wire LAN when in parasitic mode.   While 1 or 2 devices are of little concern, I started to worry about building a reliable 24/7 full time  MicroLan configuration that would report weather data from 8 or so sensors, most of which were located at the garden bed outdoors.  It became clear that some of my devices were really not performing as desired  when “parasitically”  powered when I finally put all the pieces together.

Experimentation showed me that the signal from the Arduino pin was just not up to that task of powering and communicating with all the devices without some random miscommunication here and there.  I would get values like 185F and not the 70F I was expecting from a 1-wire temperature sensor, for example.

My solution was reasonably simple.  I would create an external “middle-man” device that would insert power into the CAT-5 cable after leaving the Arduino board.  Its really just a dual supply from typical commodity wal-wart power source.  The unmodified 12VDC supply will be fed into the cable on a spare pair and treated as “unregulated” and a 5V regulator will be added to another spare pair and considered to be “regulated”.  All code will now be written to comply with the “non-parasitic” mode of 1-wire.

The Design:

The PCB:

LC Meter – Working…

This is a variation of many many other LC meters already published. It owes much of it’s design to the AADE LC meter that relies on the oscillation of a standard Analog Comparator using a capacitor and a coil. This solution is an attempt to take Kerry Wong’s Arduino implementation and simplify it a bit and to make use of latching relay for mode selection.

Notes: Initially I used a 2% tolerance .001uF capacitor and a small 5% tolerance RFC 220uH coil. results were OK, but not real close to actual values even after some tweaks so I looked for an alternative in my junk box.

I found a 1800pF Mica capacitor with 1% tolerance and a 82uH radial choke coil (Basically, the kind used in higher current situations). I did some quick math and determined that frequency of oscillation would increase to somewhere between 414473 HZ and 419973 HZ with the former being the mathematical ideal. (which I modded to an even 420000 for simplicity.)

My changes (completed and planned) to the Kerry Wong’s solution includes:

1) Software controlled backlight – no switch – I just turn it on… that works for now
2) Implementation of Latching Relay to eliminate a DPDT manual switch
3) Using an 8×2 LCD for smaller footprint
4) Battery Voltage sensing. If battery is low, shut off the backlight.
5) Push-on/push off power control with timer based auto shutoff. (5 minutes)

Testing showed me that I really didn’t like using the KHM Library from Martin Nawrath. I mean, it basically worked and that is what Kerry Wong used… but, I found that it was impacting my mode switch and calibrate button sensing. And that was just not good now that I was using a latching relay instead of a DPDT switch for mode change.

In the end, I opted for the Frequency counting library from PJRC instead:


Sprint Layout File:
Sprint Layout (V6)


Layout (only 2 minor errors crept in during etching):

Etched PCB (tinned and sealed with matte clear laquer AKA Dullcote):

Silkscreen: Toner Transfer to TOP SIDE PCB, sealed with Future floor wax (clear acrylic)

Front Panel:

LC Meter revisited

So I really liked this LC meter that Kerry Wong came up with… with the understanding that it was based on a plethora of comparator based ocillator LC meters on the web but I wanted both less and more.

Kerry Wong LCF Meter

I wanted less of the Frequency meter… I already have ways to measure frequency… and I wanted to eliminate the DPDT L/C switch.

Here is my version of the circuit:

You probably already knew this but… latching relays are neat

So, I’m hanging out in IRC and a guy wants to be able to use a latching relay (and hasn’t bought one yet) and wants to know how it can help his battery operated Arduino device switch contacts but not lose power to an engaged relay coil. “Simple”, I say, and then realize that I had intended on researching small current latching relays for my own project.

So here’s the circuit.

…and here’s the explanation.

The relay that was chosen is from the very likable OMRON G6 series of tiny relays. It is a dual coil type that latches to a position after a brief “impulse”. In this case… after the Arduino briefly supplies a connection to GND for the coil using an NPN transistor.

The specifics of the part are: G6SK-2-DC5 (You can check out the the full specs HERE )

This device is a 5V unit with a pair of 125 Ohm relay coils. (works out to be about 40 mA, too much for a MCU pin… so NPN drivers are required, not optional)

So, why do we have a DPDT unit? Because we need a spare pair of contacts to let the Arduino know which state the relay is in after power up… since it can be in either position when power off. The Arduino can know the relay’s current state by checking to see if (pin 7 in this case) a high is seen on the sense pin. The sense pin is set to draw 0.5 mA when in the SET state and 0 mA in the RESET state.

For the curious: stocks this part

PD2435 and Arduino using I2C Port Expander

This information has been collecting dust on my hard drive.   Time to resurrect it…  Recently I have been working on a Temperature and  Humidity display and while working on it,  decided to use these RETRO parts I got from BGMICRO sometime around 2000. Even then, these parts were considered “pure unobtanium”.  I still had a few leftover displays, so out from the parts collection they come.

Now I had never taken the time to really get these displays working on an Arduino and what I really wanted was a test that would show off how much information you can really show using only 4 characters.

Since this project was to be inserted into an already working sketch, I made sure it was as modular as possible, sprinkled with subroutines that could be called from “who knows where” to get the job done.

I’ve tried to comment where it made sense and I have drawn up a quick schematic drawing to show just how its connected.  Since this part was designed for a CPU Bus Architecture of the 70’s and 80’s, it is annoying to see how demanding it is of the limited pin resources on the Arduino. The display assumes you provide data in a Parallel 8-bit format.  To relax this demand for pins, I employed a PCF8574 ( I2C port expander) that was harvested from some abandoned electronic board.  “YAY for recycling!”

The parts I’m talking about are the PD243x displays from OSRAM.

So, what we have here is some sample code, for the Arduino, that allows you to send ASCII strings (including text scrolling) to these vintage displays.  Some of the information that helped me get beyond the datasheet was gathered from around the Internet (including blogs in New York, Japan and Korea)  Kudo’s to TechBlog in Korea for creating such a great resource.


Interesting side story: WAY BACK WHEN… BG Micro had horrible 3rd party photocopies of a facsimile for these parts. They were almost entirely unreadable.  At the time, datasheets were generally unavailable on the Internet,  so, after spending hours searching with “Altavista”, I finally found a clean PDF copy of the datasheet. Rather than just keep them to myself, I decided to give a nice clean datasheet back to BG Micro so they could share it with other customers who purchased the parts.

PD2435 PD24xx






// PPPP  DDDD  2222  4  4  3333  77777        III  N   N OOOOO
// P   P D   D     2 4  4      3    7          I   NN  N O   O
// PPPP  D   D  222  44444  333    7           I   N N N O   O
// P     D   D 2        4      3  7     ..     I   N  NN O   O
// P     DDDD  22222    4  3333  7      ..    III  N   N OOOOO

// Program:      PD2437.ino
// Author:       Pete Willard
// Version:      0.01
// Target:       328p IDE 1.03
// Date:         2013/01/27
// Time:         12:00:18
// Notes:

// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <>.

// Reference: "nautes Tech Blog", "David Croft @"

//=====[ INCLUDE ]==============================================================
#include stdlib.h
#include Wire.h
//=====[ CONSTANTS ]============================================================
#define   DEBUG     1   // 0 = debugging disabled, 1 = enabled
// Address of PCF8574 IC on TWI bus is address 0100xxx (0x20)
// while the PCF857A address is 0111xxx. (0x38)
#define IO_ADDR (0x20)

//=====[ PINS ]=================================================================
int Led = 13;  // Not used
// Connected to PD2437 directly
int PA0 = 2;   // Address 0 (pin 9)
int PA1 = 3;   // Address 1 (pin 8)
int PA2 = 4;   // Address 2 (pin 7)
int WR = 7;   // Write (pin 7)
int CE = 5;   // Chip Enable (pin 6)
int RST = 6;  // Reset (NEG, pin 11)
//=====[ VARIABLES ]============================================================
char messagebuffer[21];

//=====[ SETUP ]================================================================
void setup()                    // run once, when the sketch starts
	Wire.begin();        // initialize the I2C/TWI interface

	// Setup pins for PD2437
	pinMode(PA0, OUTPUT);
	pinMode(PA1, OUTPUT);
	pinMode(PA2, OUTPUT);
	pinMode(WR, OUTPUT);
	pinMode(CE, OUTPUT);
	pinMode(RST, OUTPUT);

	// Reset PD2437
	digitalWrite(CE, HIGH);
	digitalWrite(WR, HIGH);
	digitalWrite(RST, LOW);

//=====[ LOOP ]=================================================================
void loop()                     // run over and over again

	// Can do this...
	char messagebuffer[] = "  Temperature: 68F  ";

	// Random Length String with INT value added
	int n = 34;
	sprintf(messagebuffer,"   Humidity: %2d%%  ",n);


//=====[ SUBROUTINES ]==========================================================

void CommandMode(){
	digitalWrite(PA2, LOW);  // enable command mode

void AsciiMode(){
	digitalWrite(PA2, HIGH);  // enable ASCII mode

void TogglePin(char bitpin) {

void PulsePin(char bitpin) {

void ClearDisplay() {
	PutChar(0, 0x83);


// Note: This looks funny because it reads the buffer from right to left
// Blame the display...  😛

void WriteDisplay(char *input) {
	for (int i=0; i<4; i++) {
		PutChar(i, input[3-i]);
	input = "";

void SetByte(int ch) {
	// Use TWI output Mode to Write to DATA BUS PINS on PD243x
// set address for PD243x

void SetAddr(int adr) {
	digitalWrite(PA0, (adr&0x1));
	digitalWrite(PA1, (adr&0x2));
// Main Character writing routine

void PutChar(int pos, int ch) {
	SetByte(ch);			// Pre-set the 8 bit data bus
	SetAddr(pos);			// pre-set the address bus
	digitalWrite(CE, LOW);	// Enable Display
	PulsePin(WR);  			// Read inputs and display it
	digitalWrite(CE, HIGH);	// Disable Diplay

void ScrollDisplay(char *ascii) {
	char buffer[4];
	int i = 0;
	boolean blank;
	while(ascii[i] != 0){
		blank = false;
		for (int ii = 0; ii<4; ii++) {
			if ( !blank && ascii[i + ii] == 0 ) {
				blank = true;

			if ( blank ) {
				buffer[ii] = ' ';
			else {
				buffer[ii] = ascii[i + ii];

No updates? I blame writers block…

Yeah, that’s the ticket.

So where am I as I start 2013.  Well, My Arduino based weather thingy is basically working.  The rain counter still dead… the now obsolete Maxim DS2423 seems a bad design choice now.  There must be a better way to keep track of the tipping rain bucket ( 5o tips per inch) that is non-volatile for those power outage times.

My Arduino based “make your own work bench tool” project is sort of stalled. Though I did find a neat oversize retro cabinet to put it in. (So 1980’s)

I’ll close up this update by sharing an old project… the Live For Speed Outgauge Bus Arduino interface (gear and RPM meter).

PC Network UDP to Serial conversion:  “PC CODE” and the Schematic.

Arduino Code: (pre-IDE 1.0)

 //----[ OutGaugeBus ]------------------------------------------------------
 // Name : OGBUS.PDE
 // Purpose : Receive serial commmands from "Live For Speed" INSIM OUTGAUGE
 // : Client and then display real-time dashboard information
 // : on Arduino based output devices, such as LED's.
 // : Live For Speed References:
 // :
 // :
 // : See Also:
 // Date : 25 Oct, 2007 ( Started as a Parallax SX28 project )
 // Version : 2.11
 // Modified: 12/22/2010 11:30:34 AM
 // Author : Pete Willard
 // :
 // Credits : * Mike McRoberts - Earthshine Design -
 // : Arduino Starter Kit PDF
 // :
 // : * Hacktronics -
 // :
 // : * Arduino ShiftOut tutorial
 // :
 // : To keep code "recognizable", available references were used
 // : and changed very little from reference sources listed above.
 // Notes : Includes using a 74HC595 Shift Register for the Bar Graph
 // : and discrete 7-segment display for gear indicator
 // :
 // : Commands come from OGBUS.EXE (DevC++ UDP Client) and convert
 // : INSIM OUTGAUGE data into serial packet data for Arduino
 // : INSIM Client Software will send ALL vaalues every update
 // : but can send as little as Clear Command "C0"
 // :
 // : Expansion:
 // : With a little creative wiring, it would be possible to
 // : daisy chain multiple serial Arduino boards or if USB is
 // : used, multiple OGBUS clients can be run at one time
 // :
 // : Command Examples:
 // : (Comma Separated Values) Any Order up to 24 Characters
 // : Format: <command></command>,<command></command>...
 // : C0 = Clear All Outputs
 // : G0-G8 = Gear Indicator
 // : R0-R8 = RPM Bargraph
 // : S0|S1 = Shift Light Pin On|Off (binary)
 // : P0|P1 = Pit Limiter Pin On|Off (binary)
 // :

//----[ Variables ]--------------------------------------------------------
 const int buffsize = 25; // Buffer Size
 char buffer[buffsize]; // Incoming Serial Data Buffer
 int debug = 0; // Set to NON-ZERO to test with Serial Monitor
 int ledCount = 8; // The number of LEDs in the Bar Graph LED
 // Seven segment LED layout for the Gear Indicator
 // Arduino pins must be sequential
 int GIstartpin = 2;
 // Arduino pin: 2,3,4,5,6,7,8
 byte seven_seg_digits[9][7] = { { 0,0,0,0,1,0,1 }, // = R
 { 0,0,1,0,1,0,1 }, // = N
 { 0,1,1,0,0,0,0 }, // = 1
 { 1,1,0,1,1,0,1 }, // = 2
 { 1,1,1,1,0,0,1 }, // = 3
 { 0,1,1,0,0,1,1 }, // = 4
 { 1,0,1,1,0,1,1 }, // = 5
 { 1,0,1,1,1,1,1 }, // = 6
 { 0,0,0,0,0,0,0 }, // = 7 (blank)
 // a b c d e f g ------> LED segment
 // Bargraph Values for 8 LED Bargraph
 // Only 8 values of BYTE are needed to light the 8 bargraph LED's
 // sequentially
 // NOTE: Most Bargraph LED's are "10 unit" so I have bottom 2 and top 2
 // LED's tied together.
 // Part Number used: AVAGO "HDSP-4832" 3-Green 4-Yellow 3-Red
 // Mouser Part Number: 630-HDSP-4832
 // The Shift Register lowest outputs start with Green Anodes of the
 // Bargraph.
 byte bargraph[9] = {0x00,0x01,0x03,0x07,0x0F,0x1F,0x3F,0x7F,0xFF};
 // LED PINS - optional since we are low on pins
 int shiftlight = 12;
 //int pitlimit = 13; // Pick one
 //int lowfuel = 13;
 // 74HC595 Pin Setup
 int latchPin = 9; // Pin connected to ST_CP (12) of 74HC595
 int clockPin = 10; // Pin connected to SH_CP (11) of 74HC595
 int dataPin = 11; // Pin connected to DS (14) of 74HC595

//----[ SETUP ]-----------------------------------------------------------
 void setup() {
 // Speed needs to match INSIM - Outgauge Client Configuration setting

// Set all pins to Outut Mode
 int a;
 for(a=0;a < 13;a++){ pinMode(a, OUTPUT); 

//----[ MAIN LOOP ]------------------------------------------------------ 
void loop()  { 
// Mike McRoberts serial input command routines 
// from the "Serial Controlled Mood Lamp" example 
// in Arduino Starter Kit Manual from Earthshine Design 
if (Serial.available() > 0) {
 int index=0;
 delay(10); // let the buffer fill up
 int numChar = Serial.available();
 if (numChar>buffsize) {
 while (numChar--) {
 buffer[index++] =;
 splitString(buffer); // Process Serial Packet

//----[ SubRoutines ]----------------------------------------------------

void splitString(char* data) {
 // also from "Serial Controlled Mood Lamp" example

if (debug) {
 Serial.print("Data entered: ");

// Sequentially De-Tokenize the Serial Commands received
 char* parameter;
 parameter = strtok (data, " ,");
 while (parameter != NULL) {
 // Pass result to parseCMD for each Command received
 // remove processed commands from the list
 parameter = strtok (NULL, " ,");

// Clear the text and serial buffers
 for (int x=0; x<buffsize; x++) {

 void parseCMD(char* data) {
 // Flexible, easily expanded Command Parser
 // based on "Serial Controlled Mood Lamp" example
 // *** Marvelous coding by Mike MCRoberts

 if ((data[0] == 'G') || (data[0] == 'g')) {
 // Have command, now get Argument "value" while removing whitespace
 int ArgVal = strtol(data+1, NULL, 10);
 // then limit the results to what we expect for this command
 ArgVal = constrain(ArgVal,0,8);

if (debug) {
 Serial.print("Gear is set to: ");

//--[shift light]--------------------------------
 if ((data[0] == 'S') || (data[0] == 's')) {
 int ArgVal = strtol(data+1, NULL, 10);
 ArgVal = constrain(ArgVal,0,1);

if (debug) {
 Serial.print("SHIFT is set to: ");

 if ((data[0] == 'C') || (data[0] == 'c')) {
 int ArgVal = strtol(data+1, NULL, 10);
 ArgVal = constrain(ArgVal,0,1);


if (debug) {
 Serial.print("Clear Outputs");

//--[rpm bar graph]-----------------------------
 if ((data[0] == 'R') || (data[0] == 'r')) {
 int ArgVal = strtol(data+1, NULL, 10);
 ArgVal = constrain(ArgVal,0,8);


if (debug) {
 Serial.print("RPM is set to: ");

} // End parseCMD Loop

 void sevenSegWrite(byte digit) {
 byte pin = GIstartpin;
 for (byte segCount = 0; segCount < 7; ++segCount) {
 digitalWrite(pin, seven_seg_digits[digit][segCount]);
 void shiftWrite(byte Rdata){
 // prepare the register for data
 digitalWrite(latchPin, LOW);
 // shift out the bits:
 shiftOut(dataPin, clockPin, MSBFIRST, Rdata);
 //Set the latch pin high to enable the outputs
 digitalWrite(latchPin, HIGH);

Weather Shield

I grew tired of working with a solderless breadboard and was worrying about the wires falling out of the makeshift  INSIDE portion of the DALLAS 1-wire weather station circuit I am working on (also the interface to other assorted 1-wire stuff outside) so I decided it was time for a PCB. The board contains a 2-wire BMP085 pressure sensor BOB and level converter… as well as a 1-wire temperature sensor.  This board contains the 1-wire bus connection (RJ45) to the outside world.


Here is the design I came up with:

A reference to how heat can impact common components

I decided to pull some information from old notes while cleaning up the really old paper in my desk.  Here is a list I created to remember how heat (in excess of 100°F) can impact common parts like capacitors and transistors, etc.

Selector Switch with ARDUINO

A fellow Arduino guy from Texas asked about how to set up a multi-mode selector switch using a single pushbutton and 3 states (not including the boot up state). What follows is this discussion that we had becoming a back and forth collaboration of ideas until I got off work and decided to see if I could make it more robust and simpler at the same time.

Lets talk about the original code…  it essentially worked… with some quirks.

The original code would continuously set all the pins… every loop, even though it didn’t need to…

It also tried to process the loop even if the mode was equal to zero (IE; No button presses have occurred yet and in that case, all LED’s should be off)

Lastly, it got weird when mode was incremented to 4 and set back to 1 and in here is the behavior that I wanted to eliminate.  It would change to mode 1 and 2 and 3 when the key was PRESSED but would only go back to mode 1 when button was released when in mode 3.  This is just not the way to make all the button presses seem similar.  All the other buttons react on the button press, not the release.

So it was SWITCH/CASE to the rescue.  With switch case statements I could handle all the mode switching and deal with mode 1 and any other mode that was not 2 or 3 with the default statement.  This allowed it to have all button mode migration to appear to behave the same.

The code also makes sure that pins do not get changed when they don’t need to be… IE; every loop traversal.

On to the final code example…

 Using a single switch to select between 3 modes
// Schematic:
// Global Variables & Constants

const int ledPinOne = 2; // LED1 ANODE
const int ledPinTwo = 4; // LED2 ANODE
const int ledPinThree = 7; // LED3 ANODE
const int modePin = 13; // Active HIGH, held low by 4.7K

int mode = 0; // Selector State (Initial state = ALL OFF)
int val = 0; // Pin 13 HIGH/LOW Status
int butState = 0; // Last Button State
int modeState = 0; // Last Mode State
boolean debug = 1; // 1 = Print Serial Enabled / 0 = disabled

void setup () {
 pinMode(ledPinOne, OUTPUT);
 pinMode(ledPinTwo, OUTPUT);
 pinMode(ledPinThree, OUTPUT);
 pinMode(modePin, INPUT);
 if (debug){
 Serial.print("Initial Mode: ");
 Serial.print("Setup Complete\n");

// Main Loop
void loop() {

 val = digitalRead(modePin);

 // If we see a change in button state, increment mode value
 if (val != butState && val == HIGH){

 butState = val; // Keep track of most recent button state

 // No need to keep setting pins *every* loop
 if (modeState != mode){

 // If no keys have been pressed yet don't execute
 // the switch code below
 // if (mode != 0) {

 switch ( mode ) {
 //case 1 is actually handled below as default

case 2:
 digitalWrite(ledPinOne, LOW);
 digitalWrite(ledPinTwo, HIGH);
 case 3:
 digitalWrite(ledPinTwo, LOW);
 digitalWrite(ledPinThree, HIGH);
 mode = 1;
 // loop back to 1 by default, seems redundant but
 // it also handles the "mode is > 3" problem
 digitalWrite(ledPinThree, LOW);
 digitalWrite(ledPinOne, HIGH);
 } // end switch
// } // end of "if mode = 0" check
 } // end of ModeState check
 modeState = mode; // Keep track of mode recent mode value
 delay(10); // slow the loop just a bit for debounce

// Subroutine
void showState() {
 if (debug){
 Serial.print("Mode: ");


Current Weather Station

Arduino Mega

AAG One Wire Weather Instrument Series 2. (Wind Speed, Temperature, Wind Direction)  DS18B20 temperature, DS2423 (wind speed) DS2450(wind vector)

Hobby Boards: Humidity/Temperature Board – Built from my own parts

Rain Gauge (See my post about it)

BMP085 – Pressure Sensor

Internal Temperature via DS18B20

1-Wire Power Injector (see my “how to make a PCB guide):

In progress: COSM upload – nope.

FAIL:  Adding COSM/PACHUBE support ran me out of working RAM… so project for upload of data is scrapped at the moment.