Meccano MAX and Arduino

After a bit more research ...

The face pattern is set using a format different from that set out in the protocol document. A similar pulse width arrangement is used, but the bit period is shorter at 416 us. There is a 140us LOW, 550 us HIGH, 140 us LOW sequence as a START combination. LEDS in the display are OFF if the message bit is high for 277 us on average,ON if it is about 138 us.

The first bit is the bottom left LED, and the sequence is bottom to top, left to right as viewed from the front.

After the 16 bytes carrying the display data, two more bytes are added presumably as some sort of error check. There also appears to be 2 very short pulse which I cannot resolve with my equipment.

Hi bmd1103,

Have you made any progress in interfacing to the MAX's ultrasonic sensor, face, etc? If so, could you share your finding please?

Getting there - I have managed to build a signal sniffer that lets me eavesdrop on the communications between the brain and the outlying devices, and am trying to complete code that will allow me to record a complete series of transactions. At the moment, I can receive and decode a single command/response pair but have a gremlin that stops it repeating on subsequent cycles. Once I have that working, I'll try to build up a library of commands and associated effects. I'm currently using the motors as there are 2 of them which allows me to look at how subsequent response are set out, bu will get into the ultrasonic sensor asap.

I'll keep this stream up-to-date when I start to make progress.

Looking forward to hearing your latest update. It will be interesting to know how the new devices communicate differently from that defined in the Smart Module Protocol. And SpinMaster has not updated its "Open Source" from a long while!

I have managed to get signals from the system - both commands and responses. There is still an issue I have to sort out with picking up the initial traffic when the MAX is first turned on, (which is of course the most interesting part).

The two Smart motors, when stationary, both return 0. Using 0x24 as the command byte drives the motor forward; 0x34 drives it back. Using the Remote Controller, there seems to be another command in there to change the speed. So when I start the first motor in the forward direction, then the second in the same direction, the command sequence is:

FF 0 0 FE FE C0 - 8
FF 0 0 FE FE C1 - 0
FF 0 0 FE FE C2 - ~~
FF 45 20 FE FE 93 - ~~
FF 24 0 FE FE 40 - 8
FF 24 0 FE FE 41 - 0
FF 24 0 FE FE 42 - ~~
FF 24 0 FE FE 43 - ~~
FF 24 0 FE FE 40 - c
FF 24 45 FE FE D1 - 0
FF 24 24 FE FE A2 - ~~
FF 24 24 FE FE A3 - ~~
FF 24 24 FE FE A0 - 14
FF 24 24 FE FE A1 - 0
FF 24 24 FE FE A2 - ~~
FF 24 24 FE FE A3 - ~~
FF 24 24 FE FE A0 - 1a

where the first 6 bytes are the command, and the final value is the response. (the ~~ indicates there is no response). I'm presuming the response is something to do with the speed, as it increases after the "45" command. The command to go to full speed is 0x4A.

Starting just the second motor in reverse gives:

FF 0 0 FE FE C2 - ~~
FF 20 45 FE FE 93 - ~~
FF 0 34 FE FE 50 - 27
FF 0 34 FE FE 51 - 1e
FF 0 34 FE FE 52 - ~~
FF 0 34 FE FE 53 - ~~
FF 0 34 FE FE 50 - 27
FF 20 34 FE FE 71 - 18
FF 0 34 FE FE 52 - ~~
FF 0 34 FE FE 53 - ~~
FF 0 34 FE FE 50 - 27
FF 0 34 FE FE 51 - 11

I still need to work on my sniffer program so I can get at the start-up codes, but at least I'm getting sensible results. I also need to sort out what the responses mean.

What is your interest in the MAX?

I have a MAX. I want to use it as a robotic platform ie, as a base for use as a vision-based robot. Before that can happen, I have to be able to control its motion, face expression (the strong point of MAX) and the hand and head movements. Hence my interest in how the meccabrain protocol works for these new devices. I am looking forward to your analysis of the communication protocol for these devices. I may borrow a Xprotolab scope to do some analysis of my own during the weekend :wink:

mrdreambot -

I've got as far as reading a string of transactions during start-up - see the attachment. I have given my interpretation of each step. I've also attached the current version of my sniffer program. It probably needs some refinement around the final presentation of results and there are a few little glitches from time to time that might need sorting.

The results are presented as the 6-byte command string, followed by the module response - ~~ shows that there is no response. Some interesting things are that it appears that a command may be addressed to a particular module even though the "item code" (last nibble of the string) refers to a different module.

Next step is to see if I can replicate the command strings from the Arduino in some sort of clever way (probably involving a multidimensional string array) and get the same responses back. I'm also going to set up MAX programs to repetitively do a series of commands such as move the servos, and see what the traffic is then.

Max_Sniffer_2007a.ino (5.54 KB)

Meccano MAX command codes - starting.pdf (57.2 KB)

Further testing on the servos installed as specified:

Using the remote control display to adjust the position of the servos gives:

FF B4 8D FE FE 41 - 8d Claw fully open

FF B4 C7 FE FE 11 - c8 Claw partly open

FF B4 E8 FE FE 41 - e2 Claw fully shut

FF 18 C7 FE FE A1 - c8 Head tilted to right

FF 78 C7 FE FE 11 - c8 Head central

FF E8 C7 FE FE 81 - c8 Head tilted to left

So a command
FF nn xx FE FE c1
will tilt the head at an angle dependent on nn in a range of 0x00 to 0xFA, and open the claw to a amount dependent xx in a range 0x80 to 0xFA.

Thanks for that.

Try Xprotolab scope with Windows Interface. Did not get anywhere. Recorded trace as a file but when playing back, the app always crashes. Here are a couple of screenshots. Can't analyse unless able to record and playback. Have to use your approach of writing a sniffer!

I've managed to get a sniffer reading the commands to the LED array.

The first table gives time in us for each logic level after the first HI-LO transition. - indicates a low level, + a high. So there is a preamble or "start bit' consisting of a 132 us LOW, a 564 us HIGH, and a 140 uS LOW.

-132 +564 -140
+280 -144 +276 -176 +236 -144 +280 -144 +136 -284 +280 -144 +280 -144 +280 -140
+280 -144 +280 -140 +280 -144 +280 -144 +156 -272 +284 -144 +280 -152 +260 -140
+280 -144 +280 -144 +276 -144 +280 -144 +148 -272 +280 -144 +284 -140 +280 -140
+280 -144 +280 -144 +276 -144 +280 -144 +144 -276 +280 -144 +280 -144 +280 -140
+280 -144 +280 -144 +280 -140 +280 -144 +144 -288 +312 -108 +272 -144 +280 -140
+280 -144 +280 -140 +284 -140 +280 -144 +160 -260 +280 -144 +280 -140 +284 -140
+280 -144 +280 -140 +284 -140 +280 -140 +148 -276 +280 -144 +280 -140 +284 -140
+280 -144 +280 -140 +284 -140 +280 -140 +152 -296 +260 -140 +280 -144 +280 -140
+280 -144 +280 -144 +280 -140 +280 -144 +144 -276 +280 -144 +280 -144 +280 -140
+280 -144 +280 -144 +280 -140 +280 -144 +140 -280 +280 -144 +280 -144 +280 -140
+280 -144 +280 -144 +280 -140 +280 -152 +144 -284 +276 -132 +280 -144 +332 -124
+256 -140 +280 -144 +280 -144 +276 -144 +140 -284 +280 -140 +280 -144 +280 -144
+280 -140 +280 -144 +280 -144 +276 -144 +140 -284 +280 -140 +280 -144 +280 -144
+280 -140 +280 -144 +280 -144 +280 -160 +132 -280 +272 -140 +280 -144 +280 -140
+284 -140 +280 -144 +280 -140 +284 -140 +140 -280 +284 -140 +280 -144 +280 -140
+284 -140 +280 -176 +240 -140 +140 -284 +140 -280 +140 -284 +280 -140 +284 -140
+280 -144 +280 -140 +284 -140 +288 -156 +144 -268 +284 -132 +144 -276 +280 -140
+280 -144 +148 -276 +144 -280 +276 -144 +280 -144 +280 -140 +280 -144 +144 -280
+20 -56 +128 -340
################# #################

The second table has the above data converted to binary: 1 = a long HIGH (>210us) and 0 a short HIGH. The pattern on the screen at the time was the standard horizontal line with a "moving" vertical bar of 3 dots. The first line is the long HIGH in the preamble, and the last 2 lines are some sort of check-sum (which needs a bit of working on).
1
1 1 1 1 0 1 1 1
1 1 1 1 0 1 1 1
1 1 1 1 0 1 1 1
1 1 1 1 0 1 1 1
1 1 1 1 0 1 1 1
1 1 1 1 0 1 1 1
1 1 1 1 0 1 1 1
1 1 1 1 0 1 1 1
1 1 1 1 0 1 1 1
1 1 1 1 0 1 1 1
1 1 1 1 0 1 1 1
1 1 1 1 0 1 1 1
1 1 1 1 0 1 1 1
1 1 1 1 0 1 1 1
1 1 1 1 0 1 1 1
1 1 1 0 0 0 1 1
1 1 1 1 0 1 0 1
1 0 0 1 1 1 1 0
0 0 - 0

The tab

Great work. I am going to write a library incorporating your work for experimentation in the next few day. Shall keep you informed.

I'm working on analysing the check-sum - remembered overnight that the data is transmitted LSB first, so the hex version of the data above is:

1 1 1 1 0 1 1 1 EF
1 1 1 1 0 1 1 1 EF
1 1 1 1 0 1 1 1 EF
1 1 1 1 0 1 1 1 EF
1 1 1 1 0 1 1 1 EF
1 1 1 1 0 1 1 1 EF
1 1 1 1 0 1 1 1 EF
1 1 1 1 0 1 1 1 EF
1 1 1 1 0 1 1 1 EF
1 1 1 1 0 1 1 1 EF
1 1 1 1 0 1 1 1 EF
1 1 1 1 0 1 1 1 EF
1 1 1 1 0 1 1 1 EF
1 1 1 1 0 1 1 1 EF
1 1 1 1 0 1 1 1 EF
1 1 1 0 0 0 1 1 C7
1 1 1 1 0 1 0 1 AF
1 0 0 1 1 1 1 0 79

I've got information from a number of the array patterns provided as part of the "Programming" function, and they all have AF as the first byte in the checksum. I'll assume that the calculation is a variant on the one used for the standard serial mode and see where that gets me.

Then I'll have to see what is involved in getting the Arduino to generate this type of string - probably won't be too bad with the PWM feature, but the subtle changes in timing for the start bit, and the need for an initial standard 2400 bd serial link will make it interesting.

OK. You keep analyzing the protocol. I've started writing a framework for MAX. Right now I can control the servos and motors. It is work in progress. I shall put it on Guthub soon so that others may improve on it. I am using Gang of 4's Chain of Responsibility Design pattern to loosely couple the different modules. I shall describe it in more details when I put it onto Github.

Here is a photo of my setup using Smart Power and an UNO. Also here is a screenshot of the Serial Monitor displaying the communication with the attached devices. Note that the header byte FF has been omitted. Also the checksum has been removed. Only the module number is shown. The response from the device is shown after the "-".

Good work! - I haven't done anything with the Mega apart from using it to snoop on the Max communications.

Here is the list of checksums derived from the standard face displays provided under the "Programming" option. I'll be away from home for a few weeks from Saturday so will have to work on the system on paper only. If I can't come up with a reasonably easy formula, I might try a brute strength approach - generate messages for simple patterns such as a single LED, and try all 256 possibilities until I find one that works.

LED array messages.pdf (101 KB)

Here is the UML class diagram of the framework I am working on now. Still in progress. As I said earlier, I am using the GOF Chain of Responsibility Design Pattern.

Need some time to digest your findings. I am going to be away for a week too. Enjoy your break.

BTW, the max distance sensor is not an ultrasonic but an infrared device and haveing similar behavior as a Sharp infrared sensor.

OK - I've got an algorithm for the checksum for the LED array.

First, the 8 bits for each of the 16 columns have to be converted into numerical form. The LS bit of each byte is the top one, rather than the bottom one as I assumed earlier, and each byte is therefore transmitted MSB first.

Second, the 16 bytes for the full display are added together using 1's complement arithmetic if there is an overflow, it is wrapped around and added in to the LSB position. The checksum flag value of 0xAF is also added in this fashion,

Third, the resultant is subtracted from 0xFF to get the checksum to be transmitted as byte 18 of the message.

byte checkSum(byte data[])
{
  int cs = 0;
  for (int i = 0; i < 17; i++)
  {
    cs = cs + data[i];
    if (cs > 255) cs = cs - 255;
    Serial.print(i);Serial.print("  ");Serial.println(cs);
  }
  cs = 0xFF - cs;
  return (byte)cs;
}

bmd1103,

Question: after identifying the device ID=6 which is the face after the exchange:

Starting Max Tests...
FE FE FE FE 0 - 0
FE FE FE FE 1 - 0
FE FE FE FE 2 - 0
FE FE FE FE 3 - 0
FE FE FE FE 0 - FE
FC FE FE FE 1 - 0
FC FE FE FE 2 - 0
FC FE FE FE 3 - 0
FC FE FE FE 0 - 6

Do I need to send a command before sending the data for display? If so, what command code is it?

If not, does it mean one can send data to the Face at anytime? That appears to violate the protocol above?

I tried sending the data right after identifying the device. But it does not work. I also try send a command (cycle between 0 and f8 before sending the data, it does not work either.

I did not calculate the checksum but used your recorded AF, checksum in your Lead_array_message PDF for the various images.

Any suggestion will be appreciated.