8 Remote Buttons over 1 wire

cloudy

Member
Trying to work out the best way to communicate between 8 buttons (ideally would like to know the state of all buttons, don't need to sample any faster than 5hz) over a single wire (with common GND and power supply) back to a PICAXE

Possibles:

  • R-2R 8 bit resistor network - risks problems as the 1 wire is several meters in a noisy environment? even with 10bit adc, wonder if I could misread buttons
  • another PICAXE 18m2 transmitting back with serial. Is there an easy way to code 8 inputs into a serial string, and decode that into a Case statement with actions for each button being active?
  • is there a made for the job IC or something else?

All help appreciated!
 

hippy

Ex-Staff (retired)
another PICAXE 18m2 transmitting back with serial. Is there an easy way to code 8 inputs into a serial string, and decode that into a Case statement with actions for each button being active?
That would be the easy option. The button reader, sender ...

Code:
Do
  SerOut TX_BIN, BAUD, ( pinsC )
  Pause 200
Loop
The receiver ...

Code:
Do
  SerIn RX_PIN, BAUD, b0
  Gosub HandleIt
Loop
The receiver's b0 will contain an exact copy of what the sender read on pinsC, that is 8 separate digital levels, which can come from buttons or switches.

You probably wouldn't use a CASE statement, but you can test each bit ...

If bit0 = 1 Then ...
If bit1 = 1 Then ...
 

cloudy

Member
Love this forum! Both look like easily workable options - I did not know the X chips supported 1wire!

Many Thanks all


James
 

eggdweather

Senior Member
You could use a second 18M2 as per your option list, that reads the state of buttons, then sends a string to another 18M2, like this:
Send "ABCDEFGH" to mean all buttons off/not-pressed
Send "abcdefgh" to mean all buttons on/pressed
Send "AbCdEfGh" to mean every other button was pressed
And of course all the combinations in-between. The decoding code then takes each character in-turn and using a CASE statement, you determine what to do with each button state:
SELECT CASE character
CASE "A"
GOSUB do_something
CASE "a"
GOSUB do_something_else
ENDCASE

Alternatively, send a byte that represents address and state of two buttons, codifying each byte thus: 'abc'S'def'S where 'abc' = binary address of a button-0 and S is the state of the button where S=0 or 1 or off/on and 'def' is the address of button 1 and S its state, for example:
00010010 means Button-0 is ON and Button-1 is OFF and 00010101 means both Button-0 and 1 are ON
010S011S for buttons 2 and 3
100S101S for buttons 4 and 5
110S111S for buttons 6 and 7

So in 4-bytes transmitted you can code the state of each of the 8-buttons. All you have to do is read and store the states of the 8-buttons, code them accordingly and then send the bytes.
 

erco

Senior Member
An old-school series resistor ladder (voltage divider) read by an ADC could be made to work with some brute force effort. You might have to use trimpots instead of fixed resistors for exact calibration in situ, using shielded cable in your noisy environment.
 

AllyCat

Senior Member
Hi,

@eggdweather: Seems rather complicated when hippy has explained how to do it with one transmitted byte and a couple of lines of code.

@erco: Yes, the problem is that the analogue method requires 256 distinct levels. Therefore the "most significant bit" resistor needs to be accurate to better than +/- 0.2%, even without allowing for a "guard band" between levels (e.g. to allow for small voltage drops in the cable supply lines).

So probably 3 - 4 carefully-adjusted (multi-turn) pots might be needed before the rest of the ladder, or a "weighted resistor chain" (1 : 2 : 4 : ... : 128), can use ordinary (1% - 5%) fixed resistors. Also beware that DAC "ladders" (8 x "R : 2R") normally switch between '0' and '1' levels, not with open/closed switches. You'd probably also need a capacitor / low-pass filter on the receiving PICaxe ADC input, but the capacitance of a (long) coaxial cable might suffice.

Cheers, Alan.
 

Technoman

Senior Member
I don't know if it has to be installed in a noisy environment, but in the case you choose the solution using a second 18M2, I would add a checksum or having the receiver to see twice the same information before updating.
 

hippy

Ex-Staff (retired)
I would add a checksum or having the receiver to see twice the same information before updating.
Probably best to put it all in a packet to make it reliable. Not sure what the ideal checksum technique is for a single byte but perhaps something like ...

Code:
Symbol STX = ...
Symbol ETX = ...
Do
  b0 = pinsC
  b1 = b0 ^ 0xFF
  b2 = b0 + b1
  SerOut TX_BIN, BAUD, ( STX, b0, b1, b2, ETX )
  Pause 200
Loop
I would just send a byte until it's working on the desktop.
 
Top