6

I am doing a project with an ATtiny85 and of course I'm short on I/O pins. One idea I had was to use a single pin for two outputs (let's call them EN and DATA).

schematic

simulate this circuit – Schematic created using CircuitLab

I know that DATA doesn't matter when EN=0. In other words, these two outputs can only assume the values EN=0/DATA=x, EN=1/DATA=0, EN=1/DATA=1. Is there an easy way to map for example 0 to EN=0/DATA=x, 1 to EN=1/DATA=1, Z (input pin) to EN=1/DATA=0? Power consumption only matters when EN=0.

Marcus Müller
  • 88,280
  • 5
  • 131
  • 237
  • 1
    Not from a binary input. If you use an ADC input you might. – Trevor_G Oct 15 '17 at 16:38
  • 3
    I'm confused! Title says, "*Getting a 0 and a 1 from a floating input*" but question says, "*use a single pin for two outputs*". Which is it? – Transistor Oct 15 '17 at 16:54
  • @Transistor: I'd like to get two outputs (three states in total) from my board using a single GPIO pin from the microcontroller and some glue logic on the board. My idea was that the microcontroller can configure the pin as output-low/output-high/input to get the desired states. – Paolo Bonzini Oct 15 '17 at 16:59
  • @Trevor: using a PWM output instead of the floating input might be possible as I am not using any, but how would I do that? ;) – Paolo Bonzini Oct 15 '17 at 17:01
  • @Paulo: It's still not clear. Are you trying to use one pin for two *outputs* or are you trying to monitor two signals on one input pin. There's a schematic button on the editor toolbar. Sketch it out. You need to edit your question. – Transistor Oct 15 '17 at 17:02
  • @Transistor: one pin for two outputs, added a schematic – Paolo Bonzini Oct 15 '17 at 17:10
  • It's a lot easier to get 5 outputs from 4 pins than it is to get 2 outputs from 1 pin. Perhaps you're asking the wrong question. – David Schwartz Oct 15 '17 at 21:18
  • You have 3 output states: 0, 1, and hi-Z; so use 2 Rs to set the hi-Z voltage midway, then 2 comparators to give 00, 01 (or 10), and 11. – amI Oct 15 '17 at 21:48
  • So I doubt the PWM solutions are what you are looking for, but my first thought is telephony. Telephones transmit all the numbers on the keypad using a single wire (plus a return). And I'm certain there's hardware to do that =) – Cort Ammon Oct 15 '17 at 22:50
  • You have three distinct states. Could you do something with pin low for one state, pin high for the next state, and pin low-to-high-to-low real quickly for the third state? – Jennifer Oct 16 '17 at 19:24

7 Answers7

13

Honest truth: What you're trying to do is easier implemented just by using a microcontroller with enough pins. It's probably even cheaper than an Attiny85. Who knows.

But: If you really must, you can do various things to get more output out of a single line:

  • Buy an IO expander that uses the 1-Wire (pseudo)standard, and implement a 1-Wire transmitter on the Attiny
  • an UART device might do as well, but I don't know of any single-wire-UART-to-IO adapters that aren't actually just another programmed microcontroller
  • Implement a DAC, followed by an ADC
    • DAC by PWM'ing your output,
    • feeding the PWM into an RC low pass filter, yielding a "smooth" variable voltage
    • buy a cheap parallel output ADC, or
    • implement your own parallel output ADC with Zener diodes
Marcus Müller
  • 88,280
  • 5
  • 131
  • 237
  • That could be a solution indeed (buying another microcontroller :) or just using PB5 and a high-voltage programmer). It is mostly a learning exercise in electronics, building my own I/O expander with as little programming as possible and discrete glue logic. I was thinking of using resistors and diodes, but couldn't get it to work. – Paolo Bonzini Oct 15 '17 at 17:19
  • Upvoted. I have a solution known to work but requires the pin in question to be unnaturally advanced. – Joshua Oct 16 '17 at 02:24
9

Of course, I'm a nerd, so here's solutions less likely to be implemented by you, but worth mentioning for the fun of it:

Shift Register based Shenanigans

The following ideas are based on serial-to-parallel shift registers.

Output Pin -> Data In

You can just shift in your data to your shift register's serial data input.

Problem: Shift registers need a clock to know when to "sample" the input.

Solution: Generate a clock impulse whenever the input changes.

New Problem: OK, we can do that with a simple logic AND gate, combining your DataIN and a minimally delayed version of its output (delay through discrete components, e.g an RC filter). But: Then we can only have alternating bit patterns.

Solution: The output sequence of your pin must always be

0->1[long]->B[short]->0.

What happens here is that the first 1 loads a capacitor (hence the "long" 1), the voltage across that cap triggers a delayed one-shot (for example, through a NE555) when it crosses a threshold, which then causes an clock pulse for the shift register.

The moment that pulse happens, you already have set the desired output bit B to the output. That must be shorter than the "fixed" 1 to avoid triggering the clock pulse again.

You do the above twice to shift in two different bits B1 and B2 into the shift register.

You can implement the above scheme sending

0b1111BB00

with the UART unit (if your microcontroller has such).

If you look closely, this is very similar to what the WSxxxx "neopixel" thingies do to communicate: 0->1 marks the start of a period, and the amount of 1 within that period sets whether its a logical 0 or 1.

Polynomial Passive Popular Pulsing

This needed a rhyming title. In all truth, this should probably be called "linear feedback shift register generation of an output sequence" or so.

The idea is that when you use a shift register, and connect its input to a logical combination of its internal cells, you can build something that cycles through all possible output states (if you choose the feedback function appropriately). I'd explain that here, but meh, lazy, so read the wikipedia article on Linear Feedback Shift Registers.

Takeaway: if you can have such a LFSR, you can, just by toggling its clock, achieve all outputs (just toggle the right amount of times).

Doh'. That's nice, but it's harder to explain than a counter

Of course, the above is very cool (because it has numerous applications, e.g. in communication, data integrity checking and so on), and it's very effective in terms of the number of gates you need for that, but:

You can just as well buy or build a 2bit (or more) counter. And count the toggles of your Attiny pin. The parallel bit output of the counter can be your 2 output pins (or more).

I think it says a lot I first thought of LFSRs instead of counters.

Frequency-Based Discrimation

Filterbank with two discrete frequencies

Idea is simple:

  1. Generate two different frequencies with the pin, for example, by toggling it with a frequency 1 kHz (ie. every 1ms the output repeats, you need to toggle every 500µs), or at 2 kHz (toggle every 250µs) or the logical sum of both oscillations (kinda hard to do in the head, but it boils down to having alternating long and short high periods).
  2. Filter the output with two different filters:
    1. a low pass filter that only lets through everything below let's say 1.2 kHz, an RC will do
    2. a band pass filter that lets through 2 kHz, but not 1 kHz nor 3 kHz.
  3. rectify and low-pass filter the output of these two filters. Tada, you've built a 2-Tone 2FSK receiver, if you're so inclined.
  4. These are your two output signals; use a thresholding device, a "discriminator" (Zener diode, Comparator) to convert them to binary 0 or 1.

Bonus

If you don't use 1 and 2 kHz, but a couple of MHz, you can actually replace your connecting wire with suitable antennas, and do that transfer over the air. You'd also break the law by abusing spectrum that you have no license for.

PWM that

Idea: same as above, but easier.

Let there be two independent pieces of info:

  1. Output Duty cycle > 50%
  2. Output changes at all

You can have the duty cycle > 50% either by

  • switching the pin constantly high (100% duty cycle), or low (0%), or by
  • setting the PWM unit to give you 25% or 75% duty cycle.

Then same as above, one low pass filter, followed by a discriminator that switches at half output voltage range, gives you the first bit of output.

A high pass filter, followed by a rectifier, and a capacitor and a discriminator gives you the second bit.

Marcus Müller
  • 88,280
  • 5
  • 131
  • 237
6

You can use two comparators and the high-input-low values. For instance:

schematic

simulate this circuit – Schematic created using CircuitLab

The two comparators will give out a logic 1 when the voltage at the input is higher than 3/4 * Vcc (DATA one) or 1/4 * Vcc (EN one).

When the attiny pin is pulled low, the voltage will be fixed to 0V; the comparators will then have the value 0 and 0. When the pin is left floating (set as input), the voltage will go to Vcc/2 due to the two resistors; the comparators will show 1 for the EN, 0 for the DATA. When the pin is pulled high, the voltage will be fixed to Vcc; both comparators will show a 1. Summing up:

Pin state |  EN  | DATA
------------------------
  OUT 0   |   0  |   0
  INPUT   |   1  |   0
  OUT 1   |   1  |   1

Note that this is not scalable unlike the solutions with the PWM or port expander. If you need more pins, maybe it is better to get a shift register and dedicate two pins to it (clock and data); this way you will have more outputs if you need them.

EDIT: Another solution, which does not involve using ICs but only discrete components, is the following one:

schematic

simulate this circuit

In this case, you will have to choose the MOSes so that they can turn on with Vcc/2; note that the values of resistors may be also increased if you want lower current to flow. You can also change the P-MOS with a PNP and the N-MOS with a NPN, but you'll have to add a current limiting resistor on their base (and I'm not sure how this influences the three states).

In any case, here is the table showing the statuses

Pin state |  EN  | DATA
------------------------
  OUT 0   |   1  |   1
  INPUT   |   1  |   0
  OUT 1   |   0  |   0
frarugi87
  • 1,225
  • 1
  • 11
  • 18
  • 1
    More elegant than my solution. I forgot about tri-state option. +1. – Transistor Oct 16 '17 at 12:14
  • This is the closest to what I was thinking about. At Vcc=3.3V, BSS84 and BSS138 should work for the MOSFETs. To reduce power consumption for EN=0 I might add two diodes between R1 and R2, connecting the input between the diodes and the gates on the two sides. Then the right part of the circuit can use CMOS inverters. When the input is floating, they should go to 0 (for DATA) and 1 (for EN) respectively. – Paolo Bonzini Oct 17 '17 at 13:34
  • @PaoloBonzini be aware that you may be working slightly out of specs, since the threshold voltage is very close to Vcc/2... As for the diodes, why should it decrease the power consumption? You can (and probably should) increase the value of the resistors up to some hundreds of kiloohms. As for the CMOSs, be aware that the region between 0.8V and 2.0V is forbidden (so 1.65V is not ok for CMOS ports). – frarugi87 Oct 17 '17 at 14:30
  • The diodes would give different voltage at the gates rather than 1.65V for both, so that I can use CMOS inverters (discrete, not 7404) and decrease the static power consumption. Does that make sense at all? – Paolo Bonzini Oct 17 '17 at 15:22
5

schematic

simulate this circuit – Schematic created using CircuitLab

Figure 1. A simple 3-state binary coding fed through a low-pass filter and monitored by two comparitors to extract the data. Note that many comparitors are open collector output and require a pull-up resistor.

You will face some challenges getting the R1-C1 time-constant right.

Transistor
  • 168,990
  • 12
  • 186
  • 385
  • yep, nice, that's one of the possible ADC implementations mentioned in my [first answer](https://electronics.stackexchange.com/a/334574/64158). – Marcus Müller Oct 15 '17 at 18:08
1

One (bad) solution is as follows.

data = gpio
weak inverting schmitt trigger from gpio to gpio.
inverted retriggerable monostable from gpio to en.

Basic idea is that if output is tristated, the schmitt will cause it to oscillate which will be picked up by the monostable to disable the output. This will glitch when disabling output, though. And has power consumption when disabled.

TLW
  • 608
  • 4
  • 9
  • 3
    Actually that's not a bad idea. I forgot about the tri-state option when writing my answer. Feed it into an RC debouncer on the other chip's input. The second chip can read the input status, switch the input to an output and try and pull it to the other logic level, release it and see if it stays there. If it does the first chip is tri-stated. If not then it's data. Beef up your answer. – Transistor Oct 15 '17 at 19:25
  • 1
    To fix the power consumption issue I could just flip the direction of EN and DATA. – Paolo Bonzini Oct 15 '17 at 20:22
0

Unless you are doing an assignment that specifically states you must use an Attiny85, not matter what, then by far the simplest solution is to use a chip with more pins (eg. the Atmega328P). The cost would be virtually the same (eg. $2.00 compared to $1.50).

Some of the other answers which suggest using one-wire protocol, shift registers, schmitt triggers, comparators, etc. are simply adding more parts (and cost) anyway. It would be much easier to use a microprocessor that actually does what you want, than adding in extra chips to extend its functionality in a less easy-to-use way.


Another possibility: The /RESET pin can be configured as a general IO pin. You can get an extra pin that way. Be warned that reprogramming it afterwards will be more difficult. Having said that, it's not impossible. I have a post about doing high-voltage programming of chips like the Attiny85, using another processor (in this case an Arduino Uno). A few parts allow the 12V to the /RESET pin to be switched on at the appropriate moment.

Nick Gammon
  • 908
  • 1
  • 9
  • 23
0

Spinning off of @frarugi87's second example (https://electronics.stackexchange.com/a/334700/53375), you could do a similar thing with optoisolators:

schematic

simulate this circuit – Schematic created using CircuitLab

The advantage of this version is that it can consume very little current if the optos' forward voltage (including any extra diodes in series to ensure this) is more than half the supply. Of course, it can't be more than the full supply or they'll never come on at all.

OUT0 and OUT1 can have the appropriate names and pull-up/down resistors to produce the combination of signals that you want.

AaronD
  • 5,596
  • 10
  • 36