Pages: [1]   Go Down
Author Topic: GPS EM 406 A - Arduino Demi.  (Read 843 times)
0 Members and 1 Guest are viewing this topic.
0
Offline Offline
Newbie
*
Karma: 0
Posts: 9
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

ich habe eine box nach newbrightidea.com/?p=15 nachgebaut mit arduino, GPS EM 406 A, LCD, 2 Servos, welche die Schublade zum öffnen freigibt , wenn man im Umkreis von 5 km von den Zielkoordinaten ist. Mein Problem:
Mein Garmin GPS Emfänger zeigt am Standort:
49.45728 N 006.38368E an
Die Box zeigt an:
49.762241 N 006.639300E
Ist das ein Technische Fehler oder ein Einheiten Fehler oder sonst was?
Vielleicht hat jemand Erfahrung und kennt eine Antwort.
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 9
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Der Code v. Herrn Weeks mit anderen Zielkoordinaten Zeile 25/26 ist:
001 #include <TinyGPS.h>  
002 #include <NewSoftSerial.h>  
003 #include <LiquidCrystal.h>  
004 #include <SoftwareServo.h>  
005 #include <math.h>  
006 #include <EEPROM.h>  
007 #include <avr/interrupt.h>  
013 #define RXPIN 2  
014 #define TXPIN 3  
016 #define POLULUPIN 5  
018 #define LIDPIN 6  
019 #define DRAWERPIN 4  
020 #define IRPINA 0  
022 #define EARTH_RADIUS 6378.1f  
023 #define DEG_TO_RAD 0.0174532925f  
025 #define TOFINO_LAT 49.122444f  
026 #define TOFINO_LON 125.900871f  
028 #define XXXX_LAT 0.0f  
029 #define XXXX_LON 0.0f  
031 #define HOME_LAT 64.0f  
032 #define HOME_LON 128.0f  
034 #define GPS_DELAY_MS 60000  
036 /* 5km is pretty generous, but  better safe than sorry, right? */
038 #define DIST_THRESHOLD 5.0f  
040 #define ADDR_TRIES 0  
041 #define ADDR_STAGE1 1  
042 #define ADDR_STAGE2 2  
043 #define ADDR_BACKDOOR 3  
045 TinyGPS gps;  
046 SoftwareServo drawerServo;  
047 SoftwareServo lidServo;  
049 /* Set up the NewSoftSerial to talk to the GPS */
050 NewSoftSerial nss(RXPIN,TXPIN);  
052 LiquidCrystal lcd(7, 8, 9, 10, 11, 12);  
054 unsigned long waitUntil;  
055 int attemptsRemaining;  
057 void setup() {  
058   pinMode(POLULUPIN, OUTPUT);  
059   Serial.begin(9600);  
060   Serial.print( "In setup.\n" );  
061   nss.begin(4800);  
062   lcd.begin(2,16);  
063   lcd.clear();  
064   lcd.setCursor(0,0);  
066   /* Check how many tries are left */
067   attemptsRemaining = EEPROM.read(ADDR_TRIES);  
068   Serial.print( "Attempts Remaining: " );  
069   Serial.print( attemptsRemaining, DEC );  
070   Serial.print("\n");  
071   if ( attemptsRemaining == 0xFF )  
072   {  
073     // First time through  
074 Serial.print( "First time through, initializing EEPROM\n" );  
075     initializeEEPROM();  
076     Serial.print( "Locking lid\n" );  
077     lockLid();  
078     shutdown();  
079   }  
080   lcd.print( " ...Loading..." );  
081 }  
083 void loop()  
084 {  
085   waitUntil = millis() + 2000;  
086   if ( waitForBackdoor() )  
087   {  
088     /* If we get here, then the backdoor was triggered */
089     unlockLid();  
090     shutdown();  
091   }  
092   else if ( EEPROM.read( ADDR_BACKDOOR ) != 0 )  
093 {  
094     // clear the backdoor flag, if it was set from a previous  
095     // run.  this lets us try to unlock the backdoor multiple times  
096     // in case the first try jammed or something.  
097     lockLid();  
098     EEPROM.write( ADDR_BACKDOOR, 0 );  
099     shutdown();  
100   }  
102   if ( attemptsRemaining <= 0 )  
103   {  
104     lcd.clear();  
105     lcd.setCursor(0,0);  
106     lcd.print( " No More Tries!" );  
107     delay(5000);  
108     lcd.clear();  
109     lcd.setCursor(0,0);  
110     lcd.print( "   Return to" );  
111     lcd.setCursor(0,1);  
112     lcd.print( "     Russ" );  
113     delay(5000);  
114     shutdown();  
115   }  
117   // ... Normal Operation begins here  
118   bool stage1Complete = (EEPROM.read(ADDR_STAGE1) != 0);  
119   bool stage2Complete = (EEPROM.read(ADDR_STAGE2) != 0);  
121   waitUntil = millis() + 120000;  
122   if ( !stage1Complete )  
123   {  
124     lcd.clear();  
125     lcd.setCursor(0,0);  
126     lcd.print( " Searching  for " );  
127     lcd.setCursor(0,1);  
128     lcd.print( "     Signal     " );  
129     float stage1Dist = 100.0f;  
130     if ( distanceTo( TOFINO_LAT, TOFINO_LON, &stage1Dist ) )  
131     {  
132  /* If we get here, we received a valid distance measurement */
133       if ( stage1Dist < DIST_THRESHOLD )  
134       {  
135         EEPROM.write( ADDR_STAGE1, 0xFF );  
136         lcd.clear();  
137         lcd.setCursor(0,0);  
138         lcd.print( "Stage One" );  
139         lcd.setCursor(0,1);  
140         lcd.print( "Complete!");  
141         unlockDrawer();  
142       }  
143       else
144       {  
145         /* Sorry, try again */
146         decrAttemptsRemaining();  
147         lcd.clear();  
148         lcd.setCursor(0,0);  
149         lcd.print( "Access Denied!" );  
150         lcd.setCursor(0,1);  
151         lcd.print( attemptsRemaining );  
152         lcd.print( " tries left" );  
153         delay(25000);  
154         lcd.clear();  
155         lcd.setCursor(0,0);  
156         lcd.print( "Out of Range" );  
157         lcd.setCursor(0,1);  
158         lcd.print( stage1Dist );  
159         lcd.print( " km" );  
160       }  
161       delay(25000);  
162       shutdown();  
163     }  
164     else
165     {  
166       /* We never received a good GPS signal */
167       failNoSignal();  
168     }  
169   }  
170   else if ( !stage2Complete )  
171   {  
172     /* This chunk of code is just different enough from stage 1  
173        to make it awkward to write in a loop. */
174     lcd.clear();  
175     lcd.setCursor(0,0);  
176     lcd.print( " Searching  for " );  
177     lcd.setCursor(0,1);  
178     lcd.print( "     Signal     " );  
179     float stage2Dist = 100.0f;  
180     if ( distanceTo( XXXX_LAT, XXXX_LON, &stage2Dist ) )  
181     {  
182       if ( stage2Dist < DIST_THRESHOLD )  
183       {  
184         EEPROM.write( ADDR_STAGE2, 0xFF );  
185         lcd.clear();  
186         lcd.setCursor(0,0);  
187         lcd.print( "Stage Two" );  
188         lcd.setCursor(0,1);  
189         lcd.print( "Complete!" );  
190         unlockLid();  
191       }  
192       else
193       {  
194         decrAttemptsRemaining();  
195         lcd.clear();  
196         lcd.setCursor(0,0);  
197         lcd.print( "Access Denied!" );  
198         lcd.setCursor(0,1);  
199         lcd.print( attemptsRemaining );  
200         lcd.print( " tries left" );  
201         delay(25000);  
202         lcd.clear();  
203         lcd.setCursor(0,0);  
204         lcd.print( "Out of Range" );  
205         lcd.setCursor(0,1);  
206         if ( stage2Dist < 10 )  
207         {  
208           lcd.print( "? km" );  
209         }  
210         else if ( stage2Dist < 100 )  
211         {  
212           lcd.print( "?? km" );  
213         }  
214         else if (stage2Dist < 1000 )  
215         {  
216           lcd.print( "??? km" );  
217         }  
218         else
219         {  
220           lcd.print( "???? km" );  
221         }  
222       }  
223       delay(25000);  
224       shutdown();  
225     }  
226     else
227     {  
228       failNoSignal();  
229     }  
230   }  
231   else
232   {  
233     // Game Over!  
234     lcd.clear();  
235     lcd.setCursor(0,0);  
236     lcd.print( "      Game" );  
237     lcd.setCursor(0,1);  
238     lcd.print( "      Over!" );  
239     delay(10000);  
240     shutdown();  
241   }  
242   // We should never get here, but just in case...  
243   shutdown();  
244 }  
246 /*  
247  * Tries to calculate the distance to the specified lat+lon, using the GPS sensor.  
248  * Returns true iff the sensor returned a valid reading.  
249  * On successful return, result will hold the great circle distance to the specified point.  
250  */
251 bool distanceTo( float targetLat, float targetLon, float* result)  
252 {  
253   int numFixes = 0;  
254   while ( millis() < waitUntil )  
255   {  
256     if (nss.available())  
257     {  
258       int c = nss.read();  
259       if (gps.encode(c))  
260       {  
261         unsigned long fix_age;  
262         float flat,flon;  
263         gps.f_get_position(&flat, &flon, &fix_age);  
264         if ( fix_age > 60000 ) continue;  
265         if ( numFixes < 5 )  
266         {  
267           numFixes++;  
268           continue;  
269         }  
270         flat = fabs(flat);  
271         flon = fabs(flon);  
273         float dist = gcd( flat * DEG_TO_RAD, flon * DEG_TO_RAD, targetLat * DEG_TO_RAD, targetLon * DEG_TO_RAD );  
274         *result = dist;  
275         return true;  
276       }  
277     }  
278   }  
279   return false;  
280 }  
282 /*  
283  * This is a super-kludge to turn off all pin-change interrupts. 284  * It will disable all serial functionality.  Pretty much the  285  * only way to restore the Arduino to a usable state after calling this  286  * function is to cut the power and reboot.  Which is a little tricky to do  287  * if you're running on USB _and_ a battery pack.  288  *  
289  * I use this as a hack to get NewSoftSerial and SoftwareServo to play nice  290  * with each other, but I think that the latest version of NewSoftSerial has  291  * a much cleaner fix for this.  292  */
293 void disablePCI()  
294 {  
295   PCICR = 0;  
296   PCMSK2 = 0;  
297   PCMSK0 = 0;  
298   PCMSK1 = 0;  
299 }  
301 // Blocks until IR code received  302 // or expiry is reached (returns true iff code received)  303 // reads the waitUntil variable to determine how long  304 // to wait for the backdoor
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 9
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

und weiter gehts mit zeile 305:
305 bool waitForBackdoor()  
306 {  
307   uint8_t pulseCount = 0;  
308   unsigned long pulseStart;  
309   bool pulseActive;  
311   while ( millis() < waitUntil )  
312   {  
313     int irval = analogRead(IRPINA);  
314     if (irval < 0x0F)  
315     {  
316       // pulse started  
317       if ( !pulseActive )  
318       {  
319         pulseActive = true;  
320         pulseStart = millis();  
321       }  
322     }  
323     else
324     {  
325       if ( pulseActive )  
326       {  
327         pulseActive = false;  
328         unsigned long duration = millis() - pulseStart;  
329         if ( (duration > 5) && (duration < 15) )  
330         {  
331           pulseCount++;  
332         }  
333       }  
334     }  
335   }  
336   /* 4 or more pulses within the duration specified by waitUntil will unlock the backdoor. */
337   if (pulseCount >= 4)  
338   {  
339     EEPROM.write( ADDR_BACKDOOR, 0xFF );  
340     return true;  
341   }  
342   return false;  
343 }  
344    
345 /*  
346  * This function only works when the Arduino is running off a battery pack.  
347  * When running on USB, maybe stick an infinite loop at the end?  
348  */
349 void shutdown()  
350 {  
351   lcd.clear();  
352   lcd.setCursor(0,0);  
353   lcd.print( " Shutting Down.");  
354   delay(2000);  
355   digitalWrite( POLULUPIN, HIGH );  
356 }  
357    
358 void unlockDrawer()  
359 {  
360   // disablePCI _MUST_ be called prior to any servo operations!  
361   disablePCI();  
362   drawerServo.attach(DRAWERPIN);  
363   // this "stepping" is only necessary due to limitations of the Software Servo library,  364   // which is an obsolete version of the Servo library that I used before  365   // I diagnosed the problem with the pin change interrupts and never  366   // had time to replace.  
367   for ( int i = 150; i >= 5; i-- )  
368   {  
369     drawerServo.write(i);  
370     SoftwareServo::refresh();  
371     delay(15);  
372   }  
373   drawerServo.detach();  
374 }  
376 void rotateLidServo(bool lock, int steps)  
377 {  
378   disablePCI();  
379   // In my setup, the lid servo is a continuous rotation servo and so writing an angular  380   // value to it makes it go a little crazy.  
381   lidServo.attach(LIDPIN);  
382   lidServo.write((lock) ? 0 : 180);  
383   for ( int i = 0; i < steps; i++ )  
384   {  
385     SoftwareServo::refresh();  
386     delayMicroseconds(15000);  
387   }  
388   lidServo.detach();  
389 }  
391 void unlockLid()  
392 {  
393   // give it a bit more juice on the "unlock" just in case  
394   rotateLidServo(false, 10);  
395 }  
397 void lockLid()  
398 {  
399   rotateLidServo(true, 7);  
400 }  
402 /*  
403  * Great Circle Distance calculation.  If anyone knows a fixed-point version  404  * of this function I'd love to see it.  405  */
406 float gcd(float lat_a, float lon_a, float lat_b, float lon_b)  
407 {  
408   float d = acos(sin(lat_a)*sin(lat_b)+cos(lat_a)*cos(lat_b)*cos(lon_a-lon_b));  
409   return fabs(EARTH_RADIUS * d);  
410 }  
412 void decrAttemptsRemaining()  
413 {  
414   attemptsRemaining--;  
415   // save the new state.  
416   EEPROM.write(ADDR_TRIES, attemptsRemaining);  
417 }  
419 void failNoSignal()  
420 {  
421   decrAttemptsRemaining();  
422   lcd.clear();  
423   lcd.setCursor(0,0);  
424   lcd.print( "Access Denied!" );  
425   lcd.setCursor(0,1);  
426   lcd.print( attemptsRemaining );  
427   lcd.print( " tries left" );  
428   delay(5000);  
429   lcd.clear();  
430   lcd.setCursor(0,0);  
431   lcd.print( "No Signal!" );  
432   delay(5000);  
433   shutdown();  
434 }  
436 /* This function resets the box to its original state. */
437 void initializeEEPROM()  
438 {  
439   // 101 Tries remaining  
440   EEPROM.write(ADDR_TRIES, 101);  
441   EEPROM.write(ADDR_STAGE1, 0);  
442   EEPROM.write(ADDR_STAGE2, 0);  
443   EEPROM.write(ADDR_BACKDOOR, 0);  
444 }
Logged

Bremen
Offline Offline
Jr. Member
**
Karma: 0
Posts: 61
Arduino!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ja, ist ein Einheitenproblem (0,639300 dezimal = 0,38 Minuten/Sekunden...)
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 9
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Besten Dank für die Info.
Logged

Pages: [1]   Go Up
Jump to: