AnsweredHot!PIC12F683 Unexpected Output - Semi High?

Page: 12 > Showing page 1 of 2
Author
peteGSX
New Member
  • Total Posts : 11
  • Reward points : 0
  • Joined: 2019/02/06 11:43:13
  • Location: 0
  • Status: offline
2019/02/08 02:34:36 (permalink)
0

PIC12F683 Unexpected Output - Semi High?

Hi all,
 
Working on my first PIC project here, and I'm really not sure where I'm going wrong. I've spent a number of weeks getting my head around PIC assembly (been ~25 years since I did Z80 assembly in college so I'm beyond rusty) to a point where I've become comfortable enough to adapt code found around the 'net to my needs.
 
The program I've written is to monitor the charging system on my motorcycle as they're notoriously bad for having the charging system fail. I want a simple single tri-colour common cathode LED output to tell me the charging status. I found a project that sort of did what I wanted but the LED output is far more complex than I'd like as I want simplicity - orange is low charging, green is good, red is over charging. I also wanted to be able to adjust the low and high thresholds in code so if I change to a LiPO battery I can set appropriate thresholds for it.
 
So, I took what I found, adjusted the code to suit my needs, and the output in the MPLAB X IDE (version 5.10) does exactly what I want.
 
I used a breadboard to test the code with all the components, and that's where I started seeing issues.
When using the default thresholds in the code, there seems to be a very narrow band where the LED shows green, where it should be green from ~13.2V all the way up to 15V. It seems to not go green until it's in the 14V area.
 
If I use the jumper to go through the threshold adjustment subroutine, this works as expected and sets the new thresholds in the EEPROM. Once done, the thresholds set via this subroutine work correctly, but then I see the other unexpected behaviour where between 14V and 15V, the red side of the tri-colour LED occasionally turns on, but it is not fully on. The output pin on the PIC measures 0.99V when it does this, so the LED is not fully orange. This happens at about four different voltages between 14V and 15V and it seems to be consistent voltages when this occurs. The behaviour in the rest of the range is correct. Below 13.2V is green, above 15V is red, below 14V and at or above 13.2V is green.
 
I initially thought my breadboard circuit was a fault, so I moved the components over to some prototyping board so everything is soldered in place (although using an IC socket for the PIC), but the behaviour persists exactly the same.
I've spent days searching around but either my terms are incorrect or I've done something fundamentally wrong in the code or in the circuit that is causing this behaviour.
 
I've attached the schematic to this as well as including my code below.
 
If anyone has any insight as to either why this is occurring, or a tip as to how I can start troubleshooting, that'd be great as I'm completely stumped at present.
 
I've attempted to use relocatable code which has required adapting absolute examples I have found, and I'm aware my code is likely messy and inefficient.
 
Sorry I cannot get my code to post, keep getting access denied, so I have attached it along with the schematic PNG.

Attached Image(s)

#1
qhb
Superb Member
  • Total Posts : 9170
  • Reward points : 0
  • Joined: 2016/06/05 14:55:32
  • Location: One step ahead...
  • Status: offline
Re: PIC12F683 Unexpected Output - Semi High? 2019/02/08 14:29:49 (permalink) ☄ Helpfulby peteGSX 2019/02/14 02:48:56
+2 (2)
One thing that jumps out at me is that you are enabling interrupts, but do not have an interrupt service routine.
Therefore, you don't need interrupts, so get rid of these two lines:
    bsf    INTCON,GIE        ; Enable global interrupts
    bsf    INTCON,PEIE        ; Enable peripheral interrupts



 
n.b. that is the best laid out and commented code I have seen in a first post on this forum in MANY years.
 
post edited by qhb - 2019/02/08 14:34:37
#2
peteGSX
New Member
  • Total Posts : 11
  • Reward points : 0
  • Joined: 2019/02/06 11:43:13
  • Location: 0
  • Status: offline
Re: PIC12F683 Unexpected Output - Semi High? 2019/02/08 15:21:37 (permalink)
0
Thanks for the quick reply! And compliment Smile: Smile
 
I do a fair bit of Perl, Python, and Powershell scripting in my day job so I'm used to formatting and commenting code for readability. I'm no developer though!
 
The one place I require interrupts is to wake the PIC at the end of the ADC conversion, and maybe I read the datasheet incorrectly but I thought I required at least peripheral interrupts for that to occur.
 
I'll certainly adjust those interrupt settings and will see if that has an effect on the output.
 
Thanks again!
#3
Ian.M
Super Member
  • Total Posts : 13222
  • Reward points : 0
  • Joined: 2009/07/23 07:02:40
  • Location: UK
  • Status: offline
Re: PIC12F683 Unexpected Output - Semi High? 2019/02/08 15:45:54 (permalink) ☄ Helpfulby peteGSX 2019/02/14 02:49:11
+2 (2)
See datasheet: FIGURE 12-7: INTERRUPT LOGIC.
The SLEEP wakeup signal is tapped off immediately before the combined interrupt request is gated with  GIE.   Therefore you don't need to set GIE, enabling global interrupts, but you *DO* need to set ADIE and PEIE to allow ADIF to reach the wakeup signal, as you have done.
 
Fortunately as you have no other interrupt sources enabled, and always disable ADIE before reenabling GIE, the lack of an ISR doesn't crash your code.

--
NEW USERS: Posting images, links and code - workaround for restrictions.
I also support http://picforum.ric323.com because this forum is sometimes too broken to use!
#4
1and0
Access is Denied
  • Total Posts : 8740
  • Reward points : 0
  • Joined: 2007/05/06 12:03:20
  • Location: Harry's Gray Matter
  • Status: offline
Re: PIC12F683 Unexpected Output - Semi High? 2019/02/08 16:26:12 (permalink)
+1 (1)
Ian.M
Fortunately as you have no other interrupt sources enabled, and always disable ADIE before reenabling GIE, the lack of an ISR doesn't crash your code.

Agreed, but it's ADIF in OP's code, not ADIE. ;)
 
AVG_RESULTS res .1     ; 8 x memory locations for rolling average calculation
                                            ; Defining these at the end as I don't know how to reserve
                                            ; 8 locations equivalent to AVG_RESULTS:8 in relocatable mode

Just use
AVG_RESULTS res .8

 
#5
1and0
Access is Denied
  • Total Posts : 8740
  • Reward points : 0
  • Joined: 2007/05/06 12:03:20
  • Location: Harry's Gray Matter
  • Status: offline
Re: PIC12F683 Unexpected Output - Semi High? 2019/02/08 16:37:41 (permalink)
+1 (1)
; Divide sum by 8 to get average of last 8 values
 rrf AVG_SUM_HI,F
 rrf AVG_SUM_LO,F ; /2
 rrf AVG_SUM_HI,F
 rrf AVG_SUM_LO,F ; /4
 rrf AVG_SUM_HI,F
 rrf AVG_SUM_LO,W ; /8

You need to clear the carry bit before shifting the HI bytes.
 
... and the following
; If carry set round result up
 skpnc
 addlw .1
 movwf INPUT ; put averaged result into variable

can result in INPUT equals to zero when WREG = 0xFF prior adding one.
 
Edit: Actually, since you're interested in only the lower 8 bits, clearing of the carry bit before shifting is not necessary.
post edited by 1and0 - 2019/02/08 19:53:46
#6
1and0
Access is Denied
  • Total Posts : 8740
  • Reward points : 0
  • Joined: 2007/05/06 12:03:20
  • Location: Harry's Gray Matter
  • Status: offline
Re: PIC12F683 Unexpected Output - Semi High? 2019/02/08 16:54:21 (permalink) ☄ Helpfulby peteGSX 2019/02/14 02:49:32
+2 (2)
I see a pitfall in your code with your variables allocation:
    UDATA ; Place constants and variables in data area only
DELAY1 res .1 ; Variable for delay loop 1 count
DELAY2 res .1 ; Variable for delay loop 2 count
INPUT res .1 ; Variable for analog input for low check
LED_FLAGS res .1 ; Variable to set LED flags: Green bit 0, red bit 1, orange bit 2
TEMP_LOW res .1 ; Temporary store of EEPROM low
TEMP_HIGH res .1 ; Temporary store of EEPROM high
T.LOW res .1 ; Low threshold variable
T.HIGH res .1 ; High threshold variable
AVG_INDEX res .1 ; Variable for our average index
AVG_SUM_LO res .2 ; 16 bit variable for rolling average (low byte)
AVG_SUM_HI res .2 ; 16 bit variable for rolling average (high byte)
AVG_RESULTS res .1 ; 8 x memory locations for rolling average calculation
; Defining these at the end as I don't know how to reserve
; 8 locations equivalent to AVG_RESULTS:8 in relocatable mode

In your code you assumed it will be allocated to Bank 0; however, the linker can and might allocate them to Bank 1. ?!!
#7
Ian.M
Super Member
  • Total Posts : 13222
  • Reward points : 0
  • Joined: 2009/07/23 07:02:40
  • Location: UK
  • Status: offline
Re: PIC12F683 Unexpected Output - Semi High? 2019/02/08 19:22:21 (permalink) ☄ Helpfulby peteGSX 2019/02/14 02:49:44
+2 (2)
@1and0: Good catch.  Fortunately the effect's the same as ADC interrupts can only be triggered under program control  (except when the conversion is triggered by a CCP module special event).
 
Fortunately the code manages to avoid the RMW effect (see: https://www.microchip.com/forums/m478014.aspx), but its got to be about the most complicated way of doing so I've seen in a *LONG* time.   It would have been sufficient to declare port port bit patterns for the possible colours + Off, using EQU and in the Init_Sequence and Check_Thresholds subroutines, directly output those bits to the port with a MOVLW followed by a MOVWF.  The code is already set up with labels Input_OK, Input_Low and Input_High that are jumped to, to set the tree colours, so there'd be no problems replacing the sngke word calls with two instruction words to update GPIO directly (assuming bank 0 is left selected when Check_Thresholds  has made its decision).
 

--
NEW USERS: Posting images, links and code - workaround for restrictions.
I also support http://picforum.ric323.com because this forum is sometimes too broken to use!
#8
peteGSX
New Member
  • Total Posts : 11
  • Reward points : 0
  • Joined: 2019/02/06 11:43:13
  • Location: 0
  • Status: offline
Re: PIC12F683 Unexpected Output - Semi High? 2019/02/09 02:15:44 (permalink)
0
Ah lots of feedback, thanks all!
 
I've now disabled global interrupts and have commented out all the lines where I was enabling/disabling them during my subroutines but unfortunately the behaviour is still the same with GP4 occasionally turning partially on unexpectedly. Still the same 0.99V.
 
@1and0 I also updated AVG_RESULTS to res .8 thank you, I wasn't sure how to address that.
 
@Ian.M, one of my many "talents" is over complicating simple things, so I am not surprised to see your comment that my mitigation of the RMW effect is over complicated :) I did come across the RMW effect earlier on developing this, and the various subroutines etc. are all an evolution of that and obviously requires some more tidying up!
 
Any thoughts where I can go from here? Do I need to do something to avoid the potential pitfall of the linker allocating variables in bank 1?
#9
1and0
Access is Denied
  • Total Posts : 8740
  • Reward points : 0
  • Joined: 2007/05/06 12:03:20
  • Location: Harry's Gray Matter
  • Status: offline
Re: PIC12F683 Unexpected Output - Semi High? 2019/02/09 02:59:30 (permalink) ☄ Helpfulby peteGSX 2019/02/14 02:49:55
+2 (2)
Looking closely, I see you have enabled _MCLRE_ON config bit but the /MCLR pin is left floating.  Add a pull-up resistor of 10K to the /MCLR pin.
 
Since internal weak pull-ups are enabled in your code, R1 can be removed.
 
As for the variables can be allocated to Bank 1, it probably is not an issue in your code if you have selected the same bank when accessing them, as they are located at the same offset in Bank 0. Or, you can allocate them to the Shared Memory 0x70-0x7F, and access your buffer with FSR.
 
This is not a problem
AVG_SUM_LO res .2 ; 16 bit variable for rolling average (low byte)
AVG_SUM_HI res .2 ; 16 bit variable for rolling average (high byte)

but these should be RES 1.
 
post edited by 1and0 - 2019/02/09 03:03:07
#10
Ian.M
Super Member
  • Total Posts : 13222
  • Reward points : 0
  • Joined: 2009/07/23 07:02:40
  • Location: UK
  • Status: offline
Re: PIC12F683 Unexpected Output - Semi High? 2019/02/09 03:29:33 (permalink) ☄ Helpfulby peteGSX 2019/02/14 02:50:03
+3 (3)
The problem with relocatable mode, is in exchange for easier management of project containing a lot of code, you give up a lot of control of where code and data are placed.   On larger chips with more than one code page, this can be particularly problematic, requiring you to insert page select code before every non-local call or goto.  In your case as the PIC12F683 only has one code page, you only have to contend with data banking.   There are two possible roads to go down here: either add bank select code before any variable access that isn't via FSR/INDF, or override the default allocation to put the udata section containing the variables at a fixed address so you know which bank its in.
 
Decluttering the code may well help you find where its glitching, so I would suggest fixing the variable section address to the bottom of bank 0 with udata 0x20, then looking carefully at the number of levels of subroutines you are using for some fairly trivial tasks.
 
On the 16 bit (and larger) variable declaration and access issue, take a look at
https://www.microchip.com/forums/m537696.aspx where I showed my preferred method of handling contiguous multi-byte variables.
 
 
post edited by Ian.M - 2019/02/09 03:38:12

--
NEW USERS: Posting images, links and code - workaround for restrictions.
I also support http://picforum.ric323.com because this forum is sometimes too broken to use!
#11
1and0
Access is Denied
  • Total Posts : 8740
  • Reward points : 0
  • Joined: 2007/05/06 12:03:20
  • Location: Harry's Gray Matter
  • Status: offline
Re: PIC12F683 Unexpected Output - Semi High? 2019/02/09 04:18:38 (permalink) ☄ Helpfulby peteGSX 2019/02/14 02:50:15
+3 (3)
I'll have to agree with Ian in that you have way over complicated a simple program, which just read a voltage and set two LEDs.
 
Ian has mentioned one (multiple steps just to set two LEDs) in Post #8. Another one is your EEPROM routines. When the jumper is shorted upon power-on, your Reset_Thresholds writes two 0xFF to the EEPROM. When the program starts, Set_Thresholds reads the EEPROM and if it reads 0xFF for low and/or high it set the default thresholds of 167 and/or 190, respectively; otherwise, it uses the values read off the EEPROM. Instead of using multiple steps, Reset_Thresholds should writes 167 and 190 to the EEPROM. By the way, the EEPROM can be preset to 167 and 190 with 
;
; EEPROM Initialization
;
eeprom  code    0x2100
        de      .167, .190

#12
Chris A
Super Member
  • Total Posts : 818
  • Reward points : 0
  • Joined: 2010/07/20 04:37:07
  • Location: 0
  • Status: offline
Re: PIC12F683 Unexpected Output - Semi High? 2019/02/09 06:08:28 (permalink)
0
I haven't checked your code, but from the description it made me think it might be switching range very quickly and your ADC readings are being effected by LED change.  
#13
peteGSX
New Member
  • Total Posts : 11
  • Reward points : 0
  • Joined: 2019/02/06 11:43:13
  • Location: 0
  • Status: offline
Re: PIC12F683 Unexpected Output - Semi High? 2019/02/09 13:09:30 (permalink)
0
Thanks again guys, looks like I've got some changes to make!
 
@1and0 Ok, will add a pull up to MCLR, I wasn't aware I'd caused myself an issue there! The reason for the pull up on GP0 was that I was seeing the Adjust_Thresholds subroutine being entered unexpectedly, leading me to believe that pin was still effectively floating. I can't recall now if that was before or after I added delays to de-bounce the input. I initially expected the weak pull-ups to hold that pin high until the jumper was installed, so what you say makes sense.
 
@ian.M Thanks, that's very helpful! Given how simple this code should be, I think I'll opt for the udata 0x20 option and I'll definitely start reducing the number of subroutines, and in fact will refine the code in general. I agree with the both of you that there is too much code there for what should be a simple program.
 
With regards to the 16 bit registers, I'll be 100% honest here and say I can't quite get my head around what's happening in that averaging function. I found that in some code and I used it because it works. I knew I needed some way to keep a rolling average as once this circuit gets onto my bike it's not going to be a nicely controlled variable voltage source like I have on the work bench, and if I didn't average the input routinely I would get some unexpected results.
 
I'll definitely incorporate the suggested EEPROM changes as they make perfect sense, and I'll have a read of Ian.M's linked thread and see if I can make some sense of that.
 
@Chris A At the moment the circuit is just on the test bench running from a variable voltage source, so I don't believe that's the case. However, your comment intrigues me as to how the LED changes could affect the ADC conversion? Should I be turning the LED's off prior to starting the conversion or something along those lines?
#14
peteGSX
New Member
  • Total Posts : 11
  • Reward points : 0
  • Joined: 2019/02/06 11:43:13
  • Location: 0
  • Status: offline
Re: PIC12F683 Unexpected Output - Semi High? 2019/02/09 16:31:33 (permalink)
0
Ok, I've attached the updated asm file and schematic, no huge changes as I didn't want to change too many things in one go. My over complicated method for setting the LED colours is still in place, but setting the thresholds via the EEPROM and initial programming is fixed up.
 
The simulator tells me all is good, so I programmed the PIC again.
 
With the updated schematic, I first added the 10K pull-up to MCLR but left the 10K pull-up resistor for GP0 in place.
 
What happened then is that the program seems to run through the initialisation process ok and displays the LED output, unless the input voltage at GP1 is >= 3.5V, whereby the program seems to reset itself and gets in an endless loop flashing the initialisation LED sequence until I drop the input voltage back below 3.5V again, where it behaves normally.
 
I also then removed the 10K pull-up from GP0 but I don't see a difference in behaviour there.
 
I'm a little lost as to how that's now happening, although I must admit I'm not exactly sure what the deal with MCLR's function in relation to my circuit. I've endeavoured to understand what the datasheet tells me about it but my brain is just not comprehending it at this point in time.

Attached Image(s)

#15
1and0
Access is Denied
  • Total Posts : 8740
  • Reward points : 0
  • Joined: 2007/05/06 12:03:20
  • Location: Harry's Gray Matter
  • Status: offline
Re: PIC12F683 Unexpected Output - Semi High? 2019/02/09 23:16:31 (permalink)
0
I don't have time to look at your code at the moment. Hardware-wise, you need a bypass capacitor of 0.1 uF across the Vdd and Vss pins of the PIC device and as close as possible to the Vdd pin.
#16
peteGSX
New Member
  • Total Posts : 11
  • Reward points : 0
  • Joined: 2019/02/06 11:43:13
  • Location: 0
  • Status: offline
Re: PIC12F683 Unexpected Output - Semi High? 2019/02/10 03:13:50 (permalink)
0
No problems, this has been weeks in the making so there's most definitely no rush.
 
Despite how it looks on the schematic, C4 (100nF multi layer ceramic) is the bypass capacitor. On the prototype board it's literally the next hole beside the Vdd pin.
 
I probably should adjust the schematic to be a little more like reality.
#17
1and0
Access is Denied
  • Total Posts : 8740
  • Reward points : 0
  • Joined: 2007/05/06 12:03:20
  • Location: Harry's Gray Matter
  • Status: offline
Re: PIC12F683 Unexpected Output - Semi High? 2019/02/10 05:45:39 (permalink) ☄ Helpfulby peteGSX 2019/02/14 02:51:09
+1 (1)
Your buffer index variable AVG_INDEX is not initialized, so the first time around the buffer it corrupts the data memory. It is good practice to clear the RAM during the initialization of the device.
 
With that said, your Average_Input routine is over complicated. Instead of using an index, use the address (FSR) of the buffer AVG_RESULTS to step thru it.
#18
peteGSX
New Member
  • Total Posts : 11
  • Reward points : 0
  • Joined: 2019/02/06 11:43:13
  • Location: 0
  • Status: offline
Re: PIC12F683 Unexpected Output - Semi High? 2019/02/10 12:25:06 (permalink)
0
Ok, thanks again, I'll endeavour to figure that out and take care of those things.
 
That does explain why I see some unexpected values in some registers while stepping through the code in the simulator. I figured they were unexpected due to a lack of understanding on my part, rather than just being unexpected.
 
The averaging stuff is not something I've managed to comprehend just yet (someone else's code I incorporated), so I will dig through it and try to get my head around it as well which will help.
 
I'll probably take the extra time to start simplifying the LED output also, as that should mean a lot less code to read and interpret.
#19
peteGSX
New Member
  • Total Posts : 11
  • Reward points : 0
  • Joined: 2019/02/06 11:43:13
  • Location: 0
  • Status: offline
Re: PIC12F683 Unexpected Output - Semi High? 2019/02/13 12:43:54 (permalink)
0
Ok, finally got some time to look at it again this morning.
 
I've attached my altered asm file, but not quite as optimised as recommended. If I switch from calling subroutines to set the LED colours, my adjustment subroutine will get quite lengthy due to using the LED colours to visually display what is going on.
 
I have however removed using flags to set the colours and am just setting them directly.
 
I've also fixed the incorrect assignment of 2 bytes for AVG_SUM_LO and AVG_SUM_HI.
 
I've not started investigating how to avoid using the AVG_INDEX variable yet.
 
The behaviour I'm seeing at present is when the analog input is ~3.2V, it triggers what appears to be the reset cycle where it constantly appears to go through the initialisation LED sequence. Once the analog input reaches ~3.4V, this behaviour stops. It's repeatable behaviour between power cycles too.
 
I've attempted to watch the various file registers and variables while running through the simulator, but the only thing I noticed that I didn't expect is the timer0 counter and interrupt flag being set, but from what I can understand from the datasheet this looks to be ok and will not cause me any issues.
 
What I'm not sure on is what variables or flags to look at to see what could be triggering a reset?
 
Given this behaviour is repeatable there absolutely must be something wrong with my code. I guess it could be my circuit as well but aside from changing the pull-up on MCLR and GP0 it's still essentially the same as what I started with.
#20
Page: 12 > Showing page 1 of 2
Jump to:
© 2019 APG vNext Commercial Version 4.5