Accelerometer Trigger Level Setting Problems - Error Code 5

C, C++, and Visual C++
RobOrt
Phidgeteer!
Posts: 85
Joined: Wed Jun 17, 2009 11:39 am
Contact:

Accelerometer Trigger Level Setting Problems - Error Code 5

Postby RobOrt » Thu Sep 10, 2009 7:40 am

Hello,

I'm using C++ to create an application which uses a 3 axis accelerometer.I have written some C++ wrapper classes i.e. C++ code that simply wraps the C code for the Phidget API so that I can then write the application in an object oriented manner. So far everything is ok and I can display 'live' axis output data from an attached accelerometer.

The problem I have now is that I would like to implement a trigger-level setting control, but whenever I call the appropriate API function 'CPhidgetAccelerometer_setTriggerLevel' I always get an error return.

Initially it was error code 17 (Wrong device error !) but after some tinkering I now get error code 5 (device not attached !). It's obviously something to do with the Accelerometer handle that I am using but I cannot work out what. I've included a stripped down version of my code, unnecessary code has been removed.

Accelerometer.h

Code: Select all

#ifndef ACCELEROMETER_H
#define ACCELEROMETER_H
#include <cphidgetbase.h>



class Accelerometer : public CPhidgetBase
{
public:
    Accelerometer(CPhidgetHandle hnd);
    virtual ~Accelerometer();

    static int createAccelHandle(CPhidgetAccelerometerHandle *accel);
    ...
    int setAccelerationChangeTrigger(int axis, double trigger);
    ...
    static CPhidgetAccelerometerHandle ca; //included to try a different way of getting it to work

private:
    CPhidgetAccelerometerHandle accelHnd; //Instance of the Accelerometer handle
   ...
};

#endif // ACCELEROMETER_H


The important thing to not is that I am saving the Accelerometer handle as a private instance variable, therefore accesed with 'this->accelHnd'

Accelerometer.cpp

Code: Select all

#include "accelerometer.h"

CPhidgetAccelerometerHandle Accelerometer::ca;

Accelerometer::Accelerometer(CPhidgetHandle hnd)
{
    int s;
    this->cPhidHnd = hnd;
    CPhidgetAccelerometerHandle accelHnd = NULL;
    this->ptr2DataRxFunction = NULL;    //Sets the pointer to the external receiving function to null;
    this->ptr2RxDataObject = NULL; //Sets the pointer to the external object using the data - Set by the user functions){
    int r = Accelerometer::createAccelHandle(&accelHnd); //Create a handle
    if (r == EPHIDGET_OK ){
        this->accelHnd = accelHnd; //save the handle in THIS instance
        Accelerometer::ca = accelHnd; //save it as a CLASS variable too for debuggind purposes
    }else{
        this->accelHnd = NULL;

    }
    r = CPhidgetBase::getSerialNumber(hnd,s);
    this->serialNumber = s;
    // set trigger level
    //r = this->setAccelerationChangeTrigger(0,1.1); // this doesn't work
    r = CPhidgetAccelerometer_set_OnAccelerationChange_Handler(Accelerometer::ca,Accelerometer::accelerometerCallback,this);
    //r = CPhidgetAccelerometer_set_OnAccelerationChange_Handler(accelHnd,Accelerometer::accelerometerCallback,this);


    if (r == EPHIDGET_OK ){
        int y = 0;
    }
}

Accelerometer::~Accelerometer(){
    if (this->accelHnd != NULL){
        /* Close Handle */
        CPhidgetBase::close((CPhidgetHandle)this->accelHnd);
    }
}

int Accelerometer::accelerometerCallback(CPhidgetAccelerometerHandle phid,void *usrData,int axis,double accel){
    /* Now call the instance callback - instance being given by the usrData pointer */
    ((Accelerometer*)usrData)->accelerometerInstanceCallback(axis,accel);
    return 0;
}

...

int Accelerometer::setAccelerationChangeTrigger(int axis,double trigger){
    //trigger = 0.5;
    int a;
    //int r = CPhidgetAccelerometer_setAccelerationChangeTrigger(this->accelHnd,axis,trigger);
    int r = CPhidgetAccelerometer_setAccelerationChangeTrigger(Accelerometer::ca,axis,trigger);
    r = CPhidgetAccelerometer_getAxisCount(this->accelHnd,&a); //this also gives error code 5
    return r;
}

int Accelerometer::createAccelHandle(CPhidgetAccelerometerHandle *accel){
    int r = CPhidgetAccelerometer_create(accel);
    return r;
}

void Accelerometer::accelerometerInstanceCallback(int axis,double accel){
    if (this->ptr2DataRxFunction != NULL){
        /* A receiving function has been defined so call it */
        this->ptr2DataRxFunction(this->ptr2RxDataObject,axis,accel);
    }
}

...

void Accelerometer::openDevice(){
    //int r = CPhidget_open((CPhidgetHandle)(this->accelHnd),this->serialNumber);
    int r = CPhidget_open((CPhidgetHandle)(Accelerometer::ca),this->serialNumber);
}


When an instance of Accelerometer is created, an empty Accelerometer handle is created and stored in the variable 'accelHnd'. The instance function Accelerometer::openDevice() is called to open the accelerometer and as you can see I currently have the code using a static accelerometer handle. I did this temporarily as a debugging step but the same error code occurs.

To change the trigger lever for an axis the function Accelerometer::setAccelerationChangeTrigger is called but this is where the error occurs. Even though I'm using an instance variable. this->accelHnd, the error code 5 is returned ! (device not attached). this is simply not true as the device is giving output as soon as I open it with my openDevice() function. You will also see in Accelerometer::setAccelerationChangeTrigger i have also tried a call to getAxisCount() but this too results in error code 5.

Can anyone help ? I think it has something to do with the way I create and then open the Accelerometer handle but I'm totally baffled.

User avatar
Patrick
Lead Developer
Posts: 3091
Joined: Mon Jun 20, 2005 8:46 am
Location: Canada
Contact:

Re: Accelerometer Trigger Level Setting Problems - Error Code 5

Postby Patrick » Thu Sep 10, 2009 10:00 am

You need to call open, and then either waitForAttachment, or wait for the attach event to fire, before you call any other functions on the Phidget - including setting the change trigger or getting the number of axes.

-Patrick

RobOrt
Phidgeteer!
Posts: 85
Joined: Wed Jun 17, 2009 11:39 am
Contact:

Re: Accelerometer Trigger Level Setting Problems - Error Code 5

Postby RobOrt » Thu Sep 10, 2009 11:05 am

Hello Patrick,

I have indeed already 'opened' the device however it might not be clear from my above code. And I definately know that it has been opened because I then get data from the device to my program.

I use a CPhidgetManager wrapped in my own class PhidgetManager to detect when a Phidget is attached. This is the relevant static 'deviceattached' function that the phidget manager calls :

Code: Select all

int PhidgetManager::attachHandler(CPhidgetHandle phid, void* userPtr){

        CPhidgetBase *cpb;
        int serialNo;
        CPhidget_DeviceClass cls;
        CPhidgetBase::getDeviceClass(phid,cls);
        CPhidgetBase::getSerialNumber(phid,serialNo);
        /******************************************8
         * Dependent upon the device class cls
         * create instance of phidget module
         *******************************************/
        switch(cls){

            case PHIDCLASS_ACCELEROMETER:
                cpb = new Accelerometer(phid);
                break;
            case PHIDCLASS_ADVANCEDSERVO:
            //break;
            case PHIDCLASS_ENCODER:
            //break;
            case PHIDCLASS_GPS:
            //break;
            case PHIDCLASS_GYROSCOPE:
            //break;
            case PHIDCLASS_INTERFACEKIT:
            //break;
            case PHIDCLASS_LED:
            //break;
            case PHIDCLASS_MOTORCONTROL:
            //break;
           case  PHIDCLASS_PHSENSOR:
            //break;
            case PHIDCLASS_RFID:
            //break;
            case PHIDCLASS_SERVO:
            //break;
            case PHIDCLASS_STEPPER:
            //break;
            case PHIDCLASS_TEMPERATURESENSOR:
            //Phidget Temperature Sensor
            case PHIDCLASS_TEXTLCD:
            //Phidget TextLCD
            case PHIDCLASS_TEXTLED:
            //Phidget TextLED
            case PHIDCLASS_WEIGHTSENSOR:
            case PHIDCLASS_NOTHING:
            default:
                break;
        };

         /*Now call instance of PhidgetManager so it can alert its external functions */
        ((PhidgetManager*)userPtr)->managerInstanceAttachCallback(cpb);

            PhidgetManager::ph[ serialNo ] = cpb;
            //void *p = cpb->getMyHandle();
            CPhidgetHandle p = (CPhidgetHandle)(((Accelerometer*)cpb)->getHandle());
            //int r = CPhidget_open(p,serialNo);
            cpb->openDevice();              //<==== ****device opened here ! *****
            ((Accelerometer*)cpb)->setAccelerationChangeTrigger(0,0.5);
            return 0;
}


As you can see at the end of the function there is a call to cpb->openDevice.

cpb is an instance class of my own design, and implements a pure vitual funtion openDevice(). The actual code for openDevice() for an accelerometer can be seen in my first posting under the Accelerometer.cpp listing. Without going into unnecessary details of my code, I can confirm the device DOES open as it outputs data to my application. Yet when I try to use the specific CPhidget_Accelerometer handle with an accelerometer specific function I get a code 5 error. I have also had an error code 17 but I cannot remember how my own code was arranged to get this result.

I've built the Acceloremeter-simple example and can confirm that setting the trigger level works, and that is under C. I am now using C++ and it's as if there is some problem with the way I create and store the Accelerometer handle.

User avatar
Patrick
Lead Developer
Posts: 3091
Joined: Mon Jun 20, 2005 8:46 am
Location: Canada
Contact:

Re: Accelerometer Trigger Level Setting Problems - Error Code 5

Postby Patrick » Thu Sep 10, 2009 11:52 am

As I said - after you call open, you need to call either waitForAttachment, or wait for the attach event to fire - open is asynchronous - it returns immediately whether or not there is actually a Phidget attached to the system, which is why you MUST call waitForAttachment, or do you initializations in the attach handler. Read the programming manual, this is all well documented.

-Patrick

RobOrt
Phidgeteer!
Posts: 85
Joined: Wed Jun 17, 2009 11:39 am
Contact:

Re: Accelerometer Trigger Level Setting Problems - Error Code 5

Postby RobOrt » Fri Sep 11, 2009 7:51 am

OK. I didn't realise had to wait for the 'device attached' signal (I only have half read the manual for the PhidgetManager) but that doesn't matter now as I found the bug in my program. I was using a type cast but I was casting to the incorrect type, which resulted bad data in my CPhidgetAccelerometer handle.


Return to “C/C++”

Who is online

Users browsing this forum: No registered users and 1 guest