What Adurino do I need for Meccanoid?

I've spent a fair amount of time examining the Arduino library code as it was supplied by Spinmaster. Here's what I've learned so far.

The communicate() routine seems designed to be called constantly, probably in the sketch's loop() routine. Each time it's called it would elicit a return value from one module on the bus. Hence, it would have to be called 4 times to ensure that the module that you wanted to hear from would get the chance to reply.

The various high level routines (set colour, set position, set servo to LIM mode) didn't call communicate() internally. They would just set up values in the output data array, apparently relying on the sketch to continually poll the communicate() routine.

The first modification I tried was having the high level routine directly call the communicate() routine, passing the module number that I wanted to hear from. communicate() would then send a single data packet and pass back the return value. It all sounded great in theory but it didn't work. It seems that you have to treat the bus as the thing you're communicating with rather than an individual module. So all four modules on the bus have to be polled in turn.

A further modification that does appear to work involved multi byte commands being sent to an individual module. For example, I was able to have communicate() poll a module, ask for its type and finally set its colour (3 data packets for a servo, 4 for an LED) before moving on to the next module. Getting that to work simplified things.

A quirk of the protocol means that it takes longer tao talk to a bus with only a single module on it than it does to talk to a fully populated (4 modules) bus. The timeouts waiting to hear from a module that isn't there take a significant amount of time.

I discovered this when I had each high level routine call communicate() up front before setting its values and calling communicate() a second time. It may seem like an odd thing to do, but what it did was allow for hot plugging modules onto the bus. But it really slowed things down. I ended up only making the up front call if no modules were detected on the bus after the last call. It accomplished exactly the same thing and was a whole lot faster.

The LED module returns its module type (0x02) each time a set colour command is issued.

The servo module returns the actual position of the servo (0x04 to 0xF9) after either a set colour, set position or set to LIM command. The original library code would only send 0x18 to 0xE8 for position data but I modified mine to be able to send the whole range. It seems to work.

Since neither module appears capable of returning a value of 0x03, I'm assuming that it's been reserved for identifying a future type of smart module. Additionally, 0xFB isn't used for either a command or a response so that may well be reserved as a command for that hypothetical future smart module type. I don't know what (if anything) Spinmaster might have in mind for that hypothetical module type, but something that could read and report on some sort of sensor (optical, electrical, or mechanical contact, etc.) would be a huge plus. As things stand now the only input we can read is each servo's position. With an input module, we'd have the ability to move a servo in response to an input signal (think photocell or microswitch, for example).

Latest tinkering: I put one arm's servos into LIM mode. The servo position values were then inverted (low value positions were mapped to high values and vice versa) and sent to the other arm so that it would replicate the first arm's movements.

The first try worked but it was very jerky. Even with all four servos daisy chained to eliminate any "missing module" timeouts I was still making way too many calls to communicate() for things to work smoothly. Time for a re-think.

Incidentally, you can take a servo out of LIM mode by sending it a position value other than 0xFA.

I connected a 2 inch flex sensor to the analog port of the arduino today and it works great. I can reliably control a single arm (3 servos).

I plan to continue exploring servo control via sensor input. I also want to modify the arm to improve range of motion. (I think it needs a rotator cuff?)

In my previous post I described two types of errors I have seen in the Smart Module protocol: a module returning the wrong module type, and a module not responding to a poll.

I have also seen a third type of error. I wrote a loop which displays (on the serial monitor) the position returned by a particular servo at regular intervals, say once a second. I find that there is the occasional "rogue" value, quite different from those before and after. For example one sequence I have seen is AC AC AC 2C AC AC ....

It occurs to me that these three types of errors are not necessarily the fault of the servos. They may, for example, be caused by electrical noise in the servo cables or incorrect timing in the Arduino code.

Has anybody else seen any of these errors?

David

I am working on mine, and I haven't gotten to that yet. So far I implemented a non-blocking timing system and was able to write to the servos. The library is very poorly written. You should consider optimizing it. That will speed things up considerably.

I have to disagree with goodinventor and others about the library being badly written. I believe that it is impossible to communicate with the servos using either a UART or interrupt-driven code, and the only way to do it is by bit-banging with fixed delays. I would be very happy to be proven wrong in this. But if it is true, then the library implements it in a straightforward way, and I don't see how it could be improved on.

The problem is in the protocol, not the library code.

The communicate() function is quite clever in the way it manages the protocol behind the scenes. After receiving (or not) each response from a servo it sets the status of that servo and the next command to be sent to it. This means you don't have to keep track of the state of the protocol, but just keep calling the function.

David

deeceethree:
displays (on the serial monitor) the position returned by a particular servo

deeceethree:
each response from a servo

Interesting.... servos don't typically publish their whereabouts, although they do know internally if they arrived or not. So presumably this Meccanoid thingy has feedback enabled servos, perhaps along the lines of these from adafruit?

Yes, these servos have feedback functionality. It's even supported in the MeccaBrain library.

check this out: www.meccontrol.com

Tegument:
check this out: www.meccontrol.com

Yes, firmware that actually works. Unlike the meccano library which never did work.

I'ld love to know if you have done any more with your Meccanoid. If so, if you be willing to post it. We just bought a Arduino Mega and H-bridge and would like to see ho to connect it up so that we to can have a Meccanoid running like you did in the video. Thanks a bunch. Hopefully, you have gotten further with yours and can post some more info

Hi

I consulted this forum a while ago to learn about Meccanoid and Arduino.
Using T. Volkova's code on the smaller robot, here is a draft tutorial if people want to do the same thing.
(it will also help me to rebuilt it when i will do something else)

Regards

Meccanoid G15 Arduino - Brother - Basic Code 1_2.pdf (887 KB)

FolloWw-up

Meccanoid G15 Arduino - Brother - Basic Code 2_2.pdf (1.06 MB)

Hi

I just set up a daisy chain of 2 meccano servos to my arduino and set one of the servo to LIM mode.

when i printed the servo positions to the serial montor using this command:

servo.communicate();
servo.setServotoLIM(0);
Serial.println(servo.getServoPosition(0));

I am getting this output:

18
0
18
0
35
0
78
0
136
0
168
0
239
0
240
0
130
0
65
0
0
0
0

i don't know why i am getting 0 after each correct position?

any help will be appreciated.
Regards

If I buy this kit from smraza will the arduino clone mega board by them work with meccanoid?

I have the 4 feet meccanoid and would like to program it.

Is this a good kit or any other recommendations?

Just an update for MeccaBrain / Servo Motors Users :

  • Looking at the code,
    I see that the Module Number (moduleNum) is included in the CheckSum () :
byte MeccaBrain :: calculateCheckSum(byte Data1, byte Data2, byte Data3, byte Data4)
{
  int CS;

  CS =  Data1 + Data2 + Data3 + Data4;  // ignore overflow
  CS = CS + (CS >> 8);                  // right shift 8 places
  CS = CS + (CS << 4);                  // left shift 4 places
  CS = CS & 0xF0;                       // mask off top nibble
  CS = CS | moduleNum;    // <<--**

  return CS;
}

I would take an educated guess that the Servos - do not recognize the Communicated Packets - unless the CheckSum + moduleNum matches it.
Initialize might be an exception though - how do the Servos identify their own Module Num ?
... Maybe the Servos block Output to the next Servo - and only output their own reply, if they are not initialized yet.

It may be possible to communicate to a single Motor,
without rotating through the other 3x Motors (present or not)
by simply specifying the ModuleNum in the CheckSum,

  • and so Speed up the Control of the Motor(s).

Would suggest testing this, by setting the ModulNum in the SetServoPosition() func :

void MeccaBrain :: setServoPosition(int servoNum, byte pos)
{
  int servoPos = 0;

  /// MOD - JLC : ///
  moduleNum = servoNum ;

  if( moduleType[servoNum] == 'S' )
  {
 
    if(pos < 0x18)
    {
      servoPos = 0x18;
    }
    else 
    if(pos > 0xE8)
    {
      servoPos = 0xE8;
    }
    else
    {
      servoPos = pos;
    }
 
    outputByte[servoNum] = servoPos;
 } 
}

Has anyone see this or test this ?

Note - to fix the misread Servo as LED lockout, suggest adding this mod:

    /// SERVO MODULE IN : ///
    if ( 
		inputByte == 0x01 
	/// REMOVED - Not Needed : ///
//	&& 	moduleType[moduleNum] == '_'
	  )                 // if received back 0x01 (module ID is a servo), then change servo color to Blue
    {
    	outputByte[moduleNum] = 0xF4;
    	moduleType[moduleNum] = 'S';
    }

For anyone playing with these, I've done a bit of research and produced the attached.

Meccano MAX Control codes.pdf (696 KB)

Nice piece of work @bmd1103...

I have both a M.A.X. and an XL on order, so new to all this, but what I see as more interesting is the reverse of this thread - I want to see if I can use the voice-recognition (VoR) aspect of the Meccano brains to control another robot, such as the Robotis Bioloid and give it VoR control...

When I look around, most of what I see as available is voice control using a phone - seems much better to have it on-board, but there seems to be a split in approach philosophies...

I am amazed that Meccano has produced so much VoR power for such an inexpensive part...thinking the M.A.X. is more recent so will be more powerful than the Meccabrain?

Anyway, I look forward to this new journey, and I do appreciate your work...!

Frank

1 Like