PIC18f with GPS to the LCD, small issue--need help

Thread Starter

chillcat

Joined Jan 23, 2018
15
I will send SMS, I have the basic code written, my PIC seems to cycle through the sending routine 3 times and stops, based on my oscilloscope. I can't figure that one out yet, I want it to continually send every 15 secs (for now). Attached is my new code.
Code:
// GPS function using PIC18f4520....Team Unicorn
#define _XTAL_FREQ 8000000 // subject to change
#include <stdint.h> // width values
#include <stdio.h>
#include <stdlib.h>
#include <xc.h>
#include <string.h> // string readout data
#pragma config BOREN=ON,LVP=OFF,CPD=OFF,OSC=INTIO7,WDT=OFF

void GPS_DATA(void);
void LCDinit(), LCDcmd(int unicorn), LCDstring(char *unicorn), LCDdata(int unicorn);        // LCD stuff
void Delay_Ms(unsigned int delay);
void UART_Write(char data),UART_Write_Text(char *text);
void UART_Read_Text(char *Output, unsigned int length),uart_init(void);
// void UTC_to_EST(void);
char UART_Read(),UART_Data_Ready(),UART_TX_Empty();
char UART_Init(const long int baudrate);

unsigned char LATITUDE[9],LAT_Dir[1],LONGITUDE[10],LON_Dir[1],buffer[7],gps_header[]="GPGGA,";      // for GPS string array
unsigned char TIME[6];

char UART_TX_Empty(){
  return TRMT;}

void UART_Read_Text(char *Output, unsigned int length){
    int i;
    for(int i=0; i<length; i++)
        Output[i] = UART_Read();}

void UART_Write(char data){
  while(!TRMT);
  TXREG = data;}

void UART_Write_Text(char *text){
    int i;
    for(i=0; text[i]!='\0'; i++)
    UART_Write(text[i]);}

void send_sms(){
UART_Write_Text("AT+CMGF=1\r\n");
__delay_ms(10);           // sets SMS mode to text
UART_Write_Text("AT+CMGS=");
__delay_ms(10);
UART_Write_Text("\"");
__delay_ms(10);
UART_Write_Text("+013526010100");
__delay_ms(10); 
UART_Write_Text("\"\r\n");
__delay_ms(10);
UART_Write_Text("LAT=");
__delay_ms(10);
UART_Write_Text(LATITUDE,LAT_Dir);
__delay_ms(10);
UART_Write_Text("LON=");
__delay_ms(10);
UART_Write_Text(LONGITUDE,LON_Dir);
__delay_ms(10);
UART_Write(0x1A);
__delay_ms(50);
}

void GPS_DATA(void){    // $GPRMC,[194530][.000,A,][3051.8007],[N],[10035.9989],[W],1.49,111.67,310714,,,A*74
                        // HOME: 29.0152284,-82.5726796
    int i;
//    i = 0;
    char Temp = 0;
    Temp = UART_Read();
    if(Temp == '$'){
        for(i=0; i<6; i++){
            Temp = UART_Read();
            buffer[i] = Temp;}             // puts $GPGGA, into buffer
        if(strcmp(buffer, gps_header) == 0){     // compare buffer data with header title "GPGGA", STARTS AT THAT STRING!
// UTC TIME (character count)
            for(i=0; i<6; i++){
                Temp = UART_Read();
                TIME[i] = Temp;            }
// garbage (.000,A,)
            for(i=0; i<5; i++){
                Temp = UART_Read();}
// LATITUDE (character count)
            for(i=0; i<9; i++){
                Temp = UART_Read();
                LATITUDE[i] = Temp;}
// garbage (,)
            for(i=0; i<1; i++){Temp = UART_Read();}
// NORTH
            for(i=0; i<1; i++){
                Temp = UART_Read();
                LAT_Dir[i] = Temp;}
// garbage (,)
            for(i=0; i<1; i++){Temp = UART_Read();}
// LONGITUDE (character count)
            for(i=0; i<10; i++){
                Temp = UART_Read();
                LONGITUDE[i] = Temp;}
// garbage (,)
            for(i=0; i<1; i++){Temp = UART_Read();}
// WEST
            for(i=0; i<1; i++){
                Temp = UART_Read();
                LON_Dir[i] = Temp;}
// UTC TIME (LCD display)
            LCDcmd(0x80),LCDstring("TIME:  ");
            LCDdata(TIME[0]),LCDdata(TIME[1]),LCDstring(":");
            LCDdata(TIME[2]),LCDdata(TIME[3]),LCDstring(":");
            LCDdata(TIME[4]),LCDdata(TIME[5]),LCDstring("     ");
// LATITUDE (LCD display)
            LCDcmd(0xC0),LCDstring("LAT:    ");
            LCDdata(LATITUDE[0]),LCDdata(LATITUDE[1]),LCDstring("°"),LCDdata(LATITUDE[2]);
            LCDdata(LATITUDE[3]),LCDdata(LATITUDE[4]),LCDdata(LATITUDE[5]);
            LCDdata(LATITUDE[6]),LCDdata(LATITUDE[7]),LCDdata(LATITUDE[8]);
            LCDstring(" "),LCDdata(LAT_Dir[0]);
// LONGITUDE (LCD display)
            LCDcmd(0x94),LCDstring("LON:   ");
            LCDdata(LONGITUDE[0]),LCDdata(LONGITUDE[1]),LCDdata(LONGITUDE[2]),LCDstring("°");
            LCDdata(LONGITUDE[3]),LCDdata(LONGITUDE[4]),LCDdata(LONGITUDE[5]);
            LCDdata(LONGITUDE[6]),LCDdata(LONGITUDE[7]),LCDdata(LONGITUDE[8]);
            LCDdata(LONGITUDE[9]),LCDstring(" "),LCDdata(LON_Dir[0]);
// HORSE STATUS (LCD display)  <--------------- Interrupt will take over elsewhere from this point!!!
            LCDcmd(0xD4),LCDstring("Status:   Healthy   ");
        }
    }
}

int main(void){

    OSCCON = 0x76;                      // Sets internal oscillator to 8MHz
    TRISA = 0b11111110;                 // LED: for Interrupt warnings. breakaway, horse health
//    TRISB = 0b11110111;                 // Interupt: B3 (breakaway out), B4 (breakaway in), PIC2 input on port B also!!!
    TRISD = 0b01100000;                 // LCD: E-D7,RS-D4, Data-3:0
    TRISC = 0b11111111;                 // GPS(RC7)
    Delay_Ms(10);
    LCDinit();
    Delay_Ms(10);
    LCDcmd(0x80),LCDstring("   TEAM UNICORN   "),LCDcmd(0xC0),LCDstring("My Horse is Amazing");
    LCDcmd(0x94),LCDstring(""),LCDcmd(0xD4),LCDstring("Searching Satellites");
//   Delay_Ms(100);
    UART_Init(9600);
    Delay_Ms(10);
    PORTAbits.RA0 = 0;
    while(1){
        GPS_DATA();
        Delay_Ms(500);
        send_sms();
        Delay_Ms(50);
   //     PORTAbits.RA0 = 1;
        Delay_Ms(1000);
    //    LATITUDE[9]=0,LAT_Dir[1]=0,LONGITUDE[10]=0,LON_Dir[1]=0,buffer[7]=0;
    //    Delay_Ms(100);
    }
}

char UART_Init(const long int baudrate){
    unsigned int x;
    x = (_XTAL_FREQ - baudrate*64)/(baudrate*64);
        SPBRG = x;
        SYNC = 0,       SPEN = 1;
        TRISC7 = 1,     TRISC6 = 1;
        CREN = 1,       TXEN = 1;
        return 1;
  //  return 0;
}

char UART_Read(){
    while(RCIF == 0);                   // wait until receive completes
    return RCREG;}
 

Thread Starter

chillcat

Joined Jan 23, 2018
15
Ok with the gps fixed, now the output TX is giving me an issue. So upon reprogramming or restarting chip I get 3 data sends occurring on the osillosope within 5 secs of each other. I set the delay time after SEND_SMS function low so it's outputing to gsm every 5 secs or so, I see the data pulse 3 times in row then stops. I don't have any limitation that I know of so I'm not sure why it stops, I should see it continually send every 5 secs. Does the PIC have a limitation that if the gsm doesn't respond then it quits sending data ? Currently have no gsm connected as I'm still shopping for one. Just scoping it for now

Code:
// GPS function using PIC18f4520....Team Unicorn
#define _XTAL_FREQ 8000000 // subject to change
#include <stdint.h> // width values
#include <stdio.h>
#include <stdlib.h>
#include <xc.h>
#include <string.h> // string readout data
#pragma config BOREN=ON,LVP=OFF,CPD=OFF,OSC=INTIO7,WDT=OFF

void GPS_DATA(void);
void LCDinit(), LCDcmd(int unicorn), LCDstring(char *unicorn), LCDdata(int unicorn);        // LCD stuff
void Delay_Ms(unsigned int delay);
void UART_Write(char data),UART_Write_Text(char *text);
void UART_Read_Text(char *Output, unsigned int length),uart_init(void);
// void UTC_to_EST(void);
char UART_Read(),UART_Data_Ready(),UART_TX_Empty();
char UART_Init(const long int baudrate);

unsigned char LATITUDE[9],LAT_Dir[1],LONGITUDE[10],LON_Dir[1],buffer[7],gps_header[]="GPGGA,";      // for GPS string array
unsigned char TIME[6];

char UART_TX_Empty(){
  return TRMT;}

void UART_Read_Text(char *Output, unsigned int length){
    int i;
    for(int i=0; i<length; i++)
        Output[i] = UART_Read();}

void UART_Write(char data){
  while(!TRMT);
  TXREG = data;}

void UART_Write_Text(char *text){
    int i;
    for(i=0; text[i]!='\0'; i++)
    UART_Write(text[i]);}

void send_sms(){
UART_Write_Text("AT+CMGF=1\r\n"),       __delay_ms(10);           // sets SMS mode to text
UART_Write_Text("AT+CMGS="),            __delay_ms(10);
UART_Write_Text("\""),                  __delay_ms(10);
UART_Write_Text("+013526010100"),       __delay_ms(10);
UART_Write_Text("\"\r\n"),              __delay_ms(10);
UART_Write_Text("LAT="),                __delay_ms(10);
UART_Write_Text(LATITUDE),              __delay_ms(10);
UART_Write_Text("LON="),                __delay_ms(10);
UART_Write_Text(LONGITUDE),             __delay_ms(10);
UART_Write(0x1A),                       __delay_ms(50);
}

void GPS_DATA(void){    // $GPRMC,[194530][.000,A,][3051.8007],[N],[10035.9989],[W],1.49,111.67,310714,,,A*74

    int i;
//    i = 0;
    char Temp = 0;
    Temp = UART_Read();
    if(Temp == '$'){
        for(i=0; i<6; i++){
            Temp = UART_Read();
            buffer[i] = Temp;}             // puts $GPGGA, into buffer
        if(strcmp(buffer, gps_header) == 0){     // compare buffer data with header title "GPGGA", STARTS AT THAT STRING!
// UTC TIME (character count)
            for(i=0; i<6; i++){
                Temp = UART_Read();
                TIME[i] = Temp;            }
// garbage (.000,A,)
            for(i=0; i<5; i++){
                Temp = UART_Read();}
// LATITUDE (character count)
            for(i=0; i<9; i++){
                Temp = UART_Read();
                LATITUDE[i] = Temp;}
// garbage (,)
            for(i=0; i<1; i++){Temp = UART_Read();}
// NORTH
            for(i=0; i<1; i++){
                Temp = UART_Read();
                LAT_Dir[i] = Temp;}
// garbage (,)
            for(i=0; i<1; i++){Temp = UART_Read();}
// LONGITUDE (character count)
            for(i=0; i<10; i++){
                Temp = UART_Read();
                LONGITUDE[i] = Temp;}
// garbage (,)
            for(i=0; i<1; i++){Temp = UART_Read();}
// WEST
            for(i=0; i<1; i++){
                Temp = UART_Read();
                LON_Dir[i] = Temp;}
// UTC TIME (LCD display)
            LCDcmd(0x80),LCDstring("TIME:  ");
            LCDdata(TIME[0]),LCDdata(TIME[1]),LCDstring(":");
            LCDdata(TIME[2]),LCDdata(TIME[3]),LCDstring(":");
            LCDdata(TIME[4]),LCDdata(TIME[5]),LCDstring("     ");
// LATITUDE (LCD display)
            LCDcmd(0xC0),LCDstring("LAT:    ");
            LCDdata(LATITUDE[0]),LCDdata(LATITUDE[1]),LCDstring("°"),LCDdata(LATITUDE[2]);
            LCDdata(LATITUDE[3]),LCDdata(LATITUDE[4]),LCDdata(LATITUDE[5]);
            LCDdata(LATITUDE[6]),LCDdata(LATITUDE[7]),LCDdata(LATITUDE[8]);
            LCDstring(" "),LCDdata(LAT_Dir[0]);
// LONGITUDE (LCD display)
            LCDcmd(0x94),LCDstring("LON:   ");
            LCDdata(LONGITUDE[0]),LCDdata(LONGITUDE[1]),LCDdata(LONGITUDE[2]),LCDstring("°");
            LCDdata(LONGITUDE[3]),LCDdata(LONGITUDE[4]),LCDdata(LONGITUDE[5]);
            LCDdata(LONGITUDE[6]),LCDdata(LONGITUDE[7]),LCDdata(LONGITUDE[8]);
            LCDdata(LONGITUDE[9]),LCDstring(" "),LCDdata(LON_Dir[0]);
// HORSE STATUS (LCD display)  <--------------- Interrupt will take over elsewhere from this point!!!
            LCDcmd(0xD4),LCDstring("Status:   Healthy   ");
        }
    }
}

int main(void){

//   OSCCON = 0x76;                      // Sets internal oscillator to 8MHz
    TRISA = 0b11111110;                 // LED: for Interrupt warnings. breakaway, horse health
//    TRISB = 0b11110111;                 // Interupt: B3 (breakaway out), B4 (breakaway in), PIC2 input on port B also!!!
    TRISD = 0b01100000;                 // LCD: E-D7,RS-D4, Data-3:0
    TRISC = 0b11111111;                 // GPS(RC7)
    Delay_Ms(10);
    LCDinit();
    Delay_Ms(10);
    LCDcmd(0x80),LCDstring("   TEAM UNICORN   "),LCDcmd(0xC0),LCDstring("My Horse is Amazing");
    LCDcmd(0x94),LCDstring(""),LCDcmd(0xD4),LCDstring("Searching Satellites");
//   Delay_Ms(100);
    UART_Init(9600);
    Delay_Ms(10);
    PORTAbits.RA0 = 0;
    while(1){
        PORTAbits.RA0 = 0;
        GPS_DATA();
        PORTAbits.RA0 = 1;
        Delay_Ms(250);
        send_sms();
//        Delay_Ms(50);
        Delay_Ms(1000);
        PORTAbits.RA0 = 1;
        Delay_Ms(500);
    //    LATITUDE[9]=0,LAT_Dir[1]=0,LONGITUDE[10]=0,LON_Dir[1]=0,buffer[7]=0;
    //    Delay_Ms(100);
    }
//   return;
}

char UART_Init(const long int baudrate){
    unsigned int x;
    x = (_XTAL_FREQ - baudrate*64)/(baudrate*64);
        SPBRG = x;
        SYNC = 0,       SPEN = 1;
        TRISC7 = 1,     TRISC6 = 1;
        CREN = 1,       TXEN = 1;
        return 1;
  //  return 0;
}

char UART_Read(){
    while(RCIF == 0);                   // wait until receive completes
    return RCREG;}

void LCDinit(){
    LCDcmd(0x33);           // 4b Mode
    LCDcmd(0x32);           // E
    LCDcmd(0x2C);           // 2-L mode
    LCDcmd(0x0C);           // Disp On,Curs Off,Blink On
    LCDcmd(0x01);}          // clear

void LCDcmd(int unicorn){                                                   // LCD CMD 4-BIT, E(bit7),RS(bit4)
    PORTD = 0;                                                                  // E=0 RS=0
    int temp = unicorn;
    _delay(2000);
    unicorn = ((unicorn >> 4) & 0x0F)|0x80;                                         // E=1 RS=0, writes UPPER NIB to LCD: S.R. 4 bits, clears upper bits, bitmask
    PORTD = unicorn, _delay(2000);
    unicorn = unicorn & 0x0F;                                               // E=0, preserve lower (lower nib is to be sent)
    PORTD = unicorn, _delay(2000);
    PORTD = 0;                                                  // E=0 RS=0
    unicorn = temp;
    unicorn = (unicorn & 0x0F)|0x80;                                    // E=1 RS=0, writes LOWER NIB to LCD: clears upper bits, bitmask
    PORTD = unicorn, _delay(2000);
    unicorn = unicorn & 0x0F;                                               // E=0, preserve lower (lower nib is to be sent)
    PORTD = unicorn, _delay(2000);}

void LCDdata(int unicorn){                                                          // LCD CMD 4-BIT, E(bit7),RS(bit4)
    PORTD = 0;                                                                      // E=0 RS=0
    int temp = unicorn;
    _delay(1000);
    unicorn = ((unicorn >> 4) & 0x0F)|0x90;                                 // E=1 RS=1, writes UPPER NIB to LCD: S.R. 4 bits, clears upper bits, bitmask
    PORTD = unicorn, _delay(1000);
    unicorn = (unicorn & 0x0F)|0x10;                                // E=0 RS=1, preserve lower (lower nib is to be sent)
    PORTD = unicorn, _delay(1000);
    PORTD = 0;                                              // E=0 RS=0
    unicorn = temp;
    unicorn = (unicorn & 0x0F)|0x90;                        // E=1 RS=1, writes LOWER NIB to LCD: clears upper bits, bitmask
    PORTD = unicorn, _delay(1000);
    unicorn = (unicorn & 0x0F)|0x10;                                        // E=0 RS=1, preserve lower (lower nib is to be sent)
    PORTD = unicorn, _delay(1000);}

void LCDstring(char *unicorn){
    int I = 0;
    int temp;
    int count = strlen(unicorn);                            // count = the length of the string john
    while(I < count){                                               // While loop to determine the length of data for LCD string
    temp = unicorn[I++];                                            // temp = part2LCD increment for the null value places
    LCDdata(temp);}}

void Delay_Ms(unsigned int delay){
    unsigned int i,j;
    for(i=0; i<delay; i++)
    for(j=0; j<1000; j++);}
 
Last edited:

Thread Starter

chillcat

Joined Jan 23, 2018
15
Disregard post #22. Ok so I commented out GET_GPS function so it should only be outputting and it is indeed outputting nonstop, so something in my Get_Gps function is stopping things.
 
Top