Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: 4DGL-uLCD-SE AX12 NetServices mbed spxml
Fork of AX12-HelloWorld by
Revision 2:2a3493799f03, committed 2016-04-25
- Comitter:
- conantina
- Date:
- Mon Apr 25 17:28:13 2016 +0000
- Parent:
- 1:b12b06e2fc2d
- Commit message:
- n
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/4DGL-uLCD-SE.lib Mon Apr 25 17:28:13 2016 +0000 @@ -0,0 +1,1 @@ +http://developer.mbed.org/users/4180_1/code/4DGL-uLCD-SE/#2cb1845d7681
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Helios.cpp Mon Apr 25 17:28:13 2016 +0000
@@ -0,0 +1,160 @@
+/*
+ Helios.cpp-
+ Copyright (c) 2011 Hannes Hassler. All rights reserved.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+ This library can be used for calculating the solar position on Arduino.
+
+ The algorithm is an adaption from
+ the "PSA" solar positioning algorithm, as documented in:
+
+ Blanco-Muriel et al.: Computing the Solar Vector. Solar Energy Vol 70 No 5 pp 431-441.
+ http://dx.doi.org/10.1016/S0038-092X(00)00156-0
+
+ According to the paper, "The algorithm allows .. the true solar vector
+ to be determined with an accuracy of 0.5
+ minutes of arc for the period 1999–2015.
+ The original code has been downloaded from
+ http://www.psa.es/sdg/sunpos.htm
+
+ Adaptions:
+ Modified calculation of number of Days since 1.Jan 2000 (dJulianDate-2451545.0)
+ Neccessary because of the limited double precision on Arduino
+ (double has the same precision as float on the current Arduino (2011))
+ It should be used only for dates between 1.1.2000 and 31.12.2100
+ (PSA itself has garantueed accuracy only until 2015)
+
+*/
+
+#include "Helios.h"
+#include <math.h>
+
+
+Helios::Helios(){}
+
+
+void Helios::calcSunPos(
+ int iYear,
+ int iMonth,
+ int iDay,
+ double dHours,
+ double dMinutes,
+ double dSeconds,
+ double dLongitude,
+ double dLatitude)
+{
+
+
+ // Calculate difference in days between the current Julian Day
+ // and JD 2451545.0, which is noon 1 January 2000 Universal Time
+ {
+
+ //double dJulianDate;
+ //long int liAux1;
+ //long int liAux2;
+ // Calculate time of the day in UT decimal hours
+ dDecimalHours = dHours + (dMinutes
+ + dSeconds / 60.0 ) / 60.0;
+
+ // Calculate current Julian Day
+ /* original calculation; does not work
+ for Arduino, because double precision is the same
+ same as float.
+ liAux1 =(iMonth-14)/12;
+ liAux2=(1461*(iYear + 4800 + liAux1))/4 + (367*(iMonth
+ - 2-12*liAux1))/12- (3*((iYear + 4900
+ + liAux1)/100))/4+iDay-32075;
+ dJulianDate=(double)(liAux2)-0.5+dDecimalHours/24.0;
+ // Calculate difference between current Julian Day and JD 2451545.0
+ dElapsedJulianDays = dJulianDate-2451545.0;
+ */
+
+ long int iYfrom2000=iYear-2000;
+ long int iA=(14-(iMonth))/12;
+ long int iM=(iMonth)+12*iA-3;
+
+ long int liAux3=(153*iM+2)/5;
+ long int liAux4=365*(iYfrom2000-iA);
+ long int liAux5=(iYfrom2000-iA)/4;
+
+
+ dElapsedJulianDays=(double)(iDay+liAux3+liAux4+liAux5+59)+
+ -0.5+dDecimalHours/24.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)
+ {
+
+ /*double dMeanLongitude;
+ double dMeanAnomaly;
+ double 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)
+ {
+
+ dSin_EclipticLongitude= sin( dEclipticLongitude );
+ double dY1 = cos( dEclipticObliquity ) * dSin_EclipticLongitude;
+ double dX1 = cos( dEclipticLongitude );
+ dRightAscension = atan2( dY1,dX1 );
+ if( dRightAscension < 0.0 ) dRightAscension = dRightAscension + twopi;
+ dDeclination = asin( sin( dEclipticObliquity )*dSin_EclipticLongitude );
+ }
+
+ // Calculate local coordinates ( azimuth and zenith angle ) in degrees
+ {
+
+ dGreenwichMeanSiderealTime = 6.6974243242 +
+ 0.0657098283*dElapsedJulianDays
+ + dDecimalHours;
+
+ dLocalMeanSiderealTime = (dGreenwichMeanSiderealTime*15
+ + dLongitude)*rad;
+ dHourAngle = dLocalMeanSiderealTime - dRightAscension;
+ dLatitudeInRadians = dLatitude*rad;
+ dCos_Latitude = cos( dLatitudeInRadians );
+ dSin_Latitude = sin( dLatitudeInRadians );
+ dCos_HourAngle= cos( dHourAngle );
+ dZenithAngle = (acos( dCos_Latitude*dCos_HourAngle
+ *cos(dDeclination) + sin( dDeclination )*dSin_Latitude));
+ double dY = -sin( dHourAngle );
+ double dX = tan( dDeclination )*dCos_Latitude - dSin_Latitude*dCos_HourAngle;
+ dAzimuth=atan2( dY, dX );
+ if ( dAzimuth < 0.0 )
+ dAzimuth = dAzimuth + twopi;
+ dAzimuth = dAzimuth/rad;
+ // Parallax Correction
+ dParallax=(dEarthMeanRadius/dAstronomicalUnit)
+ *sin(dZenithAngle);
+ dZenithAngle=(dZenithAngle
+ + dParallax)/rad;
+ dElevation=90-dZenithAngle;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Helios.h Mon Apr 25 17:28:13 2016 +0000
@@ -0,0 +1,84 @@
+/*
+ Helios.h - Library for calculating the solar
+ position.
+ Copyright (c) 2011 Hannes Hassler. All right reserved.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+#ifndef Helios_h
+#define Helios_h
+
+
+#include <math.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
+
+
+class Helios
+{
+ public:
+ Helios();
+ void calcSunPos(
+ int iYear,
+ int iMonth,
+ int iDay,
+ double dHours,
+ double dMinutes,
+ double dSeconds,
+ double dLongitude,
+ double dLatitude);
+
+ // Main variables
+ double dElapsedJulianDays;
+ double dDecimalHours;
+ double dEclipticLongitude;
+ double dEclipticObliquity;
+ double dRightAscension;
+ double dDeclination;
+
+ // Auxiliary variables
+ double dSin_EclipticLongitude;
+
+
+ double dMeanLongitude;
+ double dMeanAnomaly;
+ double dOmega;
+
+ double dGreenwichMeanSiderealTime;
+ double dLocalMeanSiderealTime;
+ double dLongitude;
+ double dLatitudeInRadians;
+ double dHourAngle;
+ double dCos_Latitude;
+ double dSin_Latitude;
+ double dCos_HourAngle;
+ double dParallax;
+ double dAzimuth;
+ double dZenithAngle;
+ double dElevation;
+
+
+
+};
+
+
+
+
+#endif
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/NetServices.lib Mon Apr 25 17:28:13 2016 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/segundo/code/NetServices/#966a0265edfc
--- a/main.cpp Thu Mar 31 12:03:04 2011 +0000
+++ b/main.cpp Mon Apr 25 17:28:13 2016 +0000
@@ -1,14 +1,198 @@
+/*
+This Mbed code is a demo code of a DIY dual-axis solar tracker
+Since the solar position is different from place to place, the variables: YourLongitude and YourLatitude needs to be changed based on
+user's location
+The PSA solar positioning algorithm use UTC. There may be a time difference. The variable time_difference should be calibrated as well.
+The calibration can be done by calculated the longitute difference between the user's loaction and Greenwich. 30 degree is 0.25 hours.
+The futher calibration can be done by compare the PSA results with the solar position GUI results, for example:
+http://www.esrl.noaa.gov/gmd/grad/solcalc/azel.html
+The real time needs to be set manually at the beginning of main function
+*/
+
#include "mbed.h"
#include "AX12.h"
+#include "Helios.h"
+#include "EthernetNetIf.h"
+#include "HTTPClient.h"
+#include "spdomparser.hpp"
+#include "spxmlnode.hpp"
+#include "spxmlhandle.hpp"
+#include <string>
+#include "uLCD_4DGL.h"
+
+uLCD_4DGL lcd(p9,p10,p11); // serial tx, serial rx, reset pin;
+EthernetNetIf eth;
+HTTPClient http;
+
+HTTPResult result;
+bool completed = false;
+void request_callback(HTTPResult r)
+{
+ result = r;
+ completed = true;
+}
+
+
+AX12 Hax12 (p13, p14, 1);
+AX12 Vax12 (p28, p27, 1);
+//uLCD_4DGL lcd(p28, p27, p29);
+Serial pc(USBTX,USBRX);
+
+Helios helios;
+
+/////////// TEMPORARY TEST VARIABLES //////////////////////
+int TheYear = 2016;
+int TheMonth = 4;
+int TheDay = 9;
+double TheHour = 12; /* UTC TIME! */
+double TheMinute = 0.00;
+double TheSeconds = 0.00;
+double YourLongitude = 84.39; // your longitude [e.g 151.857964];
+double YourLatitude = 33.4; // your latitude [e.g -33.579265];
+////// LIVE VARIABLES SHOULD BE USED FROM A GPS //////////
+
+
+//real_time variable
+struct tm *t;
+float time_difference = 6.1; //calibrated time difference of Atlanta
+
+//update the solar position and roate the panel accordingly with the time interval of update_period
+float update_period = 0.5*60; //10 minutes by default
+
+//HTTP variables
+int n = 0;
+string delimiter = "weather";
+string delimiter2 = ",";
+string delimiter3 = ":";
+string place;
+string weather;
+string condition;
+
+void get_sun_position(){
+ helios.calcSunPos(TheYear, TheMonth, TheDay, TheHour, TheMinute, TheSeconds, YourLongitude, YourLatitude);
+ pc.printf("Sun Zenith Angle: %f\n",helios.dZenithAngle); // Degrees down from vertical
+ pc.printf("Sun Azimuth Angle: %f\n",helios.dAzimuth); // Degrees from north
+ pc.printf("Sun Elevation Angle: %f\n",helios.dElevation); // Degrees up from horizontal
+}
+
+
+//rotate the horizontal angle to get the proper azimuth angle
+void rotate_horizontal(float angle){
+ Hax12.SetGoal(angle);
+}
+
+//rotate the vertical angle to get the proper zenith angle, the zero of the servo points vertical
+void rotate_vertical(float angle){
+ Vax12.SetGoal(angle+60);
+}
+
int main() {
-
- AX12 myax12 (p9, p10, 1);
+ // setup time structure for Wed, 28 Oct 2016 3:12:00
+ struct tm mytime;
+ mytime.tm_sec = 00; // 0-59
+ mytime.tm_min = 50; // 0-59
+ mytime.tm_hour = 16; // 0-23
+ mytime.tm_mday = 28; // 1-31
+ mytime.tm_mon = 3; // 0-11
+ mytime.tm_year = 116; // year since 1900
- while (1) {
- myax12.SetGoal(0); // go to 0 degrees
- wait (2.0);
- myax12.SetGoal(300); // go to 300 degrees
- wait (2.0);
+ time_t seconds = mktime(&mytime);
+ set_time(seconds);
+
+ lcd.cls();
+ lcd.printf("Start\n");
+
+ lcd.printf("Setting up...\n");
+ EthernetErr ethErr = eth.setup(100000);
+ if(ethErr)
+ {
+ lcd.printf("Error %d in setup.\n", ethErr);
+ return -1;
}
-}
\ No newline at end of file
+ lcd.printf("Setup OK\n");
+
+ HTTPStream stream;
+ SP_XmlDomParser parser;
+
+ char BigBuf[512 + 1] = {0};
+ stream.readNext((byte*)BigBuf, 512); //Point to buffer for the first read
+ int i = 0;
+ char buffer [512*5+1];
+ while(true){
+ HTTPResult r = http.get("http://openweathermap.org/data/2.1/find/city?lat=33.75&lon=-84.39&cnt=1&type=XML", &stream, request_callback); //Load a very large page, such as the hackaday RSS feed
+ //http://openweathermap.org/data/2.1/find/city?lat=33.75&lon=-84.39&cnt=1&type=XML
+ //http://wxdata.weather.com/wxdata/weather/local/USGA0028:1:US?cc=*&unit=m&dayf=1
+ //HTTP://hackaday.com/feed/
+ //http://openweathermap.org/data/2.1/find/city?lat=40.71&lon=-74.00&cnt=1&type=XML
+ i = 0;
+
+ while(!completed)
+ {
+ Net::poll(); //Polls the Networking stack
+ if(stream.readable())
+ {
+ i++;
+ BigBuf[stream.readLen()] = 0; //Transform this buffer in a zero-terminated char* string
+ parser.append( BigBuf, strlen(BigBuf)); // stream current buffer data to the XML parser
+ if (i == 1){
+ sprintf(buffer,"%s",BigBuf);
+ } else{
+ printf("%s",BigBuf); //Display it while loading
+ }
+ //Note: some servers do not like if you throttle them too much, so printf'ing during a request is generally bad practice
+ stream.readNext((byte*)BigBuf, 512); //Buffer has been read, now we can put more data in it
+ }
+ }
+ //lcd.printf("\n--------------\n");
+ n = sizeof(buffer);
+ string ret(buffer, n);
+
+ place = ret.substr(ret.find("name"),ret.length());
+ place = place.substr(place.find(delimiter3),place.find(delimiter2)-4);
+ //lcd.printf("Location:%s\n", place);
+
+ weather = ret.substr(ret.find(delimiter), ret.length());
+ weather.erase(0,weather.find(delimiter3)+1);
+ condition = weather.substr(weather.find("main"),weather.length());
+ condition = condition.substr(condition.find(delimiter3),place.find(delimiter2)-2);
+ //lcd.printf("weather condition%s\n",condition);
+
+ while (true) {
+ time_t local_time = time(NULL);
+ lcd.cls();
+ lcd.printf("The Current Time is: %s\n", ctime(&local_time));
+ pc.printf("The Current Time is: %s\n", ctime(&local_time));
+ lcd.printf("\n--------------\n");
+ lcd.printf("Location:%s\n", place);
+ lcd.printf("weather condition%s\n",condition);
+ pc.printf("weather condition%s\n",condition);
+ t = localtime(&local_time);
+ TheYear = t->tm_year + 1900;
+ TheMonth = t->tm_mon;
+ //change the local time to UTC TIME according to longitude
+ if(t->tm_hour - time_difference < 0){
+ TheDay = t->tm_mday -1;
+ TheHour = t->tm_hour + 24 - time_difference;
+ } else{
+ TheDay = t->tm_mday;
+ TheHour = t->tm_hour - time_difference;
+ }
+ TheMinute = t->tm_min;
+ TheSeconds = t->tm_sec;
+ get_sun_position();
+ pc.printf("%d\n",condition.find("Clear"));
+ if( helios.dZenithAngle<90 && (condition.find("Clear")!=-1)){
+ rotate_horizontal(helios.dAzimuth);
+ rotate_vertical(helios.dZenithAngle);
+ lcd.printf("Sun Zenith Angle: %f\n",helios.dZenithAngle); // Degrees down from vertical
+ lcd.printf("Sun Azimuth Angle: %f\n",helios.dAzimuth); // Degrees from north
+ }else{
+ lcd.printf("The solar tracker is not tracking the sun...");
+ }
+ wait(update_period);
+ if(t->tm_hour == 6) break;
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/spxml.lib Mon Apr 25 17:28:13 2016 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/hlipka/code/spxml/#3fa97f2c0505
