Meccano MAX and Arduino

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.

mrdreambot,

The sequence I logged repeated the commands FF FC FE FE FE FE 8n twice - I don't know if that is the requirement. Then there is FF 00 FF 00 FF 00 - ~~, with no response from the module, then it appears to start on the pwm sequence.

However, I haven't looked for any more detail at the transition between the two modes and can't do any hands-on testing till I get home in a month. I'll try and run my transition timing program on the startup sequence, or trigger my oscilloscope from the Arduino so I can grab the last couple of frames of the serial and the start of the pwm mode.
There is about a 33 ms delay between the pwm frames so you could try that between the serial and pwm as well.

So I'd suggest -
send

FF FE FE FE FE A1 - ~~
FF FE FE FE FE A1 - ~~
FF FE FE FE FE A2 - ~~
FF FE FE FE FE A3 - ~~
FF FE FE FE FE A0 - fe Module 0 replies with 0xfe
FF FE FE FE FE A1 - ~~
FF FE FE FE FE A2 - ~~
FF FE FE FE FE A3 - ~~
FF FE FE FE FE A0 - fe Module 0 repeats reply
FF FC FE FE FE 81 - ~~
FF FC FE FE FE 82 - ~~
FF FC FE FE FE 83 - ~~
FF FC FE FE FE 80 - 06 Module 0 replies with type code 6
FF FC FE FE FE 81 - ~~
FF FC FE FE FE 82 - ~~
FF FC FE FE FE 83 - ~~
FF FC FE FE FE 80 - 06 Module 0 repeats reply
FF FC FE FE FE 81 - ~~
FF FC FE FE FE 82 - ~~
FF FC FE FE FE 83 - ~~
FF 00 FF 00 FF 00 - ~~ ?? Change to pwm command ??

then wait 30 ms, then start sending the pwm strings.

Hope that helps.

Tried different variations and delays but still not able to get any LED on the Face to light up. Shall try some more tomorrow and keep you informed.

mrdreambot-

If you are using the program I wrote to write to the array, the csFlag array is wrong - it needs to be

boolean csFlag[] = { true, true, true, true, false, true, false, true };

The original was written when I was assuming that the message was sent lsb-first.

I'm going to go back to my original data stream tests and try to translate them into the correct format - but it's easy to make a mistake. I've written an Excel app to see if I can tidy it up but need to double-check the results against the hardware. (unfortunately, I can't attach an Excel file).

For the default horizontal bar, the correct sequence is:
0xF7
0xF7
0xF7
0xF7
0xF7
0xF7
0xF7
0xF7
0xF7
0xF7
0xF7
0xF7
0xF7
0xF7
0xF7
0xE3
0xF5 - checksum marker
0x9E - checksum

mrdreambot -

I've modified the list of face array data - see the attachment. I haven't completed it but have gone through my face array designer and verified the hex bytes and checksums. Try these and see if they work.

LED array messages.pdf (93.9 KB)

BMD1103,

Thanks for spending time on your trip to do this. I am using my own code. Using your new data, it is still not working for me. I have the following:

FF FF F1 E6 E4 B1 7F 7F 7F 7F F1 E6 E4 F1 FF FF F5 2D
Checksum: 2D vs EC
F7 F7 F7 F7 F7 F7 F7 F7 F7 F7 F7 F7 F7 F7 F7 E3 F5 9E
Checksum: 9E vs 9E
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
Last device has been discovered...
Face: Connected at position: 0
Device #0: Face
0 FF 0 FF 1 - 0
0 FF 0 FF 2 - 0
0 FF 0 FF 3 - 0
0 FF 0 FF 0 - 0
Face: Connected at position: 0
Device #0: Face
0 FF 0 FF 1 - 0
0 FF 0 FF 2 - 0
0 FF 0 FF 3 - 0
0 FF 0 FF 0 - 0

This first array is the happy face in your latest pdf. Note that the checksum is different from using the algorithm you posted. The second array is the horizontal line. The checksums agree.

The exchange is similar to your working observation. After sending 0 FF 0 FF x - y 2 times, I waited for 30 ms before sending the array MSB first. I tried sending them MSB first and LSB first and no LED was lit. Just to confirm, there is a start bit consisting of -132 +564 -140 ie, 132 us low, 564 us high and 140us low, which is followed by the values of the array. And there is no stop bit. Is this correct?

BTW, don't ruin your holidays working on this. It can wait. I can work on other aspects of the project.

No problem- it's too hot here (in the UK) to do a lot ( - and my room is on the shady side of the house).

I'm working with a timing base of 140 us. The "preamble" is 1 time interval LOW, 4 HIGH, and 1 LOW. Then each message bit is made up from 1 HIGH, 1 HIGH or LOW depending on the data bit, and 1 LOW. There is something at the end of the message but I have not been able to resolve it - it looks as if there is possibly some tri-stating going on as there is a definite exponential charge curve from LOW to HIGH, followed by a LOW. It looks as if I'll have to check that out when I get home.