CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

Structure Usage problems

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Jerry I



Joined: 14 Sep 2003
Posts: 96
Location: Toronto, Ontario, Canada

View user's profile Send private message

Structure Usage problems
PostPosted: Tue Mar 24, 2020 10:24 pm     Reply with quote

Hi

Thank you in advance for any help.

This is some code I downloaded from http://www.psa.es/sdg/sunpos.htm which is supposed to calculate the sun position from anywhere in the world by passing some parameters.

I have always had problems using structures and I got it to compile to the point where I have commented the call to the function that causes the error.

The original code used DOUBLE variable, I have changed it to a float.

Compiler version I am using 4.134.
2 Files attached.

See code below.
Code:

// This file is available in electronic form at http://www.psa.es/sdg/sunpos.htm

#define PIC_18F2620

#define BAUD1_SPEED 9600
#define BAUD2_SPEED 19200

#case

#include <18F2620.h>
#fuses h4, nowdt, noprotect, nolvp, put
#device *=16

#use delay(clock=40000000)   /////////// Check Crystal Value ////////////

#use rs232(baud=9600,parity=N,xmit=PIN_C5,rcv=PIN_C4,bits=8, ERRORS, stream=HOSTPC)

#include "sunpos.h"
#include <math.h>

void sunpos(struct cTime udtTime, struct cLocation udtLocation, struct cSunCoordinates *udtSunCoordinates)
{
   // Main variables
   float dElapsedJulianDays;
   float dDecimalHours;
   float dEclipticLongitude;
   float dEclipticObliquity;
   float dRightAscension;
   float dDeclination;

   // Auxiliary variables
   float dY;
   float dX;

   // Calculate difference in days between the current Julian Day
   // and JD 2451545.0, which is noon 1 January 2000 Universal Time
   {
      float dJulianDate;
      long int liAux1;
      long int liAux2;

      // Calculate time of the day in UT decimal hours
      dDecimalHours = udtTime.dHours + (udtTime.dMinutes
         + udtTime.dSeconds / 60.0 ) / 60.0;
      // Calculate current Julian Day
      liAux1 =(udtTime.iMonth-14)/12;
      liAux2=(1461*(udtTime.iYear + 4800 + liAux1))/4 + (367*(udtTime.iMonth
         - 2-12*liAux1))/12- (3*((udtTime.iYear + 4900
      + liAux1)/100))/4+udtTime.iDay-32075;
      dJulianDate=(float)(liAux2)-0.5+dDecimalHours/24.0;
      // Calculate difference between current Julian Day and JD 2451545.0
      dElapsedJulianDays = dJulianDate-2451545.0;
   }

   // Calculate ecliptic coordinates (ecliptic longitude and obliquity of the
   // ecliptic in radians but without limiting the angle to be less than 2*Pi
   // (i.e., the result may be greater than 2*Pi)
   {
      float dMeanLongitude;
      float dMeanAnomaly;
      float dOmega;

      dOmega=2.1429-0.0010394594*dElapsedJulianDays;
      dMeanLongitude = 4.8950630+ 0.017202791698*dElapsedJulianDays; // Radians
      dMeanAnomaly = 6.2400600+ 0.0172019699*dElapsedJulianDays;
      dEclipticLongitude = dMeanLongitude + 0.03341607*sin( dMeanAnomaly )
         + 0.00034894*sin( 2*dMeanAnomaly )-0.0001134
         -0.0000203*sin(dOmega);
      dEclipticObliquity = 0.4090928 - 6.2140e-9*dElapsedJulianDays
         +0.0000396*cos(dOmega);
   }

   // Calculate celestial coordinates ( right ascension and declination ) in radians
   // but without limiting the angle to be less than 2*Pi (i.e., the result may be
   // greater than 2*Pi)
   {
      float dSin_EclipticLongitude;

      dSin_EclipticLongitude= sin( dEclipticLongitude );
      dY = cos( dEclipticObliquity ) * dSin_EclipticLongitude;
      dX = cos( dEclipticLongitude );
      dRightAscension = atan2( dY,dX );
      if( dRightAscension < 0.0 ) dRightAscension = dRightAscension + twopi;
      dDeclination = asin( sin( dEclipticObliquity )*dSin_EclipticLongitude );
   }

   // Calculate local coordinates ( azimuth and zenith angle ) in degrees
   {
      float dGreenwichMeanSiderealTime;
      float dLocalMeanSiderealTime;
      float dLatitudeInRadians;
      float dHourAngle;
      float dCos_Latitude;
      float dSin_Latitude;
      float dCos_HourAngle;
      float dParallax;

      dGreenwichMeanSiderealTime = 6.6974243242 +
         0.0657098283*dElapsedJulianDays
         + dDecimalHours;
      dLocalMeanSiderealTime = (dGreenwichMeanSiderealTime*15
         + udtLocation.dLongitude)*rad;
      dHourAngle = dLocalMeanSiderealTime - dRightAscension;
      dLatitudeInRadians = udtLocation.dLatitude*rad;
      dCos_Latitude = cos( dLatitudeInRadians );
      dSin_Latitude = sin( dLatitudeInRadians );
      dCos_HourAngle= cos( dHourAngle );
      udtSunCoordinates->dZenithAngle = (acos( dCos_Latitude*dCos_HourAngle
         *cos(dDeclination) + sin( dDeclination )*dSin_Latitude));
      dY = -sin( dHourAngle );
      dX = tan( dDeclination )*dCos_Latitude - dSin_Latitude*dCos_HourAngle;
      udtSunCoordinates->dAzimuth = atan2( dY, dX );
      if ( udtSunCoordinates->dAzimuth < 0.0 )
         udtSunCoordinates->dAzimuth = udtSunCoordinates->dAzimuth + twopi;
      udtSunCoordinates->dAzimuth = udtSunCoordinates->dAzimuth/rad;
      // Parallax Correction
      dParallax=(dEarthMeanRadius/dAstronomicalUnit)
         *sin(udtSunCoordinates->dZenithAngle);
      udtSunCoordinates->dZenithAngle=(udtSunCoordinates->dZenithAngle
         + dParallax)/rad;
   }
}

main()
{
    struct cTime udtTime;
    struct cLocation udtLocation;
    struct cSunCoordinates udtSunCoordinates;

   udtSunCoordinates.dZenithAngle = 0;
   udtSunCoordinates.dAzimuth = 0;

   udtLocation.dLongitude = -79.4520;
   udtLocation.dLatitude = 43.7072;

    udtTime.iYear = 2020;
    udtTime.iMonth = 3;
    udtTime.iDay = 24;
    udtTime.dHours = 12;
    udtTime.dMinutes = 30;
    udtTime.dSeconds = 00;


// COMMENTED ERROR BELOW
//    sunpos(udtTime, udtLocation, udtSunCoordinates);

// ORIGINAL CODE UNMODIFIED
sunpos(cTime udtTime,cLocation udtLocation, cSunCoordinates *udtSunCoordinates)

      fprintf (HOSTPC, "azim %3.1f  zenref %3.1f \r\n", udtSunCoordinates.dAzimuth, udtSunCoordinates.dZenithAngle);
}


Code:

// File Sunpos.h
// This file is available in electronic form at http://www.psa.es/sdg/sunpos.htm

#ifndef __SUNPOS_H
#define __SUNPOS_H


// Declaration of some constants
#define pi    3.14159265358979323846
#define twopi (2*pi)
#define rad   (pi/180)
#define dEarthMeanRadius     6371.01   // In km
#define dAstronomicalUnit    149597890   // In km

typedef struct cTime
{
   int16 iYear;
   int16 iMonth;
   int16 iDay;
   int16 dHours;
   int16 dMinutes;
   int16 dSeconds;
};

typedef struct cLocation
{
   float dLongitude;
   float dLatitude;
};

typedef struct cSunCoordinates
{
   float dZenithAngle;
   float dAzimuth;
};

void sunpos(struct cTime udtTime, struct cLocation udtLocation, struct cSunCoordinates *udtSunCoordinates);

#endif

Thanks again,
Jerry
Ttelmah



Joined: 11 Mar 2010
Posts: 19215

View user's profile Send private message

PostPosted: Wed Mar 25, 2020 2:14 am     Reply with quote

Two things:

First, wherever 'long' is used, replace this with signed int32. A 'long' on
most C's is an int32, and the default for most int's is signed. The maths
won't give the right result, unless an int32 is used.

Then the reason it fails is you are missing one key character.

Look at the declaration for sunpos:

void sunpos(struct cTime udtTime, struct cLocation udtLocation, struct cSunCoordinates *udtSunCoordinates)

Note the '*' on the coordinates.

You need to pass this the address of the variable:

sunpos(udtTime, udtLocation, &udtSunCoordinates);

Note the '&'.

With those two changes, it then merrily compiles and has a chance
of working. No idea if it will.... Very Happy
Jerry I



Joined: 14 Sep 2003
Posts: 96
Location: Toronto, Ontario, Canada

View user's profile Send private message

PostPosted: Wed Mar 25, 2020 4:17 pm     Reply with quote

Thanks Ttelmah,

Got it compiled found lots of calculation errors with complex equations.

Trying to make equations less complex.

Still working on it.
Very Happy
temtronic



Joined: 01 Jul 2010
Posts: 9096
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Wed Mar 25, 2020 4:52 pm     Reply with quote

That's a lot of high powered math for an itty bitty PIC to run.... Laughing
Be sure to print out intermediate results and be careful of brackets, use lots of them so the calculations are in the correct sequence.
Jerry I



Joined: 14 Sep 2003
Posts: 96
Location: Toronto, Ontario, Canada

View user's profile Send private message

PostPosted: Wed Mar 25, 2020 4:59 pm     Reply with quote

Hi All,

I think I am going to give up. Math errors everywhere.

Tried simplifing calculations then got to Sin() and Cos() functions.
all answers appeared wrong based on calculator.

Strange I never had so many calculation errors using floats.

I tried??. Sad
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Mar 25, 2020 5:03 pm     Reply with quote

Radians vs. degrees ?
temtronic



Joined: 01 Jul 2010
Posts: 9096
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Wed Mar 25, 2020 5:15 pm     Reply with quote

yikes....

udtLocation.dLongitude = -79.4520;
udtLocation.dLatitude = 43.7072;

I saw these and figure you have to live near me !! I scroll up and see Toronto..... under your name.

small world.

wrong calculator ?
I know QB4.5 under Win98 runs accurate numbers..
Ttelmah



Joined: 11 Mar 2010
Posts: 19215

View user's profile Send private message

PostPosted: Thu Mar 26, 2020 1:48 am     Reply with quote

As PCM_Programmer says, degrees versus radians.

In C all angular calculations are done using radians not degrees. This is
common in proper mathematics. However most normal calculators will
use degrees.
Declare yourself some basic #defines:
Code:

#define RADFACT (0.0174532925)
#define DEGTORAD(x) (x*RADFACT)
#define RADTODEG(x) (x/RADFACT)


Then when you have your angle and want the sin:

result = sin(DEGTORAD(angle));

You shouldn't need to convert the other way, but if you do, RADTODEG
does this.

I've written it to be 'optimised', so that the conversion from degrees to
radians is done as a single multiplication, since this is the conversion
you are most likely to need.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group