Calculates azimuth and elevation of a satellite dish based on its longitude, latitude and selected satellite.
Dependencies: PinDetect TextLCD mbed MODGPS
Revision 0:fe8decc6a938, committed 2012-03-29
- Comitter:
- BartJanssens
- Date:
- Thu Mar 29 09:26:14 2012 +0000
- Commit message:
Changed in this revision
diff -r 000000000000 -r fe8decc6a938 CircularLinkedList.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CircularLinkedList.h Thu Mar 29 09:26:14 2012 +0000 @@ -0,0 +1,161 @@ + +/* A circular double linked list + * + * Copyright (c) 2012 Bart Janssens + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +template <typename T> +class Node +{ +public: + Node(T data) : data(data), next(NULL) {} +//private: + Node *next; + Node *prev; + T data; +}; + +template <typename T> +class CircularLinkedList +{ +public: + CircularLinkedList() : head(NULL),size(0) {} //constructor + ~CircularLinkedList(); // decunstructor + bool isEmpty() { return (head == NULL);} // is list Empty ? + void moveForward(); // move cursor forward + void moveBackward(); // move cursor backward + void toHead(); // move cursor to head + T * getNode(); + void addNode(T data); + void deleteNode(T data); + int getSize(); +private: + Node<T> *head; + Node<T> *cursor; + int size; +}; + +template <typename T> +CircularLinkedList<T>::~CircularLinkedList() +{ + if (!isEmpty()) { + Node<T> *tmp = head; + while (tmp->next != head) { + Node<T> *t = tmp; + tmp = tmp->next; + delete(t); + } + delete tmp; + head = NULL; + } +} + + + +template <typename T> +T * CircularLinkedList<T>::getNode() +{ + return &(cursor->data); +} + +template <typename T> +void CircularLinkedList<T>::addNode(T data) +{ + Node<T> * t = new Node<T>(data); + + if (isEmpty()) + { + t->next = t; + t->prev = t; + head = t; + size++; + cursor = head; + return; + } + + Node<T> *tmp = head; + while (tmp->next != head) + { + tmp = tmp->next; + } + + tmp->next = t; + t->next = head; + t->prev = tmp; + head->prev = t; + size++; +} + +template <typename T> +void CircularLinkedList<T>::deleteNode(T data) +{ + Node<T> *tmp = head; + Node<T> *prev = NULL; + while (tmp->next != head) + { + if (tmp->data == data) break; + prev = tmp; + tmp = tmp->next; + } + + if (tmp == head) + { + while (tmp->next != head) + { + tmp = tmp->next; + } + tmp->next = head->next; + head->next->prev = tmp + delete head; + size--; + head = tmp->next; + } + else + { + prev->next = tmp->next; + tmp->next->prev = prev; + delete tmp; + size--; + } +} + +template <typename T> +void CircularLinkedList<T>::moveForward() +{ + if (!isEmpty()) cursor = cursor->next; +} + +template <typename T> +void CircularLinkedList<T>::moveBackward() +{ + if (!isEmpty()) cursor = cursor->prev; +} + +template <typename T> +void CircularLinkedList<T>::toHead() +{ + cursor = head; +} + +template <typename T> +int CircularLinkedList<T>::getSize() +{ + return size; +} \ No newline at end of file
diff -r 000000000000 -r fe8decc6a938 MODGPS.lib --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MODGPS.lib Thu Mar 29 09:26:14 2012 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/AjK/code/MODGPS/#64771e31464e
diff -r 000000000000 -r fe8decc6a938 PinDetect.lib --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/PinDetect.lib Thu Mar 29 09:26:14 2012 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/AjK/code/PinDetect/#cb3afc45028b
diff -r 000000000000 -r fe8decc6a938 SatGps.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/SatGps.h Thu Mar 29 09:26:14 2012 +0000 @@ -0,0 +1,54 @@ +/* Satelitte locator + * + * Copyright (c) 2012 Bart Janssens + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +typedef struct +{ + float lo; // longitude + float la; // latitude + float ht; // height + float ob; // orbit satellite + float az; // azimuth + float el; // elevation + float tm;// temperature +} pos_t; + +typedef enum +{ + buttonNone, + buttonMode, + buttonPlus, + buttonMin + +} buttons; + +typedef enum +{ + modeAzimuth, + modePosition, + modeTime, + modeTemperature, + modeNone +} modes; + + + \ No newline at end of file
diff -r 000000000000 -r fe8decc6a938 Satellite.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Satellite.cpp Thu Mar 29 09:26:14 2012 +0000 @@ -0,0 +1,40 @@ +#include "Satellite.h" + +Satellite::Satellite(string n, string c, float o, float i){ + name = n; + cname = c; + orbit = o; + inclination = i; +} + +string Satellite::getName(){ + return name; +} + +string Satellite::getCname(){ + return cname; +} + +float Satellite::getOrbit(){ + return orbit; +} + +float Satellite::getInclination(){ + return inclination; +} + +void Satellite::setName(string n){ + name = n; +} + +void Satellite::setCname(string c){ + cname = c; +} + +void Satellite::setOrbit(float o){ + orbit = o; +} + +void Satellite::setInclination(float i){ + inclination = i; +} \ No newline at end of file
diff -r 000000000000 -r fe8decc6a938 Satellite.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Satellite.h Thu Mar 29 09:26:14 2012 +0000 @@ -0,0 +1,21 @@ +#include <string> +using namespace std; + +class Satellite +{ +public: + Satellite(string n, string c, float o, float i); + string getName(); + string getCname(); + float getOrbit(); + float getInclination(); + void setName(string n); + void setCname(string c); + void setOrbit(float o); + void setInclination(float i); +private: + string name; //name + string cname; // commen name + float orbit; + float inclination; +}; \ No newline at end of file
diff -r 000000000000 -r fe8decc6a938 SatelliteList.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/SatelliteList.cpp Thu Mar 29 09:26:14 2012 +0000 @@ -0,0 +1,88 @@ +#include "SatelliteList.h" +#include <iostream> + +SatelliteList::SatelliteList(char *f, char delimiter){ + + string line; + vector<string> v; + + sfile.open(f); + if (sfile.is_open()) { + while ( getline(sfile,line) ){ + if( line.empty() ); // ignore empty lines + else if (line.at(0) != ';'){ // ignore comments + split( v, line, ';' ); + //for ( int i = 0; i < v.size(); i++) printf("%s ",v[i].c_str()); + //printf("\r\n"); + if (v.size() == 4) { + Satellite *s = new Satellite(v[0],v[1], ::atof(v[2].c_str()), ::atof(v[3].c_str())); + clist.addNode(*s); + delete s; + } + v.clear(); + } + } + //printf("Size Circular List = %d \r\n", clist.getSize()); + sfile.close(); + } else printf("Can't open filename %s\r\n", f); +} + +void SatelliteList::split(vector<string> & theStringVector, /* Altered/returned value */ + const string & theString, + const char theDelimiter) +{ + + + size_t start = 0, end = 0; + + while ( end != string::npos) + { + end = theString.find( theDelimiter, start); + + + theStringVector.push_back( theString.substr( start, + (end == string::npos) ? string::npos : end - start)); + + + start = ( ( end > (string::npos - 1) ) + ? string::npos : end + 1); + } +} + +void SatelliteList::display() +{ + string n, c ; + float o,i ; + + clist.toHead(); + for ( int j = 0; j < clist.getSize(); j++) { + Satellite *s = clist.getNode(); + n = s->getName(); + c = s->getCname(); + o = s->getOrbit(); + i = s->getInclination(); + printf("Size = %d i = %d Name = %s Cname = %s \r\n",clist.getSize(), j, n.c_str(), c.c_str()); + clist.moveForward(); + } +} + +Satellite * SatelliteList::getNext() +{ + clist.moveForward(); + Satellite *s = clist.getNode(); + return(s); +} + +Satellite * SatelliteList::getPrev() +{ + clist.moveBackward(); + Satellite *s = clist.getNode(); + return(s); +} + +Satellite * SatelliteList::getCurrent() +{ if (!clist.isEmpty()) { + Satellite *s = clist.getNode(); + return(s); + } +}
diff -r 000000000000 -r fe8decc6a938 SatelliteList.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/SatelliteList.h Thu Mar 29 09:26:14 2012 +0000 @@ -0,0 +1,22 @@ +#include <fstream> +#include <vector> +#include "Satellite.h" +#include "CircularLinkedList.h" + +class SatelliteList +{ +public: + SatelliteList(char *f, char delimiter); + void display(); + Satellite * getNext(); + Satellite * getPrev(); + Satellite * getCurrent(); +private: + void split(vector<string> & theStringVector, /* Altered/returned value */ + const string & theString, + const char theDelimiter); + + string filename; //name + ifstream sfile; + CircularLinkedList<Satellite> clist; +}; \ No newline at end of file
diff -r 000000000000 -r fe8decc6a938 TextLCD.lib --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/TextLCD.lib Thu Mar 29 09:26:14 2012 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/simon/code/TextLCD/#44f34c09bd37
diff -r 000000000000 -r fe8decc6a938 main.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Thu Mar 29 09:26:14 2012 +0000 @@ -0,0 +1,362 @@ +/* Satelitte Positioner + * + * Calculates azimuth and elevation of a satellite dish based on its longitude, latitude + * and selected satellite. + * see: http://www.alcyone.com/max/writing/essays/geostationary-orbits.html + * http://www.spaceacademy.net.au/watch/track/locgsat.htm + * http://www.dishpointer.com/ + * + * Copyright (c) 2012 Bart Janssens + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include "mbed.h" + +#include "TextLCD.h" +#include "PinDetect.h" +#include "GPS.h" + +#include "SatGps.h" +#include "SatelliteList.h" + + +#define GPSRX p10 +#define GPSBAUD 4800 + +#define MAXGPRMC 3 +#define MAXGPRMCA 4 + +#define PI 3.14159265 + +TextLCD lcd(p24, p26, p27, p28, p29, p30, TextLCD::LCD16x2 ); // rs, e, d0, d1, d2, d3, LCD16x2 +LocalFileSystem local("local"); +GPS gps(NC, GPSRX); +AnalogIn ain(p20); //temperature from LM35 +PinDetect modeButton(p13); +PinDetect plusButton(p14); +PinDetect minButton(p15); + +// heartbeat +DigitalOut led1(LED1); +// 0.05 second flash of LED2 +DigitalOut led2(LED2); +Timeout t2; + +// 0.05 second flash of LED3 +DigitalOut led3(LED3); +Timeout t3; + +// 0.05 second flash of LED4 +DigitalOut led4(LED4); +Timeout t4; + +int gprmc_c = 0; + + +int mode = modeAzimuth; + +SatelliteList slist("/local/SAT.TXT",';'); +Satellite *s; +pos_t pos; + +const float G = 6.67421e-11; // ( m�/kg/s�) +const float Mr = 5.9736e24; // Mass of Earth (Kg) +const float Rr = 6.378137e6; // Radius of Earth (m) +const float T = 23.934192*60*60; // the period of Earth rotation (s) + +const float degreesPerRadian = 180/PI; +const float dr = PI/180; + +const float r1 = ((G*Mr*T*T)/(4*PI*PI)); // the radius of the path of the geostatic satellite +const float r = pow(r1, float(1.0 / 3.0)); +const float h = r - Rr; // the height of the satelite +const float b = Rr/r; // the geostationary orbit constant + +void switch_mode(buttons); +void display_satellite(); +void display_position(); +void display_time(); +void display_temperature(); +void display_welcome(); +void calculate_satellite(); + +void t2out(void) { led2 = 0; } +void blip2(void) { led2 = 1; t2.attach(&t2out, 0.05); } + +void t3out(void) { led3 = 0; } +void blip3(void) { gprmc_c = 0;led3 = 1; t3.attach(&t3out, 0.05); } + +void t4out(void) { led4 = 0; } +void blip4(void) { led4 = 1; t4.attach(&t4out, 0.05); } + +void buttonModePressed( void ) { + //led4 = !led4; + mode = (((mode + 1) % 4)); + //printf("Mode button pressed %d \r\n", mode); + switch_mode(buttonNone); +} + +void buttonPlusPressed( void ) { + //led4 = !led4; + switch_mode(buttonPlus); +} + +void buttonMinPressed( void ) { + //led4 = !led4; + switch_mode(buttonMin); +} + +void switch_mode(buttons button) +{ + switch(mode) + { + case modeAzimuth: + //printf("Azimuth mode \r\n"); + switch(button) + { + case buttonPlus: + s = slist.getNext(); + break; + case buttonMin: + s = slist.getPrev(); + break; + default: + break; + } + calculate_satellite(); + display_satellite(); + break; + case modePosition: + //printf("Position mode \r\n"); + display_position(); + break; + case modeTime: + //printf("Time mode \r\n"); + display_time(); + break; + case modeTemperature: + display_temperature(); + //printf("Temperature mode \r\n"); + break; + default: + //printf("Invalid mode \r\n"); + break; + } +} + +void calculate_satellite(){ + float denominator, B, Gc; + float la,lo,ob,az,el; + + lo = pos.lo; + la = pos.la; + ob = s->getOrbit(); + pos.ob = ob; + + la = la * dr; //convert latitude observer from deg to rad + B = (lo - ob) * dr; //longitude diff between satellite and observer + Gc = cos(B) * cos(la); //Gc is the great circle angle between observer and satellite + Gc = atan(sqrt(1 - Gc * Gc) / Gc); + if (Gc < 1.419) { //if greater than 81.3deg skip + denominator = sin(la); + if (denominator != 0.0) { + az = atan(tan(B) / denominator); //compute azimuth angle + if (la >= 0) az = az + PI; //adjust for northern hemisphere + } else az = 0.0; + el = (( (1.0 / b) * cos(la) * cos(B)) - 1); + denominator = ( (1.0 /b) * sqrt(1-(pow(cos(la),2) * pow(cos(B),2))) ); + if (denominator!=0) + { + el/=denominator; + el = atan(el); + } + else el = PI/2; + } else { + az = 0.0; + el = PI/2; + } + + // convert from rad to deg + az = az/dr; + el = el/dr; + pos.az = az; + pos.el = el; + + //printf("Azimuth observer = %.2f \r\n", az); + //printf("Elevation observer = %.2f \r\n", el); + +} + +void display_satellite(){ + + string sname; + + sname = s->getCname(); + + lcd.cls(); + lcd.locate(0,0); + lcd.printf("%.1f\xDF %s",pos.ob,sname.c_str()); //DF is the grade sign '�' + lcd.locate(0,1); + lcd.printf("A:%.1f\xDF",pos.az); + lcd.printf(" E:%.1f\xDF",pos.el); + //printf("Sat: %.2f LAT: %.2f LON: %.2f AZ: %.2f EL: %.2f tem: %.1f \r\n",pos.ob, pos.la, pos.lo, pos.az, pos.el, pos.tm); + } + + void display_position(){ + + lcd.cls(); + lcd.locate(0,0); + lcd.printf("LAT: %.4f\xDF",pos.la); //DF is the grade sign '�' + lcd.locate(0,1); + lcd.printf("LON: %.4f\xDF",pos.lo); + } + + void display_temperature(){ + + lcd.cls(); + lcd.locate(0,0); + lcd.printf("Temp: %.1f\xDF",pos.tm); //DF is the grade sign '�' + } + + void display_time(){ + + GPS_Time now; + gps.timeNow(&now); + //printf("Time: %d-%d-%d %d:%d:%d UTC\r\n", now.day, now.month, now.year, now.hour, now.minute, now.second); + + lcd.cls(); + lcd.locate(0,0); + lcd.printf("Date: %d-%d-%d", now.day, now.month, now.year); + lcd.locate(0,1); + lcd.printf("Time: %d:%d:%d",now.hour, now.minute, now.second); + } + + void display_welcome(){ + lcd.cls(); + lcd.locate(0,0); + lcd.printf("SatGPS v1.0"); + lcd.locate(0,1); + lcd.printf("4 PVDV"); + } + + +int main() { + + + + GPS_Time q1; + GPS_VTG v1; + int gprmca_c; //Counter for the GPRMC 'Valid A' field + + pos.az = 0.0; + pos.el = 0.0; + pos.tm = 0.0; + + display_welcome(); + wait(2); + + + //slist.display(); + s = slist.getCurrent(); + + + gps.baud(GPSBAUD); + gps.format(8, GPS::None, 1); + gps.attach_gga(&blip2); + // Sample of a callback to a function when a NMEA RMC message is recieved. + gps.attach_rmc(&blip3); + + //printf("Wait for the GPS NMEA data to become valid. \r\n"); + lcd.cls(); + lcd.locate(0,0); + lcd.printf("Waiting for"); + lcd.locate(0,1); + lcd.printf("valid GPS signal"); + while (!gps.isTimeValid()) { + //printf("%s \r\n",gps.buffer); + led1 = !led1; + wait(1); + } + + modeButton.mode( PullDown ); + modeButton.attach_asserted( &buttonModePressed ); + minButton.mode( PullDown ); + minButton.attach_asserted( &buttonMinPressed ); + plusButton.mode( PullDown ); + plusButton.attach_asserted( &buttonPlusPressed ); + modeButton.setSampleFrequency(); + minButton.setSampleFrequency(); + plusButton.setSampleFrequency(); + led4 = 0; + + + + + + while(1) { + + wait(2); + led1 = 1; + //printf("%s \r\n",gps.buffer); + + + if (gprmc_c > MAXGPRMC){ + lcd.cls(); + lcd.locate(0,0); + lcd.printf("Lost connection"); + lcd.locate(0,1); + lcd.printf("with GPS module"); + } + else { + if (!gps.isTimeValid()){ + gprmca_c++; + if (gprmca_c > MAXGPRMCA) { + lcd.cls(); + lcd.locate(0,0); + lcd.printf("Waiting for"); + lcd.locate(0,1); + lcd.printf("valid GPS signal"); + } + + } else { + + gprmca_c = 0; //Resets the bad GPRMC counter + // Grab a snapshot of the current time. + gps.timeNow(&q1); + + // Grab velicity + gps.vtg(&v1); + + // Grab longitude, latitude and height + pos.lo = gps.longitude(); + pos.la = gps.latitude();; + pos.tm = ain.read() *330; + + switch_mode(buttonNone); + } + } + + gprmc_c++; + led1 = 0; + + + } + + +}
diff -r 000000000000 -r fe8decc6a938 mbed.bld --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed.bld Thu Mar 29 09:26:14 2012 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/mbed/builds/737756e0b479