Importing NREL's SPA

Dear embedded people,

I am having trouble importing the NREL’s Solar Positioning Algorithm. (SPA)
check link: http://rredc.nrel.gov/solar/codesandalgorithms/spa/ in FEZ cobra as RLP.

The following approach was taken:

  1. Compile the Spa.c and Spa.h for EMX in ELF format (Finally worked with -lm switch)
  2. Import in VS 2010 as a resource (Great, Project properties - >Add Resource)
  3. Now have to somehow import / export the spa_data structure and interact with managed C# code (interop ?)

Have no clue how to approach point 3.

I would be very thankfull if someone could help me on this or may share the same interest.

Regards,

Mon11
http://www.youR2Power.com

You need a simple serialization class to convert the structure into a byte array to transfer.

You can use thing like Util.InsertIntoArray

Dear Gus,

You are as fast as lightning I will look into this serialization thing. You are my hero!

Regards,

Mon11

Gus,

I am having a hard time implementing your suggestion. (serializtion)
Problem:
import/export the spa_data structure and interact with managed C# code.

What does seem to work:
Filling the structure with float’s (C# -> RLP) via float *generalArray (invokeEx C#)

What does not work:
Somehow I am not able to get a pointer from the structure in RLP. I need to get the changed values from the structure in RLP.

  • I read something about using RLP extensions like RLP->malloc is this the way to go?
  • Need to convert all my data (float, int, double) to byte[] then translate back in RLP ?

I am clueless please help !!

Regards,

Mon11

I do not understand what you need. RLP lets you pass float from C# down to C so where is the problem. If you have a structure then break it down into individual pieces that you pass individually or convert your structure into byte array.

something like
InstertVlaueIntoArray( MyStruct.SomeFloat, byte_array, index);

Gus,

The structure resides in the C (RLP) realm. What I need to do is:
fill some parts of the structure from C# -> C and read
some parts of the structur from C-> C#.

Sorry for my poor explanation I’m dutch and not really C literate.

Can you pls give little example? In the meantime I will try the InstertVlaueIntoArray function.

Great many thanks in advance !

Mon11

Your gateway of transferring data is byte array.

I just gave you an example in last post :slight_smile:
InstertVlaueIntoArray( MyStruct.SomeFloat, byte_array, index);

I will try to explain again. What you need is code that reads or writes your data (float, int…etc.) into a byte array (serialize the data) your data can be anything, including a structure.

Gus,

Thank you for the tutor etc, read it and it worked great!!! I now am getting pointers from RLP/C realm to the C# realm.

I am still having problem’s with te following:

I have a stream of INT’s in C# that I want to read in the RLP/C realm.

  1. How to convert INT stream to byte[] array.
    (I used the InsertValueArray with offsets but not sure if this the way because
    of the float type in the function)
  2. How to read/convert the byte[] array with INT stream back to seperate INT’s
  • I tried the byte shift trick but I have more than 4 bytes in the stream (let’s say 28 bytes) a stream of 7 INT’s.

Can you please help me again on this puzzle , forgive my noobishness or otherwise point me to some tutor.

Regards,

Mon11.

For anyone reading this, here is the tutorial GHI Electronics – Where Hardware Meets Software

What do you mean by “stream”. Do you mean an int array? If so then you do not need to convert that, just pass it as is. This is actually really fast as there is no need to convert anything. Look at the RLP docs and find “GeneralArray”.

GUS,

I thought my gateway of transferirng data was byte array. I Already use the GeneralArray for passing a floatingpoint stream. The other (7) arguments only accept byte[] array types.

objective:
I want to pass three array’s to RLP as function arguments/parameters

example C#:
int Spa_Result = Set_Get_Spa_Structure.InvokeEx(FloatEnvArray,intDateTimeArray,FloatPostionData)

Result:
FloatPositionData is a pointer to an Array of floats inside RLP (output RLP -> C#) ** (THIS WORKS WITH ExtractValuefromarray function).

int [] intDateTimeArray = new [] {2011, 4, 40, 34, 50, -1, 5, 3}
intDateTimeArray as an Array of int’s (input C# -> RLP) **Wrong format

I tried the following:
for INT’s InsertValueIntoArray with correct offset I am somehow getting wrong/weird values from RLP.

I really appreciate your help.

Regards,

mon11

Please provide code on how you transferred the int[] to byte[] in C# and how you are reading them in RLP.

Gus,

------------------------C#---------------------
byte[] intDateTimeArray = new byte [28];

       Util.InsertValueIntoArray (SPA.year, intDateTimeArray, 0);
       Util.InsertValueIntoArray (SPA.month, intDateTimeArray, 4);
       Util.InsertValueIntoArray(SPA.day, intDateTimeArray, 8);
       Util.InsertValueIntoArray(SPA.hour, intDateTimeArray, 12);
       Util.InsertValueIntoArray(SPA.minute, intDateTimeArray,16);
       Util.InsertValueIntoArray(SPA.second, intDateTimeArray, 20);
       Util.InsertValueIntoArray(SPA.function, intDateTimeArray, 24);


       int Input_Environment_error = Set_SPA_Environment_Inputs.InvokeEx(floatEnvironmentArray,intDateTimeArray,SolarPositionData);

------------------------RLP---------------------

//int Input_Environment_error = Set_SPA_Environment_Inputs.InvokeEx(floatEnvironmentArray,intDateTimeArray,SolarPositionData);

int Set_SPA_Environment_Inputs (float *generalArray, void **args, unsigned int argsCount, unsigned int *argData)

unsigned char *intDateTimeArray = (unsigned char *)args[0];
spavalue.year = ( (intDateTimeArray[0] <<24 ) + (intDateTimeArray[1] << 16) + (intDateTimeArray[2] << 8) + (intDateTimeArray[3] ));


And please don’t laugh :0)

Mon11

http://www.your2power.com

[quote]Util.InsertValueIntoArray (SPA.year, intDateTimeArray, 0);
[/quote]
The Util we have is for float. You have to use Microsft.SPOT.Hardware.Utility one for ints.

[quote]unsigned char *intDateTimeArray = (unsigned char *)args[0];
spavalue.year = ( (intDateTimeArray[0] <<24 ) + (intDateTimeArray[1] << 16) + (intDateTimeArray[2] << + (intDateTimeArray[3] ));
[/quote]
It is little endian, so the other way around: intDateTimeArray[3] << 24 | intDateTimeArray[2] << 16…etc
But you can access it directly with no need for conversion:
unsigned int *intDateTimeArray = (unsigned int *)args[0];

Dear Support,

Totally awesome!

Thank you for your swift answers and reply.

Everything works right now! I am so happy you can’t inmagine.
Still many puzzels to solve but this one I think was the hardest for the time being !

Marcel,

Http://www.your2power.com