Pin read always zero - Page 1
Forum section: electronics / general

author: Jan Audio
author_rank: Frequent Contributor
timestamp: September 14, 2021, 01:59:42 pm
content: Hi, i have a problem :Reading pin RD2 from a PIC16F1789 gives always zero as result.Other pins all work fine.I measured the RD2 pin, i can measure the weak-pullup.Pin RD2 have digital output from the start, no peripherals, it can only be opamp or dac, both off default.How is this possible ?thank you

author: Andy Watson
author_rank: Super Contributor
timestamp: September 14, 2021, 02:23:54 pm
content: RD2 can be configured as an analogue or digital input even when the DAC and op-amp are disabled. Looking at section "13-10 - Register 13-29" of the datasheet, indicates that RD2 input is controlled by bit 2 of the ANSELD register - which defaults to being an analogue input after reset.

author: Jan Audio
author_rank: Frequent Contributor
timestamp: September 14, 2021, 02:47:46 pm
content: Oh, i forgot to mention, i have all ADCs off.That is not the problem.The problem is i see no problem so i cant solve it.By the way : i build 2 of the same project, both have the same problem.Nothing connected on that pin with WPU on, reads zero.

author: JPortici
author_rank: Super Contributor
timestamp: September 14, 2021, 02:50:17 pm
content: But did you make sure to make the pin digital by clearing the ANSEL bits?

author: DrG
author_rank: Super Contributor
timestamp: September 14, 2021, 02:55:14 pm
content: If you would show your initialization code, you would help folks who want to help you. This, even if you have to write some demonstration code just to illustrate your problem.Alternatively, you could simply conclude that it is magic.

author: Jan Audio
author_rank: Frequent Contributor
timestamp: September 14, 2021, 03:31:23 pm
content: Yes all ANSEL are clear.Yes i will upload the code after diner.All TRIS are also good.

author: AaronLee
author_rank: Regular Contributor
timestamp: September 14, 2021, 04:40:02 pm
content: In situations where I have issues with pins not behaving as expected, I typically start up in debug mode with no program loaded, and just manually manipulate the Special Function Registers directly. It's easy to think your software is doing the right thing, but when you look at the SFRs, realize something went amiss. So, in this case, I'd start the debugger and first set the ANSELD SFR to 0. The TRISD SFR should default to all 1's, so verify it's set as it should be, then check the PORTD SFR in the debugger when you set the pin to high, and see if the bit is still 0. This will rule out any issues with your code doing something you don't realize it's doing.

author: jpanhalt
author_rank: Super Contributor
timestamp: September 14, 2021, 04:48:20 pm
content: I am not sure what you are doing without the code. The following from the datasheet might be of interest: (see attachments)So, WPU's should be disabled on outputs, but apparently you are reading them. Something is wrong. What voltage do you see? What happens if you disable the WPU?Second, are you reading LATD,2 or PORTD,2 ?

author: Jan Audio
author_rank: Frequent Contributor
timestamp: September 14, 2021, 04:57:26 pm
content: init :TRISA = 0b11000000;TRISB = 0b00000000;TRISC = 0b10001111;TRISD = 0b00001111;TRISE = 0b1000;PORTA = 0;PORTB = 0;PORTC = 0b01000000; // keep UART send pin highPORTD = 0;PORTE = 0;ANSELA = 0b00000;ANSELB = 0b000000;ANSELE = 0b000;WPUA = 0b11000000;WPUB = 0b00000000;WPUC = 0b00001111;WPUD = 0b00001111;WPUE = 0b0000;reading the pin :if( PORTDbits.RD2 )

author: AaronLee
author_rank: Regular Contributor
timestamp: September 14, 2021, 05:00:52 pm
content: Quote from: Jan Audio on September 14, 2021, 01:59:42 pmDo you mean you're assuming RD2 is set to digital mode and output from default power up? This is not the case. ANSD2 default's to 1, which is analog, not digital. And TRISD2 defaults to 1 which is input, not output. Perhaps you misinterpreted the datasheet and reversed the values of one or both of those SFRs.

author: AaronLee
author_rank: Regular Contributor
timestamp: September 14, 2021, 05:02:18 pm
content: Quote from: Jan Audio on September 14, 2021, 04:57:26 pmYou need to set ANSELD = 0;

author: AndyC_772
author_rank: Super Contributor
timestamp: September 14, 2021, 06:55:32 pm
content: Quote from: AaronLee on September 14, 2021, 05:02:18 pm^^^ this.Data sheet PDF, page 152.

author: jpanhalt
author_rank: Super Contributor
timestamp: September 14, 2021, 08:22:59 pm
content: @Jan AudioQuoteYou are setting POrtD,2 =1, which is an inputQuoteI am not sure what you are doing or expect.

author: AaronLee
author_rank: Regular Contributor
timestamp: September 14, 2021, 10:00:38 pm
content: Quote from: Jan Audio on September 14, 2021, 01:59:42 pmAs jpanhalt mentioned also, the datasheet says that the WPUEN bit of the OPTION_REG needs to be 0 for internal pull-ups to be enabled. In your code you're not setting this, but say that other pins work. I've never used that particular PIC MCU, so can't say for sure, but based on the datasheet it sounds like setting WPUEN to 0 is necessary.However, being you said all other pins work fine, this doesn't make sense, because if the same test is done on the other pins, it should fail on those other pins. So I assume that WPUEN is 0, even though your code doesn't show it, or there's something I don't understand about the datasheet. Anyways, try setting it to 0 if you still can't get it to work after setting ANSELD to 0.

author: jpanhalt
author_rank: Super Contributor
timestamp: September 14, 2021, 11:25:18 pm
content: @Aron LeeYour interpretation is correct. I use that chip in my current project. OPTION_REG,7 = 1 (default) = WPU disabled; OPTION_REG_7 = 0, WPU are enabled by individual registers.What worries me is the TS's apparent reluctance to post these important parts of his code. There is nothing proprietary in those settings. For eample, he said,QuoteIt is unclear what that means, since he clearly sets TRISD,2 =1 but says it is an output. WPUD,2 =1 (enabled), but as you say, we don't know what the the OPTION_REG settings are. It makes no sense to have a WPU on an output with that device, so they are inactive except when inputs. (NB: Those pins can be set to open-drain, but the TS has said nothing about doing that. Default is standard push-pull.)

author: AaronLee
author_rank: Regular Contributor
timestamp: September 14, 2021, 11:49:48 pm
content: Quote from: jpanhalt on September 14, 2021, 11:25:18 pmI'm assuming that was a typo by Jan Audio, or else perhaps a language issue, and maybe meant it was assumed the pin was "digital GPIO" by default but said "digital output" instead (which is incorrect either way because the default is analog). We'll need to wait to see what Jan says about that, but everything else leads me to believe indeed the pin is intended to be a digital input. I think we're all in agreement that in addition to the initialization code posted, two settings are needed for it to be digital input with pull-up enabled, and those are ANSELD is 0 and OPTION_REG,7 is 0.

author: AaronLee
author_rank: Regular Contributor
timestamp: September 15, 2021, 01:57:12 am
content: Quote from: AaronLee on September 14, 2021, 10:00:38 pmAh, the lightbulb finally came on, and I realized the error in my thinking. Of course, WPUEN of OPTION_REG when 1 means ALL internal pull-ups are enabled. When 0, it means individual pull-ups can be enabled. In this case, if WPUEN is 1 (default), then it matters not what the individual pull-up settings are, and if it's 0, then already you set the individual pull-ups appropriately. So for your code, there shouldn't be a need to check that, other than for clarity you should probably only enable the individual pull-ups if you've disabled the global pull-up, otherwise when you go back to your code later, and want to turn some on and some off, you might not realize why it doesn't work if they're globally enabled.In other words, either way your code should work, leaving only the need for you to add:ANSELD = 0b000;And also, you didn't set ANSELC in your code, so assuming you're not using any ADC on any C ports, it's best to have:ANSELC = 0b00000000;By the way, many years ago, if my memory's correct, some of the PIC lines use opposite bit settings, where a 0 bit turns on the ADC function for that port, and a 1 turns it off. So you need to check that whenever changing to a different line of PIC MCU. It's very easy to forget to do this as well. When I first started out, I wasted many hours trying to figure out why a GPIO pin didn't work, only to realize I failed to set the Analog/Digital mux. Even after having it happen once, I forgot the next several times. Finally I drilled it into my head that the very first thing I do when I start coding for a PIC is to verify that ALL the Analog/Digital muxes are set appropriately.

author: Jan Audio
author_rank: Frequent Contributor
timestamp: September 15, 2021, 01:24:12 pm
content: Oh i see i need to set ANSELD to zero, oops.*yes it need to be input.I go try right now.

author: Jan Audio
author_rank: Frequent Contributor
timestamp: September 15, 2021, 01:48:13 pm
content: Ok it works, thank you very much.Why i did not have it in there i dont know.Maybe i read the manual to good it says : PIC16(L)F1789 only.This machine is so complex, then such a simple error ruins it.

author: Andy Watson
author_rank: Super Contributor
timestamp: September 15, 2021, 01:57:45 pm
content: Hooray !Blimey, only took 24 hours

author: Jan Audio
author_rank: Frequent Contributor
timestamp: September 15, 2021, 02:41:36 pm
content: Time to make a casing with the 3D printer then i,m done for this year.Free to make something for next year.