Pages: [1]   Go Down
Author Topic: [solved]creating a library dependent library  (Read 718 times)
0 Members and 1 Guest are viewing this topic.
Holland
Offline Offline
Sr. Member
****
Karma: 0
Posts: 439
Arduino likes cookies too
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hello,

I am trying to create a library to interface with my URM37 ultrasonic range finder sensor.
I've had success communicating with this sensor over serial (success with the NewSoftSerial library, aswell as through the hardware serial).
And since I have it working from a sketch, I want to turn it into a library to keep my sketch clean.
Now this is where I've ran into a snag, since I want to make use of the NewSoftSerial library from within the one I am creating.

I get the following errors (basically, it sees all methods of the NewSoftSerial class as undefined references):
Code:
/tmp/build5679186724173996948.tmp/RangeFinder/RangerFinder.cpp.o: In function `RangeFinder::Begin(unsigned char, unsigned char, int, long)':

/home/imahilus/Arduino-0018/libraries/RangeFinder/RangerFinder.cpp:22: undefined reference to `NewSoftSerial::available()'

/home/imahilus/Arduino-0018/libraries/RangeFinder/RangerFinder.cpp:25: undefined reference to `NewSoftSerial::read()'

/home/imahilus/Arduino-0018/libraries/RangeFinder/RangerFinder.cpp:19: undefined reference to `operator new(unsigned int)'

/home/imahilus/Arduino-0018/libraries/RangeFinder/RangerFinder.cpp:19: undefined reference to `NewSoftSerial::NewSoftSerial(unsigned char, unsigned char, bool)'

/home/imahilus/Arduino-0018/libraries/RangeFinder/RangerFinder.cpp:20: undefined reference to `NewSoftSerial::begin(long)'

It is a shame there aren't any references as to library development that use other libraries (as is so often done in the coding industry).
I know the problem lies in the NewSoftSerial object, since I wrote another library that is completely unrelated to this one, that doesn't use an object from another library, that compiled and works just fine.

I've tried various things, but without effect..
A little help would be appreciated =)

The header file:
Code:
#ifndef rangefinder_h
#define rangefinder_h

#include "../NewSoftSerial/NewSoftSerial.h"
#include "WProgram.h"



/**
* The RangeFinder class is a completely transparant class that relies on the NewSoftSerial library.
* The measurements occur through serial communications, which can be set to any combination of digital I/O pins.
* While the NewSoftSerial library operates in a non-blocking fashion, to keep the use of this class simple,
* the measurements that are performed work in a blocking fashion (but allow for interrupts to happen normally during this blocking period).
* The Range Finder operates its own orientational servo, making it possible for it to control in which direction it performs its measurements.
**/
class RangeFinder
{
    public:
        RangeFinder();
        void Begin(uint8_t rx, uint8_t tx, int resetpin, long baudrate); //initialise the range finder on the provided pins as a NewSoftSerial device with the specified baudrate. The resetpin is needed to ensure a properly working sensor.
        void SetServoPosition(uint8_t rotation);                         //the rotation, in degrees, to which to set the servo. the servo has a range of 0~46, the physical range this represents should be 0~270 but might be smaller. The new rotation is applied with the next call to DistanceMeasurement.
        int  DistanceMeasurement();                                      //perform a distance measurement, this yields a result generally between 10~300 (cm's).
        int  TemperatureMeasurement();                                   //perform a temperature measurement. The value returned should be in degrees celsius with a resolution of .1, however, the value returned appears to be wrong?
    private:
        uint8_t        _servoPosition;
        int            _resetPin;
        NewSoftSerial* _serial;
};

#endif


The source file:
Code:
#include "../NewSoftSerial/NewSoftSerial.h"
#include "RangeFinder.h"



RangeFinder::RangeFinder()
{
}



/**
* Initialise the NewSoftSerial object and the Range Finder itself so it can be used.
**/
void RangeFinder::Begin(uint8_t rx, uint8_t tx, int resetpin, long baudrate)
{
    _resetPin = resetpin;
    pinMode(_resetPin, OUTPUT);
    _serial = new NewSoftSerial(rx, tx);
    _serial->begin(baudrate);
    
    digitalWrite(_resetPin, LOW); //resets while pin is low
    delay(500);                   //is apparently enough
    digitalWrite(_resetPin, HIGH);
}



/**
* Set the servo to a new rotation. The change is applied the next time DistanceMeasurement is called.
**/
void RangeFinder::SetServoPosition(uint8_t rotation)
{
    _servoPosition = rotation;
}



/**
* Send the 4 bytes of the Distance Measurement command to the Range Finder, subsequently wait for the reply and read it.
* The first byte returned is the command code, the fourth is a checksum byte (and as such these two bytes can be ignored).
**/
int RangeFinder::DistanceMeasurement()
{
    //send the command
    _serial->print(0x22,              BYTE);
    _serial->print(_servoPosition,    BYTE);
    _serial->print(0x00,              BYTE);
    _serial->print(34+_servoPosition, BYTE);
    while(_serial->available() < 4);
    
    //read the response
    _serial->read();
    delayMicroseconds(1);
    int distance = _serial->read();
    delayMicroseconds(1);
    distance = distance << 8;
    uint8_t byte2 = _serial->read();
    delayMicroseconds(1);
    distance += byte2;
    _serial->read();
    delayMicroseconds(1);

    //return the value
    return distance;
}



/**
* Send the 4 bytes of the Temperature Measurement command to the Range Finder, subsequently wait for the reply and read it.
* The first byte returned is the command code, the fourth is a checksum byte (and as such these two bytes can be ignored).
* The first 4 bits of the first data byte (the high byte) indicate whether the measurement is above 0C (by being all 0's), or below 0C (by being all 1's).
* The value returned from this measurement doesn't appear to be correct?
**/
int RangeFinder::TemperatureMeasurement()
{
    //send the command
    _serial->print(0x11, BYTE);
    _serial->print(0x00, BYTE);
    _serial->print(0x00, BYTE);
    _serial->print(0x11, BYTE);
    while(_serial->available() < 4);

    //read the response
    _serial->read();
    delayMicroseconds(1);
    uint8_t highbyte = _serial->read();
    delayMicroseconds(1);
    uint8_t lowbyte = _serial->read();
    delayMicroseconds(1);

    //process the response
    int temperature = 0;
    if((highbyte == 255)&&(lowbyte == 255))
    {
        temperature = 32767;
    }
    else
    if(highbyte > 127)
    {
        highbyte = highbyte & 0x0F;
        temperature = -(highbyte << 8)-lowbyte;
    }
    else
    {
        highbyte = highbyte & 0x0F;
        temperature = (highbyte << 8)+lowbyte;
    }
    _serial->read();
    delayMicroseconds(1);
    return temperature;
}

PS: I have verified that the path to the NewSoftSerial library and that the caps of the filenames are correct.
And thank you for any assistance =)
« Last Edit: April 08, 2010, 03:08:18 pm by Imahilus » Logged

Wuppertal/Germany
Offline Offline
God Member
*****
Karma: 1
Posts: 895
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

This has been discussed (at length) here:
http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1260904176
Eberhard
Logged

Holland
Offline Offline
Sr. Member
****
Karma: 0
Posts: 439
Arduino likes cookies too
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Must've missed that one  :-[

Thank you for the glance!
Logged

Pages: [1]   Go Up
Jump to: