Go Down

Topic: What Adurino do I need for Meccanoid? (Read 2684 times) previous topic - next topic


So you're saying it would be much better if I use Serial rather than digitalWrite? The board I'm using has 3 UART interfaces (enough to run both servo daisy chains).


So you're saying it would be much better if I use Serial rather than digitalWrite?
Yes. IIRC, the Meccanoid library is just bit banging asynchronous serial output. You should be able to send the data using a hardware UART using an appropriate baud. The Meccanoid's software serial blocks the execution of the program until the message have been sent (at excruciatingly slow speeds). It doesn't matter how fast your processor is, if you have to send messages using their driver, the program will spend most of the time waiting for messages to be sent.


So that means if I optimize their library my controller should have plenty of processing power even for the sensors as well.


I have installed an Arduino Uno with an Adafruit motor shield in my Meccanoid G15 KS, and connected it to the servos and foot motors. I have also used the head servos to make gripping hands, making four servos daisy-chained on each arm. All this hardware works fine.

I have written Arduino code to control the servos, using the published library. I included code to print out the module number, sent byte (for that module), received byte and elapsed time after each call to the communicate() function, so that I can monitor the protocol in detail. Here is what I have found.

Calls to communicate() go in groups of four, even if there are fewer than four servos present. Each transmission contains sent bytes for all four servos, but the servos take turns to respond, one per call. In the first group usually no servos respond. In the second the first servo in the chain responds and starts its initialisation. In the third group the first servo completes its initialisation and the second one starts. The same for the third and fourth servos. So it take at least six groups or 24 calls to communicate() to initialise four servos (20 for three servos and 16 for two). Calls take 50 milliseconds if the servo responds and 78 msec if it does not. The total time to start up four servos is about 1.5 seconds.

Simply executing repeated calls to communicate() usually works, but not always. A servo will sometimes (at random and too often) respond to the query byte FC with a 2, meaning LED, instead of a 1, meaning servo. Once this happens no amount of calls to communicate() will discover that it is a servo. The only fix with the current library is to call the function MeccaBrain() to reinitialise all the variables for the chain and start again.

The other problem I have seen is that, after the servos are initialised, one will sometimes fail to respond to a transmission. When this happens the library code marks that servo and all others further down the chain as absent, and performs the initialisation for them again on subsequent calls to communicate(). The protocol recovers, but with a small delay.

Incidentally, I have observed that the servos report their positions in response to every transmission, and do not need to be put into LIM mode to do so. Also the current library provides no way to get a servo out of LIM mode.

It has been suggested that the bit-banging method of transmission could be replaced by the use of a UART, though nobody has reported trying it. I can believe that this would work for the transmission. However receiving the response from the servo is another matter. As the protocol document explains, this byte is encoded differently, using short and long high pulses to represent 0 and 1. I would think that the UART could not deal with this, and the only way to read the byte is to use the Arduino pulseIn instruction. The response starts 1.5 msec after the end of the transmisson, and the code must be ready to receive it at that time. It is hard to see how the timing could be correct if the UART transmits asynchronously. Unless a way round this can be found it means that the CPU will be blocked most of the time just maintaining the servo protocol.

Let's have a closer look at the timing. A single transmission, carrying position commands to all the servos, takes 50 msec (longer on average if there are fewer than four servos in the chain). So the servos can be updated 20 times a second at most. You will probably want to program both arms, so that means only 10 updates per second each. Add in the head servos and LED module and it is down to less than 8 per second, using 100% of the CPU time. If you want to read servo positions, the rate is down to a quarter of that, i.e. two times per second. All this is due to the nature of the protocol and does not depend on the choice of processor.

One possibility that has occurred to me is to use a dedicated processor just to maintain the servo protocol, or better still one for each chain. If someone has four Arduinos and can figure out how to get them to talk to each other perhaps they can tell us if this works.

I will wait to see if anyone disagrees with what I have said before I make further comments.

There are similar discussions going on at the New Zealand Meccano web site at http://www.nzmeccano.com/forum/showthread.php?tid=2534
and the MeccanoZone web site at http://www.meccanozone.com/replacing-the-meccabrain-t255.html



My setup is a little interesting. It has the equivalent processing power of nearly 60 Arduino Unos. I have created a program to control the servos and so far it is taking anywhere from 3 to 10 seconds from boot up to controlling the first servo. I think this is partly because of the BIOS and boot loader (it's an x86 system), and partly because of my code. I will try to improve the execution speed of my program by timing without delay() and fixing up that awfully written library by Meccanoid.

Go Up

Please enter a valid email to subscribe

Confirm your email address

We need to confirm your email address.
To complete the subscription, please click the link in the email we just sent you.

Thank you for subscribing!

via Egeo 16
Torino, 10131