PDA

View Full Version : TTL input - 3rd states possible?



flotulopex
- 26th March 2007, 21:37
Hello,

I was asking myself about the possibility of using any TTL input of my PIC to "read" 3 different levels.

Roughtly, for TTL values, the LOW level is from 0V to 1V and the HIGH is from 3,5V to 5V.

Assuming this is not completely wrong, would it be possible to read 3 different states on the PIC?

I tried to make it a simple way with a 2 resistor divider between Vdd and Vss. The middle point of the divider is logically connected to the pin.

Two buttons are parallel connected each to a resistor.

In theory, I can simulate 3 states:
1.- 0V (if button "A" is pressed)
2.- something around 2V (no button is pressed)
3.- 5V (if button "B" is pressed)

I can't achieve to read state 2.- but is it really possible... or am I dreaming?

skimask
- 26th March 2007, 22:19
Hello,

I was asking myself about the possibility of using any TTL input of my PIC to "read" 3 different levels.

Roughtly, for TTL values, the LOW level is from 0V to 1V and the HIGH is from 3,5V to 5V.

Assuming this is not completely wrong, would it be possible to read 3 different states on the PIC?

I tried to make it a simple way with a 2 resistor divider between Vdd and Vss. The middle point of the divider is logically connected to the pin.

Two buttons are parallel connected each to a resistor.

In theory, I can simulate 3 states:
1.- 0V (if button "A" is pressed)
2.- something around 2V (no button is pressed)
3.- 5V (if button "B" is pressed)

I can't achieve to read state 2.- but is it really possible... or am I dreaming?

You can do 3 states with a regular ol' TTL pin right now, but it takes a bit of programming.
1 and 0 are self explanatory, set the pin to an input and read it...
then you can read the 3rd state...open...
set the pin to an output, output a 1, read the input back...if it's a 0, it's being held to a 0 (in other words, not open), then set the output to 0, read the pin back, if it's a 1, it's being held to a 1 (again, not open)...however if you read back exactly what you put out, then the pin can be reasonably assumed it's open.

But the way you described works well too, if you're using a button sort of thing.

Luciano
- 26th March 2007, 22:50
Hi,

See tip #3:

http://ww1.microchip.com/downloads/en/devicedoc/40040b.pdf

Best regards,

Luciano

flotulopex
- 27th March 2007, 06:09
Thanks to both of you,

The Tips & Tricks documentation is cool :-)

I'll have a try with tis stuff.

flotulopex
- 28th March 2007, 20:43
Well,

After a few hours trying to get a positiv result, I just got nothing working.

I would like to read two buttons connected to one pin.

The states are "0" and "1". The third "Z" state is not relevant to me here.

To make sure I have an intermediate level, I use a 2 resistor divider like described in the first post.

Currently, I can't get clear "0" or "1" states.

Any idea?



OSCCON = %01100000 '4MHz
OPTION_REG = %10000000 'D I S A B L E PORTB's Pull-Ups for buttons
ANSEL = %00000000 'Disable Analogue Inputs
TRISB = %00010000 'Inputs/Outputs
PORTB = %00000000 'Drive all ports low

MAIN:
IF PORTB.5 = 0 THEN PORTB.0 = 1
IF PORTB.5 = 1 THEN PORTB.1 = 1
PAUSE 1000
PORTB.0 = 0
PORTB.0 = 0
Goto MAIN
end

I use PORTB.5 of my PIC16F88 for buttons because it is a TTL input only.

paul borgmeier
- 28th March 2007, 21:39
TRISB = %00010000 'Inputs/Outputs

you have PORTB.4 set as input, not PORTB.5

flotulopex
- 28th March 2007, 22:30
Thanks Paul,

It was again far to obvious to me (the tree in the forest story...).

I'll try again tomorrow and let you know.

Thanks a lot.

flotulopex
- 28th March 2007, 22:38
Well,

I've still got one led always ON.

In my understanding, I should get a state where no Led is ON.

Is this correct?

skimask
- 28th March 2007, 22:42
Well,

I've still got one led always ON.

In my understanding, I should get a state where no Led is ON.

Is this correct?

Show us your code again...

flotulopex
- 28th March 2007, 23:16
<img src="http://www.picbasic.co.uk/forum/attachment.php?attachmentid=1504&stc=1&d=1175119865">

I'm not sure about the ANSEL register. Shall I stay DIGITAL or ANALOG?

I tried both but I get always the same result.

I found this in the data-sheet; it's about the TTL levels.<img src="http://www.picbasic.co.uk/forum/attachment.php?attachmentid=1505&stc=1&d=1175120065">

As far as I can understand, the LOW level will be between Vss and 0,15V and the HIGH level between 2V and Vdd.

Is this correct?

skimask
- 28th March 2007, 23:29
Do you have the other side of the LEDs connected to +5v or ground?
Never mind the above


Put another pause 1000 after your led1 = 0 : led0 = 0, see what happens.
You might be missing the 'both leds off state' because it happens too quickly.

flotulopex
- 29th March 2007, 06:19
Both leds are connected to ground.

I added the PAUSE as you mentionned. Now, Led0 is blinking slowly without any button pressed.

Before I added the PAUSE, the Led0 was always ON until I pressed the button to make Led1 switch ON.

So, unfortunately, no big change.

I can see I never get a Z state (between Low and High TTL).

I also measured my resistors and the voltage levels are correct.

paul borgmeier
- 29th March 2007, 07:22
The only options for a digital input are high or low (1 or 0). If you provide a voltage (on a TTL pin) above 0.15*VDD but below 2 V, then the PIC has to decide whether to read the input as high or low - but the PIC will always pick one or the other, high or low (and this may fluctuate back and forth). If you stay below 0.15VDD or above 2V, then you know what the PIC will do ... if you are between these, then you do not know what the PIC will pick (1 or 0) or whether it will stick with the selected value.

For your original logic shown in post #10, you would expect one of the LEDs to always be on (Skimask noted this for you). If you add the pause like he suggested, you would always expect to get the blinking you are getting because the pin is always read as high or low. With the pause added, the light goes on for a second, then off for a second and repeats as expected.

flotulopex
- 29th March 2007, 08:54
Paul,

Previously, I have mentionned a doubt I had about the ANSEL (analog) settings because I agree with you, in DIGITAL, I can have only two states (0 & 1).

Do I have to conclued that the reading of a "3 states ports" can be achieved only by means of software (as stated in the "Tips & Tricks" doc) and that it is not possible by reading the inputs states on the PIC's pins?

I don't care about the Z state.

I would like to read only both "0" and "1" states (2 buttons)...

T.Jackson
- 29th March 2007, 09:27
TTL - Transistor-Transistor-Logic, valid logic low between (0 - 0.8v), while valid logic high must be within the region of (2 - 5v) Any where between (0.8 - 2v) may be read as either logic high or low. You can't predict it. Could even oscillate.

CMOS - Complementary-Metal-Oxide-Semiconductor on the other hand can be feed with up to 26% of VCC for a logic low and a minimum of 73% of VCC for a logic high.

This industry standard ensures that CMOS is guaranteed to produce no more than 26% of VCC for a low output and no less than 73% of VCC for a high out.

CMOS is far, far superior to TTL in that it mirror's current from in to out. Some CMOS chips can even partially function even without supply. i.e. if there's something on an input you still get something on an output. TTL is however much more robust. That's the trade off. Plus TTL has a much bigger fanout,
which means that more inputs can be driven from an output.

Trent Jackson

sougata
- 29th March 2007, 09:57
Hi,
This is just an idea using the MChip Tips n' Tricks. No timer, no comparator just an idea. Flotulopex please test it out. Others on the forum please comment if it is crap.

1507


READ_SWITCH:
TRISA.0 = 0 ' MAKE THE PIN AN OUTPUT
PORTA.0 = 0 ' MAKE IT LOW
PAUSE 100 ' WAIT FOR THE CAPACITOR TO DISCHARGE

TRISA.0 = 1 ' MAKE THE PIN AN INPUT
PAUSE 100 '

IF PORTA.0 = 1 THEN SWITCH_HIGH '

LED1 = 0 ' DEFINATELY NOT HIGH
TRISA.0 = 0 ' MAKE THE PIN AN OUTPUT
PORTA.0 = 1 ' MAKE IT HIGH
PAUSE 100 '

TRISA.0 = 1 ' MAKE THE PIN AN INPUT
PAUSE 100 '

IF PORTA.0 = 0 THEN SWITCH_LOW '
LED0 = 0 ' DEFINATELY NOT LOW

GOTO READ_SWITCH

SWITCH_LOW:
LED0 = 1
GOTO READ_SWITCH

SWITCH_HIGH:
LED1 = 1
GOTO READ_SWITCH


P.S. - The code can be made shorter!! :D

flotulopex
- 29th March 2007, 21:53
Hello Sougata,

Thanks for your code (I copied/pasted it without any change and worked!!!). Unfortunately, the Led0 is still blinking.

I made a code (also based on the Tips & Tricks) very similar to yours and had the same result.

As one can multiplex 6 Leds with only 3 pins, I thought I could do something similar with buttons on 1 port.

After a lots of trials, I think it is not feasable... or I still miss something.

As already said, I don't care about the Z state. Only both "0" and "1" states would be used.

skimask
- 29th March 2007, 22:31
Hello Sougata,
Thanks for your code (I copied/pasted it without any change and worked!!!). Unfortunately, the Led0 is still blinking.
I made a code (also based on the Tips & Tricks) very similar to yours and had the same result.
As one can multiplex 6 Leds with only 3 pins, I thought I could do something similar with buttons on 1 port.
After a lots of trials, I think it is not feasable... or I still miss something.
As already said, I don't care about the Z state. Only both "0" and "1" states would be used.

Curious...why are you worried about the 'Z' state?
Is it the fact that it can 'hover' around the trip point and cause false readings if left open?

sougata
- 30th March 2007, 05:35
Hi,

It is possible. Did you connect your PIC according to the schematic I provided. <img src="http://www.picbasic.co.uk/forum/attachment.php?attachmentid=1507&d=1175158348" align="absmiddle">Try increasing the pause. Please post your entire code and schematic. It is possible in one way or the other. I have chosen the Digital way. Detecting multiple switches with one pin is also possible using the ADC. By the way the circuit doesn't work when both the switches are pressed simultaneously. The 1K resistors are provided for that purpose so that you don't blow up your PS. When both are pressed most likely your PIC would read a logic high. As you get 1/2VDD and @ 5 volts it is good enough to be a logic 1. In any TTL/CMOS gate your cannot have anything other than 0 or 1 in your output whether your inout is at 0,1 or Z. So software tricks does it. By switching your port pin between input and output and detecting the holding capacitors state. I repeat please post your exact code and schematic and it should work.
Let me clarify my understanding about your requirement.

You need to use only one pin of your PIC.
You need to connect 2 switches to that.
You need to determine whether your input is hanging idle (Z)
Switch connected to VDD was pressed (H)
Switch connected to VSS was pressed (L)


I am waiting.

flotulopex
- 30th March 2007, 14:06
Curious...why are you worried about the 'Z' state?
? I don't understand. I said I don't care about the Z state. I would like to read "0" and "1" states (= read two buttons on 1 pin).

Sougata,

The code I use is almost the same as yours. I'll post it this evening (I'm in the office now).

The shematic is absolutely the same as yours but I've some different values:
PIC16F88-4MHz int osc
R1 = 10k
R2/R3=1k2

Nevertheless, you have pointed out what I was expecting.

So software tricks does it.
I'm afraid that reading states that must be defined by software will slow down the maniability of your program.

In my case, I'm (re)making a SIMON game and when you get use to play with this, you can be quite fast on the buttons.

I already tried with A/D; this was far to slow. RCTime was to slow too.

I'll have another try and come back for a feedback.

skimask
- 30th March 2007, 14:36
Ok, now I smell what you're cooking.
I know you don't care about the 'Z' state, but you probably have to 'worry' about it in this case.
How about this... when you write to a port, you write the data register, when you read a port, you read the actual pin...so...
The button's are set up just like in the schematic above.
You set the pin to an output, and high...read back the pin...
If it's still high, either the one button pulling it high is pressed or, neither are pressed, if it's low, the other button is pressed...
Then you set the pin low...read back the pin...
If it's still low, the one button pulling it low is pressed or, neither are pressed, if it's high, the other button is pressed...
Problem with this approach is finding a low value to pull the pin far enough (either way) to change states, and yet not smoke the guts of the pin itself.

pinput var portd.0 : temp var bit : realinput var byte '0=lo, 1=hi, 2=no push
output pinput : pinput = 1 : temp = pinput
if temp = 0 then
realinput = 0 : goto finish
else
pinput = 0 : temp = pinput
if temp = 1 then
realinput = 1
else
realinput = 2 : goto finish
endif
endif
finish: 'done here

I haven't tried this, might work, might not. If you do go this route, start with high resistor values (10k or so) and work your way down. It'll either start working or smoke the PIC.
Personally, I like sougata's solution better. If you drop the cap and resistor values, you'll be able to drop the pause values as well, and make everything a lot faster.

mister_e
- 30th March 2007, 15:40
in general you don't want to add the capacitor. In this case you just need a current limiting resistor, anything bellow 10 and above Vcc/25mA. Just do what Skimask said.

Set pin as output
set it high
Set the pin as input
read it
Set pin as Output
Set it low
Set pin as input
read it

Now compare both reading and have fun with.

It may work in PBP, but i'll suggest some ASM lines.

flotulopex
- 30th March 2007, 15:42
Okay; finally, it works.

Here is my code I had to correct according to Sougata's example.


' Fuses
@ DEVICE PIC16F88,INTRC_OSC_NOCLKOUT
@ DEVICE PIC16F88,PROTECT_OFF
@ DEVICE PIC16F88,WDT_OFF
@ DEVICE PIC16F88,PWRT_ON
@ DEVICE PIC16F88,MCLR_ON
@ DEVICE PIC16F88,BOD_OFF
@ DEVICE PIC16F88,LVP_OFF
@ DEVICE PIC16F88,CPD_OFF
@ DEVICE PIC16F88,DEBUG_OFF
@ DEVICE PIC16F88,CCPMX_OFF

'-------------------------------------------------------------------------------
' Registers 76543210
OSCCON = %01100000 '4MHz
OPTION_REG = %10000000 'D I S A B L E PORTB's Pull-Ups for buttons
'ANSEL = %00000000 'Disable Analogue Inputs
TRISA = %00000000 'Inputs/Outputs
TRISB = %00100000 'Inputs/Outputs

'-------------------------------------------------------------------------------
' Variables
Led0 var PORTA.0
Led1 var PORTA.1
HiLow var PORTB.5 'this port is TTL only
InOut var TRISB.5
Time var byte
time = 2

'-------------------------------------------------------------------------------
' Program
MAIN:
inout = 0
hilow = 0
pause time
inout = 1
pause time
if hilow = 1 then led1 = 1 : goto main
led1 = 0
inout = 0
hilow = 1
pause time
inout = 1
if hilow = 0 then led0 = 1 : goto main
led0 = 0
Goto MAIN
end
ANSEL or not, it works.

I changed the 0,1µF cap for a 0,01µF and reduced the pause time to 2 so it goes drastically faster.

Thanks a lot for your patience.

In fact, I was stuck in my mind thinking this problem would have to be resolved another way than by a software routine...

flotulopex
- 30th March 2007, 15:46
Thanks mister_e, I just read your post.

I removed the cap and PAUSEs.

It works too very well.

Cool ;)

mister_e
- 30th March 2007, 15:47
use a ADC input....

EDIT: just read yours... WOOOHOOO! good luck!

flotulopex
- 31st March 2007, 11:16
mister_e,

May I ask you what this BASIC routine would have become in assembly?

Please, don't waste your time if it is long to do.

I'm just curious to compare what "I know" (=BASIC) to what I don't (=ASM).

I don't really understand the difference between BASIC and ASSEMBLY in terms of program execution speed (looks to be faster in ASM but I don't understand why - have to find other threads for more info) because I never looked into it up to now - looks very complicated.

skimask
- 31st March 2007, 16:04
I used to worry about how tightly BASIC compiles down to actual assembly. I don't anymore. If you look at PBP source code relatively close, you'll see that most of the PBP commands directly relate to straight assembly programming, while others may take 1-2-3 ASM instructions to complete a PBP instruction. Again...I used to worry about it. There's only a few instances where straight assembly can make anything faster. If you really want to see it, take a look at your .LST file generated during assembly. Put a couple of labels around the code you're interested in and do a search of the file.