Go Down

Topic: Output error with for loop using sin (Read 673 times) previous topic - next topic

g_von

Hi everyone. New Arduino programmer here!
I'm having a problem with the output for my sin wave calculation. I'm getting some unexpected numbers from the program.  I'm creating a program that will allow me to change the resolution of the sin wave. I'm able to monitor the serial port to get the calculated values.

Code: [Select]
/*
Sin Fade

This code is setup to fade an LED using a Sinusoidal function.
Brightness is max at 255 and divided into 51 steps (255/5 = 51)
*/

int led = 3;           // the pin that the LED is attached to
float brightness = 0;       
float halfPi = 1.5707963267949;
int divisions = 51;     // Divisions
int rate = 50;          // Delay date
int upArray[] = {};
int downArray[] = {};

// the setup routine runs once when you press reset:
void setup()  {
  Serial.begin(9600);
  delay(3000);
  Serial.println("Program Start");
  // declare pin 13 to be an output:
 
  pinMode(led, OUTPUT);
  for (int i = 0; i < (divisions + 1); i++){
    upArray[i] = round(255 * sin( (halfPi / divisions) * i));
    Serial.print("i:");
    Serial.print(i);
    Serial.print(" value = ");
    Serial.println(upArray[i]);
    delay(500);
  }
  Serial.println("upArray DONE");
  for (int j = (divisions - 1); j > 0; j--){
    downArray[j] = round(255 * sin( (halfPi / divisions) * j));
    Serial.print("j:");
    Serial.print(j);
    Serial.print(" value = ");
    Serial.println(downArray[j]);
    delay(500);
  }
  //delay(5000);
  //Serial.println("Ready?");
  //Serial.println(upArray[5]);
  //Serial.println(downArray[5]);
  Serial.println("Done!");
}

// the loop routine runs over and over again forever:
void loop()
{
}


The output shows that the calculations are working except for a few points.
Program Start
i:0 value = 0
i:1 value = 8
i:2 value = 16
i:3 value = 24
i:4 value = 31
i:5 value = 39
i:6 value = 47
i:7 value = 55
i:8 value = 62
i:9 value = 70
i:10 value = 77
i:11 value = 85
i:12 value = 92
i:13 value = 99
i:14 value = 107
i:15 value = 114
i:16 value = 121
i:17 value = 128
i:18 value = 134
i:19 value = 141
i:20 value = 147
i:21 value = 154
i:22 value = 160
i:23 value = 166
i:24 value = 172
i:25 value = 178
i:26 value = 183
i:27 value = 188
i:28 value = 194
i:29 value = 199
i:30 value = 203
i:31 value = 208
i:32 value = 213
i:33 value = 217
i:34 value = 221
i:35 value = 225
i:36 value = 228
i:37 value = 232
i:38 value = 235
i:39 value = 238
i:40 value = 241
i:41 value = 243
i:42 value = 245
i:43 value = 247
i:44 value = 249
i:45 value = 251
i:46 value = 252
i:47 value = 253
i:48 value = 254
i:49 value = 255
i:50 value = 255
i:51 value = 255
upArray DONE
j:50 value = 255
j:49 value = 255
j:48 value = 30240
j:47 value = 253
j:46 value = 252
j:45 value = 27745
j:44 value = 249
j:43 value = 247
j:42 value = 25973
j:41 value = 243
j:40 value = 241
j:39 value = 15648
j:38 value = 235
j:37 value = 232
j:36 value = 228
j:35 value = 225
j:34 value = 221
j:33 value = 217
j:32 value = 213
j:31 value = 208
j:30 value = 203
j:29 value = 199
j:28 value = 194
j:27 value = 188
j:26 value = 183
j:25 value = 178
j:24 value = 172
j:23 value = 166
j:22 value = 160
j:21 value = 154
j:20 value = 147
j:19 value = 141
j:18 value = 134
j:17 value = 128
j:16 value = 121
j:15 value = 114
j:14 value = 107
j:13 value = 99
j:12 value = 92
j:11 value = 85
j:10 value = 77
j:9 value = 70
j:8 value = 62
j:7 value = 55
j:6 value = 47
j:5 value = 39
j:4 value = 31
j:3 value = 24
j:2 value = 16
j:1 value = 8
Done!


Does anyone have any idea where these big numbers are coming from? Also, note that I'm using the round() function because without it, I was getting "ovf" as the output for some of the numbers (around i = 33) and then it would actually restart the program and loop this problem.

Thanks.

fungus

#1
Mar 06, 2013, 08:24 am Last Edit: Mar 06, 2013, 08:49 am by fungus Reason: 1

I'm using the round() function because without it, I was getting "ovf" as the output for some of the numbers (around i = 33)


That message was trying to tell you something important!

An intermediate value is too big to fit in an 'int' (ie. it "overflows") so bits of that number are being lost.
No, I don't answer questions sent in private messages (but I do accept thank-you notes...)

dgarcia42

Your first big problem that i can see is that you aren't allocating your arrays, which means you're indexing off into random places.  You either want:

int upArray[51];
int downArray[51];

or you want to say

int *upArray;
int *downArray;

then in setup:

upArray = malloc(sizeof(int) * divisions);
downArray = malloc(sizeof(int) * divisions);

What you have currently is creating a pair of arrays with 0 elements in them.

* you should precompute the value of halfPi / divisions, division, especially floating point division is expensive on the AVR platform.
* make your first for loop i <= divisions instead of adding one each time around through the loop (again, for performance). 
* make your second loop condition j >= 0 - and this way you will fill in downArray[0] with a value.
--

FastLED (formerly FastSPI_LED) -- new home http://fastled.io

g_von

@fungus,
Thanks for the reply.
Before using the round() function and int, I had the data in the arrays setup as float. That's when I was getting the ovf returned.

@dgarcia42
Thanks! Yeah after reading the tutorials I wasn't sure if
int upArray[51];
int downArray[51];
was defining the size of the array of it it was simply pointing to the 50th entry and defining it as int.

I am not familiar with this function:
int *upArray;
int *downArray;

And I'll have to look in to what
upArray = malloc(sizeof(int)
does.

What is sizeof(int) referencing anyways?

Thanks for the suggestions on the loop design to help with efficiency. I'm not an expert programmer so it's hard to tell what functions are taking up the most resources. I can only use the size of the binary sketch as a gauge.

marco_c

Quote
What is sizeof(int) referencing anyways?


The size of an integer in bytes.
Arduino libraries http://arduinocode.codeplex.com
Parola for Arduino http://parola.codeplex.com

Go Up