Stuck on Interrupts

Store Forums Video Experimenter General Discussion Stuck on Interrupts

Viewing 15 posts - 1 through 15 (of 34 total)
  • Author
    Posts
  • #529
    joey
    Member

    Hi,

    So I finished up my project and ran into two problems, one I can work around, another I’m stuck on.

    My project involves an arduino, the VE, a GPS shield, and a temperature probe. I’m displaying an overlay with this and another piece of data.

    Problem 1: I wanted to put the GPS on top of the stack but the pins are not in the standard place on the VE board. Thankfully the GPS works in the middle of the sandwich of boards.

    Problem 2: I’ve run across a problem with RX/TX. The GPS uses pins 0 & 1 and it appears that the VE also uses these. If I enable these


    // EIMSK = _BV(INT0);
    // EICRA = _BV(ISC11);

    then the GPS stops working. If I leave them disabled, I get the correct output from my sketch over serial but when I put the VE on, the stack stops working. As soon as I remove it, serial works again.

    Any ideas on how to get around this problem?


    // This is an example of how to always present your callsign and other goodies on a VE
    // Note that there is no known way to display the degree symbol as the char chart is different
    // joey@stan4d.net

    // Make sure to install newsoftserial from Mikal Hart
    // http://arduiniana.org/libraries/NewSoftSerial/
    #include

    #include
    #include

    // Use pins 2 and 3 to talk to the GPS. 2 is the TX pin, 3 is the RX pin
    NewSoftSerial mySerial = NewSoftSerial(2, 3);

    // Use pin 4 to control power to the GPS
    const int powerpin = 4;

    // Set the GPSRATE to the baud rate of the GPS module. Most are 4800
    // but some are 38400 or other. Check the datasheet!
    const int GPSRATE=4800;


    // The buffer size that will hold a GPS sentence. They tend to be 80 characters long
    // so 90 is plenty.
    const int BUFFSIZ=90; // plenty big

    TVout tv;
    char messageTop[96] = "";
    char messageBottom[96] = "";
    char messageBottom2[96] = "";
    const char callsign[] = "NV0N";

    //TMP36 Pin Variables
    const int temperaturePin = 0; //the analog pin the TMP36's Vout (sense) pin is connected to
    //the resolution is 10 mV / degree centigrade
    //(500 mV offset) to make negative temperatures an option
    char charTemp[3] = ""; //the char representation of the float for temp


    // GPS global variables
    char buffer[BUFFSIZ]; // string buffer for the sentence
    char *parseptr; // a character pointer for parsing
    char buffidx; // an indexer into the buffer

    // The time, date, location data, etc.
    uint8_t hour, minute, second, year, month, date;
    uint32_t latitude, longitude;
    uint8_t groundspeed, trackangle;
    char latdir, longdir;
    char status;

    char charTmp[4] = " ";
    char charTime[6] = "00:00";
    char charDate[9] = "00/00/00";
    char gpsCoords[13] = "";



    void setup() {
    tv.begin(0);
    initOverlay();
    tv.select_font(font6x8);
    tv.fill(0);
    if (powerpin) {
    pinMode(powerpin, OUTPUT);
    }
    // Use the pin 13 LED as an indicator
    // pinMode(13, OUTPUT);

    // connect to the serial terminal at 9600 baud
    Serial.begin(9600);

    // connect to the GPS at the desired rate
    mySerial.begin(GPSRATE);

    // prints title with ending line break
    Serial.println("void setup running");

    digitalWrite(powerpin, LOW); // pull low to turn on!
    }


    // Initialize ATMega registers for video overlay capability.
    // Must be called after tv.begin().
    void initOverlay() {
    TCCR1A = 0;
    // Enable timer1. ICES0 is set to 0 for falling edge detection on input capture pin.
    TCCR1B = _BV(CS10);

    // Enable input capture interrupt
    TIMSK1 |= _BV(ICIE1);

    // XXX this causes the GPS to stop working when enabled
    // Enable external interrupt INT0 on pin 2 with falling edge.
    // EIMSK = _BV(INT0);
    // EICRA = _BV(ISC11);
    }

    // Required to reset the scan line when the vertical sync occurs
    ISR(INT0_vect) {
    display.scanLine = 0;
    }


    void loop() {

    uint32_t tmp;

    // Serial.print("nrRead: ");
    readline();

    // check if $GPRMC (global positioning fixed data)
    if (strncmp(buffer, "$GPRMC",6) == 0) {
    // hhmmss time data
    parseptr = buffer+7;
    tmp = parsedecimal(parseptr);
    hour = tmp / 10000;
    minute = (tmp / 100) % 100;
    second = tmp % 100;

    parseptr = strchr(parseptr, ',') + 1;
    status = parseptr[0];
    parseptr += 2;

    // grab latitude & long data
    // latitude
    latitude = parsedecimal(parseptr);
    if (latitude != 0) {
    latitude *= 10000;
    parseptr = strchr(parseptr, '.')+1;
    latitude += parsedecimal(parseptr);
    }
    parseptr = strchr(parseptr, ',') + 1;
    // read latitude N/S data
    if (parseptr[0] != ',') {
    latdir = parseptr[0];
    }

    //Serial.println(latdir);

    // longitude
    parseptr = strchr(parseptr, ',')+1;
    longitude = parsedecimal(parseptr);
    if (longitude != 0) {
    longitude *= 10000;
    parseptr = strchr(parseptr, '.')+1;
    longitude += parsedecimal(parseptr);
    }
    parseptr = strchr(parseptr, ',')+1;
    // read longitude E/W data
    if (parseptr[0] != ',') {
    longdir = parseptr[0];
    }


    // groundspeed
    parseptr = strchr(parseptr, ',')+1;
    groundspeed = parsedecimal(parseptr);

    // track angle
    parseptr = strchr(parseptr, ',')+1;
    trackangle = parsedecimal(parseptr);


    // date
    parseptr = strchr(parseptr, ',')+1;
    tmp = parsedecimal(parseptr);
    date = tmp / 10000;
    month = (tmp / 100) % 100;
    year = tmp % 100;

    // Serial.print("ntTime: ");
    // Serial.print(hour, DEC);
    // Serial.print(':');
    // Serial.print(minute, DEC);
    // Serial.print(':');
    // Serial.println(second, DEC);
    itoa(int(hour),charTime,10); // sprintf fails so we use this
    strcat(charTime,":");
    itoa(int(minute),charTmp,10); // sprintf fails so we use this
    strcat(charTime, charTmp);
    // Serial.print("tDate: ");
    // Serial.print(month, DEC);
    // Serial.print('/');
    // Serial.print(date, DEC);
    // Serial.print('/');
    // Serial.println(year, DEC);
    itoa(int(month),charDate,10); // sprintf fails so we use this
    strcat(charDate,"/");
    itoa(int(date),charTmp,10); // sprintf fails so we use this
    strcat(charDate, charTmp);
    strcat(charDate,"/");
    itoa(int(year),charTmp,10); // sprintf fails so we use this
    strcat(charDate, charTmp);

    // Serial.print("tLat: ");
    if (latdir == 'N') {
    // Serial.print('+');
    strcpy(gpsCoords,"+");
    }
    else if (latdir == 'S') {
    // Serial.print('-');
    strcpy(gpsCoords,"-");
    }

    // Serial.print(latitude/1000000, DEC);
    // Serial.print("* ");
    itoa(int(latitude/1000000),charTmp,10); // sprintf fails so we use this
    strcat(gpsCoords, charTmp);
    strcat(gpsCoords, "*");
    strcat(gpsCoords, " ");
    // Serial.print((latitude/10000)%100, DEC);
    // Serial.print(''');
    itoa(int((latitude/10000)%100),charTmp,10); // sprintf fails so we use this
    strcat(gpsCoords, charTmp);
    strcat(gpsCoords, "'");
    strcat(gpsCoords, " ");
    // Serial.print(' ');
    // Serial.print((latitude%10000)*6/1000, DEC);
    // Serial.print('.');
    // Serial.print(((latitude%10000)*6/10)%100, DEC);
    // Serial.println('"');

    // Serial.print("tLong: ");
    if (longdir == 'E'){
    // Serial.print('+');
    strcat(gpsCoords,"+");
    }
    else if (longdir == 'W') {
    // Serial.print('-');
    strcat(gpsCoords,"-");
    }
    // Serial.print(longitude/1000000, DEC);
    // Serial.print("* ");
    itoa(int(longitude/1000000),charTmp,10); // sprintf fails so we use this
    strcat(gpsCoords, charTmp);
    strcat(gpsCoords, "*");
    strcat(gpsCoords, " ");
    // Serial.print((longitude/10000)%100, DEC);
    // Serial.print(''');
    itoa(int((longitude/10000)%100),charTmp,10); // sprintf fails so we use this
    strcat(gpsCoords, charTmp);
    strcat(gpsCoords, "'");
    strcat(gpsCoords, " ");
    // Serial.print(' ');
    // Serial.print((longitude%10000)*6/1000, DEC);
    // Serial.print('.');
    // Serial.print(((longitude%10000)*6/10)%100, DEC);
    // Serial.println('"');
    }
    // temperature

    float temperature = getVoltage(temperaturePin); //getting the voltage reading from the temperature sensor
    temperature = (((temperature - .5) * 100)*1.8) + 32; //converting from 10 mv per degree wit 500 mV offset


    // setup the messages for output on the tv

    // clear at start of loop
    sprintf(messageTop, "");
    sprintf(messageBottom, "");
    sprintf(messageBottom2, "");

    //assemble top message
    strcat(messageTop,callsign);

    // assemble bottom message
    strcat(messageBottom,charTime);
    strcat(messageBottom," ");
    strcat(messageBottom,charDate);
    strcat(messageBottom,"Z ");
    itoa(int(temperature),charTemp,10); // sprintf fails so we use this
    strcat(messageBottom,charTemp);
    strcat(messageBottom,"F");

    // assemble 2nd bottom meessage
    strcat(messageBottom2,gpsCoords);

    // write out to TV
    tv.select_font(font6x8);
    tv.print(0,0, messageTop);
    // Serial.print("messageTop=");
    // Serial.println(messageTop);


    // the 4x6 font is awefully small. I thought of scrolling but that's too distracting.
    // right now it's a bit small to read.
    tv.select_font(font4x6);
    tv.print(0,75, messageBottom);
    Serial.print("messageBottom=");
    Serial.println(messageBottom);
    tv.print(0,85, messageBottom2);
    Serial.print("messageBottom2=");
    Serial.println(messageBottom2);

    }



    uint32_t parsedecimal(char *str) {
    uint32_t d = 0;

    while (str[0] != 0) {
    if ((str[0] > '9') || (str[0] < '0'))
    return d;
    d *= 10;
    d += str[0] - '0';
    str++;
    }
    return d;
    }

    void readline(void) {
    char c;

    buffidx = 0; // start at begninning
    while (1) {
    c=mySerial.read();
    // Serial.print("readline while 1. c=");
    // Serial.println(c);
    if (c == -1)
    continue;
    // Serial.print(c);
    if (c == 'n')
    continue;
    if ((buffidx == BUFFSIZ-1) || (c == 'r')) {
    buffer[buffidx] = 0;
    return;
    }
    buffer[buffidx++]= c;
    }
    }


    /*
    * getVoltage() - returns the voltage on the analog input defined by
    * pin
    */
    float getVoltage(int pin){
    return (analogRead(pin) * .004882814); //converting from a 0 to 1024 digital range
    // to 0 to 5 volts (each 1 reading equals ~ 5 millivolts
    }
    #1337
    joey
    Member

    I found two possible solutions that I’ll try later today.

    1) I’m using soft serials so I could potentially just change the soft serial ports!

    2) If that fails I found the docs to hook my GPS directly to the board. I could try this and hook it to the VE.

    J

    #1338
    joey
    Member

    looks like the VE and the GPS Shield both share D2. I can fix that on the GPS shield so off to the workbench I go.

    #1339
    joey
    Member

    So with some soldering I got the stack to work but am having an issue with interrupts.

    The newsoftserial uses int 0 – 4 which conflicts with


    void initOverlay() {
    TCCR1A = 0;
    // Enable timer1. ICES0 is set to 0 for falling edge detection on input capture pin.
    TCCR1B = _BV(CS10);

    // Enable input capture interrupt
    TIMSK1 |= _BV(ICIE1);

    // Enable external interrupt INT0 on pin 2 with falling edge.
    EIMSK = _BV(INT0);
    EICRA = _BV(ISC11);
    }

    Is there anyway to change these interrupts?

    #1340
    joey
    Member

    fwiw, I found tinygps and rewrote the program using it. It uses newsoftserial too so the interrupts are still an issue.


    // This is an example of how to always present your callsign and other goodies on a VE
    // Note that there is no known way to display the degree symbol as the char chart is different
    // joey@stan4d.net

    // Make sure to install newsoftserial and tinyGPS from Mikal Hart
    // http://arduiniana.org/libraries/NewSoftSerial/
    #include
    #include


    #include
    #include


    // Use pins 4 and 5 to talk to the GPS. 5 is the TX pin, 4 is the RX pin
    // I had to unsolder the jumpers and rewire the GPS Sheild to avoid pin 2
    // pin 2 is in use by the VE
    // Create an instance of the TinyGPS object
    const int RXPIN=5;
    const int TXPIN=4;
    TinyGPS gps;
    NewSoftSerial uart_gps(RXPIN, TXPIN);


    // Set the GPSRATE to the baud rate of the GPS module. Most are 4800
    // but some are 38400 or other. Check the datasheet!
    const int GPSBAUD=4800;

    // declare the GPS variables
    char charTmp[10] = "";
    char charTime[6] = "00:00";
    char charDate[11] = "00/00/0000";
    char gpsCoords[15] = "";
    char gpsAlt[6] = "0000M";


    // This is where you declare prototypes for the functions that will be
    // using the TinyGPS library.
    void getgps(TinyGPS &gps);

    TVout tv;
    char messageTop[96] = "";
    char messageBottom[96] = "";
    char messageLastline[96] = "";
    const char callsign[] = "NV0N";

    //TMP36 Pin Variables
    const int temperaturePin = 0; //the analog pin the TMP36's Vout (sense) pin is connected to
    //the resolution is 10 mV / degree centigrade
    //(500 mV offset) to make negative temperatures an option
    char charTemp[3] = ""; //the char representation of the float for temp



    void setup() {
    tv.begin(0);
    // the overlay code is somehow conflicting on interrupts
    // initOverlay();
    tv.select_font(font6x8);
    tv.fill(0);

    // connect to the serial terminal at 9600 baud
    Serial.begin(9600);

    // connect to the GPS at the desired rate
    uart_gps.begin(GPSBAUD);

    // prints title with ending line break
    Serial.println(" ...waiting for lock... ");

    }


    // Initialize ATMega registers for video overlay capability.
    // Must be called after tv.begin().
    void initOverlay() {
    TCCR1A = 0;
    // Enable timer1. ICES0 is set to 0 for falling edge detection on input capture pin.
    TCCR1B = _BV(CS10);

    // Enable input capture interrupt
    TIMSK1 |= _BV(ICIE1);

    // Enable external interrupt INT0 on pin 2 with falling edge.
    EIMSK = _BV(INT0);
    EICRA = _BV(ISC11);
    }

    // Required to reset the scan line when the vertical sync occurs
    ISR(INT0_vect) {
    display.scanLine = 0;
    }


    void loop() {

    while(uart_gps.available()) // if there is data on the RX pin...
    {
    int c = uart_gps.read(); // load the data into a variable...
    if(gps.encode(c)) // if there is a new valid sentence...
    {
    getgps(gps); // then grab the data.
    }
    }



    // temperature

    float temperature = getVoltage(temperaturePin); //getting the voltage reading from the temperature sensor
    temperature = (((temperature - .5) * 100)*1.8) + 32; //converting from 10 mv per degree wit 500 mV offset


    // setup the messages for output on the tv

    // clear at start of loop
    sprintf(messageTop, "");
    sprintf(messageBottom, "");
    sprintf(messageLastline, "");

    //assemble top message
    strcat(messageTop,callsign);

    // assemble bottom message
    strcat(messageBottom,charTime);
    strcat(messageBottom," ");
    strcat(messageBottom,charDate);
    strcat(messageBottom,"Z ");
    itoa(int(temperature),charTemp,10); // sprintf fails so we use this
    strcat(messageBottom,charTemp);
    strcat(messageBottom,"F");

    // assemble 2nd bottom meessage
    strcat(messageLastline,gpsCoords);


    // write out to TV
    tv.select_font(font6x8);
    tv.print(0,0, messageTop);
    // Serial.print("messageTop=");
    // Serial.println(messageTop);


    // the 4x6 font is awefully small. I thought of scrolling but that's too distracting.
    // right now it's a bit small to read.
    tv.select_font(font4x6);
    tv.print(0,75, messageBottom);
    Serial.print("messageBottom=");
    Serial.println(messageBottom);
    tv.print(0,85, messageLastline);
    Serial.print("messageLastline=");
    Serial.println(messageLastline);

    }



    /*
    * getVoltage() - returns the voltage on the analog input defined by
    * pin
    */
    float getVoltage(int pin){
    return (analogRead(pin) * .004882814); //converting from a 0 to 1024 digital range
    // to 0 to 5 volts (each 1 reading equals ~ 5 millivolts
    }



    // The getgps function will get and print the values we want.
    void getgps(TinyGPS &gps)
    {
    // To get all of the data into varialbes that you can use in your code,
    // all you need to do is define variables and query the object for the
    // data. To see the complete list of functions see keywords.txt file in
    // the TinyGPS and NewSoftSerial libs.

    // Define the variables that will be used
    float latitude, longitude;
    // Then call this function
    gps.f_get_position(&latitude, &longitude);
    // You can now print variables latitude and longitude
    Serial.print("Lat/Long: ");
    Serial.print(latitude,5);
    itoa(int(latitude),gpsCoords,10); // sprintf fails so we use this
    strcat(gpsCoords,".");
    int floatTmp = abs((latitude - (int)latitude) * 100);

    if (floatTmp < 10 ) {
    strcat(gpsCoords,"0");
    itoa(floatTmp, &gpsCoords[strlen(gpsCoords)], 10);
    }
    else {
    itoa(floatTmp, &gpsCoords[strlen(gpsCoords)], 10);
    }

    strcat(gpsCoords,", ");
    Serial.print(", ");
    Serial.println(longitude,5);
    itoa(int(longitude),charTmp,10); // sprintf fails so we use this
    strcat(gpsCoords, charTmp);
    strcat(gpsCoords,".");
    floatTmp = abs((longitude - (int)longitude) * 100);

    if (floatTmp < 10 ) {
    strcat(gpsCoords,"0");
    itoa(floatTmp, &gpsCoords[strlen(gpsCoords)], 10);
    }
    else {
    itoa(floatTmp, &gpsCoords[strlen(gpsCoords)], 10);
    }
    strcat(gpsCoords," ");

    // Same goes for date and time
    int year;
    byte month, day, hour, minute, second, hundredths;
    gps.crack_datetime(&year,&month,&day,&hour,&minute,&second,&hundredths);
    // Print data and time
    Serial.print("Date: ");
    Serial.print(month, DEC);
    Serial.print("/");
    Serial.print(day, DEC);
    Serial.print("/");
    Serial.print(year);
    Serial.print(" Time: ");
    Serial.print(hour, DEC);
    Serial.print(":");
    Serial.print(minute, DEC);
    Serial.print(":");
    Serial.print(second, DEC);
    Serial.print(".");
    Serial.println(hundredths, DEC);
    itoa(int(hour),charTime,10); // sprintf fails so we use this
    strcat(charTime,":");
    itoa(int(minute),charTmp,10); // sprintf fails so we use this
    strcat(charTime, charTmp);
    itoa(int(month),charDate,10); // sprintf fails so we use this
    strcat(charDate,"/");
    itoa(int(day),charTmp,10); // sprintf fails so we use this
    strcat(charDate, charTmp);
    strcat(charDate,"/");
    itoa(int(year),charTmp,10); // sprintf fails so we use this
    strcat(charDate, charTmp);

    // Serial.print("gpsCoords=");
    // Serial.println(gpsCoords);
    // Here you can print the altitude and course values directly since
    // there is only one value for the function
    Serial.print("Altitude (meters): ");
    Serial.println(gps.f_altitude());
    int altitude = int(gps.f_altitude());
    itoa(altitude,gpsAlt,10); // sprintf fails so we use this
    strcat(gpsAlt,"M");
    // XXX there is some sort of compiler bug here. This adds it to gpsCoords not gpsAlt
    // Serial.print("gpsCoords2=");
    // Serial.println(gpsCoords);
    // Same goes for course
    Serial.print("Course (degrees): ");
    Serial.println(gps.f_course());
    // And same goes for speed
    Serial.print("Speed(kmph): ");
    Serial.println(gps.f_speed_kmph());
    Serial.println();

    // Here you can print statistics on the sentences.
    unsigned long chars;
    unsigned short sentences, failed_checksum;
    gps.stats(&chars, &sentences, &failed_checksum);
    //Serial.print("Failed Checksums: ");Serial.print(failed_checksum);
    //Serial.println(); Serial.println();
    }
    #1346
    acton
    Member

    I think you’ll find tinyGPS just takes a character from the gps and interprets it. You need to get the character from the GPS via serial interface. The problem with the traditional serial communications is the interrupts, and because they’ve been taken over to handle the video timing to need to do it without interupts. You’re going to have to ditch newsoftserial and use the hardware uart on pins 0 & 1.

    The way to do it is to use polling. There’s already a project using this method on the Nootropic website that should get you on your way at: http://nootropicdesign.com/projectlab/category/gps/

    I need to take it a step further and get some other stuff done during the horizontal blanking period. I guess this means I will have to strip the bare minimum code out of Pollserial.begin. I can live a single baud rate and single chip/speed variant. Some hints as to the minimum I need to read the hardware serial and put it in a buffer would be appreciated from anyone who understands this sort of thing!

    #1349
    joey
    Member

    The provided sketch doesn’t run even if it’s just the VE and the Arduino. I did retrofit my code to match it and had the same results. It’s also harder to debug since I can’t see the output on the serial console.

    #1351
    Michael
    Keymaster

    Hi guys, sorry for the slow response. I’m on vacation out of the country and only have limited net access.

    Bottom line is that you must use polling serial comm provided by tvout. The project in my blog shows that I successfully read gps info and overlaid it. But you can’t read too much data using the polling approach. I configured my em406 gps to emit only the rmc and gga sentences. And my gps is only 1Hz. Joey, what doesnt work?

    #1354
    joey
    Member

    @Michael wrote:

    Hi guys, sorry for the slow response. I’m on vacation out of the country and only have limited net access.

    Bottom line is that you must use polling serial comm provided by tvout. The project in my blog shows that I successfully read gps info and overlaid it. But you can’t read too much data using the polling approach. I configured my em406 gps to emit only the rmc and gga sentences. And my gps is only 1Hz. Joey, what doesnt work?

    I have the same GPS. If I load the sketch on VE, even without the GPS, it doesn’t display (lights are, nobody is home, nothing outputted). I suspect the sketch is just stopped somewhere but since I can’t see the serial output for debugging. If I load some of my other sketches they do run and display. Suggestions?

    #1353
    Michael
    Keymaster

    I don’t think it will display anything until some data is received.

    Did you properly configure the em406 to only output RMC and GGA sentences?

    #1357
    joey
    Member

    @Michael wrote:

    I don’t think it will display anything until some data is received.

    Did you properly configure the em406 to only output RMC and GGA sentences?

    No I didn’t. I figured that for diagnostics, too much would be better than none at all. I guess I can try that.

    #1359
    joey
    Member

    Ok in attempting to figure out how to program the GPS I realized the GPS wasn’t locking on. Turns out resetting the datum was the key.

    Handy setup strings for the EM-406A:

    * NMEA 8N1 various baud rates:
    $PSRF100,1,1200,8,1,0,*2D
    $PSRF100,1,2400,8,1,0,*28
    $PSRF100,1,4800,8,1,0,*22
    $PSRF100,1,9600,8,1,0,*21
    $PSRF100,1,19200,8,1,0,*14
    $PSRF100,1,38400,8,1,0,*11

    Debug On:
    $PSRF105,1,*3E
    Debug Off:
    $PSRF105,0,*3F

    Select WGS84 Datum:
    $PSRF106,21,*0F

    Now your sketch works but mine doesn’t. Any idea on how to display debug statements? e.g. Serial.println

    #1360
    joey
    Member

    ah, pserial.println works!

    #1361
    joey
    Member

    Ok, back to troubleshooting. First off, thanks guys for helping me out.

    So right now, pserial.available is never true. I just get “loop”. This is the same routine that is in the overlay demo but it’s not working here. The GPS is setup exactly the same and the “gps lock” light is flashing. And yes, it’s on UART.

        pserial.println("loop");
    while(pserial.available()) // if there is data on the RX pin...
    {
    pserial.println("available");
    if(gps.encode(pserial.read())) // if there is a new valid sentence...
    {
    pserial.println("getgps");
    getgps(gps); // then grab the data.
    }
    }

    Here’s the current code for inspection:

    // This is an example of how to always present your callsign and other goodies on a VE
    // Note that there is no known way to display the degree symbol as the char chart is different
    // joey@stan4d.net

    #include
    #include
    #include
    #include

    TVout tv;

    // Use pins 4 and 5 to talk to the GPS. 5 is the TX pin, 4 is the RX pin
    // I had to unsolder the jumpers and rewire the GPS Sheild to avoid pin 2
    // pin 2 is in use by the VE
    // Create an instance of the TinyGPS object
    pollserial pserial;
    TinyGPS gps;


    // Set the GPSRATE to the baud rate of the GPS module. Most are 4800
    // but some are 38400 or other. Check the datasheet!
    const int GPSBAUD=4800;

    // declare the GPS variables
    char charTmp[10] = "";
    char charTime[6] = "00:00";
    char charDate[11] = "00/00/0000";
    char gpsCoords[15] = "";
    char gpsAlt[6] = "0000M";


    // This is where you declare prototypes for the functions that will be
    // using the TinyGPS library.
    void getgps(TinyGPS &gps);


    // declare overlay text vars
    char messageTop[96] = "";
    char messageBottom[96] = "";
    char messageLastline[96] = "";
    const char callsign[] = "NV0N";

    //TMP36 Pin Variables
    //the analog pin the TMP36's Vout (sense) pin is connected to
    //the resolution is 10 mV / degree centigrade
    //(500 mV offset) to make negative temperatures an option
    const int temperaturePin = 0;
    char charTemp[3] = ""; //the char representation of the float for temp



    void setup() {
    tv.begin(0);
    tv.set_hbi_hook(pserial.begin(GPSBAUD));
    initOverlay();
    tv.select_font(font6x8);
    tv.fill(0);
    }


    // Initialize ATMega registers for video overlay capability.
    // Must be called after tv.begin().
    void initOverlay() {
    TCCR1A = 0;
    // Enable timer1. ICES0 is set to 0 for falling edge detection on input capture pin.
    TCCR1B = _BV(CS10);

    // Enable input capture interrupt
    TIMSK1 |= _BV(ICIE1);

    // Enable external interrupt INT0 on pin 2 with falling edge.
    EIMSK = _BV(INT0);
    EICRA = _BV(ISC11);
    }

    // Required to reset the scan line when the vertical sync occurs
    ISR(INT0_vect) {
    display.scanLine = 0;
    }


    void loop() {

    pserial.println("loop");
    while(pserial.available()) { // if there is data on the RX pin...
    pserial.println("available");
    if(gps.encode(pserial.read())) { // if there is a new valid sentence...
    pserial.println("getgps");
    getgps(gps); // then grab the data.
    }
    }


    // temperature

    float temperature = getVoltage(temperaturePin); //getting the voltage reading from the temperature sensor
    temperature = (((temperature - .5) * 100)*1.8) + 32; //converting from 10 mv per degree wit 500 mV offset


    // setup the messages for output on the tv

    // clear at start of loop
    sprintf(messageTop, "");
    sprintf(messageBottom, "");
    sprintf(messageLastline, "");

    //assemble top message
    strcat(messageTop,callsign);

    // assemble bottom message
    strcat(messageBottom,charTime);
    strcat(messageBottom," ");
    strcat(messageBottom,charDate);
    strcat(messageBottom,"Z ");
    itoa(int(temperature),charTemp,10); // sprintf fails so we use this
    strcat(messageBottom,charTemp);
    strcat(messageBottom,"F");

    // assemble 2nd bottom meessage
    strcat(messageLastline,gpsCoords);


    // write out to TV
    tv.select_font(font6x8);
    tv.print(0,0, messageTop);

    // the 4x6 font is awefully small. I thought of scrolling but that's too distracting.
    // right now it's a bit small to read.
    tv.select_font(font4x6);
    tv.print(0,75, messageBottom);
    tv.print(0,85, messageLastline);
    }



    /*
    * getVoltage() - returns the voltage on the analog input defined by
    * pin
    */
    float getVoltage(int pin){
    return (analogRead(pin) * .004882814); //converting from a 0 to 1024 digital range
    // to 0 to 5 volts (each 1 reading equals ~ 5 millivolts
    }



    // The getgps function will get and print the values we want.
    void getgps(TinyGPS &gps)
    {

    // Define the variables that will be used
    float latitude, longitude;
    // Then call this function
    gps.f_get_position(&latitude, &longitude);

    itoa(int(latitude),gpsCoords,10); // sprintf fails so we use this
    strcat(gpsCoords,".");
    int floatTmp = abs((latitude - (int)latitude) * 100);

    if (floatTmp < 10 ) {
    strcat(gpsCoords,"0");
    itoa(floatTmp, &gpsCoords[strlen(gpsCoords)], 10);
    }
    else {
    itoa(floatTmp, &gpsCoords[strlen(gpsCoords)], 10);
    }

    strcat(gpsCoords,", ");
    itoa(int(longitude),charTmp,10); // sprintf fails so we use this
    strcat(gpsCoords, charTmp);
    strcat(gpsCoords,".");
    floatTmp = abs((longitude - (int)longitude) * 100);

    if (floatTmp < 10 ) {
    strcat(gpsCoords,"0");
    itoa(floatTmp, &gpsCoords[strlen(gpsCoords)], 10);
    }
    else {
    itoa(floatTmp, &gpsCoords[strlen(gpsCoords)], 10);
    }
    strcat(gpsCoords," ");

    // Same goes for date and time
    int year;
    byte month, day, hour, minute, second, hundredths;
    gps.crack_datetime(&year,&month,&day,&hour,&minute,&second,&hundredths);
    itoa(int(hour),charTime,10); // sprintf fails so we use this
    strcat(charTime,":");
    itoa(int(minute),charTmp,10); // sprintf fails so we use this
    strcat(charTime, charTmp);
    itoa(int(month),charDate,10); // sprintf fails so we use this
    strcat(charDate,"/");
    itoa(int(day),charTmp,10); // sprintf fails so we use this
    strcat(charDate, charTmp);
    strcat(charDate,"/");
    itoa(int(year),charTmp,10); // sprintf fails so we use this
    strcat(charDate, charTmp);

    int altitude = int(gps.f_altitude());
    itoa(altitude,gpsAlt,10); // sprintf fails so we use this
    strcat(gpsAlt,"M");
    // XXX there is some sort of compiler bug here. This adds it to gpsCoords not gpsAlt

    }








    #1362
    Michael
    Keymaster

    I’m glad you’ve made progress. You can’t use the serial monitor for debugging if the gps is connected to the uart. The uart can only communicate with one device. To debug, why not just print to the tv screen?
    Tv.println()

    Ok, here’s the deal with the gps overlay sketch: there’s barely enough SRAM for it to work, and any mods you make are likely to push it over the limit, which causes the arduino to freeze up or put funny lines of pixels on the screen. I’m not sure you’ll be able to do much more than the sketch I provided. You’re doing super cool stuff and I hope your memory usage can be trimmed down. String literals are expensive so consider storing them in flash memory with PROGMEM (see arduino site).

    I found it critical to limit gps output to rmc and GGA. Or it didn’t work.

    I’ll look at your code more next week but I’m on vacation in London now and only have an iPod and typing is tedious…

Viewing 15 posts - 1 through 15 (of 34 total)
  • You must be logged in to reply to this topic.