2012-04-19 93 views
0

我正在開發GPS記錄器項目。我有一個Arduino Mega設置發射器和接收器和GPS和GSM模塊。我也有一個Arduino Uno與發射器,接收器和蜂鳴器。如何發送文本文件並使用Arduino添加它

當兩個設備彼此距離太遠時,GPS數據將被拉出並通過GSM模塊發送到我的網絡服務器。當我將文件發送到服務器時,它會創建一個文本文件,當我移動到另一個位置時,它會覆蓋以前的位置。

我想弄清楚如何附加文本文件,而不是覆蓋它。我發現了很多東西使用SD卡盾牌,但沒有它沒有。

#define GPS_PIN_1  9  // GPS serial pin RX 
#define GPS_PIN_2  8  // GPS serial pin TX 
#define CHECKPIN  13  // Pin that lights up when things are checked 
#define GPSRATE   4800 // GPS baud rate 

#include <SoftwareSerial.h> 
#include <Flash.h> 
#include <Streaming.h> 

// How many bytes of input to buffer from the GPS? 
#define BUFFERSIZE  100  
#define ENDLN   

int rx1Pin=31; 
int txPin=30; 
int tx1Pin=11; 
int onModulePin = 2; 
int rxPin=12; 
SoftwareSerial mySerial = SoftwareSerial(GPS_PIN_1, GPS_PIN_2); //(rx,tx) 
SoftwareSerial txSerial = SoftwareSerial(rxPin, txPin); 
SoftwareSerial rxSerial = SoftwareSerial(rx1Pin, tx1Pin); 
char sendChar ='H'; 
char incomingChar = 0; 
int counter=0; 

//GPS variables 
int numSats = 0; 
int fixType = 0; 
int time[] = { 
    0, 0, 0}; 
double latitude = 0.0; 
double longitude = 0.0; 
long altitude = 0; 
long maxAlt = 0; 
int speed = 0; 
int txCount = 0; 
int ExOnce = 0; 
int FalcomCheck = 0; 
int LogCheck =0; 
unsigned long GpsOffTime = 0; 
unsigned long SmsStart = 0;  // SMS-time 
char buffer[BUFFERSIZE]; 

void switchModule(){   // Function to switch the module ON; 
    digitalWrite(onModulePin,HIGH); 
    delay(2000); 
    digitalWrite(onModulePin,LOW); 
    delay(2000); 
} 

void setup(){ 
    pinMode(rxPin, INPUT); 
    pinMode(txPin,OUTPUT); 
    pinMode(rx1Pin, INPUT); 
    pinMode(tx1Pin,OUTPUT); 
    pinMode(GPS_PIN_1, INPUT); 
    pinMode(GPS_PIN_2, OUTPUT); 
    pinMode(7, OUTPUT); 
    pinMode(13, OUTPUT); 
    digitalWrite(7, HIGH); 
    pinMode(onModulePin, OUTPUT); 

    txSerial.begin(4800); 
    rxSerial.begin(4800); 
    mySerial.begin(4800); 
    Serial.begin(19200);  // The GPRS baud rate 
    switchModule();   // Switch the module ON 

    for (int i=0;i<2;i++){ // Wait 20 sec for connection 
    delay(10000);       
    } 
} 

void loop(){ 
    txSerial.println(sendChar); 
    Serial.println(sendChar); 

    for(int i=0; i<6; i++) { 
    incomingChar = rxSerial.read(); //Read incoming message from TX. 

    if (incomingChar =='L') { 
     GPS();//Serial.println("It Works"); 
    } 
    } 
} 

void GPS(){ 
    Serial.flush(); 

    // Get a GGA string from the GPS, and 
    // check if it's a valid fix, and extract the data. 
    getNMEA("$GPGGA");  
    delay(100); 
    numSats = getSats(); 
    fixType = getFixType(); 
    // Make sure we have a valid fix 
    if (fixType != 0) { 
    getTime(time); 
    latitude = getLat(); 
    longitude = getLong(); 
    altitude = getAlt(); 

    // Keep track of the maximum altitude 
    }  

    // Convert latitude and longitude into strings. 
    char latString[12]; 
    char longString[12]; 
    doubleToString(latitude, 4, latString); 
    doubleToString(longitude, 4, longString); 

    sprintf(buffer, "%02d:%02d:%02d,%s,%s,%ld", 
    time[0], time[1], time[2], latString, longString, altitude); 
    Serial.println(buffer); 

    if (fixType > 0) { 
    if (ExOnce==0){ 
     digitalWrite(13, HIGH); 
     //ExOnce=1; 
     sendsms(); 
     logftp(); 
     // for (int i=0; i<3; i++) { // Wait 30 sec for a connection. 
     // delay(10000);       
     // } 
    } 
    } 

    delay(200); 
} 

void sendsms(){ 
    Serial.println("AT+CMGF=1");   // Set the SMS mode to text. 
    delay(500); 
    Serial.print("AT+CMGS=");   // Send the SMS the number. 
    Serial.print(34,BYTE);    // Send the " char. 
    Serial.print("**********");   // Send the number change ********* 
             // by the actual number. 
    Serial.println(34,BYTE);    // Send the " char. 
    delay(1500); 
    Serial.print("Hi this is the General text testing."); // The SMS body 
    delay(500); 
    Serial.print(0x1A,BYTE);    // End of message command 1A (hex) 

    delay(20000); 
} 

void logftp(){ 
    Serial.println("AT&k3");   // Flow activate 

    delay(1000); 
    Serial.print("AT+KCNXCFG=0,");  // Connect to GPRS 
    Serial.print(34,BYTE); 
    Serial.print("GPRS"); 
    Serial.print(34,BYTE); 
    Serial.print(","); 
    Serial.print(34,BYTE); 
    //Serial.print("wap.cingular"); 
    Serial.print("epc.tmobile.com"); 
    Serial.print(34,BYTE); 
    Serial.print(","); 
    Serial.print(34,BYTE); 
    Serial.print(34,BYTE); 
    Serial.print(","); 
    Serial.print(34,BYTE); 
    Serial.println(34,BYTE); 

    delay(1000); 
    Serial.println("AT+KCNXTIMER=0,60,2,70"); // Set timers 

    delay(1000); 
    Serial.println("AT+CGATT=1");    // Network check 

    delay(1000); 
    Serial.print("AT+KFTPCFG=0,"); //FTP configuration/connect 
    Serial.print(34,BYTE); 
    Serial.print("ftp.insertaddress.com"); //FTP address 
    Serial.print(34,BYTE); 
    Serial.print(","); 
    Serial.print(34,BYTE); 
    Serial.print("username");  //Username 
    Serial.print(34,BYTE); 
    Serial.print(","); 
    Serial.print(34,BYTE); 
    Serial.print("password");  //Password 
    Serial.print(34,BYTE); 
    Serial.println(",21,0");  //Port   

    delay(500); 
    Serial.print("AT+KPATTERN=");  
    Serial.print(34,BYTE); 
    Serial.print("--EOF--Pattern--"); 
    Serial.println(34,BYTE); 

    delay(500); 
    Serial.print("AT+KFTPSND=0,,"); 
    Serial.print(34,BYTE); 
    Serial.print("log");   //Directory folder of FTP 
    Serial.print(34,BYTE); 
    Serial.print(","); 
    Serial.print(34,BYTE); 
    Serial.print("pol.txt");  //Text file 
    Serial.print(34,BYTE); 
    Serial.println(",0"); 

    delay(12000);  

    Serial.print(buffer); 
    Serial.println("--EOF--Pattern--"); 
    delay(12000); 

    Serial.println("AT+KTCPCLOSE=1,1"); 
    delay(1000); 
} 

// ------- GPS Parsing ---------- 

// Reads a line from the GPS NMEA serial output 
// Give up after trying to read 1000 bytes (~2 seconds) 
int readLine(void) { 
    char c; 
    byte bufferIndex = 0; 
    boolean startLine = 0; 
    byte retries = 0; 
    while (retries < 20) { 
    c = mySerial.read(); 

    if (c == -1) { 
     delay(2); 
     continue; 
    } 

    if (c == '\n') continue; 
    if (c == '$') startLine = 1; 
    if ((bufferIndex == BUFFERSIZE-1) || (c == '\r')) { 
     if (startLine) { 
     buffer[bufferIndex] = 0; 
     return 1; 
     } 
    } 
    if (startLine) 
     buffer[bufferIndex++] = c; 
    //} 
    else { 
     retries++; 
     delay(50); 
    } 
    } 
    return 0; 
} 

// Returns a specific field from the buffer 
void getField(int getId, char *field, int maxLen) { 
    byte bufferIndex = 0; 
    byte fieldId = 0; 
    byte i = 0; 
    while (bufferIndex < sizeof(buffer)) { 
    if (fieldId == getId) { 
     // End of string, or string overflow 
     if (buffer[bufferIndex] == ',' || i > (maxLen - 2)) { 
     field[i] = 0; // Null terminate 
     return; 
     } 
     // Buffer chars to field 
     field[i++] = buffer[bufferIndex++]; 
    } 
    else { 
     // Advance field on comma 
     if (buffer[bufferIndex] == ',') { 
     bufferIndex++;   //Advance in buffer 
     fieldId++;    // Increase field  position counter 
     } 
     else { 
     bufferIndex++;   // Advance in buffer 
     } 
    } 
    } 
    // Null terminate incase we didn't already.. 
    field[i] = 0; 
} 

// Polls for an NMEA sentence of type requested 
// Validates checksum, silently retries on failed checksums 
int getNMEA(char *getType) { 
    char type[7]; 
    byte retries = 0; 
    while (retries < 2) { 
    if (readLine() && validateChecksum()) { 
     ; 
     getField(0, type, sizeof(type)); 
     if (strcmp(type, getType) == 0) { 
     return 1; 
     } 
    } 
    else { 
     retries++; 
    } 
    } 
    Serial.println("Failed to read GPS"); 

    return 0; 
} 

// Validates the checksum on an NMEA string 
// Returns 1 on valid checksum, 0 otherwise 
int validateChecksum(void) { 
    char gotSum[2]; 
    gotSum[0] = buffer[strlen(buffer) - 2]; 
    gotSum[1] = buffer[strlen(buffer) - 1]; 
    // Check that the checksums match up 
    if ((16 * atoh(gotSum[0])) + atoh(gotSum[1]) == getCheckSum(buffer)) 
    return 1; 
    else 
    return 0; 
} 

// Calculates the checksum for a given string 
// returns as integer 
int getCheckSum(char *string) { 
    int i; 
    int XOR; 
    int c; 
    // Calculate checksum ignoring any $'s in the string 
    for (XOR = 0, i = 0; i < strlen(string); i++) { 
    c = (unsigned char)string[i]; 
    if (c == '*') break; 
    if (c != '$') XOR ^= c; 
    } 
    return XOR; 
} 

// Returns the groundspeed in km/h 
int getSpeed(void) { 
    char field[10]; 
    getField(7, field, sizeof(field)); 
    int speed = atoi(field); 
    return speed; 
} 

// Return the fix type from a GGA string 
int getFixType(void) { 
    char field[5]; 
    getField(6, field, sizeof(field)); 
    int fixType = atoi(field); 
    return fixType; 
} 

// Return the altitude in meters from a GGA string 
long getAlt(void) { 
    char field[10]; 
    getField(9, field, sizeof(field)); 
    long altitude = atol(field); 
    return altitude; 
} 

// Returns the number of satellites being tracked from a GGA string 
int getSats(void) { 
    char field[3]; 
    getField(7, field, sizeof(field)); 
    int numSats = atoi(field); 
    return numSats; 
} 

// Read the latitude in decimal format from a GGA string 
double getLat(void) { 
    char field[12]; 
    getField(2, field, sizeof(field)); // read the latitude 
    double latitude = atof(field);  // convert to a double (precise) 
    int deg = (int) latitude/100;  // extract the number of degrees 
    double min = latitude - (100 * deg); // work out the number of minutes 
    latitude = deg + (double) min/60.0; // convert to decimal format 
    getField(3, field, sizeof(field)); // get the hemisphere (N/S) 

    // sign the decimal latitude correctly 
    if (strcmp(field, "S") == 0) 
    latitude *= -1; 

    return latitude; 
} 

// Read the longitude in decimal format from a GGA string 
double getLong(void) { 
    char field[12]; 
    getField(4, field, sizeof(field)); // read the longitude 
    double longitude = atof(field);  // convert to a double 
    int deg = (int) longitude/100;  // extract the number of degrees 
    double min = longitude - (100 * deg); // work out the number of minutes 
    longitude = deg + (double) min/60.00; // convert to decimal format 
    getField(5, field, sizeof(field)); // get the E/W status 

    // sign decimal latitude correctly 
    if (strcmp(field, "W") == 0) 
    longitude *= -1; 

    return longitude; 
} 

// Converts UTC time to the correct timezone 
void convertTime(int *time) { 
    // How many hours off GMT are we? 
    float offset = -5; 
    long sectime = ((long)(time[0]) * 3600) + (time[1] * 60) + time[2]; 
    sectime += (offset * 3600.0); 
    // Did we wrap around? 
    if (sectime < 0) sectime += 86400; 
    if (sectime > 86400) sectime -= 86400; 
    // Convert back to time 
    time[0] = (int)(sectime/3600); 
    time[1] = (int)((sectime % 3600)/60); 
    time[2] = (int)((sectime % 3600) % 60); 
} 

// Parses a time field from a GGA string 
void parseTime(char *field, int *time) { 
    char tmp[3]; 
    tmp[2] = 0; // Init tmp and null terminate 
    tmp[0] = field[0]; 
    tmp[1] = field[1]; 
    time[0] = atoi(tmp); // Hours 
    tmp[0] = field[2]; 
    tmp[1] = field[3]; 
    time[1] = atoi(tmp); // Minutes 
    tmp[0] = field[4]; 
    tmp[1] = field[5]; 
    time[2] = atoi(tmp); // Seconds 
} 

// Gets the hours, minutes and seconds from a GGA string 
void getTime(int *time) { 
    char field[12]; 
    getField(1, field, sizeof(field)); 
    parseTime(field, time); 
    convertTime(time); 
} 


// ------ MISC ---------- 

// Returns a string with a textual representation of a float 
void doubleToString(double val, int precision, char *string){ 

    // Print the int part 
    sprintf(string, "%d", (int)(val)); 
    if(precision > 0) { 
    // Print the decimal point 
    strcat(string, "."); 
    unsigned long frac; 
    unsigned long mult = 1; 
    int padding = precision -1; 
    while (precision--) { 
     mult *=10; 
    } 
    if (val >= 0) 
     frac = (val - (int)(val)) * mult; 
    else 
     frac = ((int)(val)- val) * mult; 
    unsigned long frac1 = frac; 
    while (frac1 /= 10) { 
     padding--; 
    } 
    while (padding--) { 
     strcat(string, "0"); 
    } 

    // Convert and print the fraction part 
    sprintf(string+strlen(string), "%d", (int)(frac)); 
    } 
} 


// Converts a HEX string to an int 
int atoh(char c) { 
    if (c >= 'A' && c <= 'F') 
    return c - 55; 
    else if (c >= 'a' && c <= 'f') 
    return c - 87; 
    else 
    return c - 48; 
} 
+2

將代碼縮減到處理文件寫入的部分,這會使我們更容易地幫助您找到問題。 – twain249 2012-04-19 02:40:54

+0

sprintf(buffer,「%02d:%02d:%02d,%s,%s,%ld」,time [0],time [1],time [2],latString,longString,altitude); Serial.println(buffer);這部分代碼打印gps座標,並將其作爲前面定義的最大字符數爲100的字符放入緩衝區。Serial.print(「pol.txt」);是它在日誌目錄下的服務器中創建文本文件的位置。 – teddywestside 2012-04-19 06:07:34

+0

有兩個Arduinos(一個兆和一個Uno)和一臺PC嗎?如果是這樣,哪個連接到PC,並且它是正在寫入文件的PC?另外,你是否在Arduinos上運行相同的草圖?如果不是,哪個Arduino是運行的貼圖草圖? – 2012-04-19 15:29:20

回答

2

如果服務器是通過SMS/GSM接收文本文件的地方,那麼服務器程序將控制如何寫入或附加文件。您發佈的Arduino代碼不需要更改。在服務器上,您現在打開文件 - 首先檢查文件是否存在,如果存在,請更改open函數以添加追加模式。究竟如何取決於您的服務器程序的操作系統/語言。但是,您應該能夠通過閱讀open調用的文檔來了解它。

+0

感謝您的幫助讓它在服務器端工作 – teddywestside 2012-05-01 18:32:06

相關問題