Meccano MAX and Arduino

Looks like I've got a month's worth of things to do when I get back ...

btw, I've just found GitHub - alexfrederiksen/MeccanoidForArduino: An improved library written in C++ to allow an Arduino to interface with the Meccanoid robot modules which might be worth looking into - haven't had a chance yet. Perhaps a joint effort may be in order.

I've seen it. You should look at my Arduino Library which is designed for the Meccano MAX instead of the Mecanoid. My library contains an example which exercises all devices except the IR sensor. Run it using your Nano and see how it works.

Hi mrdreambot,

I'm back in action.
My first activity has been to look at the signals at low level, and I've had a couple of surprises. I wrote an app for the Mega that just looks at the times between transitions on the signal line between the Meccabrain and the display module. I had to use the Mega as there is a LOT of data to be stored - upwards of 2000 items to get useful results.

I first ran the program looking at the start-up sequence - see the file. (I've deleted a lot of repeats to save space, but nothing of significance.) I can't see anywhere in there that is a true serial sequence of FF 00 FF 000 FF 00. There is also no serial transmission between the blank screen for startup and the default sequence. The different sequences for the various forms of the default follow on one from the other with no serial message between them, which is in line with what I see with the oscilloscope.

I also managed to get a printout for a change in display using the programming mode to go from LOL! to BYE. Again, there is no indication in the timing of any serial strings between the two.

I'm currently working on getting the Nano to go - so far I've managed to get a software serial port running with the 2 stop bits needed, and am looking at how to connect up the hardware.

LOL - BYE timimg.pdf (47.9 KB)

MAX face array startup timing.pdf (57.6 KB)

btw, your timings in #29 are based on 10 bits/bye. There are only 8 bits/byte in the face display. There are 6 'ticks' needed for the preamble: 18 8-bit bytes at 3 'ticks'/bit = 18 x 8 x 3 = 432 'ticks' for the display itself: and 4 more ticks needed for the stop bit - a total of 442 ticks. At 140 us /tick, that is 61 ms - about what I see on the oscilloscope display. The original has about 32 ms between successive writes to the display - so we should be able to get better than 10 updates/second.

Greater than 10 updates per seconds is good. What are the objectives of your project?

I can now report success with sending a display! Routine is attached.

It just sends the command string in the "configure" routine, then moves on to the wrtDisplay function. Without the diagnostic Serial.writes I'm getting less than 75 ms between updates - about 14 /sec.

I've set up the display bytes in an array so that I can scroll between them initially, to see if I can get some fairly rapid movement. The preamble, message, checksum flag and checksum are converted into bits in a bit array, which is then read on each timeout of the 140 us clock and sent to the output port.

This is running in a Mega at the moment - 5000 bytes of program memory, 938 bytes of dynamic memory. (I used the extra capabilities of the Mega to help with diagnostics - now to see if it'll run in a Nano ... )

At this stage, I'm exploring the capabilities of the system to see just what it can be made to do. Ultimately, I'd like to be able to add other non-Meccano sensors (using simpler interfaces) but use the servos and motors which are much easier to interface mechanically with the Meccano hardware. I have used my 3D printer to make up some servo mounts for RC-type servos which have the 1/2" mounting holes etc. I'm keeping an eye on TradeMe (NZ equivalent of eBay) for unwanted products so I can get some more of the smart servos etc.

Mega_write_display_working_0922.ino (9.91 KB)

Interesting. Which 3d printer would you recommended? I'd like to get one!

I've got an XYZ Da Vinci 1.0 - a bit dated now. It had a few teething issues but seems to be fairly reliable now.

I have the Nano version going. Video is attached.

In the end, I simply "translated" the code from the Mega (which used pin 18 as TX1 to send the serial, and as a straight digital output to send the PWM,) to the Nano using pin 1 as TXD for the serial comms and as D1 for the PWM. I'm not using the incoming signal from the module in any way. I've lost the ability to use the serial monitor for debugging, but have used a LED array (as seen in the video) to see what is going on.

There is a difference between the Nano and the Mega versions which means I have to slow down the refresh rate with the Nano. However, that will give me about 100 ms between updates to do other things. I want to see if I can use a Mega as a master, feeding screen displays to the face array on demand (for instance, a left arrow a couple of seconds before doing a left turn.)

Nano scanning.mpg (1.5 MB)

Nice video. I like it. BTW, if you were to buy a new 3D printer, what would you buy? And what is the price range for a usable one, I mean not Micky mouse one.

mrdreambot:

  1. IR - at one time, I was able to read the distance by issuing the 0xa0 command to the device and it responds with a value. And I can map the response using a formula to get the distance. I forgot which command has to precede that. But now, I cannot repeat it anymore. Command 0xa0 always returns the same value!

On start-up, after the standard sequence, the command is FF DF FE FE FE 9n. However, this does not appear to be an active request for info as 0x00 is returned. It may be a "keep awake" check of some sort.

When I activate the remote controller, the message changes to FF DD FE FE FE 7n, and a value is returned. The value is to be read as 2 nybbles. The most significant gives the range sensed by MAX's left side sensor, with the less significant giving the range from the right sensor. So a return of 0xD8 would indicate something about 120 mm away from the right sensor. Approximate checks give a range of 50 mm for a return of 0x22, 100 mm for 0x66, and 150 mm for 0xAA

mrdreambot:
2) The MAX motors - you identified the forward and backward commands. Are there other commands eg, controlling the speed, stop, etc. It appears that if you don't send them forward/backward commands for a while, the motors will stop. There seems to be several commands that stop the motor. I am using 0x30. I have to retest this.

The startup sequence for the motors is:

...  Starting ... 
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
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
FF FC FE FE FE 81  - ~~
FF FC FE FE FE 82  - ~~
FF FC FE FE FE 83  - ~~
FF FC FE FE FE 80  - 5
FF FC FE FE FE 81  - fe
FF FC FE FE FE 82  - ~~
FF FC FE FE FE 83  - ~~
FF FC FE FE FE 80  - 5
FF FC FC FE FE 61  - 5
FF FC FC FE FE 62  - ~~
FF FC FC FE FE 63  - ~~
FF FC FC FE FE 60  - 5
FF 0 FC FE FE 91  - 5
FF 0 FC FE FE 92  - ~~
FF 0 FC FE FE 93  - ~~
FF 0 FC FE FE 90  - 0
FF 0 0 FE FE C1  - 1
FF 0 0 FE FE C2  - ~~
FF 0 0 FE FE C3  - ~~
FF 0 0 FE FE C0  - 0
FF 0 0 FE FE C1  - 1
FF 0 0 FE FE C2  - ~~
FF 0 0 FE FE C3  - ~~

The " 0 0" command group is the quiescent one, with nothing running.
check
The motor control codes are complex, and there appears to be a "keep awake" here. The static sequence is the FF 00 00 FE FE Cn group as above, but there are occasional appearances of FF 20 20 FE FE 10 as well.

When I use the programming tool to "Roll Motor 0 forward at a slow speed" there is a sequence:

FF 0 0 FE FE C0  - 0
FF 0 0 FE FE C1  - 2
FF 0 0 FE FE C2  - ~~
FF 0 0 FE FE C3  - ~~
FF 0 0 FE FE C0  - 0
FF 0 0 FE FE C1  - 2
FF 0 0 FE FE C2  - ~~
FF 45 20 FE FE 93  - ~~
FF 24 0 FE FE 40  - 0
FF 24 0 FE FE 41  - 2
FF 24 0 FE FE 42  - ~~
FF 24 0 FE FE 43  - ~~
FF 24 20 FE FE 60  - 0
FF 24 0 FE FE 41  - 2
FF 24 0 FE FE 42  - ~~
FF 24 0 FE FE 43  - ~~
FF 24 0 FE FE 40  - 8
FF 24 0 FE FE 41  - 2
FF 24 20 FE FE 62  - ~~
FF 24 0 FE FE 43  - ~~
FF 24 0 FE FE 40  - e
FF 24 0 FE FE 41  - 2
FF 24 0 FE FE 42  - ~~
FF 24 0 FE FE 43  - ~~
FF 24 20 FE FE 60  - 14
FF 24 0 FE FE 41  - 2
FF 24 0 FE FE 42  - ~~
FF 24 0 FE FE 43  - ~~
FF 24 0 FE FE 40  - 1c
FF 24 0 FE FE 41  - 2
FF 24 0 FE FE 42  - ~~
FF 24 20 FE FE 63  - ~~
FF 24 0 FE FE 40  - 22
FF 24 0 FE FE 41  - 2
FF 24 0 FE FE 42  - ~~
FF 24 0 FE FE 43  - ~~
FF 24 0 FE FE 40  - 28
FF 24 20 FE FE 61  - 2
FF 24 0 FE FE 42  - ~~
FF 24 0 FE FE 43  - ~~
FF 24 0 FE FE 40  - 30
FF 24 0 FE FE 41  - 2
FF 24 0 FE FE 42  - ~~
FF 24 20 FE FE 63  - ~~
FF 24 0 FE FE 40  - 35
FF 24 0 FE FE 41  - 2
FF 24 0 FE FE 42  - ~~
FF 24 0 FE FE 43  - ~~
FF 24 20 FE FE 60  - 3c
FF 24 0 FE FE 41  - 2
FF 24 0 FE FE 42  - ~~
FF 24 0 FE FE 43  - ~~
FF 24 0 FE FE 40  - 44
FF 24 0 FE FE 41  - 2
FF 24 20 FE FE 62  - ~~
FF 24 0 FE FE 43  - ~~
FF 24 0 FE FE 40  - 4a
FF 24 0 FE FE 41  - 2
FF 24 0 FE FE 42  - ~~
FF 24 0 FE FE 43  - ~~
FF 24 0 FE FE 40  - 0
FF 24 20 FE FE 61  - 2
FF 24 0 FE FE 42  - ~~
FF 24 0 FE FE 43  - ~~
FF 24 0 FE FE 40  - 8
FF 24 0 FE FE 41  - 2
FF 24 20 FE FE 62  - ~~
FF 24 0 FE FE 43  - ~~

If I start the same motor forward in the "fast"mode, the sequence is:

FF 4A 20 FE FE E1  - 2
FF 24 0 FE FE 42  - ~~
FF 24 0 FE FE 43  - ~~
FF 24 0 FE FE 40  - 38
FF 24 0 FE FE 41  - 2
FF 24 0 FE FE 42  - ~~
FF 24 20 FE FE 63  - ~~
FF 24 0 FE FE 40  - 43
FF 24 0 FE FE 41  - 2
FF 24 0 FE FE 42  - ~~
FF 24 0 FE FE 43  - ~~

For Motor 1 (MAX's right) the initial code is FF 20 45 FE FE 91 for slow; FF 20 4A FE FE
with the only difference being the initial 4A instead of 45. So it looks like the rotation direction is given by the ongoing command - 24 for forward, 34 for reverse - with the speed given by a command 4a, where a varies depending on the desired speed. This will need to be checked.

To stop a motor, use a speed value of 40. The actual sequence to stop motor 1 is:

FF 0 24 FE FE 40  - 1e
FF 0 24 FE FE 41  - e
FF 0 24 FE FE 42  - ~~
FF 20 24 FE FE 63  - ~~
FF 0 24 FE FE 40  - 1e
FF 20 40 FE FE 31  - 15
FF 0 20 FE FE F2  - ~~
FF 0 0 FE FE C3  - ~~
FF 0 0 FE FE C0  - 1e
FF 0 0 FE FE C1  - 1a
FF 0 0 FE FE C2  - ~~
FF 0 0 FE FE C3  - ~~

and for Motor 0 :

FF 24 0 FE FE 40  - 40
FF 24 20 FE FE 61  - 2
FF 24 0 FE FE 42  - ~~
FF 24 0 FE FE 43  - ~~
FF 40 20 FE FE 30  - 47
FF 20 0 FE FE F1  - 2
FF 0 0 FE FE C2  - ~~
FF 0 0 FE FE C3  - ~~

There's a lot to digest here, and I can't see what the significance of the returned value is. Perhaps a check in the LIM mode will help.

I hope that makes some sense to you!

Note:
Just to add to the confusion -
When the programming tool talks about "forward" and "backward" it does NOT refer to the direction of movement. The hex value 0x24 will turn both motors clockwise when viewed from the outside - for motor 0 MAX's left) this will actually move the device backward. So to get forward motion the code has to be FF 34 24 FE FE ci, and for reverse motion it will be FF 24 34 FE FE ci.

I was yet to absorb the previous post. Information overload ! :confused: :o :slight_smile:

It gets worse - if I look at what the standard Meccabrain is sending to the motors, I find a lot of different codes. The starting sequence is 25 bytes long. This is followed by 14 groups of FF 00 00 FE FECn, then 101 groups of FF 81 81 FE FE 0n (where n is the module no in the string). Then 2 groups of FF 00 00 FE FE for modules 0 and 1. Instead of 24 and 34 for the motor move commands, it uses 26 and 36. There is also the odd few groups of FF A0 A0 FE FE.

Anyway, the good news is that I have finally got a program running that does what I want it to do, and allows me to inject commands into the motors from the Mega. This will let me inject various combinations and see what happens. It works without any of the extraneous messages involving 45, 4A, etc, so I don't know how these values affect the speed. I'll see if altering the move command value between 34 and 32 changes the speed.

I am also starting to see some sense in the returned values. For motor 0 running forward, the returned value decreases. With the rest value initially 0x42. the sequence after starting is (all hex) 42, 40, 3C, 38, 35, 31, 2E, 2B, 27, ... Running the motor in reverse, the values increase instead of decrease. It looks as if the returned value is the position of the motor - I presume it's a stepper of some sort. The range seems to be from 0 to 4F.

I've just checked the speed thing. The values from 0x42 to 0x4F set the speed for the motor - 0x41 doesn't do anything. So each wheel can be set to rotate at a different speed if required. Speed with 4F is about 0.4 revs/sec: 43 is about 1/4 that speed. The value is saved so it's probably safer to set the speed for each motor as part of the sequence. So for maximum forward movement, use 0xFF 0x4F 0x4F 0xFE 0xFE before the movement. For consistency it's probably best to clear the speed memory with 0x40 when done - this is what happens with the programming mode.

Who designed such a noisy, messy protocol? Why? My head is exploding >:( :o

Certainly not in the Frank Hornby tradition!

The motor response indicating position can go to 0 - this makes it incompatible with the standard library as that assumes that a 0 response means that there is no module present.

Me interesa el proyecto