Simulation works, real PCB does not

Status
Not open for further replies.

John Thompson

New Member
I have a circuit an program using a Pic 12F683 that has 3 switches connected which drive their respective 3 servos connected to 3 outputs to one end of their travel or the other. To do this there are three identical blocks of code, one for each switch input/servo output pair.

The code de-bounces the switch and then if the switch position has changed sends 25 20ms frames of 1 or 2ms on times to the servo.

The code works just fine in the simulator. All the variables change as expected, the output poins pulse as expected in response to switch changes.

But when loaded into a Pic and the PCB tested nothing happens. My logic analyser detects the switch changes, but no resulting pulse train on any output no matter what the switch position. The servos stubbornly remain in their start position. The only sign of life is that with the switch off the voltage on the input pins read 3.45v (5v supply), which indicates the PullUp setting part of the code is working.


I have checked the program to death, especially the register and config settings, and ditto the PCB. Can't see any problem, and have reached the point where if there is a mistake I am missing it every time. Fresh thought are needed.


Anyone have a suggestion on how best to proceed?
 
So far we have very little information.
Schematics, pictures, code, etc.

One option is to start out with a very simple program. Toggle a single pin.
Maybe the PIC did not get programmed.
Maybe the PIC is held in reset.
Maybe the OSC is not oscillating.
Maybe the power is not connected.
There must be 100 maybe(s).
 
My apologies, I probably should have attached the code and the circuit first up. I was trying not to clutter the thread by asking the general question of why code would run in the simulator but not when the Pic is installed on its PCB.

So, a little more information. First, all the obvious checks have been done - There is power and the Pic did get programmed (note the PullUp function would not be active if it had not and the PiKit2 programmer verifies the program was loaded. And I tried three chips, and it is unlikely all three would be defective.

To add some spice, the program was originally intended for a Pic 12F510. The only difference in the code is what I call "Above the Line" meaning the set up/configuration stuff specific the the chip being programmed. That stuff is different for the 12F510 and the 12F683, but "below the line" the code is identical.

The 12F510 version did move the servos on power up and the analyser showed the right pulse chain. But the PCB would not respond to switch position changes. After much prodding I found the voltage on the switch pins did not go High when the switches were off. I worked out I had misread the Data Sheet to say the 12F510 PullUps were enabled for all pins, not individually. In fact only three pins have PullUps, and I used those as outputs, so the program never saw logic 1 on its pins, only logic 0. A test with PullUp resistors added worked - so then I had the real world correctly mimicking what the simulation said.

To avoid reworking 30 or so PCBs with PullUp resistors I decided to try the 12F683 (of which I have quite a few in hand) which does have individual programmable PullUps. The code works in the simulator exactly as intended. And the code activates PullUps correctly in the real world as shown by the measured voltage on the pins - that indicates the Pic is programmed and at least recognises dome code. Measuring the pin volts with the switches on and off shows less than the 0.8v threshold for logic 0 and at 3.45v above the datasheet threshold for Logic 1. But the Pic will not respond to its switches.

The root of my question is not so much how to debug the PCB. My question is why would this code work exactly as intended in the Oshonsoft simulator, but not in the real world. The whole idea of the simulator is to sort out programming problems without having to use physical testing to try and work out indirectly what is happening inside the Pic indirectly via external measurements.

This morning I built a test PCB with appropriate connections for the analyser etc to facilitate physical testing, and I expect by staggering around in the indirect dark I may narrow down why the code does not work - but of course that is in effect duplicating the jopb of the simulator.


If anyone can provide some guidance, I would be very appreciative.

Files for the code and the circuit are attached.
 

Attachments

  • 3 x Servo Switch Driver 12F683 ver IV.bas
    6.6 KB · Views: 339
  • E_..._ServoDvr x 3 12F510 VI.ckt.pdf
    35.8 KB · Views: 357
You don't appear to have turned the comparator off. Try adding CMCON0=7.

Mike.
 
A couple of points:
1) Did you do any calibration of the internal oscillator? EDIT: Oops, my mistake, the 12F683 does not have an OSCCAL...
2) What are you driving with the outputs. The output pins are limited to about 20mA output. You must have some interface chips between the PIC and the servo. What are they? What load does the servo input give? Maybe it draws too much current, and the pic cannot supply enough signal. Test the PIC without any load and look at the outputs with a scope.
3) Use the definition "ALLDIGITAL" in the code. The Oshonsoft compiler will clear all the ansel and comparator registers
4) weak pulls are just that, weak... Try something like 10k pull up resistors with the input switches.

Working in simulator and not in the real word is usually due to some hardware differences, as well as interrupts/WDT/etc. that the simulator tends to ignore. Also things like insufficient bypass caps at the PIC, noisy voltages (5V), and other things can affect real life performance.
Like I said, try it without any loads. Then make sure the servos can be triggered properly with only 20mA of current at 5V
 
Last edited:
I am not a software person and have not used your simulator; but ….
Several times on this forum this same question was asked.
On power up most PICs have all the pins set to input. Writing to a pin does nothing. You must set a pin to output first.
Several university students, that have asked this question before you, said that they found, in simulation you can write to a input pin and the simulator indicates that the data was output. This will not work in real life.

We also have a problem with many people read a analog voltage on a pin that is set to digital input. You need to set the pin to analog input first.
Disclamer:
I know nothing about this subject. I might be thinking about another type of micro, different simulator, or just not thinking. lol
 

Hobby-type servos use a control input that doesn't require much current. They are often driven directly from PIC pins. An example is shown here.

Setting the pins to digital and as outputs is likely the problem.
 
Last edited:
Thank yo to all who replied to assist.

The problem turned out to be a collection of things, the biggest of which had nothing to do with the Pi or its programming. I had a USB hub that was faiuling intermittently, dtopping correct functioning of the keyboard, mouse and the Salae Analyser and probably the PicLit2 programmer. Once identified and fixed by replacement, order returned to the anlaysis.

Comments on your various replies:
I had not turned of the comparator. That change breathed life into the outputs.

I like the suggestion of ALLDIGITAL. I shall use that in future. But along the same lines, after the turn off of comparator advice I went painstakingly through the datasheet writing ALL bits to all registers whether I used that function or not. (First through I set only the bits for functions I (thought) I was using)

The outputs being driven are servos,and they draw little current. The power interface is built into the servos, which have separate power wiring. No change in performance measured at the Pic pins with servos disconnected or not - same analyser output.

The program correctly sets the pins as digital and as IP or OP as required. Including GP3 as IO, not MCLR.
The program correctly sets PullUps for GP4 and GP5 (But it turns out cannot cannot set GP3 for PullUps when used as a digital Input)

My reading of pin voltages was to see if I had Logic 1 or Logic 0 on the pins correctly under control of the switches. In other words I was looking for below 0.8v or above 2.0v, which I understand from my reading of the datasheet are the logic threshold voltages. What I was reading was in accord with the datasheet, but in the case of GP3, not my expectations.

Outcome:
Once the analyser was reliably active post USB Hub transplant, I found the period of the pulse train to the servos was 40ms - double that expected, so the servos ignored the signal. Cause was I had set the oscillator to 8MHz, but had not told the PROGRAM this frequency applied. DEFINE OSCILLATOR FREQUENCY = 8 and I had the right period for pulse train to the servos, and they then responded.

I now had two of three channels responding correctly to switch inputs. The third was GP3, which the program set to be digital Input instead of MCLR Input. But sadly I had mis-read the datasheet to mean that being an input, this pin automatically had its PullUp enabled. I does, but on close reading of the datasheet and its notes, ONLY WHEN SET AS MCLR. Set as IO it has no PullUp, which is what my voltmeter and the analyser was telling me - always logic 0. No choice but to add an external resistor, confirmed to work by my test PCB, analyser and trusty voltmeter. Once added to the "Production" PCBs all now works fine.

Important conclusions for me from this exercise are:
* Set all registers whether you are using that function or not.

* Don't believe every problem is related to the micro-controller your program. External things we take for granted can fouls things up very effectively.

* Most important of all, read the data sheet carefully for what it actually says, not what you expect ot imagine it shold say.

Thanks again to all of you. I hope my experience in this may also help others.
 
I went painstakingly through the datasheet writing ALL bits to all registers whether I used that function or not.
Most modules default to off so this is not normally needed. The comparators are the exception. In the data sheet you will find the default values for all registers at power up - normally titled SPECIAL FUNCTION REGISTER SUMMARY.

Mike.
 
Status
Not open for further replies.
Cookies are required to use this site. You must accept them to continue using the site. Learn more…