Internet de les coses aplicat a la millora del servei de Bicing de Barcelona Pàg. 1 * Program of the TFG: Internet de les Coses Aplicat a la Millora del Servei de Bicing de Barcelona * /****** I N C L U D E S ***************************************************/ #include<p18f4520.h> #include "Configurationbits.h" #include <usart.h> #include <delays.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <math.h> #include<timers.h> #include <pwm.h> #include "definitions.h" /****** D E C L A R A T I O N S ********************************************/
Pàg. 2 unsigned char in = 0, out = 0; //Pointers of the FIFO Buffer. const rom unsigned char accel1[] = "ATS650=1,1,1,2,1"; //AT command to turn on the accelerometer with filter const rom unsigned char accel2[] = "ATS650=1,0,1,2,0";//AT command to turn on the accelerometer without filter const rom unsigned char accel3[] = "ATS650=0"; //AT command to turn off the accelerometer const rom unsigned char gps1[] = "AT$GPS=1,4,900,65535,2,0";//AT command to turn on the GPS until a valid fix is obtained const rom unsigned char gps2[] = "AT$GPS=1,4,900,65535,2,2";//AT command to turn on the GPS until a valid fix is obtained and shows it. const rom unsigned char temp1[] = "ATI26";//AT command to get the temperature const rom unsigned char accident_message[] = "AT$SSMS=accident";//AT command to send an accident message const rom unsigned char tracking_message[] = "AT$SSMS=tracking";//AT command to send a tracking message unsigned char coordinate_message[17] = "AT$SSMS=";//AT command to send a coordinate message const rom unsigned char temp_message[] = "AT$SSMS=T_alert";//AT command to send a temperature message const rom unsigned char broken_bycicle_message[] = "AT$SSMS=bike_out";//AT command to send a "bike is broken" message unsigned char latitude[9] = 0;//String containing the latitude unsigned char longitude[9] = 0;//String containing the longitude unsigned char sec[4]=0;//string used to get the seconds of the coordinates unsigned char xaxis[5] = 0, yaxis[5] = 0, zaxis[5] = 0;//Strings containing the axis acceleration. unsigned char cont=0; //Counter. int x = 0, y = 0, z = 0; //Axis acceleration. unsigned int ac1 = 0, ac2=0; //Acceleration (module).
Internet de les coses aplicat a la millora del servei de Bicing de Barcelona Pàg. 3 unsigned int dif = 0; //Difference between two consecutive acceleration samples. float ang = 0; //Angle of inclination unsigned int c = 0; //10s counter for accident unsigned int c2 = 0; //10s counter for tracking unsigned char c3 = 0; //10min counter for tracking unsigned char c4 = 0; //2h counter for tracking unsigned int pause=1; //Condition to start c unsigned char k=0; //Used in "for" structures unsigned char desac = 0; //Condition to send the accident message unsigned char temp[4]=0;//string containing the temperature int t = 0; //Temperature struct unsigned tracking_flag:1; //Flag to indicate tracking unsigned temperature_flag:1; //Flag to indicate temperature unsigned broken_flag:1; //Flag to indicate that the bike is broken Flags; #pragma udata section = 0x100//Locate the buffer from address 0x100 unsigned char Buffer[256]; //FIFO buffer with 256 positions #pragma udata unsigned int abval(int val); void ini_buffer(void); void Write(unsigned char r); void send_command(const rom unsigned char *s); void send_command2(unsigned char *s); unsigned char str_in_buffer(unsigned char v); unsigned int acceleration(unsigned char ch);
Pàg. 4 float angle(float az); void temperature(void); void send_bike_out_message(void); void pos(void); void InterruptHandlerHigh(void); void send_coordinates(void); /****** M A I N P R O G R A M ********************************************/ void main(void) TRISBbits.TRISB1 = 0; INTCON = 0x00; //Disable all the interrupts OpenTimer0(TIMER_INT_ON & T0_8BIT & T0_SOURCE_INT & T0_PS_1_4); //Open timer0 (8 bits, interrupt enabled, prescaler=4) INTCON2bits.TMR0IP = 1; //High priority for the TMR0 overflow interrupt INTCONbits.TMR0IE = 1; //Enable the TMR0 overflow interrupt TRISCbits.TRISC6 = 0; //Configures RC6 as output (RC6 is the TX-USART pin) //Opens the UART OpenUSART(USART_TX_INT_OFF & USART_RX_INT_OFF & USART_ASYNCH_MODE & USART_EIGHT_BIT & USART_CONT_RX & USART_BRGH_HIGH, 25); OpenTimer2(TIMER_INT_OFF & T2_PS_1_1); //Open timer2 (prescaler=1) OpenPWM1(T); //Configure PWM frequency with Timer2 (period = 230) SetDCPWM1(0); //Fixed Duty Cycle (0%)
Internet de les coses aplicat a la millora del servei de Bicing de Barcelona Pàg. 5 IPR1bits.RCIP = 1; //High priority for the UART interrupt PIE1bits.RCIE = 1; //Enable the UART receive interrupt RCONbits.IPEN = 1; //Enable priority levels ini_buffer();//put all characters to 0. Flags.tracking_flag = 0; Flags.temperature_flag = 0; Flags.broken_flag = 0; INTCONbits.GIEH = 1; //Enable high-priority interrupts send_command(gps1); //Activate GPS send_command(accel1); //Activate accelerometer with filter while(1) if(in!= out) //Is the FIFO Buffer empty? Delay10KTCYx(10); ac2=ac1; ac1 = acceleration(0); //Compute acceleration module dif=abval(ac2-ac1); if (dif > min_difference) //Is dif bigger than minimum difference? ac1=0; SetDCPWM1(Ton); //Fixed Duty Cycle (50%, 10 bits, 1024/2) send_command(accel2); //Activate accelerometer without filter
Pàg. 6 c = 0; pause = 0; //Activate the alarm desac = 0; while (c < t_limit_to_desactivate) //Time to desactivate the alarm if (in!= out) //Is the FIFO Buffer empty? Delay10KTCYx(10); ang = angle ((float)acceleration(1)/ac_module_motionless);//compute angle of inclination SetDCPWM1(0); //Fixed duty cycle (0%) pause = 1; c=0; if (desac == 0) //Is the alarm still activated? pos();//compute coordinates send_command(accident_message); //Send accident message while (in == out); Delay10KTCYx(10); send_coordinates();//send coordinates send_command(accel1); //Activate accelerometer with filter if (Flags.tracking_flag == 1) //Flag activated each 10min
Internet de les coses aplicat a la millora del servei de Bicing de Barcelona Pàg. 7 pressed Flags.tracking_flag = 0; pos(); send_command(tracking_message); //Send tracking message while (in == out); Delay10KTCYx(10); send_coordinates();//send coordinates send_command(accel1); //Activate accelerometer with filter if (Flags.temperature_flag == 1) //Flag activated each 10s Flags.temperature_flag = 0; temperature(); //Compute temperature and send message if (Flags.broken_flag == 1) //Flag activated if de S1 button is Flags.broken_flag = 0; send_bike_out_message();
Pàg. 8 /****** F U N C T I O N S ***********************************************/ * Function: int abval(int val) * Input: Signed integer * Output: Unsigned integer * Overview: Compute module from an integer unsigned int abval(int val) return (val<0? (-val) : val); * Function: void ini_buffer(void) * Input: None * Output: None * Overview: Clean the buffer void ini_buffer(void) unsigned char ct = 0; while (ct!= Buffer_max_position) Buffer[ct++] = 0;
Internet de les coses aplicat a la millora del servei de Bicing de Barcelona Pàg. 9 * Function: void Write(unsigned char r) * Input: Character to send * Output: None * Overview: Send a character to the TD1204 device void Write(unsigned char r) while(busyusart());//wait while UART is busy Delay10KTCYx(2); WriteUSART(r); //Write the character * Function: unsigned char str_in_buffer(unsigned char v) * Input: Buffer's output pointer * Output: Buffer's output pointer Place the out pointer to the first empty place after * Overview: reading the validation sentence unsigned char str_in_buffer(unsigned char v) unsigned char search[] = 'K',13,10; unsigned char ct=0; while(ct!= Buffer_max_position) if(buffer[v+ct] == search[0] && Buffer[v+ct+1] == search[1] && Buffer[v+ct+2] == search[2])
Pàg. 10 return v; ct++; return v+ct+3; * Function: void send_command(const rom unsigned char *s) * Input: Pointer to a ROM buffer containing a command to send * Output: None * Overview: Send a command to the TD1204 device void send_command(const rom unsigned char *s) unsigned char aux; unsigned char cont=0; while (cont < strlenpgm(s)) aux = s[cont++]; Write(aux); Write(carriage_return); Delay10KTCYx(10); * Function: void send_command2(const rom unsigned char *s)
Internet de les coses aplicat a la millora del servei de Bicing de Barcelona Pàg. 11 * Input: Pointer to a RAM buffer containing a command to send * Output: None * Overview: Send a command to the TD1204 device void send_command2(unsigned char *s) unsigned char aux; unsigned char cont=0; while (cont < strlen(s)) aux = s[cont++]; Write(aux); Write(carriage_return); Delay10KTCYx(10); * Function: unsigned int acceleration(unsigned char ch) * Input: 0 or 1 This function return the acceleration module if * Output: input=0 or the acceleration's z component if input=1 * Overview: Compute the acceleration unsigned int acceleration(unsigned char ch) while (Buffer[out]!= space) xaxis[cont++] = Buffer[out++];
Pàg. 12 cont = 0; out+= 3; while (Buffer[out]!= space) yaxis[cont++] = Buffer[out++]; cont = 0; out += 3; while (Buffer[out]!= carriage_return) zaxis[cont++]=buffer[out++]; cont = 0; out+= 2; x = atoi(xaxis); y = atoi(yaxis); z = atoi(zaxis); while(cont!=5) xaxis[cont] = yaxis[cont] = zaxis[cont] = 0; cont++; cont = 0; return (ch? (z) : (sqrt(pow(x,2)+pow(y,2)+pow(z,2)))); * Function: float angle(float az) * Input: Z axis acceleration value (normalized) * Output: Angle of inclination (in radians)
Internet de les coses aplicat a la millora del servei de Bicing de Barcelona Pàg. 13 * Overview: Measure the angle of inclination. float angle(float az) if (0 <= z) return (z > ac_module_motionless? (0) : (acos(az))); else if (0 > z) return (z < -ac_module_motionless? (pi) : (acos(az-16))); * Function: void temperature(void) * Input: None * Output: None Read temperature and send an alarm message if it's * Overview: out of the limits void temperature(void) send_command(accel3); send_command(temp1); out += 2; while (Buffer[out]!= carriage_return) temp[cont++]=buffer[out++];
Pàg. 14 cont=0; out+=8; t = atoi(temp); while(cont!=4) temp[cont++] = 0; cont = 0; if (t > t_max t < t_min) send_command(temp_message); while (in == out); Delay10KTCYx(10); send_command(accel1); * Function: void send_bike_out_message(void) * Input: None * Output: None * Overview: Send the message: bike_out void send_bike_out_message(void) send_command(accel3);
Internet de les coses aplicat a la millora del servei de Bicing de Barcelona Pàg. 15 send_command(broken_bycicle_message); while (in == out); Delay10KTCYx(10); send_command(accel1); * Function: void pos(void) * Input: None * Output: None * Overview: Compute longitude and latitude void pos(void) send_command(accel3); send_command(gps2); while (in == out); Delay10KTCYx(30); out+=17; latitude[0] = Buffer[out++]; latitude[1] = Buffer[out++]; latitude[2] = degrees; latitude[3] = Buffer[out++]; latitude[4] = Buffer[out++]; latitude[5] = minutes; out++;
Pàg. 16 for (k=0;k<4;k+=1) sec[k] = Buffer[out++]; latitude[6] = ((char)(atoi(sec)*v2seconds))/10 + '0'; latitude[7] = ((char)(atoi(sec)*v2seconds))%10 + '0'; latitude[8] = seconds; out+=5; longitude[0] = Buffer[out++]; longitude[1] = Buffer[out++]; longitude[2] = degrees; longitude[3] = Buffer[out++]; longitude[4] = Buffer[out++]; longitude[5] = minutes; out++; for (k=0;k<4;k+=1) sec[k] = Buffer[out++]; longitude[6] = ((char)(atoi(sec)*v2seconds))/10 + '0'; longitude[7] = ((char)(atoi(sec)*v2seconds))%10 + '0'; longitude[8] = seconds; out = in; * Function: void send_coordinates(void) * Input: None * Output: None * Overview: Send two messages containing longitude and latitude
Internet de les coses aplicat a la millora del servei de Bicing de Barcelona Pàg. 17 void send_coordinates(void) unsigned char c5 = 0; for (k=8;k<17;k+=1) coordinate_message[k] = longitude[c5++]; send_command2(coordinate_message); while (in == out); Delay10KTCYx(10); c5 = 0; for (k=8;k<17;k+=1) coordinate_message[k] = latitude[c5++]; send_command2(coordinate_message); while (in == out); Delay10KTCYx(10); /****** I N T E R R U P T I O N S ***********************************/ // High priority interrupt vector------------------------------------------------- #pragma code InterruptVectorHigh = 0x08 void InterruptVectorHigh(void)
Pàg. 18 _asm goto InterruptHandlerHigh //Jump to interrupt routine (ISR) _endasm //--------------------------------------------------------------------------------- // High priority interrupt routine------------------------------------------------- #pragma code #pragma interrupt InterruptHandlerHigh void InterruptHandlerHigh() //Receive interrupt if(pir1bits.rcif) //Receive interrupt flag PIR1bits.RCIF = 0; //Delete receive interrupt flag Buffer[in++] = ReadUSART();//Read the received character //Timer0 overflow interrupt if(intconbits.tmr0if) //Timer0 overflow interrupt flag INTCONbits.TMR0IF = 0; //Delete timer0 overflow interrupt flag WriteTimer0(PRELOAD); LATBbits.LATB1=!LATBbits.LATB1; //Accident alarm code if (pause == 0) //Is the alarm activated? c++; if ((S0 == 0) && (ang < max_angle)) desac = 1; //Deactivate the alarm
Internet de les coses aplicat a la millora del servei de Bicing de Barcelona Pàg. 19 c = t_limit_to_desactivate; //Tracking, temperature and bike_out code c2++; if (c2 == 10000) //Each 10s c2=0; c3++; Flags.temperature_flag = 1; //Activate temperature flag if (c3 == 60) //Each 10min c2 = 0; c3 = 0; c4++; Flags.tracking_flag = 1; //Activate tracking flag if (c4>=12) //From 2h SetDCPWM1(Ton); //Fixed duty cycle (50%, 10 bits, 1024/2) if (S1 == 0) //Is button S1 pressed? Flags.broken_flag = 1; //Activate broken flag
Pàg. 20 /****** D E F I N I T O N S ************************************************/ #define S0 PORTDbits.RD1//Define RD1 button as S0 #define S1 PORTDbits.RD0//Define RD0 button as S1 #define PRELOAD 240//Preload to fix the interrupt rate #define T 230//Periode of the square wave #define Ton 512//Duty cycle of the square wave #define min_difference 100//Tinimum difference to turn on the alarm #define t_limit_to_desactivate 10000//Time limit to desactivate the alarm (10s) #define ac_module_motionless 4096//Acceleration module resting #define Buffer_max_position 255//Number of positions of the fifo buffer #define pi 3.14159//Pi value in radians #define max_angle 0.52359 //(pi/3)//pi/3 value in radians #define carriage_return 13//Carriage_return in ASCII #define space 32//Space in ASCII #define degrees 176//Degrees symbol in ASCII #define minutes 39//Minutes symbol in ASCII #define seconds 34//Seconds symbol in ASCII #define v2seconds 0.006//Value to convert to seconds #define t_max 45//Maximum temperature #define t_min -10//Minimum temperature