sin() function misbehaving!

takao21203

Joined Apr 28, 2012
3,702
Debug mode often caused problems for my circuits. I never use it.

Isn't there a character LCD on the board, where you can display variables?
 

Papabravo

Joined Feb 24, 2006
21,228
I just downloaded the datasheets. In each case Chapter 9. on the Oscillator has two notes right in front. The first note says the datasheet is not a comprehensive reference for oscillator behavior, and gives a reference to a comprehensive spec. The second note says not all parts have the same bits.

Now I may be crazy but I don't think the two parts are NOT as similar as you think they are. I think you made this assumption and it may turn out not to be true.

The GP710A document is Section 7 of DS70186
The MC304 document is Section 39 of DS70216

If I were you I would run down both of those documents and ask myself: "Is there any rational basis for supposing that the same code will work on both parts?"
 

Thread Starter

dannybeckett

Joined Dec 9, 2009
185
If you cared to look at the oscillator setup in each of these datasheets, you would have realised they are identical. The reason why there are two different reference guides is because the current (not working properly) pic has an onboard DAC which has it's own section on DAC clocking. Every microchip example code for the dsPIC33F has the same oscillator code. thankyou for the help but less sarcasm would be appreciated
 

bretm

Joined Feb 6, 2012
152
The compiler warns me when a value is not used, but because 1, I am initializing the variable to a value and 2, I am making j equal to the value of sin(x), j is definitely used even if optimization was enabled.
No, it's not. You're writing to j but not reading from it, so the value of j is never used. The value returned from main() and the values written to volatile-marked fields such as I/O port registers is unchanged whether you do j=sin(x) or not, so the compiler is free to optimize that away.

You mention sending the results of sin() table generation to a DAC, but that's a different program. That would be an example of "using" j. The originally posted program (corrected version) doesn't do that.
 
Last edited:

Papabravo

Joined Feb 24, 2006
21,228
If you cared to look at the oscillator setup in each of these datasheets, you would have realised they are identical. The reason why there are two different reference guides is because the current (not working properly) pic has an onboard DAC which has it's own section on DAC clocking. Every microchip example code for the dsPIC33F has the same oscillator code. thankyou for the help but less sarcasm would be appreciated
Sarcasm?! I'm trying really hard to help you by eliminating possible problems. I'm not all that familiar with the parts and the setup but all systems have common threads. The data sheets for the two parts carry explicit warnings that seemed to me to indicate that making an assumption without specific knowledge was risky. I was trying to eliminate that as a source of error. It seemed more likely than a bad library routine which is used by vast numbers of people.

BTW - I did look at the PLLInit code and my point was that the same piece of code might work on one piece of hardware and not on another if the two pieces of hardware are similar but not identical in every particular.

Lastly if you would prefer you can solve this problem with no more help from me.
 
Last edited:

t06afre

Joined May 11, 2009
5,934
A trick I have used with HI-TECH C compilers is to declare variables for "volatile" then writing C code that are just made for the purpose of debugging/single stepping. At least HI_TECH C are notorious just purging such code segments. Then the optimizer is on.
 

bretm

Joined Feb 6, 2012
152
OK, I will read from j and put it into another variable.
Still not good enough if you don't use that variable. Making it volatile should work, but implementation of volatile is allowed to be compiler-specific.

Even if you use the value to conditionally toggle an output pin, the compiler could be smart enough to see that "i" doesn't change, therefore sin(i) doesn't change, therefore it could be evaluated at compile time (although that's less likely). But it could definitely be evaluated outside the loop. You mentioned everything got slower when you toggled some I/O inside the loop, that's another indicator that the loop was optimized out before.
 

Papabravo

Joined Feb 24, 2006
21,228
Are you aware that the PLLKEN bit in the FDWT register on the GP710A is not implemented on the MC204. Waiting on the PLL Locke enable could be fatal if it always reads as zero.
 

WBahn

Joined Mar 31, 2012
30,088
Here's the code I have just run to include your test papabravo:

http://pastebin.com/YbCZJTiH

When PLL is disabled, i = 1.5707964, j = 1.0 and k = 6. When PLL is enabled, i = 1.5707964, j = 3.4115467 and k = 6. I am absolutely baffled.
bretm has been addressing the 'unused variable' issue, which caught my attention as well. The thing that you want to ask yourself is whether the external user would even notice any difference if a computation were omitted.

I would not be surprised at all if the compiler recognized that the loops weren't needed and simply put one instance of the code there. It can do this pretty easily because the one line of non-trivial code (the assignment statements to j and k) do not depend on variables that can change within the loop. Sure, the loop counter changes, but that value is not used outside the loop. So the only thing the loop does is slow the whole thing down, but the compiler wants to make things run as fast as possible. Sooo....

To force the compiler to keep everything, you might try the following:

j = sin(i*(count>>n));

Where n is #defined so as to shift out all but the msb of the value your counter reaches

The you need to use j for something within the loop that the compiler can't make go away.

Perhaps something like:

while()
{
j = sin(i*(count>>n));
v += j;
}
if (v == j)
//Toggle some output pin.



My gut feel is that adding the PLL code is resulting in the memory location that you think j is being used for to be used by something else. I didn't get a good idea of how you are checking the values of the variables. Is it possible that the tool you are using thinks j is stored someplace when, in fact, something later in the process optimized it away?

Another possibility would be if you had any dynamically allocated memory that could be stomping on it, though I don't see any sign of that and j should be on the stack (assuming embedded code, which I'm only familiar with in assembly, uses a stack the same way hosted code does).

Here's an idea. What if j isn't optimized away but something in the PLL function is stomping on it (by overwriting an array bound, for instance)? This would happen after your initialization to 0. Now if your subsequent assignments to j got optimized away, that might explain what you are seeing.

One way of perhaps checking this is to swap the code for j and k. By that, I mean make j = 2+4 and k = sin(i), but leave everything else the same. The see if j, k, or both are incorrect.
 

Thread Starter

dannybeckett

Joined Dec 9, 2009
185
Thanks for all the suggestions. I believe the loops are running fine, because varying the loop sizes varies the time it takes for the program to get to the breakpoint. Moving a loop before the PLL stuff is executed really slows down the time to hit the breakpoint. I swapped j and k around, with no luck. I made all the variables volatile and still it gives me erroneous results. I put the sine code before the PLL code and the correct results came back for both calculations. I put some sine code before the PLLinit and some after, the code before PLLinit came back absolutely fine, code after was miscalculated.

WBahn your code confused me slightly but I implemented some of my own which I think achieves the same thing -

http://pastebin.com/Zrti18AA

Again, the calculation works out fine before the initPLL() function, same error afterwards. Could anything be figured out by comparing the erroneous values the sine function is churning out compared with what values it's meant to be calculating?
 
Top