0
Offline
Newbie
Karma: 0
Posts: 9
Arduino rocks
|
 |
« Reply #1 on: April 16, 2010, 11:51:46 am » |
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
|