Strange behaviour from PIC16F877 on TMR0
Good morning to everyhome.
I'm a little bit desperate because I have a very strange behaviour from a project of mine that is controlling a DC 24V motor with a single channel hall-effects encoder on the shaft.
What the project do, is open a pliers to a specified position and then come back. I've connected the open collector output of the single channel encoder of the motor to a 2.2Kohm pull-up resistor and then to a NOT gate made with a BC547 transistor and a couple of resistors. From this NOT gate, directly to a spare quad-or gate 7432. The output of the OR gate is applied to the RA4 (Timer0) input of the PIC 16F877, running at 4MHz with two 22pf capacitors on the crystal.
The RA4 pin is set to be incremented from an external source.
The 24V power needed for the motor is completely ground separated from the power that run all the logic. The motor is drived by one L298N dual H-Bridge with flyback fast diodes.
I wrote the firmware that poll the TMR0 register and if I find a value greater than zero this value will be accumulated in a word sized variable.
When this value reach a thereshold, the motor have to stop.
All the registers related to the TMR0 seems to be setup correctly, like this:
OPTION_REG.7 = 0 'Pull-up resistor set to ON over the PortB
OPTION_REG.6 = 1 'Rising Edge detection on PortB.0
OPTION_REG.5 = 1 'Set TMR0 to be incremented from an outside source
OPTION_REG.4 = 1 'TMR0 will be incremented from a high-to-low (falling edge signal transition)
OPTION_REG.3 = 1 'Assign the Prescaler to the WatchDogTimer instead of TMR0
OPTION_REG.2 = 0 'The bit from 2 to 0 define the Prescaler's reduction ratio
OPTION_REG.1 = 0 'in this case it is 1:1 of the WDT rate
OPTION_REG.0 = 0
'ADCON1 register setting (Datasheet page 112)
ADCON1.3=0 'Set the Port A in DIGITAL mode (bits from 3 to 0 of the ADCON1 register)
ADCON1.2=1
ADCON1.1=1
ADCON1.0=1
'INTCON register setting (Datasheet page 20)
INTCON.7 = 0 'Disable the Global Interrupt flag (GIE)
INTCON.1 = 0 'Clear the bit before enabling the interrupt on RB0
'If INTCON.1=1 mean that an external interrupts occurred on RB0.
'The INTCON.1 bit have to be cleared by software (INTF)
INTCON.4 = 1 'Enable external interrupts on RB0 (Pin n.6) (INTE)
INTCON.2 = 0 'Clear the bit before enabling the interrupt on TMR0 overflow.
'If INTCON.2=1 mean that TMR0 is in overflow.
'The INTCON.2 bit have to be cleared by software (TMR0IF)
INTCON.5 = 1 'Enable Overflow Interrupt on TMR0 (T0IE)
What is happening is that this circuit work MOST OF THE TIME!
But sometime happen that the motor NEVER STOP and then I will unplug the motor leads to stop it. Then, if I have a look to the variable that have to accumulate the value she show me only small values. I mean, normal values are around 500 pulses, instead I found 7 or 10 or 100...
This is let me fool and this is a project kill behaviour.
I've also putted some filter out of the encoder output made by a diode followed by a resistor, capacitor and a zener diode of 4,7V but this not helped me.
I've many 100nF capacitors all around the board and very close to the PIC, but nothing. I've also 330microF close to the PIC.
MCLR is connected by a 4,7K resistor to the Vcc.
All the unused PIC pins are set as output and left unconnected.
I've also replaced the motor with the encoder with another one of the same type, but nothing.
Seems that the PIC is NOT resetting itself. Simply seems that he ignore the incoming pulses on RA4. So, I've modified the source code to flash a led each time that a values greater than zero is found on the TMR0 register.
What is happening is that the Led still correctly flashing but seems that the variable is screwed up.
The program is quite long and seems that I'm experiencing this behaviour after I made some modifications that have made the program longer than before.
Then I've moved this variable to Bank0:
BeackEncPos VAR WORD Bank0 'Accumulate the encoder position
BeackFinalPos VAR WORD Bank0 'This is the thereshold that have to be compared with the BeackEncPos variable
This pop up another question: how many word sized variables can I store in the Bank0?
Currently I managed to have in the bank0 3 byte sized variables, 3 bit sized variables and 8 word sized varibles. Maybe I'm running out of this space and I don't know...
I'm sure that I've not touched the place where the counting is made and also I'm sure that I've not used some variables that is shared between the previous version and the new one.
Worst of all, is that I start having this behaviour 2 nights ago and after many cuts & corrections on the board (add some cap more etc), firmware upgrading etc. at the end the last night this robot was working very well for the whole night and made hundreds of movements. All very well done. Then I switched off and today in the morning, only after few movements, I'm experiencing the same behaviour I had 2 nights ago. :-(
I really don't know why and where this erratic behaviour is coming from!
Any suggestions?
Please, somebody with high knowledge like the peoples that write on this forum, can save me from the third no sleeping night?
Sorry for the long post.
Thank a lot to everyone.
Mike.
1 Attachment(s)
Schematic here and some info more
Quote:
Originally Posted by mister_e
Woohaa i try to figure out but there's too much 'maybe this or that' in my mind.
Can you post your whole code and schematic?
Thank you, mister_e.
Tonight I've found that absolutely there is not the software that cause this so strange behaviour. Since the board is under control of another one that drive 2 bigger motors in PWM (24Vdc, anytime separated from the power of the logic but this 24Vdc are the same that power the tiny motors where I loose pulses), I've found the following:
If I let one of this bigger motor to use a little bit more power (just because I'm trying to move the shaft with my hand and the PID controllers try to oppose to my strenght) THEN the strange behaviour start happening. If I turn off one of these motors, the "strangeness" do not happen.
Seems that there is some kind of disturbance that is picked-up by the micro.
I've putted so many caps and grounded any unused pin as you can see... what can I do more?
Also, when I start missing pulses on TMR0 (RA4) seems that I pick-up many other "ghost" pulses on RB0...
Thank you for your time.
Maybe the Mister_E to english dictionnary will be needed here
OR your power supply is not good enough to provide more power. Assuming a spike when you need more power, the voltage may decrease enough at the input of the 7805 to make this one unable to provide the stable 5Volt at the output. If the output of the regulator drop under the Brown Out voltage of your PIC, it may badly reset the PIC and send the PC to an unwanted program location. Hence do some strange behaviours.
How about if you use another transformer (let's say wall wart) to drive your PIC?
I'll have a look to your schematic.. maybe i could find something in.