Advertisement
stanleyseow

Tracker 0.4

Aug 16th, 2014
363
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 25.87 KB | None | 0 0
  1. /*
  2.  
  3.  SVTrackR ( Arduino APRS Tracker )
  4.  Copyright (C) 2014 Stanley Seow <[email protected]>
  5.  
  6.  This program is free software; you can redistribute it and/or
  7.  modify it under the terms of the GNU General Public License
  8.  version 2 as published by the Free Software Foundation.
  9.  
  10.  github URL :-
  11.  https://github.com/stanleyseow/ArduinoTracker-MicroAPRS
  12.  
  13.  This sketch configure the MicroAPRS for the proper callsign and ssid and
  14.  read/write data coming in from the MicroAPRS via debug port
  15.  
  16.  Pin 0/1 (rx,tx) connects to Arduino with MicroAPRS firmware
  17.  Pin 8,9 ( rx,tx ) connects to GPS module
  18.  Pin 2,3 connect to debug serial port
  19.  
  20.  Pin 4 - Buzzer during Radio Tx
  21.  
  22.  Date : 03 July 2014
  23.  Written by Stanley Seow
  24.  Version : 0.2
  25.  
  26.  Pls flash the modem Arduino with http://unsigned.io/microaprs/ with USBtinyISP
  27.  This firmware does NOT have an Arduino bootloader and run pure AVR codes. Once you
  28.  have done this, follow the instructions on the above URL on how to set it up.
  29.  We will call this Arduino/atmega328 as the "modem".
  30.  
  31.  To use with Arduino Tracker (this sketch), connect the Modem Tx(pin1) to Arduino Rx(pin8) and
  32.  Modem Rx(pin0) to Arduino Rx(pin9).
  33.  
  34.  I had dropped bytes when using Softwaredebug for the MicroAPRS modem and therefore
  35.  I'm using AltSoftdebug instead. The GPS module is still on Softwaredebug and
  36.  the hardware debug is still used for debug Monitor.
  37.  
  38.  ***** To use this sketch, pls change your CALLSIGN and SSID below under configModem().
  39.  
  40.  History :-
  41.  03 July 2014 :-
  42.  - Initial released
  43.  
  44.  06 July 2014 :-
  45.  - added checks for speed and idle speed, modify the Txinternal
  46.  - remove all debug Monitor output
  47.  
  48.  12 July 2014 :-
  49.  - Added SmartBeaconing algorithm, Tx when turn is more than 25 deg
  50.  - Reduce the Tx interval
  51.  
  52.  14 July 2014 :-
  53.  - Fixed coordinates conversion from decimal to Deg Min formula
  54.  - Formula to calculate distance from last Tx point so that it will Tx once the max direct distance
  55.   of 500m is reached
  56.  
  57.  18 July 2014 :-
  58.  - Fixed lastTx checking routine and ensure lastTx is 5 or more secs
  59.  - Check for analog0 button at least 10 secs per Tx
  60.  - Rewrote the DecodeAPRS functions for display to LCD only
  61.  
  62.  1 Aug 2014 :-
  63.  - Ported codes to Arduino Mini Pro 3.3V
  64.  - Due to checksum errors and Mini Pro 3.3V 8Mhz on SoftwareSerial, I swapped GPS ports to AltSoftwareSerial
  65.  
  66.  3 Aug 2014 :-
  67.  - Added #define codes to turn on/off LCD, DEBUG and TFT
  68.  - Added TFT codes for 2.2" SPI TFT ( runs on 3.3V )
  69.  - Added the F() macros to reduce memory usages on static texts
  70.  
  71.  6 Aug 2014
  72.  - Added Course/Speed/Alt into comment field readable by aprs.fi
  73.  
  74.  10 Aug 2014
  75.  - Added support for teensy 3.1 (mcu ARM Cortex M4)
  76.  
  77.  TODO :-
  78.  - implement compression / decompression codes for smaller Tx packets
  79.  - Telemetry packets
  80.  - Split comments and location for smaller Tx packets
  81.  
  82.  Bugs :-
  83.  
  84.  - Not splitting callsign and info properly
  85.  - Packets received from Modem is split into two serial read
  86.  - With TFT codes, the AltSoftSerial could not get the speed and course on time with lots of checksum errors
  87.  -
  88.  
  89. */
  90.  
  91. // Needed this to prevent compile error for #defines
  92. #if 1
  93. __asm volatile ("nop");
  94. #endif
  95.  
  96. #if defined(__arm__) && defined(TEENSYDUINO)
  97.     // should use uinstd.h to define sbrk but Due causes a conflict
  98.     extern "C" char* sbrk(int incr);
  99. #else  // this is for AVR
  100.     extern char *__brkval;
  101.     extern char __bss_end;
  102. #endif  
  103.  
  104. // Turn on/off 20x4 LCD
  105. #undef LCD20x4
  106. // Turn on/off debug
  107. #define DEBUG
  108. // Turn on/off 2.2" TFT
  109. #undef TFT22
  110.  
  111. #ifdef TFT22
  112. #include <SPI.h>
  113. #include <Adafruit_GFX.h>
  114. #include <Adafruit_ILI9340.h>
  115. #define _sclk 13
  116. #define _miso 12
  117. #define _mosi 11
  118. #define _cs 7
  119. #define _dc 6
  120. #define _rst 5
  121. Adafruit_ILI9340 tft = Adafruit_ILI9340(_cs, _dc, _rst);
  122. #endif
  123.  
  124. #ifdef DEBUG
  125.   #if defined(__arm__) && defined(TEENSYDUINO)
  126.   #else
  127.   #include <SoftwareSerial.h>
  128.   #endif
  129. #endif
  130.  
  131. // Only needed for ATmega328
  132. #if defined (__AVR_ATmega328P__)
  133. #include <AltSoftSerial.h>
  134. #endif
  135.  
  136. #include <TinyGPS++.h>
  137.  
  138. #ifdef LCD20x4
  139. // My wiring for LCD on breadboard
  140. #include <LiquidCrystal.h>
  141. LiquidCrystal lcd(12, 11, 4, 5, 6, 7);
  142. #endif
  143.  
  144. #define VERSION "SVTrackR v0.4 "
  145.  
  146. // Altdebug default on UNO is 8-Rx, 9-Tx
  147. //AltSoftSerial ss;
  148. #if defined (__AVR_ATmega328P__)
  149.   AltSoftSerial ss(8,9);
  150. #else
  151. // Map hw Serial2 to ss for gps port
  152.   #define ss Serial2
  153. #endif
  154.  
  155. TinyGPSPlus gps;
  156.  
  157. #ifdef DEBUG
  158. // Connect to GPS module on pin 9, 10 ( Rx, Tx )
  159.   #if defined (__AVR_ATmega328P__)
  160.     SoftwareSerial debug(2,3);
  161.   #else
  162.     #define debug Serial3
  163.   #endif
  164. #endif
  165.  
  166. // Pin for Tx buzzer
  167. const byte buzzerPin = 4;
  168. unsigned int txCounter = 0;
  169. unsigned long txTimer = 0;
  170. unsigned long lastTx = 0;
  171. unsigned long txInterval = 80000L;  // Initial 60 secs internal
  172.  
  173. int lastCourse = 0;
  174. byte lastSpeed = 0;
  175.  
  176. int previousHeading, currentHeading = 0;
  177. // Initial lat/lng pos, change to your base station coordnates
  178. float lastTxLat = 3.16925, lastTxLng =  101.64972;
  179. float lastTxdistance, homeDistance = 0.0;
  180.  
  181. const unsigned int MAX_DEBUG_INPUT = 30;
  182.  
  183. void setup()
  184. {
  185. #ifdef LCD20x4  
  186.   // LCD format is Col,Row for 20x4 LCD
  187.   lcd.begin(20,4);
  188.   lcd.clear();
  189.   lcd.setCursor(0,0);
  190.   lcd.print("Arduino OpenTrackR");
  191. #endif  
  192.  
  193. #ifdef TFT22
  194.   tft.begin();    
  195.   tft.setRotation(1);
  196.   tft.setCursor(0,0);
  197.   tft.setTextSize(3);
  198.   tft.setTextColor(ILI9340_WHITE);  
  199.   tft.print("OpenTrackR");
  200.   delay(1000);
  201.   tft.fillScreen(ILI9340_BLACK);
  202.  
  203. #endif
  204.  
  205. // This is for buzzer
  206. //pinMode(4, OUTPUT);
  207.  
  208.   Serial.begin(9600);
  209. #ifdef DEBUG
  210.   debug.begin(9600);
  211. #endif
  212.   ss.begin(9600);
  213.  
  214. #ifdef DEBUG
  215.   debug.flush();
  216.   debug.println();
  217.   debug.println();
  218.   debug.println(F("=========================================="));
  219.   debug.print(F("DEBUG:- "));
  220.   debug.println(F(VERSION));
  221.   debug.println(F("=========================================="));
  222.   debug.println();
  223. #endif
  224.  
  225.   // Set a delay for the MicroAPRS to boot up before configuring it
  226.   delay(1000);
  227.   configModem();
  228.  
  229.   txTimer = millis();
  230.  
  231. } // end setup()
  232.  
  233.  
  234. ///////////////////////////////////////////////////////////////////////////////////////////////////////
  235. void loop()
  236. {
  237.     // Speed in km/h
  238.     const byte highSpeed = 80;       // High speed  
  239.     const byte lowSpeed = 30;        // Low speed
  240.     char c;
  241.     boolean inputComplete = false;
  242.     int headingDelta = 0;
  243.     const double HOME_LAT = 3.16925 , HOME_LON = 101.64972;
  244.    
  245. #ifdef DEBUG    
  246.     // Send commands from debug serial into hw Serial char by char
  247. #if defined (__AVR_ATmega328P__)    
  248.     debug.listen();
  249. #endif  
  250.     if ( debug.available() > 0  ) {
  251.           processIncomingDebug(debug.read());
  252.     }
  253. #endif    
  254.    
  255.     // Turn on listen() on GPS
  256. #if defined (__AVR_ATmega328P__)        
  257.     ss.listen();  
  258. #endif    
  259.     while ( ss.available() > 0 ) {
  260.       gps.encode(ss.read());
  261.     }
  262.    
  263. ///////////////// Triggered by location updates ///////////////////////
  264.    if ( gps.location.isUpdated() ) {
  265.  
  266.      homeDistance = TinyGPSPlus::distanceBetween(
  267.           gps.location.lat(),
  268.           gps.location.lng(),
  269.           HOME_LAT,
  270.           HOME_LON);  
  271.          
  272.     lastTxdistance = TinyGPSPlus::distanceBetween(
  273.           gps.location.lat(),
  274.           gps.location.lng(),
  275.           lastTxLat,
  276.           lastTxLng);
  277.      
  278.     } // endof gps.location.isUpdated()
  279.  
  280. ///////////////// Triggered by time updates ///////////////////////
  281. // Update LCD every second
  282.  
  283.    if ( gps.time.isUpdated() ) {  
  284.    
  285.    // Turn on LED 13 when Satellites more than 3  
  286.    // Disable when using TFT / SPI
  287.    if ( gps.satellites.value() > 3 ) {
  288.      digitalWrite(13,HIGH);  
  289.    } else {
  290.      digitalWrite(13,LOW);    
  291.    }
  292.  
  293. #ifdef TFT22
  294.       //tft.fillScreen(ILI9340_BLACK);
  295.       tft.setCursor(0,0);
  296.  
  297.       tft.setTextSize(3);      
  298.       tft.setTextColor(ILI9340_CYAN);  
  299.       tft.print("9W2");    
  300.       tft.setTextColor(ILI9340_YELLOW);  
  301.       tft.print("SVT");  
  302.      
  303.       tft.setTextColor(ILI9340_RED);  
  304.       tft.print("APRS");  
  305.      
  306.       tft.setTextColor(ILI9340_GREEN);  
  307.       tft.println("TrackR");  
  308.  
  309.       tft.setCursor(0,22);
  310.       tft.setTextSize(2);
  311.       tft.setTextColor(ILI9340_WHITE);  
  312.       tft.print("Date:");
  313.       tft.setTextColor(ILI9340_YELLOW);
  314.       tft.print(gps.date.value());
  315.       tft.setTextColor(ILI9340_WHITE);
  316.       tft.print(" Time:");
  317.       tft.setTextColor(ILI9340_YELLOW);
  318.       tft.println(gps.time.value());
  319.      
  320.       tft.setCursor(0,32);
  321.       tft.setTextSize(3);
  322.       tft.setTextColor(ILI9340_WHITE);
  323.       tft.print("Lat:");
  324.       tft.setTextColor(ILI9340_GREEN);  
  325.       tft.println(gps.location.lat(),5);
  326.  
  327.       tft.setCursor(0,52);      
  328.       tft.setTextColor(ILI9340_WHITE);    
  329.       tft.print("Lng:");
  330.       tft.setTextColor(ILI9340_GREEN);  
  331.       tft.println(gps.location.lng(),5);
  332.  
  333.       tft.setCursor(0,100);
  334.       tft.setTextSize(2);      
  335.       tft.setTextColor(ILI9340_WHITE);  
  336.       tft.print("Sats:");
  337.       tft.setTextColor(ILI9340_CYAN);
  338.       tft.print(gps.satellites.value());
  339.      
  340.       tft.setTextColor(ILI9340_WHITE);
  341.       tft.print(" HDOP:");
  342.       tft.setTextColor(ILI9340_CYAN);
  343.       tft.print(gps.hdop.value());
  344.      
  345.       tft.setTextColor(ILI9340_WHITE);
  346.       tft.print(" Alt:");
  347.       tft.setTextColor(ILI9340_CYAN);
  348.       tft.println((int)gps.altitude.meters());
  349.  
  350.       tft.setCursor(0,100);
  351.       tft.setTextSize(2);      
  352.       tft.setTextColor(ILI9340_WHITE);
  353.       tft.print("Speed:");
  354.       tft.setTextColor(ILI9340_CYAN);
  355.       tft.print(gps.speed.kmph());
  356.  
  357.       tft.setTextColor(ILI9340_WHITE);
  358.       tft.print(" Deg:");
  359.       tft.setTextColor(ILI9340_CYAN);
  360.       tft.println(gps.course.deg());
  361.      
  362.       tft.setTextSize(1);      
  363.       tft.setTextColor(ILI9340_WHITE);
  364.       tft.print("Passed:");
  365.       tft.setTextColor(ILI9340_CYAN);
  366.       tft.print(gps.passedChecksum());
  367.  
  368.       tft.setTextColor(ILI9340_WHITE);
  369.       tft.print(" Failed:");
  370.       tft.setTextColor(ILI9340_CYAN);
  371.       tft.println(gps.failedChecksum());      
  372. #endif
  373.  
  374. #ifdef LCD20x4
  375.      lcd.setCursor(1,0);
  376.      lcd.print("   ");
  377.      lcd.setCursor(1,0);
  378.      lcd.print(txCounter);
  379.  
  380.      lcd.setCursor(4,0);
  381.      lcd.print("       ");
  382.      lcd.setCursor(4,0);
  383.      lcd.print(lastTx);
  384.      
  385.      lcd.setCursor(10,0);
  386.      lcd.print("    ");  
  387.      lcd.setCursor(10,0);
  388.      lcd.print((int)lastTxdistance);    
  389.  
  390.      lcd.setCursor(14,0);
  391.      lcd.print("    ");  
  392.      lcd.setCursor(14,0);
  393.      lcd.print((float)homeDistance/1000,1);
  394.      
  395.      lcd.setCursor(18,0);  
  396.      lcd.print("  ");
  397.      lcd.setCursor(18,0);  
  398.      lcd.print(gps.satellites.value());
  399. #endif
  400.      
  401. // Change the Tx internal based on the current speed
  402. // This change will not affect the countdown timer
  403. // Based on HamHUB Smart Beaconing(tm) algorithm
  404.  
  405.       if ( gps.speed.kmph() < 5 ) {
  406.             txInterval = 300000;         // Change Tx internal to 5 mins
  407.        } else if ( gps.speed.kmph() < lowSpeed ) {
  408.             txInterval = 70000;          // Change Tx interval to 60
  409.        } else if ( gps.speed.kmph() > highSpeed ) {
  410.             txInterval = 30000;          // Change Tx interval to 30 secs
  411.        } else {
  412.         // Interval inbetween low and high speed
  413.             txInterval = (highSpeed / gps.speed.kmph()) * 30000;      
  414.        } // endif
  415.      
  416.    }  // endof gps.time.isUpdated()
  417.      
  418.    
  419. ///////////////// Triggered by course updates ///////////////////////
  420.      
  421.     if ( gps.course.isUpdated() ) {
  422.      
  423.       // Get headings and heading delta
  424.       currentHeading = (int) gps.course.deg();
  425.       if ( currentHeading >= 180 ) { currentHeading = currentHeading-180; }
  426.      
  427.       headingDelta = (int) ( previousHeading - currentHeading ) % 360;
  428.     } // endof gps.course.isUpdated()
  429.  
  430.          
  431.  ////////////////////////////////////////////////////////////////////////////////////
  432.  // Check for when to Tx packet
  433.  ////////////////////////////////////////////////////////////////////////////////////
  434.  
  435.   lastTx = 0;
  436.   lastTx = millis() - txTimer;
  437.  
  438.     if ( (lastTx > 5000)  && (gps.satellites.value() > 3) ) {
  439.         // Check for heading more than 25 degrees
  440.         if ( headingDelta < -25 || headingDelta >  25 ) {
  441. #ifdef DEBUG          
  442.             //debug.println();        
  443.             //debug.print(F("Heading, current:"));      
  444.             //debug.print(currentHeading);
  445.             //debug.print(F(" previous:"));      
  446.             //debug.print(previousHeading);
  447.             //debug.print(F(" delta:"));      
  448.             //debug.println(headingDelta);        
  449.             debug.print(F("*** Heading Change "));
  450.             debug.println(txCounter);
  451. #endif            
  452. #ifdef LCD20x4            
  453.             lcd.setCursor(0,0);
  454.             lcd.print("H");  
  455. #endif            
  456.             TxtoRadio();
  457.             previousHeading = currentHeading;
  458.             // Reset the txTimer & lastTX for the below if statements
  459.             txTimer = millis();
  460.             lastTx = millis() - txTimer;
  461.         } // endif headingDelta
  462.     } // endif lastTx > 5000
  463.    
  464.     if ( (lastTx > 10000) && (gps.satellites.value() > 3) ) {
  465.          // check of the last Tx distance is more than 500m
  466.          if ( lastTxdistance > 500 ) {  
  467. #ifdef DEBUG                    
  468.             debug.println();
  469.             debug.print(F("*** Distance > 500m "));
  470.             debug.println(txCounter);  
  471.             debug.print(F("lastTxdistance:"));
  472.             debug.print(lastTxdistance);
  473. #endif          
  474. #ifdef LCD20x4                        
  475.             lcd.setCursor(0,0);
  476.             lcd.print("D");
  477. #endif            
  478.             TxtoRadio();
  479.             lastTxdistance = 0;   // Ensure this value is zero before the next Tx
  480.             // Reset the txTimer & lastTX for the below if statements            
  481.             txTimer = millis();
  482.             lastTx = millis() - txTimer;
  483.          } // endif lastTxdistance
  484.     } // endif lastTx > 10000
  485.    
  486.     if ( (lastTx >= txInterval) && ( gps.satellites.value() > 3) ) {
  487.         // Trigger Tx Tracker when Tx interval is reach
  488.         // Will not Tx if stationary bcos speed < 5 and lastTxDistance < 20
  489.         if ( lastTxdistance > 20 ) {
  490. #ifdef DEBUG                    
  491.                    debug.println();
  492.                    debug.print(F("lastTx:"));
  493.                    debug.print(lastTx);
  494.                    debug.print(F(" txInterval:"));
  495.                    debug.print(txInterval);    
  496.                    debug.print(F(" lastTxdistance:"));
  497.                    debug.println(lastTxdistance);              
  498.                    debug.print(F("*** txInterval "));  
  499.                    debug.println(txCounter);  
  500.  
  501. #endif                  
  502. #ifdef LCD20x4            
  503.                    lcd.setCursor(0,0);
  504.                    lcd.print("T");    
  505. #endif                  
  506.                    TxtoRadio();
  507.                    
  508.                    // Reset the txTimer & lastTX for the below if statements  
  509.                    txTimer = millis();
  510.                    lastTx = millis() - txTimer;
  511.         } // endif lastTxdistance > 20
  512.     } // endif of check for lastTx > txInterval
  513.  
  514.     // Check if the analog0 is plugged into 5V and more than 10 secs
  515.     if ( analogRead(0) > 700 && (lastTx > 10000) ) {
  516. #ifdef DEBUG                
  517.                 debug.println();            
  518.                 debug.println(analogRead(0));
  519.                 debug.print(F("*** Button "));
  520.                 debug.println(txCounter);  
  521.  
  522. #endif                
  523. #ifdef LCD20x4                            
  524.                 lcd.setCursor(0,0);
  525.                 lcd.print("B");    
  526. #endif                    
  527.                 TxtoRadio();
  528.                 // Reset the txTimer & lastTX for the below if statements  
  529.                 txTimer = millis();
  530.                 lastTx = millis() - txTimer;
  531.      } // endif check analog0
  532.  
  533.  
  534.      
  535. } // end loop()
  536.  
  537. ///////////////////////////////////////////////////////////////////////////////////////////////////////
  538.  
  539. void serialEvent() {
  540. // Disable Serial Decode  
  541. //    decodeAPRS();
  542. }
  543.  
  544. void TxtoRadio() {
  545.  
  546.      char tmp[10];
  547.      float latDegMin, lngDegMin = 0.0;
  548.      String latOut, lngOut, cmtOut = "";
  549.  
  550.      txCounter++;
  551.      
  552.      lastTxLat = gps.location.lat();
  553.      lastTxLng = gps.location.lng();
  554.  
  555.       // This prevent ANY condition to Tx below 5 secs
  556.      if ( lastTx >= 5000 ) {
  557. #ifdef DEBUG                
  558.        debug.print("Time/Date: ");
  559.        byte hour = gps.time.hour() +8; // GMT+8 is my timezone
  560.        byte day = gps.date.day();
  561.        
  562.        if ( hour > 23 ) {
  563.            hour = hour -24;
  564.            day++;
  565.        }  
  566.        if ( hour < 10 ) {
  567.        debug.print("0");      
  568.        }      
  569.        debug.print(hour);        
  570.        debug.print(":");  
  571.        if ( gps.time.minute() < 10 ) {
  572.        debug.print("0");      
  573.        }
  574.        debug.print(gps.time.minute());
  575.        debug.print(":");
  576.        if ( gps.time.second() < 10 ) {
  577.        debug.print("0");      
  578.        }      
  579.        debug.print(gps.time.second());
  580.        debug.print(" ");
  581.  
  582.        if ( day < 10 ) {
  583.        debug.print("0");
  584.        }        
  585.        debug.print(day);
  586.        debug.print("/");
  587.        if ( gps.date.month() < 10 ) {
  588.        debug.print("0");      
  589.        }
  590.        debug.print(gps.date.month());
  591.        debug.print("/");
  592.        debug.print(gps.date.year());
  593.        debug.println();
  594.  
  595.        debug.print("GPS: ");
  596.        debug.print(lastTxLat,5);
  597.        debug.print(" ");
  598.        debug.print(lastTxLng,5);
  599.        debug.println();
  600.  
  601.        debug.print("Sat:");          
  602.        debug.print(gps.satellites.value());
  603.        debug.print(" HDOP:");
  604.        debug.print(gps.hdop.value());
  605.        debug.print(" km/h:");          
  606.        debug.print((int) gps.speed.kmph());
  607.        debug.print(" Head:");
  608.        debug.print((int) gps.course.deg());          
  609.        debug.print(" Alt:");
  610.        debug.print(gps.altitude.meters());
  611.        debug.print("m");
  612.        debug.println();
  613.  
  614.        debug.print(F("Distance(m): Home:"));
  615.        debug.print(homeDistance,2);
  616.        debug.print(" Last:");  
  617.        debug.print(lastTxdistance,2);
  618.        debug.println();
  619.      
  620.        debug.print(F("Tx since "));  
  621.        debug.print((float)lastTx/1000);
  622.        debug.println(" sec");  
  623. #endif            
  624.        // Turn on the buzzer
  625.        digitalWrite(buzzerPin,HIGH);  
  626.          
  627.        latDegMin = convertDegMin(lastTxLat);
  628.        lngDegMin = convertDegMin(lastTxLng);
  629.  
  630.        dtostrf(latDegMin, 2, 2, tmp );
  631.        latOut.concat("lla0");      // set latitute command with the 0
  632.        latOut.concat(tmp);
  633.        latOut.concat("N");
  634.      
  635.        dtostrf(lngDegMin, 2, 2, tmp );
  636.        lngOut.concat("llo");       // set longtitute command
  637.        lngOut.concat(tmp);
  638.        lngOut.concat("E");
  639.      
  640.        cmtOut.concat("@");
  641.        cmtOut.concat(padding((int) gps.course.deg(),3));
  642.        cmtOut.concat("/");
  643.        cmtOut.concat(padding((int)gps.speed.mph(),3));
  644.        cmtOut.concat("/A=");
  645.        cmtOut.concat(padding((int)gps.altitude.feet(),6));
  646.        cmtOut.concat(" ");
  647.        cmtOut.concat(VERSION);      
  648.        cmtOut.concat((long) readVcc()/1000);
  649.        cmtOut.concat("V ");
  650.        cmtOut.concat(gps.hdop.value());
  651.        cmtOut.concat("/");
  652.        cmtOut.concat(gps.satellites.value());
  653.        
  654.  
  655. #ifdef DEBUG          
  656.        debug.print("TX STR: ");
  657.        debug.print(latOut);
  658.        debug.print(" ");          
  659.        debug.print(lngOut);
  660.        debug.println();
  661.        debug.print(cmtOut);  
  662.        debug.println();
  663. #endif    
  664.  
  665.        Serial.println(latOut);
  666.        delay(300);
  667.        Serial.println(lngOut);
  668.        delay(300);
  669.        Serial.println(cmtOut);
  670.        delay(300);
  671.                  
  672.        digitalWrite(buzzerPin,LOW);    
  673.        // Reset the txTimer & Tx internal  
  674.    
  675.        txInterval = 80000;
  676.        lastTx = 0;
  677. #ifdef DEBUG              
  678.        debug.print(F("FreeRAM:"));
  679.        debug.print(freeRam());
  680.        debug.print(" Uptime:");
  681.        debug.println((float) millis()/1000);
  682.        debug.println(F("=========================================="));
  683. #endif    
  684.      
  685.      } // endif lastTX
  686.      
  687. } // endof TxtoRadio()
  688.  
  689. ///////////////////////////////////////////////////////////////////////////////////////////////////////
  690.  
  691. void processDebugData(const char * data) {
  692.   // Send commands to modem
  693.   Serial.println(data);
  694. }  // end of processDebugData
  695.  
  696. ///////////////////////////////////////////////////////////////////////////////////////////////////////
  697.  
  698.  
  699. void processIncomingDebug(const byte inByte) {
  700.  
  701.   static char input_line [MAX_DEBUG_INPUT];
  702.   static unsigned int input_pos = 0;
  703.  
  704.   switch (inByte)
  705.     {
  706.     case '\n':   // end of text
  707.       input_line[input_pos] = 0;  // terminating null byte
  708.       // terminator reached! Process the data
  709.       processDebugData(input_line);
  710.       // reset buffer for next time
  711.       input_pos = 0;  
  712.       break;
  713.     case '\r':   // discard carriage return
  714.       break;
  715.     default:
  716.       // keep adding if not full ... allow for terminating null byte
  717.       if (input_pos < (MAX_DEBUG_INPUT - 1))
  718.         input_line [input_pos++] = inByte;
  719.       break;
  720.     }  // end of switch
  721.    
  722. } // endof processIncomingByte  
  723.  
  724. ///////////////////////////////////////////////////////////////////////////////////////////////////////
  725.  
  726.  
  727. void configModem() {
  728. // Functions to configure the callsign, ssid, path and other settings
  729. // c<callsign>
  730. // sc<ssid>
  731. // pd0 - turn off DST display
  732. // pp0 - turn on PATH display
  733.  
  734. /*
  735. #ifdef LCD20x4                            
  736.   lcd.setCursor(0,0);
  737.   lcd.print("Configuring modem");
  738.   lcd.setCursor(0,0);
  739.   lcd.print("Setting callsig");
  740. #endif                            
  741. */
  742.  
  743.   Serial.println("c9W2SVT");  // Set SRC Callsign ,PLEASE CHANGE THIS TOI YOUR CALLSIGN
  744.   delay(200);
  745.   Serial.println("sc8");      // Set SRC SSID
  746.   delay(200);
  747.   Serial.println("pd0");      // Disable printing DST
  748.   delay(200);
  749.   Serial.println("pp0");      // Disable printing PATH
  750.   delay(200);
  751.   Serial.println("lsn");      // Set symbol n / Bluedot
  752.   delay(200);
  753.   Serial.println("lts");      // Standard symbol
  754.   delay(200);
  755.   Serial.println("V1");      // Silent Mode ON
  756.   delay(200);
  757.   //Serial.println("H");        // Print out the Settings
  758.   //Serial.println("S");        // Save config
  759.  
  760. #ifdef LCD20x4                              
  761.   lcd.setCursor(0,0);
  762.   lcd.print("Done................");
  763.   delay(500);
  764.   lcd.clear();
  765. #endif                            
  766.  
  767. }
  768.  
  769. ///////////////////////////////////////////////////////////////////////////////////////////////////////
  770.  
  771. void decodeAPRS() {
  772.       // Dump whatever on the Serial to LCD line 1
  773.       char c;
  774.       String decoded="";
  775.       int callIndex,callIndex2, dataIndex = 0;
  776.  
  777.       while ( Serial.available() > 0 ) {
  778.          c = Serial.read();
  779. //#ifdef DEBUG        
  780. //         debug.print(c);
  781. //#endif        
  782.          decoded.concat(c);
  783.       }  
  784.  
  785. #ifdef DEBUG  
  786.       debug.print("Decoded Packets:");
  787.       debug.println(decoded);
  788. #endif  
  789.       callIndex = decoded.indexOf("[");
  790.       callIndex2 = decoded.indexOf("]");
  791.       String callsign = decoded.substring(callIndex+1,callIndex2);
  792.      
  793.       dataIndex = decoded.indexOf("DATA:");
  794.       String data = decoded.substring(dataIndex+6,decoded.length());
  795.  
  796.       String line1 = data.substring(0,20);
  797.       String line2 = data.substring(21,40);
  798.      
  799. #ifdef LCD20x4                                  
  800.       lcd.setCursor(0,1);
  801.       lcd.print("                    ");
  802.       lcd.setCursor(0,1);
  803.       lcd.print(callsign);
  804.       lcd.setCursor(0,2);
  805.       lcd.print("                    ");
  806.       lcd.setCursor(0,2);      
  807.       lcd.print(line1);
  808.       lcd.setCursor(0,3);
  809.       lcd.print("                    ");
  810.       lcd.setCursor(0,3);
  811.       lcd.print(line2);
  812. #endif      
  813.  
  814. #ifdef DEBUG        
  815.          debug.print(F("Callsign:"));
  816.          debug.println(callsign);
  817.          debug.print(F("Data:"));
  818.          debug.println(data);
  819. #endif  
  820.  
  821. #ifdef TFT22
  822.       tft.drawLine(0,199,319,199, ILI9340_WHITE);
  823.       tft.setCursor(0,200);
  824.       tft.setTextSize(2);      
  825.       tft.setTextColor(ILI9340_GREEN);  
  826.       tft.print("Callsign:");
  827.       tft.setTextColor(ILI9340_CYAN);
  828.       tft.print(callsign);
  829.      
  830.       tft.setTextColor(ILI9340_WHITE);  
  831.       tft.print(" Data:");
  832.       tft.setTextColor(ILI9340_CYAN);
  833.       tft.println(data);  
  834.  
  835. #endif
  836.  
  837. }
  838.  
  839. ///////////////////////////////////////////////////////////////////////////////////////////////////////
  840.  
  841. float convertDegMin(float decDeg) {
  842.  
  843.   float DegMin;
  844.  
  845.   int intDeg = decDeg;
  846.   decDeg -= intDeg;
  847.   decDeg *= 60;
  848.   DegMin = ( intDeg*100 ) + decDeg;
  849.  
  850.  return DegMin;
  851. }
  852.  
  853. ///////////////////////////////////////////////////////////////////////////////////////////////////////
  854.  
  855. long readVcc() {                
  856.   long result;
  857. #if defined (__AVR_ATmega328P__)      
  858.   // Read 1.1V reference against AVcc
  859.   ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
  860.   delay(2);                     // Wait for Vref to settle
  861.   ADCSRA |= _BV(ADSC); // Convert
  862.   while (bit_is_set(ADCSRA,ADSC));
  863.   result = ADCL;
  864.   result |= ADCH<<8;
  865.   result = 1126400L / result; // Back-calculate AVcc in mV
  866. #endif  
  867.   return result;
  868. }
  869.  
  870. String padding( int number, byte width ) {
  871.   String result;
  872.  
  873.   // Prevent a log10(0) = infinity
  874.   int temp = number;
  875.   if (!temp) { temp++; }
  876.    
  877.   for ( int i=0;i<width-(log10(temp))-1;i++) {
  878.        result.concat('0');
  879.   }
  880.   result.concat(number);
  881.   return result;
  882. }
  883.  
  884.  
  885. int freeRam() {
  886.     char top;
  887.     #if defined(__arm__) && defined(TEENSYDUINO)
  888.         return &top - reinterpret_cast<char*>(sbrk(0));
  889.     #else  // non ARM, this is AVR
  890.         return __brkval ? &top - __brkval : &top - &__bss_end;
  891.     #endif  
  892. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement