3 questions: float array[], PWM timer control, external clock???

Hey all. I’m experienced with programming, but new to microprocessor control, so I’ve wound up with a few seemingly simple questions. I’ve been doing a lot of reading on the forum, but still haven’t found what I need, so I thought I’d ask my specific questions to get to the root of my problem.

First question is: I’m working with an array of floating point numbers that map from pi/2 → pi, to describe a delay time in radians for triggering gate pulses to SCR switching devices.
One way I’ve done this is to simply divide pi/2 into 1000 parts, and write each value into an array.We all know this is a poor way to do this because I should just take a second and write a loop to generate these values. I’ve already done that like so:

float alphaPos[1000];
alphaPos[0] = 1.5708;  //define zeroth element of alphaPos
  for (int i = 1; i < 999; i++){   //fill alphaPos elements from alphaPos[1] to alphaPos[998]
    alphaPos[i] = (alphaPos[i-1] + 1.5708e-3); //increment each element by (1/1000) * (pi/2)
  }
  alphaPos[999] = 3.1495; // define final element of alphaPos

So, I’m trying to validate my data in either case and when I run a loop to output each value to the Serial monitor, just to double check, I wind up with total garbage after about 1.68. After this point the serial monitor just fills with scrolling random characters and garbage, which to me means that if I’m using these elements of alpha for subroutines then they too are filled with garbage and my program will be bunk. So basically the question is: What the hell am I doing wrong? Does the serial port buffer simply not allow me to read out 1000 values from memory?

for(int i = 0; i < 1000; i++){
    Serial.println(alphaPos[i]);
}

Second questions is: Can someone please explain to me, with comments, how I can change the frequency of the PWM control timers? Can you also show me the way you do the math for that? I keep reading posts about PWM that are so convoluted that I seem to miss the part where we actually program the timers. Also, all the higher level guys seem to think I don’t need comments to understand what they’re talking about! I need to be at 60Hz, so that I can set a duty ratio for thyristor firing. In conjunction with this, I would need to invert the duty ratio, so that the pattern is OFF-ON, instead of ON-OFF.

Third question: I would like to put in an external clock signal to sync the arduino to a 60Hz sine wave (which will go in as a square wave). Is there anyway to bypass the internal timers for PWM and tell the chip to read it’s PWM time off of this same external clock? I’d rather have everything on a master clock that is generated by the same external circuit for timing.

Does the serial port buffer simply not allow me to read out 1000 values from memory?

Nothing to do with the serial buffer. A float is 4 bytes 4 * 1000 is probably more bytes of memory than you have. If you want a big table, look at using PROGMEM.

What does this 3.1495; value represent?

then they too are filled with garbage and my program will be bunk

Your program lives in a completely separate memory space, unaffected by RAM issues.

Hey AWOL, thanks for the feed back :)

3.1459 is Pi to four decimal places. I'm forcing the first value to be Pi/2 and the last value to be Pi for safety, so that I have a fully ON and OFF state.

I've looked into PROGMEM, I think I'll have to multiply all those values by 10^4 to store them as integers and then static cast them to floats and divide them by the same scalar for calculations in the program; sound about right? Arduino is telling me that floats are not supported by 'pgmspace'.

Your program lives in a completely separate memory space, unaffected by RAM issues.

so do you think that on an operational level the values will be alright the way they are? I.E. using them in a subroutine for calculations. Or do you think I will be passing garbage values to my function calls?

3.1459 is Pi to four decimal places

OK
And what is “3.1495”?

A simple way to write pi in a program is 4 * atan (1).

Arduino is telling me that floats are not supported by ‘pgmspace’.

No, but “unsigned long” casts are.

Or do you think I will be passing garbage values to my function calls

At the moment, your values are garbage because you simply don’t have enough RAM.
Put them in PROGMEM and all should be rosy.

cool trick for Pi! thanks.

I’m still having trouble using PROGMEM though. I’ve included the library and defined an array of unsigned long, but it still spits out junk to the serial port.

PROGMEM_attempt.pde (9.89 KB)

PROGMEM is a separate memory space, you can't simply access it like an ordinary RAM array. Have a look at the PROGMEM access methods.

[

vidi:
3.1459 is Pi to four decimal places

No it isn’t. Haven’t you ever heard:

“This above all numbers is sublime: Three point one four one five nine”
—Ellis Sanders.

Doesn’t exactly rhyme (a little poetic license, please), but I like the cadence.

Or, the famous cheer heard from time to time during the the Math Olympics:

“Sine, cosine, cosine, sine.
Three point one four one five nine.
Gooooo Team!”

Doesn’t make much sense, grammatically or semantically, but at least it rhymes. And I still like the cadence.

AWOL:
A simple way to write pi in a program is 4 * atan (1).

A simpler way in Arduino sketches is to use the value of PI defined in <wiring.h>

    Serial.print("PI = "); Serial.println(PI, 5);

Output


[color=blue]PI = 3.14159[/color]

See? The cheerleaders got it right!

Regards,

Dave

vidi:
…trouble using PROGMEM…

If you need floats in your program, use floats in PROGMEM. Create a table of values in another program and paste them into the definition. See Footnote.

Here’s a simple (small) test program to show one way of getting an array of floats into PROGMEM:

// An array of floats in PROGMEM.
//
// Create the (constant) values to be stored in a PROGMEM array
// in another program (or any way that you want to) and paste
// the values into the array definition.
//
//  davekw7x
//
#include <avr/pgmspace.h>


// There are lots of goofy ways to write
// the sequence of qualifiers to get stuff
// into PROGMEM.  Here's one way that works
// for me:
//
const float PROGMEM alphaPos[] =  {
    1.2,
    3.4,
    5.6
};
const int alphaPosSize = sizeof(alphaPos)/sizeof(float);

void setup()
{
    Serial.begin(9600);

    for (int i = 0; i < alphaPosSize; i++) {
        float x = pgm_read_float(alphaPos+i); // Could write x = pgm_read_float(&alphaPos[i]);
        Serial.print("alphaPos[");Serial.print(i);
        Serial.print("] = ");
        Serial.println(x, 5);
    }
}
void loop(){}

Output:


[color=blue]alphaPos[0] = 1.20000
alphaPos[1] = 3.40000
alphaPos[2] = 5.60000[/color]

Regards,

Dave

Footnote:

If you have 1000 elements and the first element has the value Pi/2, and the steps are Pi/1000, there are 999 steps and the last element should have the value
posArray[999] = Pi/2 + 999*Pi/1000, or about 3.1400218572629006, not Pi

On the other hand…

If you have 1001 elements and the first element has the value Pi/2 and the steps are Pi/1000, there are 1000 steps and the last element should have the value

posArray[1000] = Pi

Yo, davekw7x, thanks very much for the example. Also very cool to know about Pi being in the wiring library. I could have sworn I read elsewhere that there was no predefined Pi. I also read that I could not store float values in the program memory. I will try this immediately.

Thanks again.

vidi:
… I read elsewhere that there was no predefined Pi.

It’s not a standard C library thing; PI is an Arduino thing. GNU compilers (maybe others) have a macro for Pi, named M_PI, defined in <math.h> ( for C++). That also is not a standard C or C++ definition, but it’s handy if you know it’s there.

vidi:
I also read that I could not store float values in the program memory…

Well, my little example uses the pgm_read_float() macro that is defined in <avr/pgmspace.h>, so it’s not just something that I kludged up.

And, by the way…

I once read that I would go blind if I didn’t stop doing certain things, but I never believed…Hey! Who turned out the lights!

Regards,

Dave

so I I have tried your method which I appreciate being edified upon. thanks. things are now flowing smoothly, at least as far as the generation of a floating point array into the program memory and my ability to access them in my main loop :)

I'm still just forcing the last value to be Pi, but will most likely go back to the drawing board before finalizing the program anyway, in which case I will definitely use 1001 values for accuracy's sake.

Most of my experience with programming has been C++ in visual basic, so I'm accustomed to using the math library include and then just using Pi anyway. The biggest trouble so far has been talking to my Arduino in it's own language!

Thanks again for the assist. It is greatly appreciated.

To all who posted on this thread:

Just wanted to say thanks again for all the good input. I appreciate the help a lot. I have finally got my sequence timing issue sorted. It's always the easiest answer thats the hardest one to find. I'm so stuck in what I've been taught for using C++ in visual basic that I'm not thinking like a microprocessor. I finally figured out that I can do the bulk of my programs work in the setup and then leave only the firing sequence as the main loop, which is the way it should be after all. The whole loop is now just a series of on off commands to some switches, no major calculations and it's working super smooth.

Cheers!