CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

Floating input pin issue [solved]
Goto page 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
FFT



Joined: 07 Jul 2010
Posts: 92

View user's profile Send private message

Floating input pin issue [solved]
PostPosted: Sat Jan 08, 2022 7:10 am     Reply with quote

Hello,

I just realized that I made a mistake to leave 3 button input pins floating.

PIC's Inputs are connected to buttons which are tied to 3.3V over resistors, the other pins of the buttons are tied to PIC's input pins.

So when the buttons is not pushed, input pin stays floating and I get wrong parasitic button push signals..

Connection:
PIC input -----o‾o----/\/\/\/----- 3.3V
Resistor is 680 R

I use 18LF14K50
The input pins are;
- RC1/AN5/C12IN1-/INT1/VREF-
- RB5/AN11/IOCB5/RX/DT
- RB7/IOCB7/TX/CK

I can add resistors externally but I already have many PCBs assembled and I look for a software based solution.

Question;
Is it possible to solve the issue using other functionality of those pins?

Any idea would help.

Thanks!


Last edited by FFT on Mon Jan 10, 2022 6:59 am; edited 2 times in total
Ttelmah



Joined: 11 Mar 2010
Posts: 19195

View user's profile Send private message

PostPosted: Sat Jan 08, 2022 7:43 am     Reply with quote

Pins B5, and B7 both have software programmable internal pull ups. So on
these pins just enable them. port_b_pullups(0b10100000);
However the problem here is these are pull ups, so you can't tell this from
the button pushed state.
Port C does not offer these, so really does need an external resistor.

There have been historic 'cheat' ways of testing a pin by pulsing it high, and
then releasing and testing immediately, but all have issues like producing
massive spike current on the supply (if the button is made when it is pulsed),
and are very unreliable.
If the pins are wired as you show (very strange layout), then simply pulse
the pins low before testing.
Code:

output_low(PIN_B5);
delay_us(10);
output_float(PIN_B5);
delay_us(1);
if (input_state(PIN_B5)==1)
   //Here button is pushed

Personally, leave the pins all driven high when you are not testing.
temtronic



Joined: 01 Jul 2010
Posts: 9081
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Sat Jan 08, 2022 7:52 am     Reply with quote

Unless I'm seeing it wrong, from your diagram, you actually need pull down resistors not pullups, so Mr. T.'s suggestion won't work.
As shown, you expected the PIC pin normally to be low, then when the button is pressed, the pin sees the +3 volts, through the 680r resistor.
If the connections to the 3 pushbuttons are close to a ground , adding 'pulldown' resistors should be easy.
FFT



Joined: 07 Jul 2010
Posts: 92

View user's profile Send private message

PostPosted: Sat Jan 08, 2022 9:27 am     Reply with quote

Yeah, I need pull-down resistors.

I just tried to have very long debounce time and seems it worked!

I incremented a variable when pin is high and zeroed it when pin is low,
after a threshold I accept that the button is pressed.
That was my actual code but the debouce was 30 ms. So I made it 1 second and it works properly. It didn't get false push within 2 hours time.

Actually my idea was to select the pin as ADC, so maybe I didn't need pull-down resistor for an ADC pin.. But long debounce seems resolved the issue.
temtronic



Joined: 01 Jul 2010
Posts: 9081
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Sat Jan 08, 2022 10:04 am     Reply with quote

Works now.'in the lab'..... but change in temperature and humidity will make it fail again. Also any EMI can look like a '1'.
You really should use a proper,reliable pulldown circuit.
Ttelmah



Joined: 11 Mar 2010
Posts: 19195

View user's profile Send private message

PostPosted: Sun Jan 09, 2022 6:17 am     Reply with quote

Yes, as I said:
Quote:

However the problem here is these are pull ups, so you can't tell this from
the button pushed state.


Thew wiring really is completely stupid. You must have had the brain switched
off when this was done.

Do what I suggested, and drive the pins low all the time. Then release this,
wait a tiny moment, and test the pin. Then switch it back to driving low.
This means that what you have is a pin capacitance (with it's tracks), being
driven 'high' by the resistor if the button is made. Assume the input has
something like 15pF capacitance, so the time constant to drive up to Vih
will then be perhaps 0.5uSec. Unless you have very massive EMI, this is
not going to charge the pin to this level in this sort of time.

It's a poor solution, but should work reliably.
temtronic



Joined: 01 Jul 2010
Posts: 9081
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Sun Jan 09, 2022 7:56 am     Reply with quote

Yes, Mr. T's software solution will work but adding code to compensate for very poor hardware design, is bad. To have a very reliable product, you need very good hardware.
Adding just 3 resistors shouldn't be a huge problem.
newguy



Joined: 24 Jun 2004
Posts: 1899

View user's profile Send private message

PostPosted: Sun Jan 09, 2022 10:31 am     Reply with quote

temtronic wrote:
Adding just 3 resistors shouldn't be a huge problem.


It is if there are 15,000 assemblies with this shortcoming piled up in the back of the shop.
FFT



Joined: 07 Jul 2010
Posts: 92

View user's profile Send private message

PostPosted: Sun Jan 09, 2022 11:02 am     Reply with quote

ARM have internal pull-downs, PIC have not. The confusion comes from there.

I have many assemblies and I don't want to solder that much resistors as @newguy mentioned.

I will add the resistors on the next production.

Very big debounce time really works for now, tested for 30+ hours with EMI existing env.

I will add the output_low suggestion of @Ttelmah just before reading the inputs.

I think this will be enough for now.

Thank you so much.
FFT



Joined: 07 Jul 2010
Posts: 92

View user's profile Send private message

PostPosted: Sun Jan 09, 2022 4:35 pm     Reply with quote

Ttelmah wrote:
Do what I suggested, and drive the pins low all the time. Then release this,
wait a tiny moment, and test the pin. Then switch it back to driving low.
This means that what you have is a pin capacitance (with it's tracks), being
driven 'high' by the resistor if the button is made. Assume the input has
something like 15pF capacitance, so the time constant to drive up to Vih
will then be perhaps 0.5uSec.

Hi again, can you describe the idea by code please?
I mixed it up a bit since I'm using fast IO, set_tris_a and output_low concept.
Do you mean setting the pin as input using set_tris_a by releasing it?

This is what I got;
Code:

#use fast_io(A)

// # initial state
set_tris_b(0b11111110); // Button pin is output
output_low(ButtonPIN);
......
// # in the loop
//output_float(ButtonPIN); // releasing it?
set_tris_b(0b11111111); // Button pin is input
delay_us(5);
int state = input(ButtonPIN);
set_tris_b(0b11111110); // Button pin is output
output_low(ButtonPIN);
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sun Jan 09, 2022 5:35 pm     Reply with quote

Here is how I did it once. I'm reading several bits on Ports B and D.
This was done with a 16F877 type PIC.
Code:

// The opto-sensors are active high, with 1k pullups providing the high level.
// The normal, non-activated state for the sensors is a logic low level.
// If a sensor cable falls off, the lines on the PIC processor will float.
// We are seeing false sensor "hits" when this happens.  The following
// code tries to protect against that happening.   (You can force some
// false hits by pulling the cable on the main board, and then touch the
// connector pins with your finger.  If you're displaying the last known
// sensor on your PC, then you'll see false hits).

// Set latches on ports B and D = 0, ahead of time.
port_b = 0;
port_d = 0;

// Then configure ports B and D as all outputs.  This will drive the
// pins low in 30 ns.
set_tris_b(0);
set_tris_d(0);

// Give the low level outputs some time to discharge whatever capacitive
// charge may exist on the pins.  Testing shows that this takes 30 ns.
delay_us(10);   // A larger delay doesn't hurt.

// Configure ports B and D as all inputs.  They will "float" low initially,
// because we just pre-charged the pins to a low level.
// The effects of this may vary, depending on whether the cable fell off
// an opto-sensor board or the main board.
set_tris_b(0xff);
set_tris_d(0xff);

// Do a short delay, which allows the pullup resistor on the opto-board
// (one which is still connected) to raise the level up to +5v.
// Testing shows that this takes 500 ns max.
delay_us(1);

// Now read the ports.
low_bits = port_b;
mid_bits = port_d;
temtronic



Joined: 01 Jul 2010
Posts: 9081
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Sun Jan 09, 2022 7:05 pm     Reply with quote

If you can get a copy of Microchip's 'Tips and Tricks' or whatever the book was called, (probably online at their website ??) they show, in assembler' how to do it. It'd be simple to re-code into 'C'.
The original books are now 20 ? years old but have a wealth of info on how to efficiently program PICs.
Ttelmah



Joined: 11 Mar 2010
Posts: 19195

View user's profile Send private message

PostPosted: Mon Jan 10, 2022 1:10 am     Reply with quote

Just use output_float, and drive:

So for B5:
Code:

//Set the pins low and drive them at boot:
output_drive(PIN_B5); //This sets TRIS to 0 on the pin
output_low(PIN_B5); //pin is now driven low

//then when you want to test the pin:
output_float(PIN_B5); //pin is now set as an input
delay_us(1); //wait 1uSec

state=input_state(PIN_B5); //read the pin level
output_drive(PIN_B5); //set the pin back to being driven low
FFT



Joined: 07 Jul 2010
Posts: 92

View user's profile Send private message

PostPosted: Mon Jan 10, 2022 2:26 am     Reply with quote

Ttelmah wrote:
Just use output_float, and drive:

So for B5:
Code:

//Set the pins low and drive them at boot:
output_drive(PIN_B5); //This sets TRIS to 0 on the pin
output_low(PIN_B5); //pin is now driven low

//then when you want to test the pin:
output_float(PIN_B5); //pin is now set as an input
delay_us(1); //wait 1uSec

state=input_state(PIN_B5); //read the pin level
output_drive(PIN_B5); //set the pin back to being driven low


Is this code working on FAST_IO mode?

Quote:
The tristate register is updated unless the FAST_IO mode is set on port A
Ttelmah



Joined: 11 Mar 2010
Posts: 19195

View user's profile Send private message

PostPosted: Mon Jan 10, 2022 3:16 am     Reply with quote

Yes.

The way it works:

input/output set TRIS for standard_io, but not for fast_io.
drive/float work whatever the I/O mode.

So you see, for the output_low, I have to have both the output_low, and the
drive command to set the tris.

The manual looks as if it is wrong for the output_drive command.

If you look at the generated assembler (with fast_io selected), you get:
Code:

....................    output_drive(PIN_B5); //set TRIS to drive the pin
005C:  BCF    TRISB.RB5
....................    output_low(PIN_B5); //pin is now driven low
005E:  BCF    LATB.LATB5
....................
....................    //then when you want to test the pin:
....................    output_float(PIN_B5); //pin is now set as an input
0060:  BSF    TRISB.RB5
....................    delay_us(1); //wait 1uSec
0062:  BRA    0064
0064:  BRA    0066
0066:  NOP   
....................
....................    state=input_state(PIN_B5); //read the pin
0068:  CLRF   state
006A:  BTFSC  PORTB.RB5
006C:  INCF   state,F
....................    output_drive(PIN_B5); //set the pin back to being driven low2
006E:  BCF    TRISB.RB5
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group