Arduino Mega2560 does nothing after sketch is uploaded

Hey all!

Got a strange problem with my Arduino Mega2560… just for fun I wanted to try making a sketch that implements an algorithm for calculating the sun’s position, using a library published by NREL (see here: http://rredc.nrel.gov/solar/codesandalgorithms/spa/). I basically just took their example program, and converted it to run on an Arduino and print the calculations to the Serial terminal… Unfortunately when I upload the sketch, the Arduino does nothing.

The sketch compiles successfully, and is only 29kb in size (well under the Mega’s 256kb max) to I figured I’d be ok. But after I upload the sketch the only response I get from the Mega is the “L” light… it blinks quickly two times, then about a half second pause, then again in an infinite loop. I let it run for several hours this way, but I never got anything on the Serial terminal.

I have also made very sure that I’m compiling for the right board in the Arduino IDE… so that’s not the problem either.

The code I’m using is here: http://pastebin.com/8PnnC5ur
The code depends on the NREL SPA algorithm library, which has not been modified. The SPA library only depends on the standard C math library, which I have used before on the Arduino without incident, so I don’t think the issue is there…

My only thought is that the Arduino may be getting mad because the algorithm uses references/pointers, but I havent found any evidence that the Arduino can’t handle them… if I’m wrong though, I’d sorely appreciate somebody setting me straight.

Any suggestions? Thanks!

EDIT:
I’ve put a vastly simplified version of the code, which still fails here: http://pastebin.com/eimmw2Hn
The sketch fails when I uncomment line 38 the line: result = spa_calculate( &spa );

I’ve tried creating references and pointers in the sketch elsewhere, and everything seemed to work just fine… I was also successfully able to make reference variables, and pointers to an spa_data structure without issues… its only when I pass that reference to a function that the code chokes.

I could try modifying the library to just take the straight data structure instead of a reference to it, but doing so would take a long time and probably cause a lot more problems for me…

EDIT EDIT:

Since there was some confusion below about what exactly I was trying to do, and people having difficulty getting at the code I’m using, I’ve attached all relevant code here (which in hindsight probably would have been good to do first) for future reference. The attached Arduino sketch is the simpler, easier-to-understand one, not the full sketch I linked to originally.

test.pde (1004 Bytes)

spa.h (9.06 KB)

spa.c (35.1 KB)

Please register to download the SPA C source code.

I don't think so.

PaulS:

Please register to download the SPA C source code.

I don’t think so.

EDIT:
I forgot registration was needed to download a copy of the spa.c file… sorry about that. in the hopes that it will help diagnosing the issue, I am attaching the file to my original post… I appreciate any further advice provided.

But it's not an arduino file so how can it work on an arduino. Please post the copy you are having trouble with otherwise we can't help.

Grumpy_Mike: But it's not an arduino file so how can it work on an arduino. Please post the copy you are having trouble with otherwise we can't help.

It is a standard C file, being compiled into an Arduino sketch, which is how it 'works' on the Arduino... this is pretty common practice so I didn't figure it would be a point of confusion, I apologize if I was incorrect.

I included links to my full Arduino code in my origional post... I've reproduced those links here for convenience.

flyindragon1: The code I'm using is here: http://pastebin.com/8PnnC5ur

Then a shortened version of the code which still fails (but is easier to read through)

flyindragon1: EDIT: I've put a vastly simplified version of the code, which still fails here: http://pastebin.com/eimmw2Hn The sketch fails when I uncomment line 38 the line: result = spa_calculate( &spa );

Also, for the sake of completeness, I edited my previous post above, removed the attachment, and attached them all to my first post with a note, so all my code is in the same place. I hope this takes care of any confusion people are having about what exactly I'm trying to do.

As always, I appreciate any assistance that can be offered!

Did you look at spa.c? It declares a bunch of arrays. You should determine the size of each array, in bytes. Then, add them up, and see if you really have that much SRAM to store the arrays.

flyindragon1:
…any assistance…

PaulS:
…bunch of arrays…

Since there are something like 8792 bytes in const arrays, it is not completely impossible that you could use PROGMEM for the arrays. Of course, you would have to change the code for each and every array access accordingly.

However…

A bigger issue (to me, at least) is that with avr-gcc, double precision variables are 32-bit floats.

On my workstation, using GNU gcc with 64-bit double precision variables, spa_tester gives the following output, as expected:


[color=blue]
Julian Day:    2452930.312847
L:             2.401826e+01 degrees
B:             -1.011219e-04 degrees
R:             0.996542 AU
H:             11.105902 degrees
Delta Psi:     -3.998404e-03 degrees
Delta Epsilon: 1.666568e-03 degrees
Epsilon:       23.440465 degrees
Zenith:        50.111622 degrees
Azimuth:       194.340241 degrees
Incidence:     25.187000 degrees
Sunrise:       06:12:43 Local Time
Sunset:        17:20:19 Local Time

[/color]

However…

With 32-bit floats, I get the following:


[color=blue]
Julian Day:    2452930.250000           // A "little bit" off
L:             2.395517e+01 degrees     // A "little bit" off
B:             -9.992329e-05 degrees    // A "little bit" off
R:             0.996560 AU              // A "little bit" off
H:             348.489624 degrees       // A "LOT" off
Delta Psi:     -3.999537e-03 degrees    // A "little bit" off
Delta Epsilon: 1.666407e-03 degrees     // A "little bit" off
Epsilon:       23.440464 degrees        // A "little bit" off
Zenith:        50.167198 degrees        // A "little bit" off
Azimuth:       165.144028 degrees       // A "LOT" off
Incidence:     20.395002 degrees        // "Quite a bit" off
Sunrise:       06:12:42 Local Time      // A "little bit" off
Sunset:        17:20:18 Local Time      // A "little bit" off
[/color]

Is this, by any stretch of imagination, acceptable?

Bottom line: When porting applications from one processor to another, especially one with reduced capabilities, you must be aware of resource limitations and performance limitations. Arduino uses the avr-gcc compiler, which simply doesn’t support 64-bit floating point variables or operations.

Regards,

Dave
[/begin Edited Footnote]
The above 32-bit values were obtained by simply replacing “double” with “float” in spa files and compiling with GNU gcc on my Linux workstation. Some intermediate calculations were still performed with 64-bit doubles.

If all calculations are performed totally with 32-bit floats (on an avr-gcc platform like Arduino, for example), I get the following somewhat-less-accurate results. (Note that I didn’t try to print any of the floats in scientific format.)

These were obtained on my Arduino ATmega328p homebrew system after putting all const arrays in program memory. I didn’t bother putting the string literals used in print statements in program memory, since it ran OK without doing that. Sketch size was 29002 bytes when compiled with avr-gcc version 4.3.4 on my Linux workstation.


[color=blue]Julian Day    : 2452930.250000
L             : 23.956031 degrees
B             : -0.000100 degrees
R             : 0.996560 AU
H             : 348.488769 degrees
Delta Psi     : -0.005115 degrees
Delta Epsilon : 0.001405 degrees
Epsilon       : 23.440202 degrees
Zenith        : 50.167175 degrees
Azimuth       : 165.142913 degrees
Incidence     : 20.395086 degrees
Sunrise       : 06:12:32 Local Time
Sunset        : 17:20:07 Local Time
[/color]

[/end Edited Footnote]

It may be possible to get better results with reformulation of some of the equations, but I wouldn’t count on it. (A little pun here. Get it? “Count on it.” No? Oh, well…)

PaulS: Did you look at spa.c? It declares a bunch of arrays. You should determine the size of each array, in bytes. Then, add them up, and see if you really have that much SRAM to store the arrays.

I did look at it, and noted the massive arrays, but I admit I didn't rigorously calculate the sizes... just kindof a guesstimate to see if my little plot was even feasible... I figured it was close enough to at least try.

davekw7x: Since there are something like 8792 bytes in const arrays, it is not completely impossible that you could use PROGMEM for the arrays. Of course, you would have to change the code for each and every array access accordingly.

Indeed... however due to the nature of this experiment, it's not really worth the effort (to me anyway) to try and set this up. I might still try it just for kicks, to see how bad the next issue is anyway. Thanks for the suggestion!

davekw7x: However...

A bigger issue (to me, at least) is that with avr-gcc, double precision variables are 32-bit floats.

On my workstation, using GNU gcc with 64-bit double precision variables, spa_tester gives the following output, as expected:


[color=blue]
Azimuth:       194.340241 degrees

However...

With 32-bit floats, I get the following:

Azimuth:       165.144028 degrees       // A "LOT" off [/color]




---



Is this, by any stretch of imagination, acceptable?

Bottom line: When porting applications from one processor to another, especially one with reduced capabilities, you must be aware of resource limitations and performance limitations. Arduino uses the avr-gcc compiler, which simply doesn't support 64-bit floating point variables or operations.

This is an excellent point, the extent of which I didn't fully appreciate until you pointed it out to me :) I removed all but the Azimuth numbers from the quote, because that was the value I was really interested in, and the extreme difference between the two numbers is significant to me. I realized there would be some rounding errors when downgrading to the 32-bit floats but I didn't realize the error would be so significant... mainly because I never actually tried compiling it as 32-bit application on my computer, before loading it on the Arduino... didn't even think about it! I greatly appreciate you taking the time to do so though, and showing me exactly what was wrong.

Even though the eventual idea behind this experiment is shot now, I may try the PROGMEM trick, just to see if I can get the thing to calculate at all out of curiosity.

Thanks everybody! I consider this issue now resolved.

Let me know whether NREL code has worked on Arduino mega 2560. Can you place the code if it worked. As i explored in NREL site it must be double precision floating point controllers.IS any other way you calculated the sun elevation angle. Please share the link if possible

You're after a follow-up on a post from March 2011 from someone who hasn't posted since June 2011. I can only wish you good luck on that!