Writing concise classes/libraries

02 May 2011

Evening all,

Just published this to my profile: http://mbed.org/users/go2dev/programs/SRF02_lib/lqjp2t

A work in progress library for a simple SRF02 ultra sonic range finder module (I2C interface).

If you take a look through my code, you will see it is possible to import the library and then request a measurement in one of three formats.

I don't want to publish it as a library properly just yet though as

  1. Its not documented
  2. I think it could be made more efficient (code space).

Basically, I had to copy the main chunk of code three times and change a single variable which seems really wasteful. I'm new to the C++ party and all the things I tried won't compile properly.

Instead of

float SRF02::distancecm(){
    //local variables
    const char m_addr = 0xE0;  //srf02 default slave address
    char commandsequence[2];
    
    // Get range data from SRF02 in cm
        // Send Tx burst command over I2C bus
        commandsequence[0] = 0x00;               // Command register
        commandsequence[1] = 0x51;               // Ranging results in cm
        m_i2c.write(m_addr, commandsequence, 2); // Request ranging from sensor
        wait(0.07);  // Average wait time for sonar pulse and processing
        // Read back range over I2C bus
        commandsequence[0] = 0x02;                   // 
        m_i2c.write(m_addr, commandsequence, 1, 1);  // 
        m_i2c.read(m_addr, commandsequence, 2);             // Read two-byte echo result
        //combine upper and lower bytes in to a single value
        float range = ((commandsequence[0] << 8) + commandsequence[1]);
        return range;

}

repeated a bunch of times for each measurement type, I think what I want is something like:

float SRF02::measurecm{
   float result = dosonar(0x51);
   return result;
}

float SRF02::measureblah{
   float result = dosonar(whatever);
   return result;
}


float SRF02::dosonar(char rangetype){
    //local variables
    const char m_addr = 0xE0;  //srf02 default slave address
    char commandsequence[2];
    
    // Get range data from SRF02 in cm
        // Send Tx burst command over I2C bus
        commandsequence[0] = 0x00;               // Command register
        commandsequence[1] = rangetype;          // Ranging results type
        m_i2c.write(m_addr, commandsequence, 2); // Request ranging from sensor
        wait(0.07);  // Average wait time for sonar pulse and processing
        // Read back range over I2C bus
        commandsequence[0] = 0x02;                   // 
        m_i2c.write(m_addr, commandsequence, 1, 1);  // 
        m_i2c.read(m_addr, commandsequence, 2);             // Read two-byte echo result
        //combine upper and lower bytes in to a single value
        float range = ((commandsequence[0] << 8) + commandsequence[1]);
        return range;

}

I don't know enough about C++ to know what the correct conventions for this sort of thing is, I have an idea about what should be public and what should be private but I'd like some advice or tips from those more experienced so I don't spend for ever going round in circles only to do it the "wrong" way (many ways to skin a cat, I know but some are more sensible than others).

Any advice much appreciated Cheers D

04 May 2011

Hi,

This looks like it should have worked, apart from a few typos in your example (corrected below.) What errors were you getting?

float SRF02::measurecm() {
   float result = dosonar(0x51);
   return result;
}

float SRF02::measureblah() {
   float result = dosonar(whatever);
   return result;
}

float SRF02::dosonar(char rangetype){
    //local variables
    const char m_addr = 0xE0;  //srf02 default slave address
    char commandsequence[2];
    
    // Get range data from SRF02 in cm
        // Send Tx burst command over I2C bus
        commandsequence[0] = 0x00;               // Command register
        commandsequence[1] = rangetype;          // Ranging results type
        m_i2c.write(m_addr, commandsequence, 2); // Request ranging from sensor
        wait(0.07);  // Average wait time for sonar pulse and processing
        // Read back range over I2C bus
        commandsequence[0] = 0x02;                   // 
        m_i2c.write(m_addr, commandsequence, 1, 1);  // 
        m_i2c.read(m_addr, commandsequence, 2);             // Read two-byte echo result
        //combine upper and lower bytes in to a single value
        float range = ((commandsequence[0] << 8) + commandsequence[1]);
        return range;

}

And in the .h file you'd need to add:

float dosonar(char rangetype);

In the private part of the class.

10 Jul 2011

Sorry for the massive delay - have not had much free time to play with my mBed recently.

Corrections worked like a charm, thank you so much!

D