#include <SoftwareSerial.h>
#include "Arduino.h"
#include "KIM.h"
#include <avr/interrupt.h>
#include <avr/sleep.h>
#include <avr/wdt.h>
#include <SoftwareSerial.h>
#include <Wire.h>
#include "MMA7660.h"
#define RX_PIN 7
#define TX_PIN 8
SoftwareSerial kserial(RX_PIN, TX_PIN);
SoftwareSerial SoftSerial(2, 3);
KIM kim;
//GPS variables
String heure_tot, lat, NS, longi, EW, fix, nb_sat, precision, heure, minute;
int deg_lat, min_lat, deg_longi, min_longi;
unsigned int min_dec1,min_dec2,min_dec3;
void setup() {
Serial.begin(4800); // Start PC serial port @ 4800 baud
delay(100);
Wire.begin(); //Start the BPM sensor connection
kim.set_SoftwareSerial(&kserial, 4800); //Start UART connection with KIM @ 4800 baud
}
void loop() {
//Variable initilization
int aX_MAX=0, aY_MAX=0, aZ_MAX=0;
int aX, aY, aZ;
int BPM[60];
int somme=0,den=0;
int BPM_moy;
int cpt=0;
String GPS_GGA;
int BAT, alert, wakup;
Serial.println("Accelerometer measurements");
for(cpt=0;cpt<810;cpt++) //Cycle of 810*1s with only acceleration measurements
{
aX = measure_accX(); //X axis acceleration measurement
aY = measure_accY(); //Y axis acceleration measurement
aZ = measure_accZ(); //Z axis acceleration measurement
//aX = simu_accX(0.95); //X axis acceleration simulation fonction to emule the accelerometer
//aY = simu_accY(0.63); //Y axis acceleration simulation fonction to emule the accelerometer
//aZ = simu_accZ(1.2); //Z axis acceleration simulation fonction to emule the accelerometer
aX_MAX=MAX(aX_MAX,aX); //Store the max X axis acceleration value
aY_MAX=MAX(aY_MAX,aY); //Store the max Y axis acceleration value
aZ_MAX=MAX(aZ_MAX,aZ); //Store the max Z axis acceleration value
delay(990);
}
Serial.println("Accelerometer + BPM measurements");
for(cpt=810;cpt<870;cpt++) //Cycle of 60*1s with only acceleration+BPM measurements
{
aX = measure_accX();
aY = measure_accY();
aZ = measure_accZ();
//aX = simu_accX(0.95);
//aY = simu_accY(0.63);
//aZ = simu_accZ(1.2);
aX_MAX=MAX(aX_MAX,aX);
aY_MAX=MAX(aY_MAX,aY);
aZ_MAX=MAX(aZ_MAX,aZ);
BPM[cpt-810]=measure_BPM(); //BPM measurements
//BPM[cpt-810]=simu_BPM(128); //BPM simulation fonction to emule the heart rate sensor
delay(990);
}
//Start of the BPM average calculation
for(int i=0;i<60;i++)
{
if(BPM[i]>0)
{
somme+=BPM[i];
den++;
}
}
BPM_moy=somme/den;
//End of the BPM average calculation
GPS_GGA = GPS_acquisition(); //GPS localisation
//GPS_GGA = simu_GPS_GGA("154415.000,4839.4308,N,00214.6685,E,1,5,1.66,102.9,M,47.3,M,,*51"); //GPS trame simulation fonction to emule the GPS chip
recept_val_GPS(GPS_GGA); //GPS data treatment
BAT = simu_BAT(87); //Battery level simulation
alert = simu_alert(1); //Alert state simulation
wakup = simu_Wakup(3); //Wakupe victim indication simulation
String TRANSMIT=conception_trame_sat(BAT,alert,wakup,BPM_moy,aX_MAX,aY_MAX,aZ_MAX); //Initialization of the transmission string
KIM_switch_on(); //KIM1 switch on
KIM_config("B1",300,1500); //KIM1 config
KIM_transmit(TRANSMIT); //Satelite transmission (1st try)
delay(1000);
KIM_transmit(TRANSMIT); //Satelite transmission (2nd try)
delay(1000);
KIM_transmit(TRANSMIT); //Satelite transmission (3rd try)
delay(1000);
KIM_transmit(TRANSMIT); //Satelite transmission (4th try)
delay(1000);
KIM_switch_off(); //KIM1 switch off
}
void KIM_switch_on(){
Serial.println(F("main-->Turning ON the Kim1"));
kim.set_ModuleStateON(); // Set the Kim1 On/Off pin HIGH and thus turn the Kim1 module ON
kim.get_KIMPlatform_Info();
delay(2000);
}
void KIM_config(String BAND, int FREQUENCY, int POWER){
Serial.println(F("main-->Configuring the transmission parameters"));
kim.set_TX_Band(BAND); // Assign the band for transmission using AT command
kim.set_TX_OffsetFreq(FREQUENCY); // Assign the transmission offset frequency for transmission using AT command
kim.set_TX_Power(POWER); // Assign the power for transmission using AT command
Serial.println(F("main-->Function called to check the values configured for the transmission parameters: "));
kim.get_TransmissionParameters_Values();
}
void KIM_transmit(String HEXA_STRING){
Serial.println(F("main-->-------- transmit hexadecimal user message -------"));
Serial.print(F("main-->User message length:"));
Serial.println(HEXA_STRING.length());
Serial.print(F("main-->User Data:"));
Serial.println(HEXA_STRING);
String HEXA_MESSAGE = HEXA_STRING;
String command = "AT+TX=" + HEXA_MESSAGE + "\r";
Serial.print(F("Command :"));
Serial.println(command);
kim.send_ATCommand(command);
}
void KIM_switch_off() {
Serial.println(F("main-->Stop the Kim1 and the Arduino board"));
kim.set_ModuleStateOFF();
kim.stop();
}
int measure_BPM()
{
unsigned char c;
Wire.requestFrom(0xA0 >> 1, 1); // request 1 bytes from slave device
while(Wire.available())
{
c = Wire.read(); // receive heart rate value (a byte)
}
return (int)(c);
}
int measure_accX()
{
MMA7660 acc;
acc.init();
float ax, ay, az;
acc.getAcceleration(&ax,&ay,&az);
return (int)(ax*100);
}
int measure_accY()
{
MMA7660 acc;
acc.init();
float ax, ay, az;
acc.getAcceleration(&ax,&ay,&az);
return (int)(ay*100);
}
int measure_accZ()
{
MMA7660 acc;
acc.init();
float ax, ay, az;
acc.getAcceleration(&ax,&ay,&az);
return (int)(az*100);
}
int MAX(int a, int b)
{
if(a<b)
return b;
else
return a;
}
String GPS_acquisition()
{
String trame_GPS_GGA, trame_GPS;
SoftSerial.begin(9600);
char buffer[64]; // buffer array for data receive over serial port
int count=0;
int count_trame = 0;
int etape = 0;
if (SoftSerial.available()) // if date is coming from software serial port ==> data is coming from SoftSerial shield
{
while(SoftSerial.available()) // reading data into char array
{
buffer[count++]=SoftSerial.read(); // writing data into array
if(count == 64)break;
}
for (int i=0; i<count;i++)
{
Serial.print(buffer[i]);
trame_GPS.concat(buffer[i]);
}
Serial.println();
for(count_trame=0;((count_trame<count) or (etape == 6));count_trame++)
{
int buf_ascii = trame_GPS[count_trame];
if(buf_ascii == 36)
{
etape = 1;
count_trame++;
}
else
{ etape = 0; }
buf_ascii = trame_GPS[count_trame];
if((buf_ascii == 71)and(etape == 1))
{
etape = 2;
count_trame++;
}
else
{etape = 0; }
buf_ascii = trame_GPS[count_trame];
if((buf_ascii == 80)and(etape == 2))
{
etape = 3;
count_trame++;
}
else
{etape = 0; }
buf_ascii = trame_GPS[count_trame];
if((buf_ascii == 71)and(etape == 3))
{
etape = 4;
count_trame++;
}
else
{etape = 0;}
buf_ascii = trame_GPS[count_trame];
if((buf_ascii == 71)and(etape == 4))
{
etape = 5;
count_trame++;
}
else
{etape = 0;}
buf_ascii = trame_GPS[count_trame];
if((buf_ascii == 65)and(etape == 5))
{
etape = 6;
count_trame++;
int buf_ascii2 = buffer[count_trame];
trame_GPS_GGA = "";
for(int i = count_trame;(i<count);i++)
{
buf_ascii2 = trame_GPS[i];
if(buf_ascii2== 36)
{
etape=0;
trame_GPS_GGA = "";
}
else
trame_GPS_GGA.concat(trame_GPS[i]);
}
}
else
{etape = 0;}
buf_ascii = trame_GPS[count_trame];
}
for (int i=0; i<count;i++)
{
buffer[i]=NULL;
}
trame_GPS = "";
count = 0; // set counter of while loop to zero
}
delay(10);
return trame_GPS_GGA;
}
void recept_val_GPS(String trame_GPS_GGA)
/******************************************************
Splitting GPS data function
Global variables used:
String heure_tot, lat, NS, longi, EW, fix, nb_sat, precision, heure, minute;
int deg_lat, min_lat, deg_longi, min_longi;
******************************************************/
{
//String s = "12345, 6789, 101112"; // exemple
int n_av=0, n_ap =0;
//double nb;
//String subs, newStr="";
int temp =0;
String Stemp;
n_av=0;
n_ap = trame_GPS_GGA.indexOf(",",n_av+1);
heure_tot = trame_GPS_GGA.substring(n_av+1, n_ap);
heure = heure_tot.substring(0,1);
minute = heure_tot.substring(2,3);
n_av=n_ap;
n_ap = trame_GPS_GGA.indexOf(",",n_av+1);
lat = trame_GPS_GGA.substring(n_av+1, n_ap);
n_av=n_ap;
n_ap = trame_GPS_GGA.indexOf(",",n_av+1);
NS = trame_GPS_GGA.substring(n_av+1, n_ap);
n_av=n_ap;
n_ap = trame_GPS_GGA.indexOf(",",n_av+1);
longi = trame_GPS_GGA.substring(n_av+1, n_ap);
n_av=n_ap;
n_ap = trame_GPS_GGA.indexOf(",",n_av+1);
EW = trame_GPS_GGA.substring(n_av+1, n_ap);
n_av=n_ap;
n_ap = trame_GPS_GGA.indexOf(",",n_av+1);
fix = trame_GPS_GGA.substring(n_av+1, n_ap);
n_av=n_ap;
n_ap = trame_GPS_GGA.indexOf(",",n_av+1);
nb_sat = trame_GPS_GGA.substring(n_av+1, n_ap);
n_av=n_ap;
n_ap = trame_GPS_GGA.indexOf(",",n_av+1);
precision = trame_GPS_GGA.substring(n_av+1, n_ap);
n_ap=0;
n_ap = lat.indexOf(".",0);
Stemp=lat.substring(0, n_ap);
temp = Stemp.toInt();
deg_lat = (int)(temp/100);
temp = temp%100;
Stemp="";
Stemp=lat.substring(n_ap+1);
min_lat = Stemp.toInt();
min_lat = min_lat + temp*10000;
n_ap=0;
temp=0;
Stemp="";
n_ap = longi.indexOf(".",0);
Stemp=longi.substring(0, n_ap);
temp = Stemp.toInt();
deg_longi = (int)(temp/100);
temp = temp%100;
Stemp="";
Stemp=longi.substring(n_ap+1);
min_longi = Stemp.toInt();
min_longi = min_longi + temp*10000;
}
void conv_dec_bin_20b(long unsigned int dec)
/***********************************************************
Converts a <524,288 decimal value to a binary value of 20 bits
split into 3 bytes with min_dec1 per byte of byte weight
high and min_dec3 the low byte
Global variables used :
unsigned int min_dec1,min_dec2,min_dec3;
***********************************************************/
{
long int dec_temp;
double temp=0;
min_dec1=0;
min_dec2=0;
min_dec3=0;
for(int i=19;i>=16;i--)
{
dec_temp = dec-pow(2,i);
if(dec_temp>=0)
{
dec=dec-pow(2,i);
temp= temp + pow(2,i-16);
}
}
min_dec1 = (unsigned int)(temp+1);
temp = 0;
for(int i=15;i>=8;i--)
{
dec_temp = dec-pow(2,i);
if(dec_temp>=0)
{
dec=dec-pow(2,i);
temp= temp+pow(2,i-8);
}
}
min_dec2 = (unsigned int) (temp+1);
temp = 0;
for(int i=7;i>=0;i--)
{
dec_temp = dec-pow(2,i);
if(dec_temp>=0)
{
dec=dec-pow(2,i);
temp= temp+pow(2,i);
}
}
min_dec3 = (unsigned int) (temp+1);
temp = 0;
}
String conception_trame_sat(int niv_bat,int et_alerte,int Wakup,int BPM,int acc_x,int acc_y,int acc_z)
{
String userdataS;
String HEXA_STRING;
unsigned int temp;
userdataS=String(heure.toInt(),HEX);
HEXA_STRING=generate_hexa_string(1,userdataS,HEXA_STRING);
userdataS=String((minute.toInt() + Wakup*64),HEX);
HEXA_STRING=generate_hexa_string(0,userdataS,HEXA_STRING);
if(NS=="N")
userdataS=String(deg_lat,HEX);
else
userdataS=String((deg_lat+128),HEX);
HEXA_STRING=generate_hexa_string(0,userdataS,HEXA_STRING);
userdataS=String(deg_longi,HEX);
HEXA_STRING=generate_hexa_string(0,userdataS,HEXA_STRING);
if(NS=="N")
userdataS=String(((int)(precision.toFloat()*10)),HEX);
else
userdataS=String((((int)(precision.toFloat()*10))+128),HEX);
HEXA_STRING=generate_hexa_string(0,userdataS,HEXA_STRING);
conv_dec_bin_20b(((long unsigned int) min_lat));
userdataS=String( min_dec3,HEX);
HEXA_STRING=generate_hexa_string(0,userdataS,HEXA_STRING);
userdataS= String(min_dec2,HEX);
HEXA_STRING=generate_hexa_string(0,userdataS,HEXA_STRING);
temp=min_dec1;
conv_dec_bin_20b(((long unsigned int) min_lat));
userdataS=String((temp+ (min_dec1*16)),HEX);
HEXA_STRING=generate_hexa_string(0,userdataS,HEXA_STRING);
userdataS=String( min_dec2,HEX);
HEXA_STRING=generate_hexa_string(0,userdataS,HEXA_STRING);
userdataS= String(min_dec3,HEX);
HEXA_STRING=generate_hexa_string(0,userdataS,HEXA_STRING);
userdataS=String((niv_bat + 128*et_alerte),HEX);
HEXA_STRING=generate_hexa_string(0,userdataS,HEXA_STRING);
userdataS=String(BPM,HEX);
HEXA_STRING=generate_hexa_string(0,userdataS,HEXA_STRING);
if(acc_x<0)
{
if(acc_x>127)
acc_x=127;
userdataS=String((acc_x),HEX);
}
else
{
if(acc_x<-127)
acc_x=-127;
userdataS=String(((acc_x)+128),HEX); //ajout du bit de signe
}
HEXA_STRING=generate_hexa_string(0,userdataS,HEXA_STRING);
if(acc_y<0)
{
if(acc_y>127)
acc_y=127;
userdataS=String((acc_y),HEX);
}
else
{
if(acc_y<-127)
acc_y=-127;
userdataS=String(((acc_y)+128),HEX);
}
HEXA_STRING=generate_hexa_string(0,userdataS,HEXA_STRING);
if(acc_z<0)
{
if(acc_z>127)
acc_z=127;
userdataS=String((acc_z),HEX);
}
else
{
if(acc_z<-127)
acc_z=-127;
userdataS=String(((acc_z)+128),HEX);
}
HEXA_STRING=generate_hexa_string(0,userdataS,HEXA_STRING);
return HEXA_STRING;
}
String generate_hexa_string(int init,String USDT,String HS)
{
String HEXA_STRING=HS;
if (init==1)
HEXA_STRING="";
if(USDT.length()==1)
HEXA_STRING+="0"+USDT;
else
HEXA_STRING+=USDT;
Serial.println(HEXA_STRING);
HEXA_STRING.toUpperCase();
return HEXA_STRING;
}
String simu_GPS_GGA(String GGA)
{
return GGA;
}
int simu_BAT(int lv)
{
return lv;
}
int simu_alert(int alt)
{
return alt;
}
int simu_Wakup (int wkp)
{
return wkp;
}
int simu_BPM(int BPM)
{
return BPM;
}
int simu_accX(float X)
{
return int(X*100);
}
int simu_accY(float Y)
{
return int(Y*100);
}
int simu_accZ(float Z)
{
return int(Z*100);
}
Comments