Arduino to PC secure bluetooth connection - security

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.

Related

sending data from max30100 sensor using esp8266 to thingspeak

I have two sensors linked to my Arduino UNO: MAX30100(this is the problem) and LM35 Sensor.
These two sensors work without the ESP8266, their values are shown on the Serial port of arduino.
The problem is when I include the ESP8266 to send the values to ThingSpeak. The values for LM35 sensor are sent and they appear well on ThingSpeak.
The problem is with MAX30100. MAX30100 show just the value 0, that means that MAX30100 is not measuring nothing at all.
Does anybody has any ideea what to do to make the MAX30100 sensor to work while sending data to Thingspeak? I post my code below.
#define USE_ARDUINO_INTERRUPTS true
#define DEBUG true
#define SSID "Redmi" // "SSID-WiFiname"
#define PASS "wtfwtfwtf" // "password"
#define IP "184.106.153.149" // thingspeak.com ip
#define RX 10
#define TX 11
#include <Wire.h>
#include "Stdlib.h"
#include <SoftwareSerial.h>
#include "Timer.h"
#include <PulseSensorPlayground.h> // Includes the PulseSensorPlayground
Library.
Timer t;
#include "MAX30100_PulseOximeter.h"
#define REPORTING_PERIOD_MS 1000
PulseOximeter pox;
uint32_t tsLastReport = 0;
String msg = "GET /update?key=T4RF5YWLJKOU9MVO";
SoftwareSerial esp8266(RX,TX);
//Variables
const int PulseWire = A0; // PulseSensor PURPLE WIRE connected to ANALOG PIN 0
const int LED13 = 13; // The on-board Arduino LED, close to PIN 13.
int Threshold = 550; //for heart rate sensor
float myTemp;
int myBPM;
float mybpm;
float mySPO2;
String BPM;
String temp;
String SPO2;
int error;
int panic;
int raw_myTemp;
float Voltage;
float tempC;
void onBeatDetected()
{
Serial.println("Beat!");
}
void setup()
{
Serial.begin(9600);
esp8266.begin(115200);
if (!pox.begin()) {
Serial.println("FAILED");
for(;;);
}
else {
Serial.println("SUCCESS");
}
// Double-check the "pulseSensor" object was created and "began" seeing a signal.
//This prints one time at Arduino power-up, or on Arduino reset.
pox.setIRLedCurrent(MAX30100_LED_CURR_7_6MA);
// Register a callback for the beat detection
pox.setOnBeatDetectedCallback(onBeatDetected);
Serial.println("AT");
esp8266.println("AT");
delay(3000);
if(esp8266.find("OK"))
{
connectWiFi();
}
}
void loop()
{
panic_button();
start: //label
error=0;
t.update();
//Resend if transmission is not completed
if (error==1)
{
goto start; //go to label "start"
}
delay(1000);
panic_button();
delay(1000);
panic_button();
onBeatDetected();
delay(1000);
panic_button();
heart();
delay(1000);
panic_button();
oxygen();
delay(1000);
panic_button();
temp1();
}
boolean connectWiFi()
{
Serial.println("AT+CWMODE=1");
esp8266.println("AT+CWMODE=1");
delay(2000);
String cmd="AT+CWJAP=\"";
cmd+=SSID;
cmd+="\",\"";
cmd+=PASS;
cmd+="\"";
Serial.println(cmd);
esp8266.println(cmd);
delay(5000);
if(esp8266.find("OK"))
{
return true;
}
else
{
return false;
}
}
void temp1(){
raw_myTemp = analogRead(A1);
Voltage = (raw_myTemp / 1023.0) * 5000; // 5000 to get millivots.
myTemp = Voltage * 0.1;
Serial.print("Temperature = ");
Serial.print(myTemp);
Serial.print(" Degree Celsius\n");
delay(20);
char buffer3[10];
temp = dtostrf(myTemp, 4, 1, buffer3);
String cmd = "AT+CIPSTART=\"TCP\",\"";
cmd += IP;
cmd += "\",80";
Serial.println(cmd);
esp8266.println(cmd);
delay(10000);
if(esp8266.find("Error"))
{
return;
}
cmd = msg ;
cmd += "&field3="; //field 1 for BPM
cmd += temp;
cmd += "\r\n";
Serial.print("AT+CIPSEND=");
esp8266.print("AT+CIPSEND=");
Serial.println(cmd.length());
esp8266.println(cmd.length());
if(esp8266.find(">"))
{
Serial.print(cmd);
esp8266.print(cmd);
}
else
{
Serial.println("AT+CIPCLOSE");
esp8266.println("AT+CIPCLOSE");
//Resend...
error=1;
}
}
void heart(){
pox.update();
if (millis() - tsLastReport > REPORTING_PERIOD_MS) {
Serial.print("Heart rate:");
Serial.print(pox.getHeartRate());
Serial.println("");
tsLastReport = millis();}
float mybpm = pox.getHeartRate();
delay(20);
char buffer1[10];
BPM = dtostrf(mybpm, 4, 1, buffer1);
String cmd = "AT+CIPSTART=\"TCP\",\"";
cmd += IP;
cmd += "\",80";
Serial.println(cmd);
esp8266.println(cmd);
delay(1000);
if(esp8266.find("Error"))
{
return;
}
cmd = msg ;
cmd += "&field1="; //field 1 for BPM
cmd += mybpm;
cmd += "\r\n";
Serial.print("AT+CIPSEND=");
esp8266.print("AT+CIPSEND=");
Serial.println(cmd.length());
esp8266.println(cmd.length());
if(esp8266.find(">"))
{
Serial.print(cmd);
esp8266.print(cmd);
}
else
{
Serial.println("AT+CIPCLOSE");
esp8266.println("AT+CIPCLOSE");
//Resend...
error=1;
}
}
void oxygen(){
pox.update();
if (millis() - tsLastReport > REPORTING_PERIOD_MS) {
Serial.print("bpm / SPO2::");
Serial.print(pox.getSpO2());
Serial.println("%");
tsLastReport = millis();}
/*int mySPO2 = pox.getSpO2();*/
delay(20);
char buffer2[10];
SPO2 = dtostrf(pox.getSpO2(), 4, 1, buffer2);
String cmd = "AT+CIPSTART=\"TCP\",\"";
cmd += IP;
cmd += "\",80";
Serial.println(cmd);
esp8266.println(cmd);
delay(2000);
if(esp8266.find("Error"))
{
return;
}
cmd = msg ;
cmd += "&field2="; //field 1 for BPM
cmd +=SPO2;
cmd += "\r\n";
Serial.print("AT+CIPSEND=");
esp8266.print("AT+CIPSEND=");
Serial.println(cmd.length());
esp8266.println(cmd.length());
if(esp8266.find(">"))
{
Serial.print(cmd);
esp8266.print(cmd);
}
else
{
Serial.println("AT+CIPCLOSE");
esp8266.println("AT+CIPCLOSE");
//Resend...
error=1;
}
}
void panic_button(){
panic = digitalRead(8);
if(panic == HIGH){
Serial.println(panic);
String cmd = "AT+CIPSTART=\"TCP\",\"";
cmd += IP;
cmd += "\",80";
Serial.println(cmd);
esp8266.println(cmd);
delay(2000);
if(esp8266.find("Error"))
{
return;
}
cmd = msg ;
cmd += "&field4=";
cmd += panic;
cmd += "\r\n";
Serial.print("AT+CIPSEND=");
esp8266.print("AT+CIPSEND=");
Serial.println(cmd.length());
esp8266.println(cmd.length());
if(esp8266.find(">"))
{
Serial.print(cmd);
esp8266.print(cmd);
}
else
{
Serial.println("AT+CIPCLOSE");
esp8266.println("AT+CIPCLOSE");
//Resend...
error=1;
}
}
}
Expected Output: The values of MAX30100 and LM35 should be displayed on Serial monitor and uploaded to ThingSpeak platform.

How to print an string array generated in processing to Arduino

I'm trying to send a string generated in processing to Arduino so that it can be printed on an LCD screen. Nothing appears on the LCD using this method. I Have tried various methods and from my research the method I'm trying is this :
#include <LiquidCrystal.h>
char inData[9]; // Allocate some space for the string
char inChar=-1; // Where to store the character read
byte index = 0; // Index into array; where to store the character
const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 3, d7 = 2;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);
void setup() {
lcd.begin(16, 2);
lcd.setCursor(0,1);
Serial.begin(9600); // Start serial communication at 9600 bps
}
char Comp(char* This) {
while (Serial.available() > 0) // Don't read unless
// there you know there is data
{
if(index < 8) // One less than the size of the array
{
inChar = Serial.read(); // Read a character
inData[index] = inChar; // Store it
index++; // Increment where to write next
inData[index] = '\0'; // Null terminate the string
}
}
if (strcmp(inData,This) == 0) {
for (int i=0;i<8;i++) {
inData[i]=0;
}
index=0;
return(0);
}
else {
return(1);
}
}
void loop()
{
if(Serial.available() > 0){
lcd.print(inData[index]);
}
}
I am not sure about my anwser, but it might be because indata is being terminated before its even printed. Although i feel uneasy with my answser but hopefully it helped.
the termination:
inData[index] = '\0'; // Null terminate the string

Chibios and the SIM900 Shiled

i have this problem,
i have STM32 Nucleo L152RE and a Shield SIM 900,
now if i write this easy thread all work well,
'static THD_WORKING_AREA(waRead, 128);
static THD_FUNCTION(Thread,arg) {
(void)arg;
chRegSetThreadName("th_callback");
while (TRUE){
/* This will wait for a character to be received */
uint8_t c = sdGet(&SD1); //questo prende il carattere
sdPut(&SD2, c); // questo lo spara alla terminale
}
}
'
when i sand a AT commnad i see the ok answer.
Now i create this buffer
'static uint8_t bufferMsg[128];'
and i use this thread for store the answer
' static THD_WORKING_AREA(waRead5, 128);
static THD_FUNCTION(Thread5,arg) {
chRegSetThreadName("th_Riempio_Buffer");
msg_t charbuf;
int count=0;
uint8_t c;
event_listener_t Uart1Data;
eventmask_t flags;
chEvtRegisterMask((event_source_t *)chnGetEventSource(&SD1), &Uart1Data, EVENT_MASK(1));
while (TRUE) {
chEvtWaitOneTimeout(EVENT_MASK(1), MS2ST(10));
chSysLock();
flags =chEvtGetAndClearFlags(&Uart1Data);
chSysUnlock();
if (flags & CHN_INPUT_AVAILABLE)
{
do
{
charbuf = chnGetTimeout(&SD1,TIME_IMMEDIATE);
if (charbuf != Q_TIMEOUT)
{
while((charbuf != '\n') && (count < 128)) {
sdWrite(&SD2, (uint8_t *)B3,4); // va bene
bufferMsg[count]= charbuf;
count++;
}
}
}
while (charbuf != Q_TIMEOUT);
}
}
}
'
this threads don't work and don't store the answer, can you help me?
best regards
A.
fot me i use,
Define
#define buffer_size 128
char buffer[buffer_size + 1];
int nbytes = 0;
Function
void SIM_callback(){ /* GSM900 Serial */
char x = SIM.getc();
buffer[nbytes] = x;
nbytes++; if (nbytes > buffer_size) nbytes = buffer_size;
buffer[nbytes] = '\0';
}
Main
main (){
// Clear Buffer
buffer[nbytes] = '\0';
...
while(1);
...
}

SoftwareSerial issues. Only when on power jack

My Code:
#include <SoftwareSerial.h>
SoftwareSerial bluetooth(2,3);
// Output
int redPin = 6; // Red LED,
int grnPin = 11; // Green LED,
int bluPin = 5; // Blue LED,
// Color arrays
int black[3] = { 0, 0, 0 };
int white[3] = { 100, 100, 100 };
int red[3] = { 100, 0, 0 };
int green[3] = { 0, 100, 0 };
int blue[3] = { 0, 0, 100 };
int yellow[3] = { 40, 95, 0 };
int dimWhite[3] = { 30, 30, 30 };
// etc.
// Set initial color
int redVal = black[0];
int grnVal = black[1];
int bluVal = black[2];
int wait = 10; // 10ms internal crossFade delay; increase for slower fades
int hold = 0; // Optional hold when a color is complete, before the next crossFade
int r = 0;
int g = 0;
int b = 0;
char mode = '\0';
// Initialize color variables
int prevR = redVal;
int prevG = grnVal;
int prevB = bluVal;
// Set up the LED outputs
void setup()
{
pinMode(redPin, OUTPUT); // sets the pins as output
pinMode(grnPin, OUTPUT);
pinMode(bluPin, OUTPUT);
Serial.begin(9600);
delay(1000);
bluetooth.begin(115200);
delay(100);
bluetooth.print("$$$");
delay(100);
bluetooth.println("U,9600,N");
bluetooth.begin(9600);
delay(100);
analogWrite(redPin, 0);
analogWrite(grnPin, 0);
analogWrite(bluPin, 0);
Serial.println("Bluetooth initiated.");
}
void printHEX() {
Serial.print(r, HEX);
Serial.print(g, HEX);
Serial.println(b, HEX);
bluetooth.print(r, HEX);
bluetooth.print(g, HEX);
bluetooth.println(b, HEX);
}
// Main program: list the order of crossfades
void loop()
{
//Read from bluetooth and write to usb serial
while(bluetooth.available())
{
if(mode == '\0') {
mode = (char)bluetooth.read();
}
if(mode == 'c'){
int r1 = bluetooth.parseInt();
int g1 = bluetooth.parseInt();
int b1 = bluetooth.parseInt();
if (bluetooth.read() == '\n') {
if(r1 != r || g1 != g || b1 != b) {
r = r1;
g = g1;
b = b1;
analogWrite(redPin, r);
analogWrite(grnPin, g);
analogWrite(bluPin, b);
printHEX();
mode = '\0';
} else {
printHEX();
mode = '\0';
}
}
} else if(mode == 'p') {
if (bluetooth.read() == '\n') {
printHEX();
mode = '\0';
}
}
}
//Read from usb serial to bluetooth
if(Serial.available())
{
char toSend = (char)Serial.read();
bluetooth.print(toSend);
}
}
If I run this code, everything works great. That is until I plug it into the power source and nothing else.
If I plug it into the power source, the program doesn't start (no bluetooth response). If I plug it into usb and power or usb only, the program works. If I unplug usb after plugging usb and power source the program still works! I have tried debugging as much as I can, but I don't know where the error is. The power supply is rated at 12V 2 Amps to light up the LED strips.
Update: I found out that if I press the reset button after power on everything starts to work. Is there a way to automatically reset arduino on startup???
I think you are using arduino leonardo.
Try this at very beginning of setup:
while(!Serial){}
while(!bluetooth){}
The arduino leonardo prepare the serial port after some while and may cause some problems.

How to send a text file and append it using Arduino

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.

Resources