Updated BT comms between EV3 and AI2

Recently I posted about sending Bluetooth messages from and EV3 to an AI2 app. I decided at the time not to bother considering handling receiving IEEE754 floats as strings would work. Since then I have been thinking about how cluttered the code was, and that AI2 doesn’t easily support libraries of AI2 code. So, I started investigating writing a simple EV3Mailbox extension for AI2. After a bit of learning Java (I’m a Perl programmer at heart) I now have an extension:

EV3Mailbox Extension

The extension is still quite simple, solely handling the packing and unpacking of the message bytes. The Bluetooth comms part will still need to be performed by AI2 code. An example of using this to send/receive messages is as below:

Sample send/recv AI2 code.

Downloads

As usual, I am making my code available for use under the Creative Commons Attribution-ShareAlike 4.0 International License

The sample .aia file should include the extension .aix file, but I am also making that specifically available for use in other people’s projects.

  1. Run the EV3 code first.
  2. Start the AI2 app.
  3. Long-press the BT button. This will bring up a settings box.
  4. Enter the App device’s Bluetooth name in the settings – and press ‘save’. This will be stored, and sent to the EV3. This is so that the EV3 knows where to send its messages to. This must be the same name as shown in the BT connections list on the EV3.
  5. Press “Connect EV3”. This will give the list of BT devices known the the Android device. Choose the correct EV3.
  6. Once the App is connected to the EV3, the EV3 will say “detected”.
  7. Pressing the top, middle, or bottom buttons on the EV3 will send a BT message to the App:
    • A string for the top button
    • A number for the middle button
    • A boolean for the bottom button.
  8. The App will then display the message name and contents in the top two boxes.
  9. You can send string, number or boolean values back to the EV3 via the relevant boxes and buttons.

Receiving BT Mailboxes from EV3 by an AI2 App

Recently, on the MINDSTORMS Facebook group, the question was posed about is it possible to receive Bluetooth mailbox messages in an AI2 app from an EV3. This is something I’ve been meaning to do for a while. I’d written AI2 code to send BT messages to an EV3, but hadn’t focused on receiving messages. This was the spur to actually get this code written.

It wasn’t too tricky. Receiving the message was simple, but parsing it was the harder part. The format of a message from the EV3, as covered in my update to BT messaging is:

MLenL, MLenH, 0x01, 0x00, 0x81, 0x9E, NLen, NameBytes, 0x00, TLenL, TLenH, TextBytes, 0x00

This is received as a string of bytes, so has to be parsed as a list. Add in that there doesn’t appear to be a chr(x) type function in AI2 to convert from a number to its equivalent ASCII character, I have to do some array/list lookups. Thankfully I had that code in place for sending to the EV3.

Code

I’ve got the code to a position that it can hopefully be used for other purposes. I’m releasing what I’ve done so far as a baseline for others to work from. To make the code, linked below, work do the following:

  1. Run the EV3 code first.
  2. Start the AI2 app.
  3. Long-press the BT button. This will bring up a settings box.
  4. Enter the App device’s Bluetooth name in the settings. This will be stored, and sent to the EV3. This is so that the EV3 knows where to send its messages to. This must be the same name as shown in the BT connections list on the EV3.
  5. Press “Connect EV3”. This will give the list of BT devices known the the Android device. Choose the correct EV3.
  6. Once the App is connected to the EV3, the EV3 will say “detected”.
  7. Pressing the top, middle, or bottom buttons on the EV3 will send a BT message to the App.
  8. The App will then display the message name in the top text box, and the message text contents in the bottom box.

The code only handles text message. I have no plans to develop code to handle numbers or booleans. The EV3 code will coerce those data types to strings if sent as a text message. AI2 will coerce strings to numbers if they look correct, so if the EV3 needs to send a number, simply send it as a string, and the AI2 App will still do the Right Thing™.

Images and Code

AI2 Code Image

The AI2 code and Ev3 code may be obtained from:

The code is released under the Creative Commons Attribution-ShareAlike 4.0 International License

Producing Complex Structures on the EV3DPrinter

So, for the past few weeks I’ve been working on my build of the EV3DPrinter. I’ve had it printing various geometric shapes, “College” letters, and more recently I’ve been working on a complex shape – namely a castle:

A Small Castle
A Small Castle

Development

Since I’ve been programming my instance of the EV3DPrinter in EV3G I couldn’t realistically use G-Code as the string handling in EV3G isn’t up to the task. Instead I would do it some other way.

For years I’ve been using a very old X11 drawing package Tgif; this has the great advantage that its file format is text based, and object oriented – a perfect source of drawing data. I used this package to draw out my letters:

Letters in Tgif
Letters in Tgif

This worked perfectly as it was easy to convert the polygon path of each letter in to a simple set of coordinates for use in my code on the printer. I was however accidentally fortunate in that I’d aligned the letters to a grid, so could work out which one was which based on rows and then position along that row.

When it came to making the castle I figured I’d use the same program to develop each layer, and just write a new Perl program to parse the file into plot data. It was rather more complex than I’d thought. I had to design each and every layer of PLA, bar those layers that repeated, i.e. the first 5. So, first, I started off with just the base of the windows:

Base of the castle’s windows

This took two goes as the first time I had the slope at the bottom at too shallow an angle, so they sagged badly. Next I worked my way up the walls:

Working out the walls

Eventually after some trial I got to the final castle.

Process – First Version

The luck I’d had with the letters couldn’t work with a complex object. I needed to be able to define a layer’s polygon, its position relative to the layer below and some form of order. The simple answer, for me, in Tgif was to have a bounding box, a text object with a number, and a polygon inside the bounding box, as below:

Layer 27 of the castle

Layer 27, above, is closing up the tops of all the windows and the doorway, along with producing buttresses for the crenelations at the front. So here, there is the box, the number “27” and a polygon – the just visible arrow on the inside bottom left defines the end point of the path for that layer. The line width of the polygon defines how many layers are to be repeated for this path – 1 in this case.

This was a time consuming process, which did work, but resulted in 42 layers. The final Tgif image looked as below:

Final Tgif file for the castle

Process – Second Version

Although the Tgif images, so far worked well, it was a lot of effort. Discussing with a colleague, he asked why I couldn’t define a start and an end and layer-by-layer go from one to the other. A bit of thinking and a new plan came to mind.

The same system of box, text, and polygon would be used by a way of linking a start and an end would be used – a simple dotted box would group two layers together. The layer numbers would define the start and end, and all layers between would be interpolated between the two polygons. Of course both polygons would need the same number of points, but that’s fine.

Some new coding, along with spotting a mistake in my first castle, and I get the new Tgif image of:

13 layers to define the castle
Close up on layers 22 – 27

This is so much easier to manage. I’m now thinking on what to make next. I’ll be writing another program that will be able to read in multiple complex models and give a menu to select what to make. Once that’s done, I think I’ll be ready to publish my code – watch this space.

My First 3D Printer

I was rather impressed by Baz’s 3D LEGO printer when I got to see it at LW2017. So, I figured that when I had time I’d build it and have a go at coding it myself. I finally got all the parts this month and have built it up – albeit in different colours, and with a few minor structural changes.

Today I got the code working for the first time! It’s not fully fledged, but it’s functional, so I’m going to post a link to what I have so that people can follow my progress. The link below points to this basic code:

http://www.jander.me.uk/LEGO/resources/EV3DPrinter_JN-v0-1.ev3

It will be expanded to do more things, such as simple geometric shapes/prisms/cones, and reading datafiles to print more complex structures. I doubt I’ll pursue the G-code system as that’s too complex to handle in EV3G.

New Plott3r Pen Holder

Whilst preparing for Bricktastic I developed a new, and hopefully better, pen holder for my Plott3r. This holder is a little heavier than the original, and somewhat more solid. This ought to remove some of the small erratic movements from the plots.The PDF for the building instructions can be found at:

Plott3r-PenHolder-v2

The LDR file if you wish to load it in to an LDraw package is as below:

Plott3r Pen Holder LDR file

It should be noted that the pen holder will need to be built on to the tracked section, it cannot be clipped on like the original. Build the base, attach it to the tracks, then clip the front and back sections on to it.

EV3 Text Plotting

Okay, so I’ve been rather quiet on the blogging front for a few weeks – that’s because I’ve been working on getting my Plott3r to write out text:

ASCII Text

Here’s a video of it taken a little while ago (prior to some of the improvements I’ve made):

This has been rather a journey of discovery. I’ve blogged previously about getting a bluetooth message to the EV3 and how I needed to work out a font.

Font

The font itself didn’t prove to be that tricky to work out; it’s mainly been planned out on 5mm graph paper and simply converted into coordinates. I’ve tried to have it write the letters as a Left->Right writer would, so starting on the left side of each character and probably ending on the right. This way moving the the next letter doesn’t involve a lot of travelling.

Backlash Correction

One thing my Plott3r has, is an effort to manage backlash. Since the paper and pen change direction regularly I have a system that pre-moves the paper/pen a little prior to any change in direction. One thing I hadn’t realised before is that if I want to move a really small amount I could overshoot where I wanted to be just in my backlash correction. This would cause some oscillation around the correct location in some cases. For example, look at the centre of the spiral below:

Backlash over-compensation

The centre of the spiral is crooked due to the pen “seeking” around the correct location. My solution to this was to measure where I was before the backlash correction, and after. If I had overshot, then I did not move that particular axis. The results of this improvement on the spiral are below:

Overshoot corrected backlash

Android App

I wanted to be able to send a message from a spare Android phone to the EV3. Here’s where App Inventor 2 came in. I had to learn how it worked, along with learning its Scratch-like language, and implementing some fundamental routines, such as storing an IEE754 float. The current instance of the application looks like:

EV3 Messenger

The user can simply choose between 3 text sizes, and then write their message and press “Print”. The BT button is used to set up the Bluetooth connection and the name of the sending device; this is needed so that the EV3 can acknowledge message it receives. I found that if I didn’t ACK the messages there was a race condition whereby I’d get duplicate values with the second “overwriting” what the first should have been. The core code of the messaging app is below:

AI2 Core Code

At the start of the block you can see it send its name, and towards the end of the block it waiting for a bluetooth message. It doesn’t care about the contents of the message, simply that it got one. The EV3G side of the code is as below:

EV3G Messenger

What’s not shown is the plotting code as that’s quite complex. It keeps a tally of the location of the last plotted character and works out if the next one will fit; performing <cr><nl> if needed. The font is variable width, and has a small amount of “kerning”, so that letters such as ‘j’ and ‘q’ can overlap the inter-character space.

Letter Sizes

I originally was only going to have one letter size, but this would allow for only around 11 characters per line, which isn’t a lot. Shrinking the letters will result in more artefacts, which I’ll come on to later, but I think it has a certain “hand writing” charm:

Three letter sizes

Artefacts

There are a few artefacts that I’ve tried and tried to remove. I now think I’m simply fighting with the simple fact that it’s made from LEGO bricks and I can only realistically get a certain level of accuracy in the way I’ve built it. The main artefact left is as below:

Artefacts on 0, G, Q et al

If you look at the top and bottom of the 0 (zero), G and Q, there are small overshoots on one side of the diagonal. I think this is down to using Tank Move and the Y axis motor overshooting the target before moving back a little – a result of the internal PID controller.

Signing Off

I’ll be showing this off again at Bricktastic this year, hence all this work. I’m pleased that, due to my desire to plot text, that the backlash control is better. I figured that I’d have the Plott3r do one more thing. It now “signs” its plots with the URL to this blog 🙂

Signing off

I now need to put this to bed for a bit whilst I check that all the other models still work. Then I need to get back on with my Loom – I need to do a little bit of programming for that ready for it to be shown off too.

LEGO World 2017

My Weav3r loom and I were invited to exhibit at the MINDSTORMS booth at LEGO World 2017 this year – what a blast!

Lots, and lots, and lots of people.

I had a deadline of the end of January to get the loom built and mainly functional in order to get it shipped out to Denmark. So, lots of hours in my attic across New Year, and coding in the last week of January to get it ready. One thing I did learn is that LEGO axles that need to slide, as opposed to rotate, do not mix well with traditional English Christmas cake! I managed to get icing on the axles which then turned into adhesive goo, preventing the heddles from setting – oops!

Set out on the night before.

I was so glad that it worked after being transported. I had packed it with a very large amount of bubblewrap, and the only thing that had dismantled was part of the heddle selector’s gear rack. Here’s a video of it working on Day 1:

This was the first time it had actually woven anything of any length, so I was still learning how the machine would actually run. You can see in the video that the wefts are quite spread out in places. That’s due to the cloth wind-up drum running at a constant angular velocity, so as the day ran on the cloth would wind faster and faster. This lead to me altering the programming before breakfast on Day 2 🙂

The first day’s scarf.

The change to the programming allowed me to alter the angular rate of the winding reel throughout the day. This meant that as the scarf got longer I could slow it down, keeping the weft spacing in good order.

Here’s a video of it running on Day 3. This is an attempt to show how the “Jacquard” part of it works. There is a selector that can move along the 32 heddles and set a pair of pins, to the front or back, to set which ones go up or stay down. The video is not as clear as I’d like so I shall shoot another soon:

Unfortunately the loom stopped working towards the end of Day 3. It ceased to be able to align correctly, resulting in the heddle lifter arm jamming up. This happened just before the Owner of LEGO turned up:

Kjeld looking at the loom – thanks to Martyn Boogaarts for the photo.

Fortunately for me he’d seen it working a few minutes before – phew!

On investigation for the rest of the afternoon, and the next morning it appears that one of the motors wasn’t functioning correctly:

Wounded in Action.

On Day 4 the loom, with a new motor, it worked wonderfully. The final scarf is as below:

This was an amazing event, and taught me lots about the loom. I have several upgrades planned for the loom, but before I start on those I need to take some better pictures and video for here and YouTube.

One of the flattering things was that a few people asked if they could buy one of the scarves. Since it was the first outing of the loom I declined that – I kept the first and last of the event, and gave two to members of the MINDSTORMS booth.

Bricksmith and Treads – Part 3

In this article I will finish discussing placing treads manually using Bricksmith. In Part 2 I referred to sprockets with the notch a the top:

Notch at the top.
Notch at the top.

These are much better in terms of placing the first tread as it will sit properly in the notch as it’s on an integer grid, unlike the 90˚ rotated version which is very slightly off that grid.

Technique

The technique is almost identical to that discussed in Part 2, but the first tread needs to be rotated by 18˚ after its initial placement:

Initial placement.
Initial placement.
First tread rotated 18˚.
First tread rotated 18˚.

A point of interest is that the tread was rotated around a Y coordinate value of -48, i.e. a radius of 48 from the centre of the sprocket. This is different to the 50 used by LSynth as discussed in my previous post about my investigations in to LSynth:

Sprocket Radii as defined by lsynth.mpd.
Sprocket Radii as defined by lsynth.mpd: 50 & 25.

Once that first tread is in place and aligned, it is now a simple case of copying, pasting, and rotating as shown in part 2:

Second tread in place.
Second tread in place.
Final tread in place.
Final tread in place.

All done. One thing to note is that treads 2-5 have undergone two rotations each, but don’t appear to suffer any level of cumulative error. This is probably due to the first tread being rotated about its origin only. This results in the treads 2-5 only having one orientation rotation, and one position translation, thus reducing the errors.

This does look a lot of effort to do manually, but I’m used to it now and find it quick enough to do, and the results look good.

Further Investigations into LSynth and Treads

After posting my “tutorial” articles on the LEGO MINDSTORMS EV3 Facebook group I started to look in to how LSynth does its magic, and now have a greater understanding of what the issue with treads is. I’ve worked through how the lsynth.mpd file works, including reading the source code. I’ll attempt to describe what I’m seeing.

Constraint  Radii

The lsynth.mpd file is used to describe the parameters around the various elements, in this case Bands, and Band Constraints. Each constraint is defined by its type, radius, orientation etc. The two sprocket types I’m interested are listed as:

0 // Technic Sprocket Wheel 25.4
1 25 0 0 0 1 0 0 0 1 0 0 0 1 57520.dat
0 // Technic Sprocket Wheel 40.4
1 50 0 0 0 1 0 0 0 1 0 0 0 1 57519.dat

This states that the small sprocket has a radius of 25 LDU, and the large 50. This is incorrect, since the large sprocket is 1.6x that of the small, not 2x. It is in fact the small sprocket that is wrong, it ought to be 32 LDU. The sizes as per the LSynth file can be seen in the image below:

Sprocket Radii as defined by lsynth.mpd.
Sprocket Radii as defined by lsynth.mpd.
Band Scaling

The loop of treads is defined in the lsynth.mpd file as a band of fixed size elements. Two parts are defined: one for going between, and the other for wrapping around, the constraints – i.e. the sprockets. The band definition includes a scaling value which is used for working out how many elements will be needed between constraints, i.e. the straight line segments. For the large treads this is defined as:

0 FILE TECHNIC_CHAIN_TREAD_38.ldr
0 TECHNIC_CHAIN_TREAD_38 SYNTHESIS DEFINITION
0 Name: TECHNIC_CHAIN_TREAD_38.ldr
0 Author: Willy Tschager
0 Unofficial Model
0 SYNTH BEGIN DEFINE TECHNIC_CHAIN_TREAD_38 BAND FIXED 0.03571 8
0 // Technic Chain Tread 38
1 0 0 0 0 0 1 0 0 0 -1 -1 0 0 57518.dat
0 // Technic Chain Tread 38
1 0 0 0 -32 0 -1 0 0 0 1 -1 0 0 57518.dat
0 SYNTH END

The scale value here is 0.03571. This should be 1/N where N is the LDU length of the segment unit, i.e. tread, in LDU. The value of 0.03571 gives N=28 LDU. This is also wrong. The distance between the centre of the hooks and pin on the treads is 30 LDU, so the scale value ought to be 0.03333. This incorrect scaling value is what leads to the “compressed links” I referred to in the previous blog. The original value, and one of 0.03333 can be seen in the image below:

Top = 0.03571 (original), Bottom = 0.03333 (corrected).

An additional benefit is that the parts around the sprocket are also now the correct number.

Numerical Accuracy

Unfortunately it appears that numerical accuracy has a noticeable influence on the appearance. With the corrected scaling value for the treads, wrapped around a single sprocket the result looks like below:

Numerical accuracy.
Numerical accuracy.

As can be seen, the tread pins don’t sit quite in to the sprocket’s notches. I would put this down to rounding errors.

There is another issue in the code which doesn’t actually affect things, but I will comment on it. The code works out how many treads are needed on an arc, i.e. to go around the sprocket, as the length of the arc divided by the length of the tread (as deduced from 1/scale value):

n = type->scale * 2 * pi * k->radius + 0.5;

This is making the assumption that the tread would be “bent” around the circumference of the sprocket, when in fact it is a chord between two notches. In reality this difference between arc length and chord length doesn’t have an effect.

Final Thoughts

Again, I’m not knocking LSynth – I’d be lost without it for making up cables. I just thought I’d investigate why I never seemed to get bands of treads right with it. My “fixed” lsynth.mpd file has made a difference as things are now better, but the perfectionist in me would prefer that the treads sit in the notches, so I’ll continue doing them manually.

Bricksmith and Treads – Part 2

Sprocket Orientation

When building up a model in Bricksmith it’s important to consider the orientation of the sprockets. You’ll want them rotated such that the treads sit in the notches correctly. Generally the sprockets are going to end up in one of two orientations, 90˚ rotation between them:

notch-at-top
Notch at the top.
notch-at-side
Notch at the side.

The notch at the top is better as the treads will sit in the notch easily, whereas the notch at the side will require fine-grained movement to get the initial tread in place. For this particular post I will focus on the latter, i.e. notch at the side. Although this requires more initial set up the rotation of the treads is simpler. I will cover the other variant in a third post.

Rotation Controls

Since we’re wanting to place treads on the large sprocket, in my example, we’re going to want to rotate by 36˚. This is because there are 10 notches in the sprocket, so 360˚/10 = 36˚. The rotation controls are reachable from the Edit menu, and give a control box as below:

Edit Menu.
Edit Menu – note “Rotate…” a third of the way up.
Rotation Controls.
Rotation Controls.

All of our rotations will be around a fixed point.

Initial Tread Placement

The first thing to do is align a single tread with the sprocket. This is relatively easy, but in this orientation will require the fine grid for movement. The first tread ought to look like:

Initial Tread Placement
Initial Tread Placement.
How I Used to Do Treads – aka “Introducing Cumulative Error”

When I first started  to model treads manually I’d start with a line of treads which I’d “bend” in to place:

line-of-treads
A line of treads.

I would then select the first tread and rotate it about its pin. The coordinates of this pin can be found by moving the pointer around over the pin and observing the coordinates shown at the bottom of the Bricksmith window:

Coordinate information.
Coordinate information.

You’ll notice that two of these values change as the pointer moves but the third, in this example the x value, doesn’t. The two that change are the coordinates of the line passing through the tread’s pin.

Rotation about:
Rotation about: 0, -45, -225
First tread rotated.
First tread rotated by 36˚.

Next I select the the tread I have just rotated and its neighbour. I need to rotate both of them around the second tread’s pin. I know that the pins are 30 units apart, so I already know that the coordinates will be 0,-45,-195 without needing to check:

Two treads selected.
Two treads selected.

I now simply work my way back along the treads rotating around x=0,y=-45, and z=: -165 and  -135. The result of this is:

Final result of a line of treads.
Final result of a line of treads.

This all used to make sense to me as the simplest way of doing this. However I started to notice small errors in placement. This can be seen in that the first tread doesn’t quite sit in its notches, a close up is below:

Cumulative Error
Cumulative Error.

This is due to cumulative errors appearing. The first rotation is okay, but subsequent rotations slowly add errors to the placement. This first link has undergone 4 rotations around 4 different fixed points resulting in a small drift.

Being the perfectionist I am, this wasn’t acceptable, so back to the drawing board.

Individual Treads – aka “Doing it Right”

This time around we’ll only perform one rotation per tread, thus removing the cumulative errors. To achieve this copies of the top tread will be made, and placed in exactly the same spot, i.e. select tread, then cmd-C and cmd-V. This can just be seen in the image below with the wireframe inside the other tread:

Cut and Pasted Tread.
Copy and Pasted Tread.

This tread will now be rotated 36˚around the centre of the sprocket, not its pin:

One rotated tread.
One rotated tread.

This will now be repeated, copying and pasting that top link, then rotating by 72˚, 108˚, and finally 144˚:

Second tread rotated.
Second tread rotated.
Treads with Rubber Feet.

One of the comments I made in Part 1 was that LSynth didn’t support treads with rubber feet. To do this the first tread will need a rubber foot located with it, and then those two together can be copied and rotated as above:

Tread and Rubber Foot.
Tread and Rubber Foot.
Five Treads with Feet.
Five Treads with Feet.
Completed Treads

Once the sprocket treads are in place, the top/bottom treads can be placed between the sprockets. For simplicity I copy and paste the initial tread placed on the sprocket:

Completed Treads.
Completed Treads.
LPub4 Parts List

Another comment I made in Part 1 is that the LSynth structure doesn’t show up in the parts list. Since the treads placed via the methods above are normal elements there will be a valid parts list shown both on the page and in any Bill of Materials:

lpub4-parts-list

I hope this makes sense. Feel free to leave comments if I need to make anything clearer.