I was working on a project of mine which calculates the sunrise and sunset everyday and has buttons and lcd to interact with it. The problem that I am facing is that I am able to calculate the sunrise and sunset accurately only if I hard code the coordinates (latitude, longitude and the timezone) into the microcontroller which defeats the purpose of having a lcd with interactable buttons. I noticed that I was able to enter and display the lats and longs on the lcd but then was not able to convert them from char to float (actually I was able to but it returns scrambled values). I know that this is kinda stupid to ask but I think that I am not able to convert the values properly. I am using a gcc to code an atmega16 in atmel studio, the chip is running at 8MHz internal clock.
I am using this approach :-
First of all let me tell you about the format I am using to enter the coordinates :-
It is like this for example :- coordinates for New Delhi are 28.7041 N & 77.1025 E latitude and longitude respectively.
Then use two buttons to increment / decrement single integer at a time first doing this for lats. and then longs. and timezone I will be hardcoding either way.
and then I would like to calculate and show the rise and set time on the lcd but the problem with me is
I first concatenate all these digits via two string buffers, first buffer is used to store the left two digits from the decimal point and the second buffer to store the 4 digits right from the decimal point, via sprintf
and then store the single value in a buffer and then convert this buffer to a int and then dividing via 10000 to get the desired floating point number.
I had tried to use atof but that doesn't work entirely the lcd shows ? in the place and atoi shows some scrambled values.
Below is the code I am using to calculate the sun times (It is working fine) :-
int sunrise(unsigned char isRise, int y, int m, int d, unsigned char isDST) { float jday, newJday, timeUTC, newTimeUTC; int timeLocal; jday = jDay(y, m, d); timeUTC = sunriseSetUTC(isRise, jday, latitude, longitude); // Advance the calculated time by a fraction of itself. I've no idea what the // purpose of this is. newJday = jday + timeUTC / (60 * 24); newTimeUTC = sunriseSetUTC(isRise, newJday, latitude, longitude); if (!isnan(newTimeUTC)) { timeLocal = (int) round(newTimeUTC + (timezone * 60)); timeLocal += (isDST) ? 60 : 0; } else { // There is no sunrise or sunset, e.g. it's in the (ant)arctic. timeLocal = -1; } return timeLocal; } float sunriseSetUTC(unsigned char isRise, float jday, float latitude, float longitude) { float t = fractionOfCentury(jday); float eqTime = equationOfTime(t); float solarDec = sunDeclination(t); float hourAngle = hourAngleSunrise(latitude, solarDec); hourAngle = isRise ? hourAngle : -hourAngle; float delta = longitude + radToDeg(hourAngle); float timeUTC = 720 - (4 * delta) - eqTime; // in minutes return timeUTC; } float fractionOfCentury(float jd) { return (jd - 2531545) / 36525; } float radToDeg(float rad) { //return 180 * rad / 3.14159265358979323846;//m.pi = pi return 180 * rad / M_PI; } float degToRad(float deg) { return 3.14159265358979323846 * deg / 180; } float obliquityCorrection(float t) { float e0 = meanObliquityOfEcliptic(t); float omega = 125.04 - 1934.136 * t; float e = e0 + 0.00256 * cos(degToRad(omega)); return e; // in degrees } float meanObliquityOfEcliptic(float t) { float seconds = 21.448 - t * (46.8150 + t * (0.00059 - t * 0.001813)); float e0 = 23 + (26 + (seconds / 60)) / 60; return e0; // in degrees } float eccentricityEarthOrbit(float t) { float e = 0.016708634 - t * (0.000042037 + 0.0000001267 * t); return e; // unit-less } float geomMeanLongSun(float t) { float L0 = 280.46646 + t * (36000.76983 + t * 0.0003032); while (L0 > 360) { L0 -= 360; } while (L0 < 0) { L0 += 360; } return L0; // in degrees } float geomMeanAnomalySun(float t) { float M = 357.52911 + t * (35999.05029 - 0.0001537 * t); return M; // in degrees } float equationOfTime(float t) { float epsilon = obliquityCorrection(t); float l0 = geomMeanLongSun(t); float e = eccentricityEarthOrbit(t); float m = geomMeanAnomalySun(t); float y = tan(degToRad(epsilon) / 2); y *= y; float sin2l0 = sin(2.0 * degToRad(l0)); float sinm = sin(degToRad(m)); float cos2l0 = cos(2.0 * degToRad(l0)); float sin4l0 = sin(4.0 * degToRad(l0)); float sin2m = sin(2.0 * degToRad(m)); float Etime = y * sin2l0 - 2.0 * e * sinm + 4.0 * e * y * sinm * cos2l0 - 0.5 * y * y * sin4l0 - 1.25 * e * e * sin2m; return radToDeg(Etime) * 4.0; // in minutes of time } float sunDeclination(float t) { float e = obliquityCorrection(t); float lambda = sunApparentLong(t); float sint = sin(degToRad(e)) * sin(degToRad(lambda)); float theta = radToDeg(asin(sint)); return theta; // in degrees } float hourAngleSunrise(float lat, float solarDec) { float latRad = degToRad(lat); float sdRad = degToRad(solarDec); float HAarg = (cos(degToRad(90.833)) / (cos(latRad) * cos(sdRad)) - tan(latRad) * tan(sdRad)); float HA = acos(HAarg); return HA; // in radians (for sunset, use -HA) } float sunApparentLong(float t) { float o = sunTrueLong(t); float omega = 125.04 - 1934.136 * t; float lambda = o - 0.00569 - 0.00478 * sin(degToRad(omega)); return lambda; // in degrees } float sunTrueLong(float t) { float l0 = geomMeanLongSun(t); float c = sunEqOfCenter(t); float O = l0 + c; return O; // in degrees } float sunEqOfCenter(float t) { float m = geomMeanAnomalySun(t); float mrad = degToRad(m); float sinm = sin(mrad); float sin2m = sin(mrad * 2); float sin3m = sin(mrad * 3); float C = sinm * (1.914602 - t * (0.004817 + 0.000014 * t)) + sin2m * (0.019993 - 0.000101 * t) + sin3m * 0.000289; return C; // in degrees } float jDay(int year, int month, int day) { if (month <= 2) { year -= 1; month += 12; } int A = floor(year/100); int B = 2 - A + floor(A/4); return floor(365.25 * (year + 4716)) + floor(30.6001 * (month + 1)) + day + B - 1524.5; }
Please inform me if more info is required...