Program Freeze?

10 Jan 2013

Had the following program fine, now added the GPS code which compiles correctly but all I see on the lcd screen is what's at line 27??? Also as you can see I've remarked out the HMC6352 because I'm thinking either the HMC6352 needs an address or the GPS needs an address I'm I correct?

#include "mbed.h"
#include "TextLCD.h"
#include "SRF08.h"
//#include "HMC6352.h"
#include "TMP102.h"
#include "GPS.h"

TextLCD lcd(p15, p16, p17, p18, p19, p20); // rs, e, d4-d7
SRF08 srf08(p9, p10, 0xE0);
//HMC6352 compass(p9, p10);
TMP102 temperature(p9, p10, 0x90); //A0 pin is connected to ground
GPS gps(p9, p10);

float RangeReading()
{
    float value;
    value = srf08.read();
    return (value);
}


int main()
{

    float distance = 0;

    lcd.printf("Starting HMC6352\n\n test...");
    //Continuous mode, periodic set/reset, 20Hz measurement rate.
    //compass.setOpMode(HMC6352_CONTINUOUS, 1, 20);

    while (1) {
        distance = RangeReading();
        lcd.cls();
        lcd.printf("Range: %2.f cm\n",distance);
        wait(0.10);
        lcd.printf("Temp: %f\n", temperature.read());
        wait(0.10);
        //lcd.printf("Heading: %f", compass.sample() / 10.0);
        wait(1.0);
        lcd.cls();
        if(gps.sample()) {
            lcd.printf("I'm at %f, %f\n", gps.longitude, gps.latitude);
        } else {
            lcd.printf("Oh Dear! No lock :(\n");
        }
        wait(1.0);
        lcd.printf("ReScan For Data \n");
        wait(1.0);

    }

}

Thank you in advance

10 Jan 2013

This code hangs because:

SRF08 srf08(p9, p10, 0xE0);
HMC6352 compass(p9, p10);
TMP102 temperature(p9, p10, 0x90); //A0 pin is connected to ground

All need I2C comms and they use p9,p10 which is fine.

However

GPS gps(p9, p10);

Needs a serial comm, but it also uses p9,p10 which leads to a conflict

So you have to rewire the GPS to use another serial port and change the pins (eg p13, p14).

11 Jan 2013

Thanks for that, so even with the software 'remarked' out for the HMC6352 but with the devices connected there is a hardware conflict which still exists because two devices without an address identifier are sharing the same bus? I'll re-wire the GPS device tonight to p13,p14 and reinstate the serial command.

Many thanks for your help as always.

11 Jan 2013

Derek Calland wrote:

Thanks for that, so even with the software 'remarked' out for the HMC6352 but with the devices connected there is a hardware conflict which still exists because two devices without an address identifier are sharing the same bus? I'll re-wire the GPS device tonight to p13,p14 and reinstate the serial command.

Just to clarify: All I2C devices need an address. The lib constructor methods for SRF08 and TMP102 include the address in the parameterlist to explicitly show the address or because these devices can have one of several addresses depending on the logic levels on one of their configuration pins. This feature allows you to use multiple devices of the same type on one I2C bus. Obviously every device needs to have a unique address to avoid I2C bus conflicts. The HMC6352 compass also has a unique I2C address but it is hardcoded and hidden in the software. All three lib methods declare an I2C bus internally using the provided pinnumbers (p9,p10). The internal object will configure these pins to connect with the lpc1768 I2C hardware engine.

The GPS unit needs a serial port. Hardwarewise this is completely different from I2C. It just happens that p9,p10 can also be configured to connect to the lpc1768 serial port hardware engine.

The problem with the software is that the libs first configure p9,p10 to connect with the I2C bus (3x over actually, but that works) and then, when the GPS object does its initialisation, these pins get reconnected to the serial port engine, breaking the I2C.

Without precautions in the software (ie always reconfiguring the pins before every use) this will lead to problems. It will lead to problems anyhow because the GPS will typically send its position messages automatically once per second no matter what, while the mbed needs to be the master on the I2C bus and initiate all communications with its I2C slaves. This means corrupted messages on I2C and possibly even shortcircuits with the transmitting GPS.

11 Jan 2013

Great thank you for that explanation of the internal workings between the I2C bus and the serial bus. I'll post later with the results. Many thanks.

11 Jan 2013

I have it all working now plus the I2C devices, I suspect it's returning all zero's as it's indoors, but I'm nearly there now to build everything together onto my roving unit. I still need to work out how to limit Aaron's code for the HMC6352 to return only 5 bytes of characters and not 10, but that I suspect will be the subject of another forum question.

11 Jan 2013

Most GPS will send out lat & lon of 0 as long as it receives no GPS signal, which is normally the case indoors. It also sends zeroes while it is still downloading the up-to-date almanac data from the GPS satellites which are needed to compute its location. This can take several minutes after a cold start.

You can format the printed outputs of the HMC6352 by adding some parameters to the printf format string:

lcd.printf("Heading: %5.f", compass.sample() / 10.0);  // Should give you 5 digits before decimal point
14 Jan 2013

Thanks for that line of code, I went on the cplusplus web site and read up on the printf examples they have. However I have a few questions if I may... 1. Does the % sign tell the pre-processor to start reading data from this point so that the numeric following it in the above example you provided state 5 bytes of data type float the . sign then telling it the type of data it is? 2. So %2.d would display 2 bytes of data type integer? If I just use %f as in Aaron's code example I get say 43.20000 or 332.700000. So what I'm trying to achieve is to drop of the 5 zero's, in each case. 3. I have a 20x4 lcd character display and I've read (and now witnessed)that if a line (say the first line) is > 20 characters it continues on the third line, so that using a \n and another printf statement would put that data on line 2. Another following printf statement with a \n would then put the characters on line 4? The reason I ask this question is the data I am seeing on line 4 is not starting at location 1 but further along?

Apologies if this is not the place t ask these type of questions.

15 Jan 2013

Derek Calland wrote:

1. Does the % sign tell the pre-processor to start reading data from this point so that the numeric following it in the above example you provided state 5 bytes of data type float the . sign then telling it the type of data it is?

Formatting is not handled by the pre-processor. The preprocessor takes care of stuff like replacing #defines, #ifdef etc. It is just a helper for the compiler which will use the preprocessor output. Print formatting is something you cant do at compile time. The compiler doesnt know which float or integer values you are going to get at runtime. The compiler inserts code to handle whatever it gets during runtime and makes sure it is printed the way you want it.

Derek Calland wrote:

2. So %2.d would display 2 bytes of data type integer? If I just use %f as in Aaron's code example I get say 43.20000 or 332.700000. So what I'm trying to achieve is to drop of the 5 zero's, in each case.

The formatting string defines how you want the number printed. The values %d, or %f indicate that you want to print an integer or float. The number values define how many digits you want to show. Note that it is digits, rather than bytes. The . is used only for floats and separates how many digits before and after the decimal point you want. So %3.2f will result in values like '123.45' or '789.00' The formatter will normally suppress leading zeros and insert spaces for the zeros and sign. If you want to show leading zeros use %03.2f. That will print values like '001.23' rather than ' 1.23'

Derek Calland wrote:

3. I have a 20x4 lcd character display and I've read (and now witnessed)that if a line (say the first line) is > 20 characters it continues on the third line, so that using a \n and another printf statement would put that data on line 2. Another following printf statement with a \n would then put the characters on line 4? The reason I ask this question is the data I am seeing on line 4 is not starting at location 1 but further along?

That behaviour depends on the display you use. Different vendors use different layouts of the controller and the LCD glass. The typical HD44780 controller has memory for 80 chars internally. All of that memory or part of it can be mapped onto the display glass in many different ways: 1x8, 2x8, 1x16, 2x16, 2x20, 2x24, 2x40 or 4x20. Internally the memory is not sequential. The first line of 40 chars max starts at address 0x00, the second line at 0x40. That explains the address gap between the first and second line when you use less than 40 chars/line. Your 4x20 is actually a 2x40 split in two 2x20s which are then positioned above eachother. That explains why the text continues on the third line. Things are further complicated by the fact that the display hardware has no notion about the \n or \r character. The \n or \r must be handled by the print software instead. In short, I recommend that you use the 'locate' command to position the cursor on the desired rows and columns. Just make sure your strings always fit on a 20 char line.

15 Jan 2013

Thank you for your time and patience I have a much better understanding now, particularly with whats happening. I can experiment with my system now and workout the various results.