Pages: [1]   Go Down
Author Topic: Output error with for loop using sin  (Read 580 times)
0 Members and 1 Guest are viewing this topic.
Orange, CA
Offline Offline
Newbie
*
Karma: 1
Posts: 10
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
/*
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.
Logged

Valencia, Spain
Offline Offline
Faraday Member
**
Karma: 146
Posts: 5532
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
« Last Edit: March 06, 2013, 02:49:22 am by fungus » Logged

No, I don't answer questions sent in private messages (but I do accept thank-you notes...)

US
Offline Offline
Newbie
*
Karma: 2
Posts: 35
Hi! I wrote and maintain the FastSPI_LED library. Working on trying to keep it up to date.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

--

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

Orange, CA
Offline Offline
Newbie
*
Karma: 1
Posts: 10
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

@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.
Logged

Sydney, Australia
Offline Offline
Edison Member
*
Karma: 33
Posts: 1273
Big things come in large packages
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
What is sizeof(int) referencing anyways?

The size of an integer in bytes.
Logged

Arduino libraries http://arduinocode.codeplex.com
Parola hardware & library http://parola.codeplex.com

Pages: [1]   Go Up
Jump to: