Hi all,
I have a sparkfun SAMD31 dev board, and have been playing around with it. I have a sketch (attached below) that calculates the sunrise and sunset times for a given date and time. It is almost exclusively floating point math. I've run it on the Uno, Zero based board, and Due; of all those, the Zero is the slowest. I've also changed the "float"s to "double"s, and the time difference isn't that significant. The results are:
Uno using float: 4148 microseconds
Uno using double: 4148 microseconds (same time, because the Uno does not do doubles)
Zero using float: 6109 microseconds
Zero using double: 6276 microseconds
Due using float: 1543 microseconds
Due using double: 1586 microseconds
So, my questions are why is the Zero the slowest? and why doesn't the float vs double make much difference in the calculation time of the 32 bit boards?
int Year=2016;
int Month= 8;
int Day= 13;
double UTC= 12.0;
double Lat= 43.69;
double Lon= -79.45;
double UTC_offset = -4.0;
unsigned long timer1;
unsigned long timer2;
long julian;
double j; //Julian Day
double obl;
double N;
double i;
double w;
double a;
double e;
double M;
double L;
double E;
double xv;
double yv;
double v;
double r;
double lonsun;
double xs;
double ys;
double zs;
double xe;
double ye;
double ze;
double RA;
double Dec;
double GMST0;
double GMST;
double LST;
double HA;
double x;
double y;
double z;
double xhor;
double yhor;
double zhor;
double azim;
double alt;
double h = -0.833;
double UT_Sun_in_south;
double LHA;
double Rise_time;
double Set_time;
double d0 = 1919.26;
double Apparent_Diameter;
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
timer1 = micros();
j= 367UL*Year -(7*(Year+((Month+9)/12))/4)+((275UL*Month)/9)+ Day - 730530UL + UTC/24.0;
obl = 23.4393 - 0.0000003563 * j;
N = 0;
i = 0;
w = 282.9404 + 0.0000470935 * j;
a=1;
e= 0.016709 - 0.000000001151 * j;
M = (356.047 + 0.9856002585 * j);
M = mod(M, 360);
L = mod(w + M, 360);
E = M+(180/PI)*e*sin(M/(180/PI))*(1+e*cos(M/(180/PI)));
xv= cos(E/(180/PI))-e;
yv=sqrt(1-e*e) *sin(E/(180/PI));
v=atan2(yv/(180/PI),xv/(180/PI))*(180/PI);
r=sqrt((xv*xv)+(yv*yv));
lonsun=v+w;
xs = r * cos(lonsun/(180/PI));
ys = r * sin(lonsun/(180/PI));
//zs = ?
xe = xs;
ye = ys * cos(obl/(180/PI));
ze = ys * sin(obl/(180/PI));
RA = mod(atan2(ye/(180/PI), xe/(180/PI))*180/PI, 360);
Dec= asin( ze/r)*180/PI;
GMST0 = mod(L + 180, 360)/15.0; //unit: hours.
GMST = GMST0 + UTC;
LST = GMST + Lon/15.0; //unit (hours)
if (LST > 24) LST=LST-24.0;
HA = LST*15.0 - RA; //unit:degrees
x = cos(HA/(180/PI)) * cos(Dec/(180/PI));
y = sin(HA/(180/PI)) * cos(Dec/(180/PI));
z = sin(Dec/(180/PI));
xhor = x * sin(Lat/(180/PI)) - z * cos(Lat/(180/PI));
yhor = y;
zhor = x * cos(Lat/(180/PI)) + z * sin(Lat/(180/PI));
azim = atan2( yhor/(180/PI), xhor/(180/PI) )*(180/PI) + 180;
alt = asin( zhor)*(180/PI);
h = -0.833;
UT_Sun_in_south = mod((RA-GMST0*15.0 - Lon)/15.0 ,24);
LHA =acos((sin(h/(180.0/PI)) - sin(Lat/(180.0/PI))*sin(Dec/(180.0/PI)))/(cos(Lat/(180.0/PI))*cos(Dec/(180.0/PI))))*(180/PI)/15 ;
Rise_time = mod((UT_Sun_in_south-LHA+UTC_offset)/24, 24) * 24;
Set_time = mod((UT_Sun_in_south+LHA+UTC_offset)/24, 24) * 24;
//d0 = 1919.26;
//Apparent_Diameter = 0;
timer2 = micros();
Serial.print("Time to calculate: ");Serial.print(timer2-timer1);Serial.println(" micros");
/*
Serial.print("j = ");Serial.println(j,4);
Serial.print("obl= ");Serial.println(obl,4);
Serial.print("w= ");Serial.println(w,4);
Serial.print("e= ");Serial.println(e,4);
Serial.print("M= ");Serial.println(M,4);
Serial.print("L= ");Serial.println(L,4);
Serial.print("E= ");Serial.println(E,4);
Serial.print("xv= ");Serial.println(xv,4);
Serial.print("yv= ");Serial.println(yv,4);
Serial.print("v= ");Serial.println(v,4);
Serial.print("r= ");Serial.println(r,4);
Serial.print("lonsun= ");Serial.println(lonsun,4);
Serial.print("xs= ");Serial.println(xs,4);
Serial.print("ys= ");Serial.println(ys,4);
Serial.print("xe= ");Serial.println(xe,4);
Serial.print("ye= ");Serial.println(ye,4);
Serial.print("ze= ");Serial.println(ze,4);
Serial.print("RA= ");Serial.println(RA,4);
Serial.print("Dec= ");Serial.println(Dec,4);
Serial.print("GMST0= ");Serial.println(GMST0,4);
Serial.print("GMST= ");Serial.println(GMST,4);
Serial.print("LST= ");Serial.println(LST,4);
Serial.print("Ha= ");Serial.println(HA,4);
Serial.print("x= ");Serial.println(x,4);
Serial.print("y= ");Serial.println(y,4);https://www.google.ca/webhp?hl=en&sa=X&ved=0ahUKEwjwnM_jhujOAhXL7hoKHTNsBIcQPAgD
Serial.print("z= ");Serial.println(z,4);
Serial.print("xhor= ");Serial.println(xhor,4);
Serial.print("yhor= ");Serial.println(yhor,4);
Serial.print("zhor= ");Serial.println(zhor,4);
Serial.print("azim= ");Serial.println(azim,4);
Serial.print("alt= ");Serial.println(alt,4);
Serial.println();
Serial.print("UT_Sun_in_south= ");Serial.println(UT_Sun_in_south,4);
Serial.print("LHA= ");Serial.println(LHA,4);
*/
Serial.print("Rise_time= ");Serial.print(Rise_time,0);Serial.print(":");Serial.print(mod(floor(Rise_time*60),60),0);Serial.print(":");Serial.println(mod(Rise_time*3600,60),0);
Serial.print("Set_time= ");Serial.print(Set_time,0);Serial.print(":");Serial.print(mod(Set_time*60.0,60),0);Serial.print(":");Serial.print(mod(Set_time*3600,60),0);
}
void loop() {
}
double mod (double dividend, int divisor){
if (dividend > divisor){
do{
dividend = dividend - divisor;
}while (dividend > divisor);
return dividend;
}
else if (dividend < 0){
do{
dividend = dividend + divisor;
}while (dividend <0);
return dividend;
}
else return dividend;
}
Output:
Time to calculate: 6276 micros
Rise_time= 6:20:42
Set_time= 20:24:28