source: firmware/GpsArduino/GpsControl.ino@ 17689

Last change on this file since 17689 was 17313, checked in by mknoetig, 11 years ago
add: get_status to the GPS arduino firmware and documentation
File size: 8.9 KB
Line 
1/**
2 * Firmware of the Arduino GPS reciever.
3 *
4 * This code was inspired by http://quaxio.com/arduino_gps/ ,
5 * http://playground.arduino.cc/Tutorials/GPS and
6 * http://blog.bouni.de/blog/2012/06/25/a-arduino-telnet-server/
7 *
8 *
9 * Autor: Max Knötig
10 */
11
12#include <SoftwareSerial.h>
13#include <string.h>
14#include <stdio.h>
15#include <SPI.h>
16#include <Ethernet.h>
17
18#define MAX_CMD_LENGTH 15
19
20//define led pins for display on the box
21int arduLed = 8; // on: arduino is on. blinking: serial message parsed
22int gpsLed = 7; // on: venus gps chip on. blinking: gps locked
23int vetoLed = 6; // on: veto active. off: veto not active ( active low btw. )
24
25int arduLedOn = 0;
26int gpsLedOn = 0;
27int vetoLedOn = 0;
28
29//define inputs and outputs for the veto system
30int vetoPin = 3; // the veto output pin ( active low )
31int navPin = 2; // the nav pin, from the venus gps. this is for steering the gpsLed
32
33//globals for storing the serial nema message
34int byteGPS=-1; // will become the read byte from the Venus GPS
35char cmd[7] = "$GPGGA"; // the NMEA message type we want to know
36int counter = 0; // counts how many bytes were received (max 300)
37char buf[300] = ""; // buffer to store the message
38String nemaMsg; // this buffer stores the last complete nema message
39
40//variables to save (or dump) nema message parts
41int seconds = 0; // this will become the veto trigger criterion ( seconds = 59 -> veto )
42int dump = 0; // the other variables are used when sscanf the nema message
43char cdump = '0'; // for dumping reasons
44char hexdump[8]="0000000";
45
46//the addresses for the shield (commented: ethz mode):
47byte mac[] = { 0x90, 0xA2, 0xDA, 0x0D, 0xB9, 0x32 };
48byte ip[] = { 10, 0, 100, 112 };
49//byte ip[] = { 192, 33, 103, 241 };
50//byte dns[] = { 129, 132, 98, 12 };
51//byte gatew[] = { 192, 33, 96, 1 };
52//byte smask[] = { 255, 255, 248, 0 };
53
54
55//the globals for the ethernet communication
56String etherCmd; // store the ethernet command in here
57EthernetServer server = EthernetServer(23);
58EthernetClient client;
59boolean connected = false;
60
61//the state as decided by the user. 0 = veto_off, 1 = veto_60, 2 = veto_on
62int state = 1;
63
64/**
65 * Setup arduino and gps
66 */
67void setup() {
68 // define I/O pins
69 pinMode(arduLed, OUTPUT); // Initialize Arduino LED pin
70 pinMode(gpsLed, OUTPUT); // Initialize GPS LED pin
71 pinMode(vetoLed, OUTPUT); // Initialize Veto LED pin
72 pinMode(vetoPin, OUTPUT); // Initialize Veto pin
73 pinMode(navPin, INPUT); // Initialize Nav pin
74
75 // set their startup modes
76 digitalWrite(vetoPin, HIGH); // put veto to high ( no veto ) in startup mode
77 digitalWrite(arduLed, HIGH); // put the arduino led high when starting
78 arduLedOn = 1;
79
80 //begin the ethernet and serial connections
81 Ethernet.begin(mac, ip); //, dns, gatew, smask); // this is to begin (ethz) ethernet
82 Serial.begin(115200); // the gps serial connection
83 server.begin();
84
85 reset(); // reset the counters (just in case)
86}
87
88/**
89 * the loop which processes ethernet and serial connections
90 */
91void loop()
92{
93 //serial part
94 byteGPS=Serial.read(); // Read a byte of the serial port
95
96 if (byteGPS == -1) { // See if the port is empty yet
97 delay(1);
98 } else {
99 if (!handle_byte(byteGPS)) {
100 reset();
101 Serial.flush();
102 }
103 }
104
105 //ethernet part
106 client = server.available(); // check if the server is available
107
108 if (client == true) { // if there is a new client
109 if (!connected) {
110 client.flush();
111 connected = true;
112 }
113
114 while (client.available() > 0) { // while there is incoming data read it
115 readEthernetCommand(client.read());
116 }
117 }
118
119 if( digitalRead(navPin) == 0){ // test if the gps blinkes, if yes, blink the gps led as well
120 digitalWrite(gpsLed, HIGH);
121 gpsLedOn=1;
122 } else {
123 digitalWrite(gpsLed, LOW);
124 gpsLedOn=0;
125 }
126}
127
128/**
129 * handle the byte read from the GPS module
130 */
131int handle_byte(int byteGPS) {
132
133 if (counter == 300) { // if the buffer is full return 0
134 return 0;
135 }
136
137 //read the first char
138 buf[counter] = byteGPS;
139
140 if (counter == 6) { // if 6 chars are read, check if it is the beg. of the correct message
141 for(int j=0; j<6; j++) { // if not return 0
142 if (buf[j] != cmd[j]) {
143 return 0;
144 }
145 }
146 }
147
148 //check if recieved message is gpgga compatible
149 if ( byteGPS == '\n' ) { // when '\n' read (i.e. end of message ), check if variables are at the correct pos. then continue
150 if( sscanf( buf,"$GPGGA,%2d%2d%2d.%d,%d.%d,%c,%d.%d,%c,%d,%d,%d.%d,%d.%d,M,%d.%d,M,%7s\r\n",
151 &dump,&dump,&seconds,&dump,&dump,&dump,&cdump,&dump,&dump,&cdump,&dump,&dump,&dump,&dump,&dump,&dump,&dump,&dump,&hexdump ) != 19 )
152 {
153 return 0;
154 }
155
156 blinkLed(0); // everything is ok -> message parsed, blink arduino led
157 decideVeto(); // as we have found the interesting part, do something
158 nemaMsg=buf; // save the found message to the nema string
159 // remove \r and \n from the string
160 nemaMsg = nemaMsg.substring(0,counter-1);
161
162 return 0; // return 0 as we found the interesting part
163 }
164
165 //continue with the next char if none of the actions before were needed
166 if(buf[0]=='$' || byteGPS=='$') {
167 counter++; // count one up, if it is the correct message ( the '$' at front )
168 }
169
170 return 1; // continue (return 1) if we cannot yet decide to stop
171}
172
173 /**
174 * decideVeto() veto something if the state and time demand it
175 */
176void decideVeto() {
177 if( state == 0 ) { // veto off
178 digitalWrite(vetoPin, HIGH); // put veto to not active ( HIGH )
179 digitalWrite(vetoLed, LOW); // put veto Led to not active
180 vetoLedOn = 0;
181 } else if( state == 2 ) { // veto on
182 digitalWrite(vetoPin, LOW); // put veto to active
183 digitalWrite(vetoLed, HIGH); // put veto Led to active
184 vetoLedOn = 1;
185 } else if( state == 1 ) { // veto the full minute
186 if( seconds == 59 ) { // if it is time to veto
187 digitalWrite(vetoPin, LOW); // put veto to active
188 digitalWrite(vetoLed, HIGH); // put veto Led to active
189 vetoLedOn = 1;
190 } else {
191 digitalWrite(vetoPin, HIGH); // put veto to not active
192 digitalWrite(vetoLed, LOW); // put veto Led to not active
193 vetoLedOn = 0;
194 }
195 }
196}
197
198/**
199 * reset() the counters if needed
200 */
201void reset() {
202 counter = 0;
203}
204
205/**
206 * blinkLed() toggle the Led (on or off)
207 * type: int, 0 = arduino LED, 1 = gps LED, 2 = veto LED
208 */
209void blinkLed( int type ) {
210 if(type == 0){
211 if(arduLedOn==0) {
212 digitalWrite(arduLed, HIGH);
213 arduLedOn=1;
214 } else {
215 digitalWrite(arduLed, LOW);
216 arduLedOn=0;
217 }
218 }/* else if (type == 1) {
219 if(gpsLedOn==0) {
220 digitalWrite(gpsLed, HIGH);
221 gpsLedOn=1;
222 } else {
223 digitalWrite(gpsLed, LOW);
224 gpsLedOn=0;
225 }
226 } else if (type == 2) {
227 if(vetoLedOn==0) {
228 digitalWrite(vetoLed, HIGH);
229 vetoLedOn=1;
230 } else {
231 digitalWrite(vetoLed, LOW);
232 vetoLedOn=0;
233 }
234 }*/
235}
236
237/**
238 * read ethernet command
239 */
240void readEthernetCommand(char c) {
241
242 if(etherCmd.length() == MAX_CMD_LENGTH) {
243 etherCmd = "";
244 }
245
246 etherCmd += c;
247
248 if(c == '\n') {
249 if(etherCmd.length() > 2) {
250 // remove \r and \n from the string
251 etherCmd = etherCmd.substring(0,etherCmd.length() - 2);
252 parseCommand();
253 }
254 }
255}
256
257/**
258 * parse ethernet command
259 */
260void parseCommand() {
261
262 if(etherCmd.equals("quit")) {
263 client.stop();
264 connected = false;
265 } else if(etherCmd.equals("help")) {
266 server.println("-- GPS Clock Arduino Help --");
267 server.println("---- Autor: Max Knoetig ----");
268 server.println("--- mknoetig@phys.ethz.ch --");
269 server.println("get_nema : get the last complete NEMA message");
270 server.println("get_status: get the status, veto_off, veto_60 or veto_on");
271 server.println("veto_off : switch off veto");
272 server.println("veto_on : switch on veto");
273 server.println("veto_60 : veto every pps to the full GPS UTC minute");
274 server.println("quit : close the connection");
275 } else if(etherCmd.equals("get_nema")) {
276 server.println(nemaMsg);
277 } else if(etherCmd.equals("get_status")) {
278 if(state==1) {
279 server.println("veto_60");
280 } else if(state==0) {
281 server.println("veto_off");
282 } else if(state==2) {
283 server.println("veto_on");
284 } else {
285 server.println("system state unknown");
286 }
287 } else if(etherCmd.equals("veto_off")) {
288 state=0;
289 server.println("veto now off");
290 } else if(etherCmd.equals("veto_60")) {
291 state=1;
292 server.println("veto 60 now on");
293 } else if(etherCmd.equals("veto_on")) {
294 state=2;
295 server.println("veto now on");
296 } else {
297 server.println("Invalid command, type help");
298 }
299 etherCmd = "";
300}
301
Note: See TracBrowser for help on using the repository browser.