Object names on the fly

23 Jun 2011

Hi All,

I want to create a number of objects (AX-12+ servos in this case) on the fly and give them different names. The objects use the same mbed pins so the only thing standing in my way are the names.

I want some thing like this...

//Create 10 AX-12+ objects named myAX12_1, myAX12_2, etc...

for(int i=1, i<11, i++){

    AX12 myAX12_i (p9, p10, i);

}

Can anyone help me out and tell me how to get the 'myAX12_' + i working?

Cheers, Martin

23 Jun 2011

I suppose you could do something with macros (the hashhash operator) but why would you? What you probably need is an array of objects, like:

AX12 *myAX12s[10];
for (int  i = 0; i < 10; i++)
  myAX12s[i] = new AX12(p9, p10, i+1);
23 Jun 2011

Thanks, yes an array would work fine. But I get an error when I try to compile a simple program.

#include "mbed.h"
#include "AX12.h"

int main() {
    Serial pc(USBTX, USBRX); // tx, rx
    AX12 *myAX12[10];
    float temp;
    
    // Print msg to PC
    pc.printf("Scanning chain for AX12+ Servos...\n\n");
    // Create a AX12 object for each possible address
    for (int  i = 0; i < 10; i++){
         myAX12[i] = new AX12(p9, p10, i);                  // Create object
         temp = myAX12[i].GetTemp();                        // See if the AX12 exists at this address
         if(temp != 0){
            pc.printf("Sevo found at address %d",temp);     // If it does print address to the PC
         }
    }
}

The error I get is error 153 'expression must have a class type' centred around the 'temp = myAX12[i].GetTemp();' line. Any ideas how to fix this anyone?

23 Jun 2011

Should have looked harder I needed 'temp = myAX12[i]->GetTemp();' which compiles fine

24 Jun 2011

The code now complies and works but with 2 quirks

1. If I try to create more than 15 objects the program hangs when run

2. It returns the next ID of a servo (e.g. if I find servo ID 3 it will return 4) which is centered around the line

status = myAX12[i]->'any method'();                   // See if the AX12 exists at this address

Code is shown below...

#include "mbed.h"
#include "AX12.h"

int main() {
    Serial pc(USBTX, USBRX); // tx, rx
    AX12 *myAX12[15];
    int status=0;
    int Key=0;
    int NewID=0, OldID=0;

    while(1){
        // Print msg to PC
        pc.printf("Scanning chain for AX12+ Servos...\n\n\r");
        // See which addresses contain AX12+ servos
       for (int  i = 0;i < 15; i++){
            myAX12[i] = new AX12(p9, p10, i);                  // Create objects
            status = 0;                                          // Reset status variable
            status = myAX12[i]->GetID();                   // See if the AX12 exists at this address
            if(status != -1){
                pc.printf("Sevo found at address %d\n\r",i-1);    // If it does print address and position to the PC 
            }
        }
        // Print msg to PC
        pc.printf("\nEnter AX12+ ID to Alter...  ");
        while (Key != 0x0D){
            Key=pc.getc();                                  //Get the keypad pressed
            if((Key>=0x30)&&(Key<=0x39)){                   //See if it's a number (0-9)
                OldID=OldID*10+(Key-48);                    //Strip off ASCII code, convert to int & index
                pc.putc(Key);
            }
            else if (Key == 0x20){                          // Space was pressed
                pc.printf("\n\rMoving sevros...");
                while(1){
                    Key=pc.getc();                                  //Get the keypad pressed
                    if((Key>=0x30)&&(Key<=0x39)){                   //See if it's a number (0-9)
                        pc.putc(Key);
                        myAX12[(Key-48)]->SetGoal(60);
                        wait(0.5);
                        myAX12[(Key-48)]->SetGoal(240);
                        wait(0.5);
                    }
                }
            }
        }
        Key = 0;                                            // Reset Key
        pc.printf("\n\rEnter new AX12+ ID...  ");
        while (Key != 0x0D){
            Key=pc.getc();                                  //Get the keypad pressed
            if((Key>=0x30)&&(Key<=0x39)){                   //See if it's a number (0-9)
                NewID=NewID*10+(Key-48);                    //Strip off ASCII code, convert to int & index
                pc.putc(Key);
            }
        }
        pc.printf("\n\rChanging AX12+ No. %d ID from %d to %d...\n\r",OldID,OldID,NewID);
        myAX12[OldID]->SetID(OldID,NewID);
    }
}

Anyone know why the program might be doing this???

24 Jun 2011

Quote:

1. If I try to create more than 15 objects the program hangs when run

Then don't limit yourself to 15. It's your program that reserves just 15 "slots" with that array size. If you go over it a crash is alwasy going to be the result.

        AX12 *myAX12[15];

Why are you mixing and matching number bases? One minute it's hex (0x30) the next it's decimal (48). Why not just use '0' for 0x30 and 48, it's far more obvious and will result in you finding any math error in calculating the indexes.

You should always bounds check any calculated index before attempting to use it to dereference an array item also.

24 Jun 2011

Thanks for the reply Andy, The code hangs if I reserve more space in the array for the AX12, e.g.

 AX12 *myAX12[100];

will still result in the program hanging if I then go on to create more than 15 AX12 objects later in the code.

As for the mixing of bases, I cut and paste in some old code I had written, I hadn't spotted it. I'll tidy it up later.

24 Jun 2011

concerning the ID: the array is zero based but you count from 1, therefore in my example code I passed i+1 as the third argument. The other issue: Don't know, unless an AX12 object is very large I can't explain it. In all my programs I have a hardfault handler which also shows me the amount of available memory (the largest block that can still be allocated), this sometimes gives a hint about what is going on. Even though you have 15 servo's you call SetGoal only for 0..9. The OldID variable is however not limited to 9 or 14, be careful there.

24 Jun 2011

Martin,

When you do myAX12[i] = new AX12(p9, p10, i); you should actually check the return value. If new returns null you are out of memory ;) Lets get that one out of the way before continuing:-

       for (int  i = 0;i < 15; i++){
            myAX12[i] = new AX12(p9, p10, i);                  // Create objects
            if (!myAX12[i]) error("failed to alloc new memory\n");
            status = 0;                                          // Reset status variable
            status = myAX12[i]->GetID();                   // See if the AX12 exists at this address
            if(status != -1){
                pc.printf("Sevo found at address %d\n\r",i-1);    // If it does print address and position to the PC 
            }
        }

If this results in the blue lights of death then you are out of memory.

24 Jun 2011

You need to delete the 15 AX12 objects in your myAX12 pointer array from any prior iteration of the preceding "while (1)" before creating 15 new ones. Just because you reuse the pointer doesn't mean the prior object it pointed to is destroyed.

Since deleting a NULL pointer is allowed try this:

for (int  i = 0;i < 15; i++){
            delete myAX12[i];                 // Delete object, if any, from prior iteration of while(1)
            myAX12[i] = new AX12(p9, p10, i); // Create object

That or create the 15 objects before the while(1) and reuse them.