PDA

View Full Version : I don't understand this code!



Russ Kincaid
- 6th May 2007, 02:31
I am trying to generate a quasi sine wave at 60 hz. The program runs but the waveform is upside down. I could change the circuit to accept the upside down wave, but I would like to know what is going on. This is my simple code:
REM DEVICE = 12F675 '12F629 CAN ALSO BE USED
REM USE INTERNAL OSCILLATOR, OUTPUT IS ON GP4 (PIN 3)
REM CONFIGURATION: INTOSC CLOCKOUT, WDT DISABLED, PWR UP ENABLED,
'MCLR = OUTPUT PIN, BROWN OUT DISABLED, NO PROTECTION
REM 60 HZ OUTPUT IS ON PINS 7 AND 6
REM OSCILLATOR CHOICE: USE 101, INTOSC, CLKOUT
OPTION_REG.5 = 0 'OTHERWISE GPIO.2 IS AN INPUT
TRISIO = %111111 'SETS ALL PORTS TO OUTPUT
ANSEL = 0 'SETS ALL DIGITAL MODE
DEFINE OSCCAL_1K 1 'FOR OSCILLATOR CALIBRATION, DON'T KNOW HOW IT WORKS

HIGH GPIO.0 'INITIAL CONDITIONS
HIGH GPIO.1

START:
LOW GPIO.1
PAUSEUS 4168 ' ON TIME
HIGH GPIO.1
PAUSEUS 4167 'DEAD TIME
LOW GPIO.0 'SETS PIN 7 LOW
PAUSEus 4168 'FOR 4.168 MILLISECONDS
HIGH GPIO.0
PAUSEUS 4167 'DEAD TIME

GOTO START '60 HZ FREQUENCY

END

If I change all highs to lows and all lows to high in the loop, I get the idenical same hex code. I would expect that
high gpio.0
highgpio.1
start:
low gpio.1
would give a different hex code than
high gpio.0
high gpio.1
start:
high gpio.1

Russ

Pic_User
- 6th May 2007, 02:48
Hi Russ,

Could you explain how the waveform is upside down?
Do you mean that the 60 Hertz quasi sine wave is upside down on your oscilloscope display? Switch your scope “triggering” from plus(+) to minus(-).

-Adam

Russ Kincaid
- 6th May 2007, 04:31
Thanks, I should have said that: I want the output to be low for the short time (4+ms) and high for the long time (12+ms). I think the program should do that, but it doesn't. The output is high for the short time and low for the long time.

languer
- 6th May 2007, 05:03
Your main code looks fine:

START:
LOW GPIO.1
PAUSEUS 4168 ' ON TIME
HIGH GPIO.1
PAUSEUS 4167 'DEAD TIME
LOW GPIO.0 'SETS PIN 7 LOW
PAUSEus 4168 'FOR 4.168 MILLISECONDS
HIGH GPIO.0
PAUSEUS 4167 'DEAD TIME

Your startup code does not:

TRISIO = %111111
This sets all pins to <U>inputs</U>. You want to use:

TRISIO = %001000 '(since GPIO3 is input only anyway)

skimask
- 6th May 2007, 06:04
TRISIO = %001000 '(since GPIO3 is input only anyway)

Except for the fact that HIGH and LOW automatically set the pins as outputs... :)

Now then...what is this output thing? Is this a 2 bit R/2R D/A ladder type setup or what is it?

mister_e
- 6th May 2007, 09:44
If it was me, i would use a timer interrupt, but add somes extra filter outside.

I don't understand what you mean by


The program runs but the waveform is upside down. I could change the circuit to accept the upside down wave,

Russ Kincaid
- 6th May 2007, 15:38
What I mean by "upside down" is: When the programmed output is high, the output actually goes low and when the programmed output is low, it actually goes high. I don't understand that.

Russ

Pic_User
- 6th May 2007, 17:00
Hi Russ,

What I mean by "upside down" is: When the programmed output is high, the output actually goes low and when the programmed output is low, it actually goes high.

We are not trying to give you a difficult time about this inverted waveform thing. It is just difficult to tell what you are seeing on a recurring waveform. Do you have another circuit synchronized with this output? Are you referencing the measurement to the PIC common?
The timing may be difficult to see with a rapidly cycling code. You could change the code to seconds, just to watch the sequence.

It looks like you WANT the output to be HIGH for three time increments and LOW for one. (See attachment.) http://www.picbasic.co.uk/forum/attachment.php?attachmentid=1594&stc=1&d=1178466510
Is the waveform LOW for three time increments and HIGH for one?

-Adam-

Russ Kincaid
- 6th May 2007, 18:19
Hi Russ,



It looks like you WANT the output to be HIGH for three time increments and LOW for one. (See attachment.) http://www.picbasic.co.uk/forum/attachment.php?attachmentid=1594&stc=1&d=1178466510
Is the waveform LOW for three time increments and HIGH for one?

-Adam-

Exactly right. Why does it do that?
BTW, GPIO.0 produces the positive half of an AC signal while GPIO.1 produces the negative half. The result is an AC that reads the same on a true RMS meter or one that reads 0.7 of the peak.

skimask
- 6th May 2007, 18:36
I'm thinking it might be time to post your schematic so we can quit guessing and start fixin' !

Russ Kincaid
- 6th May 2007, 18:52
This is a very simple circuit, and not part of the problem, I believe.

Russ

skimask
- 6th May 2007, 19:00
This is a very simple circuit, and not part of the problem, I believe.

Russ

Turn the LEDs around and connect them to ground.
When you apply a logic 0 to the pin, the pin sinks current and the LED lights...when you apply a logic 1 to the pin, the LED has the same voltage on both sides and doesn't light up...negative logic.
That's why everything is backwards...but it's really not...it's working just as designed.

Russ Kincaid
- 6th May 2007, 22:18
No, No, not working as designed. I know I can turn the LEDs around, but I want to know why I have to do that. I suppose I could write the program to do the opposite of what I want and see what happens.

Pic_User
- 6th May 2007, 23:40
Hi Russ,

The waveform and any talk about HIGH / LOW is assumed to be in reference to the (ground / common / Vss) of the PIC. Your LEDs are “referenced” to the plus “rail” of the supply. That would make the LED output appear to be (upside down / negative logic). You could rewire the LEDs or re-order the code.

By the way, it is very interesting to put both LEDs on the single 1k resistor. Causing the voltage to vary differently when one, two or none of the LEDs are on! Getting, the same reading on a true RMS and a cheap 0.7 of peak meter is not an easy task! Where do you measure the voltage?

I vote to re-order the code.:)
-Adam-

Russ Kincaid
- 6th May 2007, 23:54
I re-wrote the program to produce the opposite waveform, but it is the same waveform:
LOW GPIO.0 'INITIAL CONDITIONS
LOW GPIO.1

START:
HIGH GPIO.1
PAUSEUS 4168 ' HIGH TIME
LOW GPIO.1
PAUSEUS 4167 'DEAD TIME, BOTH LOW
HIGH GPIO.0 'SETS PIN 7 HIGH
PAUSEus 4168 'FOR 4.168 MILLISECONDS
LOW GPIO.0
PAUSEUS 4167 'DEAD TIME

GOTO START '60 HZ FREQUENCY

END

Since both programs produce the same waveform, I guess my only option is to turn the LEDs around!
My circuit is only for testing. If I were driving solid state relays they would burn up when both were on.

Pic_User
- 7th May 2007, 00:14
Russ, the code will cause both LEDs to be on at the same time, even if the LEDs are referenced to ground.
GPIO.0 and GPIO.1 are the same level in the “second” and the “forth” time increment.
The previously attached waveform drawing shows this.
http://www.picbasic.co.uk/forum/attachment.php?attachmentid=1594&stc=1&d=1178466510
You may have forgotten 4.168 milliseconds is one quarter (“one quadrant”) of a full cycle (16.667) – not one half.
-Adam-

skimask
- 7th May 2007, 04:55
Might sound a bit silly, but, maybe if you drew us a quick picture of what you want the output to be, like if it was a picture from an o'scope, we might be able to better understand what you actually want.
The last post by Pic_User sounds like that might be the problem, simple mistake, easily fixed...

Russ Kincaid
- 7th May 2007, 13:57
The waveform posted by Picuser is what I want the output to look like. The actual output is the inverse and I don't understand it. Perhaps my compiler is corrupted?

skimask
- 7th May 2007, 14:43
The waveform posted by Picuser is what I want the output to look like. The actual output is the inverse and I don't understand it. Perhaps my compiler is corrupted?

I'd highly doubt your compiler is corrupted, but maybe a reinstall is in order.
And I think post #16 might be your problem in the first place.

Russ Kincaid
- 7th May 2007, 16:06
Thanks for your reply. PIC_USER is correct in post #16, both GPIO.0 and GPIO.1 are at the same level in time periods 2 and 4, but they are both low. I want them to be high. Can someone tell me what is wrong with my code?

BTW, I changed to TRISIO=0, didn't make a difference.

Pic_User
- 7th May 2007, 16:26
Hi Russ,
I think with your original pins (GPIO.0 and GPIO.1), and your second (inverse) code:

LOW GPIO.0 'INITIAL CONDITIONS
LOW GPIO.1

START:
HIGH GPIO.1
PAUSEUS 4168 ' HIGH TIME
LOW GPIO.1
PAUSEUS 4167 'DEAD TIME, BOTH LOW
HIGH GPIO.0 'SETS PIN 7 HIGH
PAUSEus 4168 'FOR 4.168 MILLISECONDS
LOW GPIO.0
PAUSEUS 4167 'DEAD TIME

GOTO START '60 HZ FREQUENCY

END

...and your diodes reversed and the resistor tied to ground (as skimask said).

Your two LEDs will not be on at the same time... (try it)

I still would like to know between which points are you measuring the wave (voltage) from?:)

-Adam-

Russ Kincaid
- 7th May 2007, 17:08
Hi Pic_User. Yes, I know that, but why cannot I connect the LEDs to + and pulse to ground? I changed the program, trying to zero in on the probem. Now GPIO.1 pulses to ground like I want but GPIO.0 pulses positive in phase with GPIO.1. I would not expect GPIO.0 to change at all.

high GPIO.0 'INITIAL CONDITIONS
high GPIO.1

START:
low GPIO.1
high GPIO.0
PAUSEUS 4168 ' ON TIME
high GPIO.1
PAUSEUS 4167 'DEAD TIME, BOTH high
high GPIO.1
PAUSEus 4168 'FOR 4.168 MILLISECONDS
high GPIO.1
PAUSEUS 4167 'DEAD TIME

GOTO START '60 HZ FREQUENCY

END

I will post the final circuit so you can see what I am trying to do. I want to replace the 555, flip flops and gate with the PIC.

Pic_User
- 7th May 2007, 18:22
Hi Russ,

Looking at the circuit you want to replace:
It looks like you want to avoid both being on at the same time, at all costs (as you said).

It may be better to declare variable for the “HIGH TIME” and the “anti-overlap” time so you can change them in one place in the program, while playing with the duty cycle.

Could be missing something but it looks like you want the positive part of the cycle to take 8.336 milliseconds and same time for the negative part.
Sixty Hertz = 1/60 = 0.0167 (16.67 milliseconds).
This gives us 16.67 milliseconds for a complete (whole) cycle.

How much on or off time can be played with but the recurring 60Hz, is fixed.
So the total on and off time for GPIO.0 and GPIO.1 should equal 16.67 milliseconds, and never be on at the same time.

I used your same code and beat it up pretty bad:

LOW GPIO.0 'INITIAL CONDITIONS
LOW GPIO.1

START:

HIGH GPIO.1
PAUSEUS 8236 ' HIGH TIME - GPIO.1 only
LOW GPIO.1 ‘both pins low
PAUSEUS 100 ' anti-overlap time
‘ HIGH TIME and over-lap time should add to 8.336 milliseconds

HIGH GPIO.0 ' GPIO.1 has been low during anti-overlap time
PAUSEUS 8236 ' HIGH TIME - GPIO.0 only
LOW GPIO.0 ‘ both pins low
PAUSEUS 100 ' anti-overlap
‘ HIGH TIME and over-lap time should add to 8.336 milliseconds

GOTO START '60 HZ FREQUENCY

END

Play with HIGH TIME and anti-overlap to get the desired duty-cycle (average vs. RMS vs. 0.7 ) but they should total to 8.336 milliseconds each half cycle. Then 16.67 milliseconds for the whole cycle.

You should run the diodes (LEDs) between the PIC pins and the resistor to common (ground).

Oh yeah, I should warn you that I don’t know what I am doing!:>

-Adam-

Russ Kincaid
- 7th May 2007, 18:51
Thanks, but I have already built the board, I don't want to cut traces if I don't have to. My original program produced the inverted waveform, I want to be able to produce the waveform per the sketch. As another experiment, I modified the program, adding another HIGH GPIO.0, but now both outputs go low at the same time for 8 mS.

high GPIO.0 'INITIAL CONDITIONS
high GPIO.1

START:
low GPIO.1
high GPIO.0 'GPIO.0 GOES LOW
PAUSEUS 4168 ' ON TIME
high GPIO.1 ' GPIO.1 GOES LOW
HIGH GPIO.0 'GPIO.0 STAYS LOW
PAUSEUS 4167 'DEAD TIME,
high GPIO.1 ' BOTH GO HIGH
PAUSEus 4168 'FOR 4.168 MILLISECONDS
high GPIO.1 BOTH STAY HIGH
PAUSEUS 4167 'DEAD TIME

GOTO START '60 HZ FREQUENCY

END
GPIO.0 and GPIO.1 are synchronous but I don't know that they follow the program!

skimask
- 7th May 2007, 19:09
high GPIO.0 'INITIAL CONDITIONS
high GPIO.1
START:
low GPIO.1
high GPIO.0 'GPIO.0 GOES LOW
PAUSEUS 4168 ' ON TIME
high GPIO.1 ' GPIO.1 GOES LOW
HIGH GPIO.0 'GPIO.0 STAYS LOW
PAUSEUS 4167 'DEAD TIME,
high GPIO.1 ' BOTH GO HIGH
PAUSEus 4168 'FOR 4.168 MILLISECONDS
high GPIO.1 BOTH STAY HIGH
PAUSEUS 4167 'DEAD TIME
GOTO START '60 HZ FREQUENCY
END

I think you might be confusing yourself a bit...not sure, but that's what it looks like to me...
high GPIO.0 'GPIO.0 GOES LOW ---- GPIO.0 looks like it goes low because the LED goes out. No... it's got 5v on both sides of the LED...no current flow...

I think, in the end, you're going to end up cutting traces and doing some rewiring.

Pic_User
- 7th May 2007, 19:23
This code should work with the LEDs wired the original way.
You could even put a time delay before the ON time and after the ON time, to “push” the waveform around. To get the desired timing to get the quasi sine wave at 60 Hz. I have no idea what timing will help!
Just be sure the total adds up to the times for 60Hz.

START:
PAUSEUS 2074 ' before pulse
LOW GPIO.1 ‘ON = pulse
PAUSEUS 4168 ' ON TIME - GPIO.1 only
HIGH GPIO.1 ‘both pins OFF
PAUSEUS 2074 ' after pulse
PAUSEUS 20 ' anti-overlap time
‘should add to 8.336 milliseconds

PAUSEUS 2074 ' before pulse
LOW GPIO.0 ‘ON = pulse
PAUSEUS 4168 ' ON TIME - GPIO.0 only
HIGH GPIO.0 ‘both pins OFF
PAUSEUS 2074 ' after pulse
PAUSEUS 20 ' anti-overlap time
‘should add to 8.336 milliseconds
GOTO START '60 HZ FREQUENCY

END

I still would like to know between which points are you measuring the wave (voltage) from?:)

skimask
- 7th May 2007, 19:33
I still would like to know between which points are you measuring the wave (voltage) from?

I'm guessing just looking at the LEDs, not actually measuring voltage...
I could be wrong...been there before :)

Pic_User
- 7th May 2007, 19:37
I'm guessing just looking at the LEDs, not actually measuring voltage...
I could be wrong...been there before :)

Bet you’re right. Must be difficult to tell if both come on together at 60 Hz tho...

skimask
- 7th May 2007, 20:20
Bet you’re right. Must be difficult to tell if both come on together at 60 Hz tho...

Unless the guy has REALLY FAST eyes! :)

Pic_User
- 7th May 2007, 20:23
Unless the guy has REALLY FAST eyes! :)
Hard on the eyes!
Maybe that's why they call it 60 hurts.:)

Ioannis
- 7th May 2007, 21:02
Hard on the eyes!
Maybe that's why they call it 60 hurts.:)

Me anyways, even after a good sleep and a cup of coffee cannot see the 50 Hz. As for the 60....

Ioannis


P.S. May be it's the age!

malc-c
- 7th May 2007, 22:42
Suggestions:

1: When developing a project its always worth building the hardware on something like a solderless breadboard as it makes changes a doddle and saves on the cost of designing, etching and then throwing away a PCB.

2: I always drive LEDs from pins with their own series resistor connected to the pin, and all commoned to GND. Connecting the LEDs from +ve will cause them to light when the PIC provides a source to ground.

3: At the frequencies you are hoping to monitor (60 Hz) it will be very hard to monitor whats happening with LEDs as the eye will not be able to register the pulses. Try setting the delays and pulse timing to something that you can see, possibly by some scale factor (say by a factor of 10). Once you have the code working with the correct sequence of pins going high and low with the correct delay at this factor, then you can scale it back.

Just my 2p's worth ;)

Russ Kincaid
- 8th May 2007, 03:22
You guys are cracking me up! Of course I am using a dual trace scope and Pic_User has posted the correct waveform, which I have not been able to produce. I re-installed the software but that was no help. I like the idea of putting extra PAUSEUS in, I will try that.

skimask
- 8th May 2007, 04:25
You guys are cracking me up! Of course I am using a dual trace scope and Pic_User has posted the correct waveform, which I have not been able to produce. I re-installed the software but that was no help. I like the idea of putting extra PAUSEUS in, I will try that.

But we STILL don't know WHERE you are taking your measurements from!

Dave
- 8th May 2007, 11:43
Pssst.... Look in post #22.....

Dave Purola,
N8NTA

skimask
- 8th May 2007, 14:18
Pssst.... Look in post #22.....
Dave Purola,
N8NTA

Shows where A & B are and what they should be doing on the 'scope, but, doesn't show for sure where he's measuring from.

Pic_User
- 8th May 2007, 15:43
Shows where A & B are and what they should be doing on the 'scope, but, doesn't show for sure where he's measuring from.
skimask is right.
If your LEDs are referenced to V+ and your scope is referenced to Vcommon
the scope will show a logic high when the LEDs are off.
If you “invert” a channel on your scope it should show you what the LED is doing...

I have not tried it but this code should work:

‘ with both LEDs referenced to V+
high GPIO.0 ' OFF INITIAL CONDITIONS
high GPIO.1 ' OFF INITIAL CONDITIONS
START:
PAUSEUS 2074 ' before pulse
LOW GPIO.1 ‘ON = pulse
PAUSEUS 4168 ' ON TIME - GPIO.1 only
HIGH GPIO.1 ‘both pins OFF
PAUSEUS 2074 ' after pulse
PAUSEUS 20 ' anti-overlap time
‘should add to 8.336 milliseconds

PAUSEUS 2074 ' before pulse
LOW GPIO.0 ‘ON = pulse
PAUSEUS 4168 ' ON TIME - GPIO.0 only
HIGH GPIO.0 ‘both pins OFF
PAUSEUS 2074 ' after pulse
PAUSEUS 20 ' anti-overlap time
‘should add to 8.336 milliseconds
GOTO START '60 HZ FREQUENCY

END

I agree with Malcolm on all three points he made.
The idea about slowing the duty cycle down to visible speeds to test LEDs is good....
But, because, your board is made:
You should be able to use a single (LED) supply resistor in this circuit because you NEVER want the LEDs to be on at the same time.
You can leave the LEDs referenced to V+ as long as you remember any Vcommon referenced measurements are inverted to the LEDs.

Also:
Do you have your optocouplers on the board? If so:
You can temporarily feed them with +/-12V (instead of the 150V) and a series resistor in each leg to protect them (in case both on)...
Measure the output referenced to common.

Aside:
The programmable guard time (anti-overlap time) between polarity switching is handy, I know you have done that in your analog work with deliberate propagation delays. Keeps the smoke to a minimum.:)

The programmable “before / after pulse” time would help “push” the wave shape to what you want.

-Adam-

Russ Kincaid
- 9th May 2007, 22:05
I hate to tell you this, Adam, but your program makes the outputs high for 4 ms and low for 12 ms, just like mine. And, I am refrencing the scope to VSS.

mister_e
- 9th May 2007, 22:57
Are you sure you don't have a inverted probe type??? or scope setting.

Pic_User
- 9th May 2007, 23:46
I hate to tell you this, Adam, but your program makes the outputs high for 4 ms and low for 12 ms, just like mine. And, I am refrencing the scope to VSS.Aarrrggghh, I hate hearing that, too! :)

Mister-e’s suggestion on the other tread sounds plausible (“Where's the CMCON setting?”).

The other idea is: you may not be really re-programming the PIC.
Try changing the times to 100 times longer. Just to check.
or
Try erasing the PIC, reading it, look at the hex to make sure it is erased. Then, program it with the new code compiled from MCS and PBP. Then read the device again to see it has really been re-programmed.
I seem to remember some forum postings about forgetting to re-compile before re-burning.
So they just kept burning the original (Version 1 of their code) ASM into HEX, not the new PBP (Version 2 of their code).
-Adam-

fazan83
- 10th May 2007, 02:52
Aarrrggghh, I hate hearing that, too! :)

Mister-e’s suggestion on the other tread sounds plausible (“Where's the CMCON setting?”).

The other idea is: you may not be really re-programming the PIC.
Try changing the times to 100 times longer. Just to check.
or
Try erasing the PIC, reading it, look at the hex to make sure it is erased. Then, program it with the new code compiled from MCS and PBP. Then read the device again to see it has really been re-programmed.
I seem to remember some forum postings about forgetting to re-compile before re-burning.
So they just kept burning the original (Version 1 of their code) ASM into HEX, not the new PBP (Version 2 of their code).
-Adam-

I am proposoing to put NPN transistor to invert the waveform?

If cannot then fine.

skimask
- 10th May 2007, 04:15
I hate to tell you this, Adam, but your program makes the outputs high for 4 ms and low for 12 ms, just like mine. And, I am refrencing the scope to VSS.

I'm thinking the problem overall is the fact that you've got one resistor for current limiting for 2 LEDs. If you pull either pin low and you're measuring your signal on the LED side of the resistor, it won't matter which pin gets pulled low, they will probably both read low at back side of the LED (the connection nearest to the resistor).

What do you get if you 'scope the actual pins themselves, right at the PIC with nothing else connected?

Russ Kincaid
- 10th May 2007, 21:40
Good suggestions, Adam. But, I have done all those things (except make the time longer). Look at post#15, why is that waveform the same as post#1?

Pic_User
- 10th May 2007, 23:52
Hi Russ,
Look at post#15, why is that waveform the same as post#1?Because you are not really re-programming the PIC, with the PBP new program.

-Adam-

skimask
- 11th May 2007, 03:26
Hi Russ,Because you are not really re-programming the PIC, with the PBP new program.

-Adam-

Entirely possible! It's happened to me more than once!

Russ Kincaid
- 11th May 2007, 04:40
Thanks fellas, I started a new thread and got the answer: CMCON=7. I have not figured out why that works, maybe it is just one of those things I was not meant to know.

Ryan7777
- 13th February 2008, 02:55
Hey Russ,

You're doing a great job with N&V!
Keep it up!