Related
I'm using an Arduino Uno to build a smoke detection system, which works. Since I have to do an IoT project, I have to establish a secure connection with a (for example) Web server, and I'm using a Bluetooth module HC-05 to do it. Now I want to encrypt and decrypt messages (which contain the values of the gas sensor) using an AES library.
That's my code on Arduino IDE:
#include <AES.h>
#include <AESLib.h>
#include <AES_config.h>
#include <xbase64.h>
#define VCC2 5
int smokeA0 = A0;
int buzzer = 11;
float sensorValue;
void setup() {
pinMode(buzzer, OUTPUT);
pinMode(smokeA0, INPUT);
pinMode(VCC2, OUTPUT);
digitalWrite(VCC2, HIGH);
Serial.begin(9600);
Serial.println("Gas sensor warning up!");
delay(2000); //allow the sensor to warm up
noTone(buzzer);
}
void loop() {
sensorValue = analogRead(smokeA0);
Serial.print("Sensor value: ");
Serial.print(sensorValue);
if(sensorValue > 300){
Serial.print(" | Smoke detected!");
tone(buzzer,1000,2000);
}
else {
noTone(buzzer);
}
Serial.println("");
delay(200); //wait 2s for next reading
}
How is the code through which I can encrypt the value sensor? And have I include it to the code above?
In the site file zip containing the informations of the project there's also this file called "Receiver", on Arduino IDE, too:
#include <SoftwareSerial.h>
#include <LiquidCrystal.h>
#include <AES.h>
AES aes ;
byte key [N_BLOCK] ;
byte cipher [N_BLOCK] ;
byte check [N_BLOCK] ;
#define PIN_EN 6
#define BUTTON 13
SoftwareSerial btSerial(4, 5);
LiquidCrystal lcd(7, 8, 9, 10, 11, 12);
String msg = "";
bool isConnected = false;
String readString = "";
byte msg_received[16];
char final_str[16];
void setup( )
{
Serial.begin(9600);
Serial.print("Receiving Application\n\n");
lcd.begin(16, 2);
lcd.setCursor(0,0);
lcd.print("Receiving App");
int bits = 128;
set_bits (bits, key, 0) ; // all zero key
byte succ;
succ = aes.set_key (key, bits) ;
if (succ != SUCCESS) Serial.println ("Failure set_key") ;
checkConnection();
if(!isConnected) {
pinMode(PIN_EN, OUTPUT); // this pin will pull the HC-010 EN HIGH to switch module to AT mode
digitalWrite(PIN_EN, HIGH);
Serial.println("Going in AT mode for BLE HC-10");
btSerial.begin(38400);
delay(1000);
pinMode(A0, INPUT);
while(!isConnected) {
if (btSerial.available()) {
char c = btSerial.read();
Serial.write(c);
}
if (Serial.available()) {
char c = Serial.read();
btSerial.write(c);
}
checkConnection();
}
btSerial.flush();
btSerial.end();
btSerial.begin(9600);
digitalWrite(PIN_EN, LOW);
Serial.println("Exiting from AT mode for BLE HC-10");
}
}
void checkConnection() {
int x = analogRead(A0);
if(x > 700) {
Serial.println("HC-10 is connected");
isConnected = true;
}
}
void loop( )
{
if(isConnected) {
getBTReply();
if(msg.length() > 0) {
Serial.println("Received msg: " + msg);
lcd.clear();
lcd.begin(16, 2);
lcd.setCursor(0,0);
lcd.print("Receiving App");
lcd.setCursor(0, 1);
lcd.print("Temp. > ");
lcd.print(msg);
lcd.setCursor(13, 1);
lcd.print(" C");
} else {
Serial.println("Received no msg");
lcd.clear();
lcd.begin(16, 2);
lcd.setCursor(0,0);
lcd.print("Receiving App");
lcd.setCursor(0, 1);
lcd.print("no message received");
}
}
delay(4000);
}
void getBTReply() {
msg = "";
int i = 0;
while (btSerial.available()) {
msg_received[i] = btSerial.read();
i++;
}
if (i==16) {
byte succ;
succ = aes.decrypt (msg_received, check) ;
if (succ != SUCCESS) Serial.println ("Failure decrypt") ;
String x = prs_byte_hex(check, 128);
textFromHexString(x.c_str(), final_str);
msg = String(final_str);
memset(final_str,0,strlen(final_str));
}
}
void set_bits (int bits, byte * a, int count)
{
bits >>= 3 ;
byte bcount = count >> 3 ;
for (byte i = 0 ; i < bcount ; i++)
a [i] = 0xFF ;
if ((count & 7) != 0)
a [bcount++] = 0xFF & (0xFF00 >> (count & 7)) ;
for (byte i = bcount ; i < bits ; i++)
a [i] = 0x00 ;
}
char * hex = "0123456789abcdef" ;
void print_value (byte * a, int bits)
{
bits >>= 3 ;
for (int i = 0 ; i < bits ; i++)
{
byte b = a[i] ;
// test purpose only
Serial.print (hex [b >> 4]) ;
Serial.print (hex [b & 15]) ;
}
Serial.println () ;
}
String prs_byte_hex (byte * a, int bits)
{
bits >>= 3 ;
String str_toparse;
for (int i = 0 ; i < bits ; i++)
{
byte b = a[i] ;
str_toparse += hex [b >> 4];
str_toparse += hex [b & 15];
}
return str_toparse;
}
void textFromHexString(char *hex, char *result)
{
char temp[3];
int index = 0;
temp[2] = '\0';
while (hex[index])
{
strncpy(temp, &hex[index], 2);
*result = (char)strtol(temp, NULL, 16);
result++;
index += 2;
}
*result = '\0';
}
So I don't need to build a Web Server in VSC to establish a connection through two devices?
If yes, can you please share me the code?
Sorry, I'm not very practical in IoT and I'm completely alone to do the project.
If you're sending data using the HC-05 to another arduino, then here is how to encrypt the data:
uint8_t key[] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
char data[] = "0123456789012345"; //16 chars == 16 bytes - Your data you want to send
aes128_enc_single(key, data);
Then on the receiving arduino
aes128_dec_single(key, data);
You send that data using serial. The receiving Arduino would also need an HC-05 module, or if you're sending to your computer, you can use a USB bluetooth adapter. You don't need a webserver to establish a connection between 2 arduinos, no. If you're sending data online, then you'll need to have a way to connect to the internet from one of your devices.
I'm trying to send sensor data from nodemcu ESP32 to firebase.
When using the basic example shown below it worked fine, and also when viewing the sensor data without sending it to firebase.
https://github.com/mobizt/Firebase-ESP32/tree/master/examples/Basic
However when I tried to edit the code a bit and send my sensor's data, I get an error, I would appreciate any help, code, and error attached.
#include <WiFi.h>
#include <FirebaseESP32.h>
#include "DHT.h"
#include <OneWire.h>
#include <DallasTemperature.h>
#include "WiFi.h"
#define DHTPIN 27 // Digital pin connected to the DHT sensor
#define DHTTYPE DHT22 // DHT 22 (AM2302), AM2321
#define FIREBASE_HOST "trial-2c3ea.firebaseio.com"
#define FIREBASE_AUTH "Eu706797Vy2zOEDp3Bc9e4T9GZVAVwTyoxshl9Am"
#define WIFI_SSID "saadon 1"
#define WIFI_PASSWORD "0547258525"
//Define FirebaseESP32 data object
FirebaseData firebaseData;
FirebaseJson json;
DHT dht(DHTPIN, DHTTYPE);
const int oneWireBus = 2;
OneWire oneWire(oneWireBus);
DallasTemperature sensors(&oneWire);
const int Analog_channel_pin= 15;
double Soil_Moisture = 0;
double Soil_Moisture_analog = 0;
String path = "/Test";
void printResult(FirebaseData &data);
void setup()
{
Serial.begin(115200);
sensors.begin();
dht.begin();
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
Serial.print("Connecting to Wi-Fi");
while (WiFi.status() != WL_CONNECTED)
{
Serial.print(".");
delay(300);
}
Serial.println();
Serial.print("Connected with IP: ");
Serial.println(WiFi.localIP());
Serial.println();
Firebase.begin(FIREBASE_HOST, FIREBASE_AUTH);
Firebase.reconnectWiFi(true);
}
void loop() {
float h = dht.readHumidity();
float t = dht.readTemperature();
sensors.requestTemperatures();
float temperatureC = sensors.getTempCByIndex(0);
Soil_Moisture_analog = analogRead(Analog_channel_pin);
Soil_Moisture = (0.00531*exp(0.29*(Soil_Moisture_analog*0.006+1.0265)))*100;
if (Firebase.setFloat(firebaseData, path + "/Air Temp" + t))
{
Serial.println("PASSED");
printResult(firebaseData);
Serial.println();
}
else
{
Serial.println("FAILED");
Serial.println("REASON: " + firebaseData.errorReason());
Serial.println();
}
if (Firebase.setFloat(firebaseData, path + "/Air Humidity" + h))
{
Serial.println("PASSED");
printResult(firebaseData);
Serial.println();
}
else
{
Serial.println("FAILED");
Serial.println("REASON: " + firebaseData.errorReason());
Serial.println();
}
if (Firebase.setFloat(firebaseData, path + "/Soil Temperature" + temperatureC))
{
Serial.println("PASSED");
printResult(firebaseData);
}
else
{
Serial.println("FAILED");
Serial.println("REASON: " + firebaseData.errorReason());
Serial.println();
}
if (Firebase.setFloat(firebaseData, path + "/Soil Moisture" + Soil_Moisture))
{
Serial.println("PASSED");
printResult(firebaseData);
Serial.println();
}
else
{
Serial.println("FAILED");
Serial.println("REASON: " + firebaseData.errorReason());
Serial.println();
}
delay(5000);
}
Error:
firebasecode:74:65: error: no matching function for call to 'FirebaseESP32::setFloat(FirebaseData&, StringSumHelper&)'
The setFloat method takes three parameters:
bool setFloat(FirebaseData &dataObj, const String &path, float floatValue);
From https://github.com/mobizt/Firebase-ESP32/blob/master/src/FirebaseESP32.h#L1084
So the path and value are separate parameters. Change the calls to setFloat to look like:
if (Firebase.setFloat(firebaseData, path + "/Air Temp", t))
This is the new code which for some reason does not send the air humidity data, only air temp, the soil temp and moisture works fine.
#include <WiFi.h>
#include <FirebaseESP32.h>
#include "DHT.h"
#include <OneWire.h>
#include <DallasTemperature.h>
#include "WiFi.h"
#define DHTPIN 27 // Digital pin connected to the DHT sensor
#define DHTTYPE DHT22 // DHT 22 (AM2302), AM2321
#define FIREBASE_HOST "trial-2c3ea.firebaseio.com"
#define FIREBASE_AUTH "Eu706797Vy2zOEDp3Bc9e4T9GZVAVwTyoxshl9Am"
#define WIFI_SSID "saadon 1"
#define WIFI_PASSWORD "0547258525"
FirebaseData firebaseData;
FirebaseJson json;
void printResult(FirebaseData &data);
//Define FirebaseESP32 data object
DHT dht(DHTPIN, DHTTYPE);
const int oneWireBus = 2;
OneWire oneWire(oneWireBus);
DallasTemperature sensors(&oneWire);
const int Analog_channel_pin= 32;
double Soil_Moisture = 0;
double Soil_Moisture_analog = 0;
String path = "/Test";
void setup()
{
Serial.begin(115200);
sensors.begin();
dht.begin();
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
Serial.print("Connecting to Wi-Fi");
while (WiFi.status() != WL_CONNECTED)
Serial.println();
Serial.print("Connected with IP: ");
Serial.println(WiFi.localIP());
Serial.println();
Firebase.begin(FIREBASE_HOST, FIREBASE_AUTH);
Firebase.reconnectWiFi(true);
}
void loop() {
float h = dht.readHumidity();
float t = dht.readTemperature();
sensors.requestTemperatures();
float temperatureC = sensors.getTempCByIndex(0);
Soil_Moisture_analog = analogRead(Analog_channel_pin);
Soil_Moisture = (0.00531*exp(0.29*(Soil_Moisture_analog*0.006+1.0265)))*100;
Firebase.setFloat(firebaseData, path + "/Air Humidity", h);
Firebase.setFloat(firebaseData, path + "/Air Temp", t);
Firebase.setFloat(firebaseData, path + "/Soil Temperature", temperatureC);
Firebase.setFloat(firebaseData, path + "/Soil Moisture", Soil_Moisture);
delay(5000);
}
I'm trying to make a GPS/GSM receiver with an Arduino Uno. My program is trying to ana]yse the incoming strings with a few ifs. Then I want to convert them to save them on an SD card, or send them as SMS.
This is the correct information from the GPS:
+GPSRD:
$GPGGA,151420.000,5222.61362,N,01658.51086,E,1,03,8.9,0.0,M,,M,,0000*44
$GPRMC,151420.000,A,5222.61362,N,01658.51086,E,0.46,160.58,201017,,,A*67
$GPVTG,160.58,T,,M,0.46,N,0.86,K,A*3B
The line I need is the third one, because there are coordinates. I want to save them. So I made some functions. I'm trying also to navigate the whole device by SMS commands. Everything is in the code. Here is the code:
#include <SoftwareSerial.h>
#include <SPI.h>
#include <SD.h>
#include <string.h>
#define rxPin 7
#define txPin 8
String message="lalala", callingnumber="";
String response="";
String coords;
String data[13]={"","","","","","","","","","","","",""};
String thetime=(""), date=(""), latitude=(""), longitude=("");
SoftwareSerial mySerial(rxPin, txPin);
void setup() {
Serial.begin(115200);
mySerial.begin(19200);
while (!Serial) {
}
digitalWrite(3, HIGH);
delay(2000);
digitalWrite(3, LOW);
for(int i = 0; i < 8; i++) {
mySerial.println("AT");
Serial.println("AT");
delay(1000);
}
mySerial.println("");
delay(1000);
mySerial.println("Jestem gotowy!");
delay(1000);
mySerial.println("s - lokalizacja / g - wlacz gps / o - wylacz gps");
delay(1000);
Serial.println("AT+GPS=1");
delay(1000);
Serial.println("AT+CMGF=1");
delay(1000);
while (Serial.available()) {
mySerial.write(Serial.read());
}
}
void loop() {
RecData();
}
void RecData() {
int firstindex, lastindex;
Serial.setTimeout(1000);
response = Serial.readString();
firstindex = response.indexOf("$GPRMC");
lastindex = response.indexOf("$GPVTG");
if (response.indexOf("+CMT: ") > 0) {
int numberindex = response.indexOf("+48");
if (response.indexOf("Start") > 0) {
callingnumber = response.substring(numberindex, numberindex+12);
SendSMS("wlaczono");
OpenGPS();
}
}
if (response.indexOf("+CMT: ") > 0) {
int numberindex = response.indexOf("+48");
if (response.indexOf("Stop") > 0) {
callingnumber = response.substring(numberindex, numberindex+12);
SendSMS("zatrzymano");
CloseGPS();
}
}
if (response.indexOf("+CMT: ") > 0) {
int numberindex = response.indexOf("+48");
if (response.indexOf("Sms") > 0) {
callingnumber = response.substring(numberindex, numberindex+12);
SendSMS(message);
}
}
int a = 0;
for (int i=firstindex; i<lastindex; i++) {
mySerial.print(response[i]);
if(response[i] == ',') {
a++;
} else {
data[a] += response[i];
}
}
mySerial.print(firstindex);
mySerial.print("::");
mySerial.print(lastindex);
mySerial.println(" loop is working");
date = data[9];
thetime = data[1];
latitude = data[3] + data[4];
longitude = data[5] + data[6];
message = date.substring(0,2) + "." + date.substring(2,4) + "." + date.substring(4,6) + " " + thetime.substring(0,2) + ":" + thetime.substring(2,4) + ":" + thetime.substring(4,6) + " coords: " + latitude.substring(0,2) + "'" + latitude.substring(2,4) + "''" + latitude.substring(5,10) + "'''" + latitude.substring(10,11)+ " " + longitude.substring(1,3) + "'" + longitude.substring(3,5) + "''" + longitude.substring(6,11) + "'''" + longitude.substring(11,12);
for(int ii = 0; ii < 13; ii++) {
mySerial.print(data[ii]);
data[ii] = "";
//czyszczenie na szybko
}
if (firstindex < 0 && lastindex < 0) {
mySerial.write("test");
mySerial.print(response);
mySerial.print(response.length());
}
}
void OpenGPS() {
mySerial.println("wlaczam gps");
delay(500);
Serial.println("AT+GPSRD=1");
delay(500);
mySerial.println("Wlaczono");
}
void CloseGPS() {
mySerial.println("Wylaczam GPS");
delay(500);
Serial.println("AT+GPSRD=0");
}
void SignalQuality() {
mySerial.print("Jakosc sygnalu: ");
delay(1000);
Serial.println("AT+CSQ");
}
void SendSMS(String msg) {
mySerial.println("wysylam...");
delay(500);
Serial.println("AT+CMGS="+callingnumber);
delay(500);
Serial.print(msg);
delay(500);
Serial.println((char)26);
delay(500);
mySerial.println("wyslano");
}
I'm looking for some help, because it doesn't work well. Here is the screenshot of the executed program:
The response is not good. There was some text conversion to get 13 strings of message.
Please help, if I missed any information I can edit the post.
Thanks.
Here is my code so far the system contains an SD card reader, two buzzers, two LEDs, a PIR motion sensor, and a IR receiver.
error message I get are as follows:
1) Final_Build:100: error: redefinition of 'int val'
2) Final_Build:5: error: 'int val' previously defined here
3) Final_Build:101: error: expected unqualified-id before 'if'
4) redefinition of 'int val'
//PIR sensor
int ledPin = 7; // choose the pin for the LED
int inputPin = 2; // choose the input pin (for PIR sensor)
int pirState = LOW; // we start, assuming no motion detected
int val = 0; // variable for reading the pin status
int pinSpeaker = 10; //Set up a speaker on a PWM pin (digital 9, 10, or 11)
//IR_Sensor
int dtect=3;
int sense=A0;
int buzzpin=9;
int lightPin=6;
#include <SPI.h>
#include <SD.h>
File myFile;
void setup() {
//PIR sensor
pinMode(ledPin, OUTPUT); // declare LED as output
pinMode(inputPin, INPUT); // declare sensor as input
pinMode(pinSpeaker, OUTPUT);
Serial.begin(9600);
//IR sensor
pinMode(dtect,OUTPUT);
pinMode(lightPin,OUTPUT);
pinMode(sense,INPUT);
pinMode(buzzpin,OUTPUT);
digitalWrite(dtect,HIGH);
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect.
}
Serial.print("Initializing SD card...");
if (!SD.begin(4)) {
Serial.println("initialization failed!");
return;
}
Serial.println("initialization done.");
// open the file. note that only one file can be open at a time,
// so you have to close this one before opening another.
myFile = SD.open("test.txt", FILE_WRITE);
// if the file opened okay, write to it:
if (myFile) {
Serial.print("Writing to test.txt...");
myFile.println("testing 1, 2, 3.");
// close the file:
myFile.close();
Serial.println("done.");
} else {
// if the file didn't open, print an error:
Serial.println("error opening test.txt");
}
// re-open the file for reading:
myFile = SD.open("test.txt");
if (myFile) {
Serial.println("test.txt:");
// read from the file until there's nothing else in it:
while (myFile.available()) {
Serial.write(myFile.read());
}
// close the file:
myFile.close();
} else {
// if the file didn't open, print an error:
Serial.println("error opening test.txt");
}
}
void loop(){
//IR sensor
int val=analogRead(sense);
Serial.println(val);
if(val>=800)
{
digitalWrite(lightPin, HIGH);
buzz(50);
}
else {
digitalWrite(lightPin, LOW);
}
}
void buzz(unsigned char time)
{
analogWrite(buzzpin,170);
delay(time);
analogWrite(buzzpin,0);
delay(time);
}
//PIR sensor
int val = digitalRead(inputPin); // read input value
if (val == HIGH) { // check if the input is HIGH
digitalWrite(ledPin, HIGH); // turn LED ON
playTone(300, 160);
delay(100);
if (pirState == LOW) {
// we have just turned on
Serial.println("Motion detected!");
// We only want to print on the output change, not state
pirState = HIGH;
}
} else {
digitalWrite(ledPin, LOW); // turn LED OFF
playTone(0, 0);
delay(300);
if (pirState == HIGH){
// we have just turned off
Serial.println("Motion ended!");
// We only want to print on the output change, not state
pirState = LOW;
}
}
}
// duration in mSecs, frequency in hertz
void playTone(long duration, int freq) {
duration *= 1000;
int period = (1.0 / freq) * 1000000;
long elapsed_time = 0;
while (elapsed_time < duration) {
digitalWrite(pinSpeaker,HIGH);
delayMicroseconds(period / 2);
digitalWrite(pinSpeaker, LOW);
delayMicroseconds(period / 2);
elapsed_time += (period);
}
}
This first val definition isn't necessary.
int val = 0; // variable for reading the pin status
You are redifining val at the begining of loop() .
UPDATE:
I think that this is what you want. Your problem is that added buzz function was defined inside loopfunction and you lost some parentesis{}. I just put it out and joined loopcode.
//PIR sensor
int ledPin = 7; // choose the pin for the LED
int inputPin = 2; // choose the input pin (for PIR sensor)
int pirState = LOW; // we start, assuming no motion detected
int pinSpeaker = 10; //Set up a speaker on a PWM pin (digital 9, 10, or 11)
//IR_Sensor
int dtect=3;
int sense=A0;
int buzzpin=9;
int lightPin=6;
#include <SPI.h>
#include <SD.h>
File myFile;
void setup() {
//PIR sensor
pinMode(ledPin, OUTPUT); // declare LED as output
pinMode(inputPin, INPUT); // declare sensor as input
pinMode(pinSpeaker, OUTPUT);
Serial.begin(9600);
//IR sensor
pinMode(dtect,OUTPUT);
pinMode(lightPin,OUTPUT);
pinMode(sense,INPUT);
pinMode(buzzpin,OUTPUT);
digitalWrite(dtect,HIGH);
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect.
}
Serial.print("Initializing SD card...");
if (!SD.begin(4)) {
Serial.println("initialization failed!");
return;
}
Serial.println("initialization done.");
// open the file. note that only one file can be open at a time,
// so you have to close this one before opening another.
myFile = SD.open("test.txt", FILE_WRITE);
// if the file opened okay, write to it:
if (myFile) {
Serial.print("Writing to test.txt...");
myFile.println("testing 1, 2, 3.");
// close the file:
myFile.close();
Serial.println("done.");
} else {
// if the file didn't open, print an error:
Serial.println("error opening test.txt");
}
// re-open the file for reading:
myFile = SD.open("test.txt");
if (myFile) {
Serial.println("test.txt:");
// read from the file until there's nothing else in it:
while (myFile.available()) {
Serial.write(myFile.read());
}
// close the file:
myFile.close();
} else {
// if the file didn't open, print an error:
Serial.println("error opening test.txt");
}
}
void loop(){
//IR sensor
int val=analogRead(sense);
Serial.println(val);
if(val>=800)
{
digitalWrite(lightPin, HIGH);
buzz(50);
}
else {
digitalWrite(lightPin, LOW);
}
//PIR sensor
int val = digitalRead(inputPin); // read input value
if (val == HIGH) { // check if the input is HIGH
digitalWrite(ledPin, HIGH); // turn LED ON
playTone(300, 160);
delay(100);
if (pirState == LOW) {
// we have just turned on
Serial.println("Motion detected!");
// We only want to print on the output change, not state
pirState = HIGH;
}
} else {
digitalWrite(ledPin, LOW); // turn LED OFF
playTone(0, 0);
delay(300);
if (pirState == HIGH){
// we have just turned off
Serial.println("Motion ended!");
// We only want to print on the output change, not state
pirState = LOW;
}
}
}
void buzz(unsigned char time)
{
analogWrite(buzzpin,170);
delay(time);
analogWrite(buzzpin,0);
delay(time);
}
// duration in mSecs, frequency in hertz
void playTone(long duration, int freq) {
duration *= 1000;
int period = (1.0 / freq) * 1000000;
long elapsed_time = 0;
while (elapsed_time < duration) {
digitalWrite(pinSpeaker,HIGH);
delayMicroseconds(period / 2);
digitalWrite(pinSpeaker, LOW);
delayMicroseconds(period / 2);
elapsed_time += (period);
}
}
I'm working on a GPS logger project. I have an Arduino Mega set up with a transmitter and receiver and GPS and GSM modules. I also have an Arduino Uno with a transmitter, receiver and buzzer.
When the two devices go too far from each other, the GPS data is pulled and sent to my web server using the GSM module. When I send my file to the server it creates a text file and when I move to another location it overwrites the previous location.
I'm trying to figure out how to append the text file instead of overwriting it. I found a lot of stuff using an SD card shield but nothing without it.
#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;
}
If the server is where the text file is received via SMS/GSM, that server program controls how the file is written or appended. Your posted Arduino code would not need to be changed. On the server, where you now open the file - first check if the file exists and if it does, change the open function to add append mode. Exactly how depends on the OS/language of your server program. But you should be able to figure it out from reading the documentation on the open call.