# Final project development - FabAc 2021

FabAc 2021

Mauro Herrero-FabLabLeon-URJC

18. Final project development

Design goals

front sketch of possible final project

How am I going to achieve this?


I do not know yet, but I will find out.

Research

So far I have been diving into some sites to see what others have done before hand. I know there are quite a few really high end commercially, that can map and output a huge cloud of 3D points, defining completly huge buildings, such as Faro. On the lower side of the market, but still at around 2000€, there's the Leica approach. [Cabinet Vision](https://www.cabinetvision.com) is a big player in the cabinet bussiness, also with quite a high price tag.

Linear motion

After much thinking about how to test the device, and if it was appropiate to make a folding railing system from the start, I came to prepare a test bench, in which I could easily change both rail systems and a woobly wall, cut with cnc.

The first iteration of the bench makes use of Jens Dyvik's CNC frienly rack and pinion for the linear motion system. The stepper is a nema 14 with a 5 mm shaft, to which an 8 tooth pinion is attached. For now, the pinion has been 3d printed with nylon.

Test bench FreeCad file
Test bench Rhino & Vectric files

Carriage

The first iteration for making the carriage had several design flaws; probably, the most important one was the attempt to make the side sleds detachable: I wanted to use a snap on fixture, so I could print different versions, test them and choose the better option. But the snap-on parts were too fragile, the joint was not rigid enough (those two issues could be fixed in a couple of iterations), and there was not an optimal printing position (which was more difficult to solve).

Next, I decided to use just one part for the base of the carriage, which made the system more robust. The first test to run is checking if the stepper has enough power to overcome friction, and move the carriage without wheels. If not, the carriage should be larger, in order to house bearings.

All clearances were just fine, and all motor, carriage and pinion came together nicely. In the third iteration, I modified the sides that were in contact with the guiding rail, so it would have less friction.

Even the pinion was quite small, it matched perfectly the rack. It had been nicely milled with a 1/8" two flute straight end mill. I was pleased to see how nice and easy these parts came together. Both parts, as I previously stated, are a design of Jens Dyvik.

The fourth iteration of the carriage was asymmetrical. Since I did not notice any improvement in the stability, in the fith it was symmetrical again.

Finally, before making the carriage platform a bit larger, I still added bearings in another iteration. The movement was way smoother.

Distance sensor

During week 10, input devices, my goal was to set up and test both sensors. I barely managed to finish one board, with the sonar. Even though I wanted to test it, after the class it already was clear that I would finally use the Time of flight laser sensor.

Since the distances to be measured are circa 600 mm, I will set the distance mode to short: sensor.setDistanceMode(VL53L1X::Short). Given the speed of light and the short distance travelled, the system has the ability to measure time in fractions smaller than microseconds... yes millions of a second...

According to the datasheet, ranging error is the addition of repeatability and accuracy. Really, what matters most for this project is repeatability, which the beforementioned datasheet establishes in a typical value of +/- 0.15% - +/- 1%. I will have to test where it finally sits.Accuracy can be adffected by offest error, temperature or voltage drift. But, in more advanced iterations, a single measure could be taken by the user and intruduced in the system, in order to correct the output.

Microcontroller

Needs to be able to:

Encoder

After input devices class, I thought that a kind of 'encoder' could be made with a LED and a phototransistor. The set up would be placing one part along the other, in the device, and have, in the rail, a black pocket (which would reflect very little light), and white 'bridges', (which would reflect more light). The rail can be machined out of black core HPL with white surface.

Commnunication

Send data to a device that is then able to plot the final polyline:

Serial communication worked fine. I just had to take care of how the data was going to be sent by the microcontroller, and how was the interface going to organize it. I decided that the data would be sent in pairs, separated by commas. Between each pair, a line ending. In that way, the interface would retrieve each pair, and assign them to two dynamic lists of items, that were growing as data was comming in.

System integration - packaging

Options to explore, running away from the finger joint lasercut mdf box:

During the Computer aided design week I designed a first possible enclousure for the device.

During week 6, I printed a test case in PLA, which was great due to the feedback of actually manipulating the physical object:

The next iteration will change the shape a lot, the main axis will be the vertical, to house the nema 14 stepper. I will make it in two parts, so it can be easily disassembled to access the PCB(s).

Finally I opted for a deformed hexagon shape, to house both battery (even I realized it does not last long), stepper and electronics.

I decided to base the design in similar concept as the one used by Herzog & de Meuron back in the 90's itn the signal box building in Basel. I like the idea of this part being a little building, housing conecctions and sensors, and being itself kind of a rack railway. The picture was taken by Nelson Garrido, and it is licensed to use in academic sites.

To design it, I used panelling tools in Rhino. I defined a grid of points, and then modified it to fit the look I wanted for the openings. Then, removed the panels in the corners, replaicing it with lofts. Finally, I opened the hole for the ToF sensor, taking into account the 17 deg field of vision.

I made two tests, to decide if it was better to print it upside-down or not. Finally it was printed as it is, but using supports: otherwise, the print quality around the gaps was not enough.

I had established in Taskjuggler a total of 9 hours for the design & printing of the casing, and while the design part took me about that, I am sending it to print overnigh. So if the print is ok, but there is room for improvement, I will make a second design, using another kind of tesselation.

As a remote student, I've enjoyed the warmth of working from home. But the very last weekend, I have travelled to Fab Lab Leon, to give the final push to my final project.

It was really great to work by two of my classmates and my three instructors. I really have a fond memory of that weekend. I sincerely recommend to whoever wants to go through Fab Academy, to do it locally, and if possible, in a node with a few fellow students. It really enhances the experience.

The first thing was to retouch the design of the casing, since the openings I designed the first time came out way smaller than I thought. I went again throug the proccess, just much quicker than the firs time; I spaced the points generated by the grid creation tool, and left the two Prusas work overnight, to have two cases, one slightly taller than the second.

Adrian walked me through the proccess of manually adding supports with the paint tool, and establish setting for both PLA and PETG. He uses a noticeable higher temperature than I do for PLA (215 vs. 190 Celcius), and definetly he is getting much better results. I am aware that it is probably due to the fact that his printers are at least two generations ahead mine, but I will test with his settings and my printer once I go back home.

I also designed a 3d printed mechanisnm, with a spring system, to access the surface mount button on the pcb. It has two parts, and a nice touch and feedback.

For the system integration, to get rid of the tangle of wires, I first attemped to make, with foam and copper strips, a bus. But it did not work, probably at some point there was a lack of continuity, for what I found using the multimeter. I then swithed back to the wires, adding a layer of flexible wood so it goes nicely along the device while it is running.

How will it work - electronics & interface

After going throug input / output devices, networking and application programming weeks, I have now a clearer idea of what can I achieve for this project. On one hand, I would like to make it as modular as possible, regarding the electronic boards. That way, I will be able to debug each subsystem separately. Debugging has been a huge time drain for me in the last month. Also, in the future, I could replace and test the different subsystem, not having to repeat what can already work. What I fear most is how each of the subsytem is going to talk & listen to each other.

The subsystems that I have in mind for now are:

The sequence of functioning is:

  1. The user pushes the button on the Manager board
  2. The button acts as a switch, turns on the LED
  3. While the LED is on, the measuring loop takes place:
    1. The stepper moves a number of steps
    2. Once the stepper is done, sends signal to VL53L1X to perform a number of single-shot ranging measurement
    3. The microcontroller averages the reads and sends it via serial to the interface, for now in a computer
    4. Loop starts over
  4. When the user pushes the button again, LED goes off, exit measuring loop

Starting this project I had not decided if I was going to use just one or several microcontrollers. After drawing by hand both very basic schemes, I decided to use just a single microcontroller in the first spiral, to keep networking as simple as possible.

Next, I designed it in Kicad, first the Eeschema:

Then I reviewed it with my local instructor, Adrian, who pointed out that I had missed the button pull-down resistor, and suggested that it would be a good idea to also add two 4.99k resistors betwenn SCL and SDA and Vcc. I checked that the topology of the board was viable:

And finally, finished it up with a six sided shape, to integrate the 9v battery alongside the stepper:

Later, after retouching in Inkscape, I went through the mods workflow, to get the g-code. But while I was milling it, the computer that my CNC is attached to, just froze, and I still have not been able to recover it. It is an already old computer, running Mach3 in WindowsXP, using an Ethernet Smooth Stepper driver. At this point, I can not afford to spend a lot of time fixing it, so if in a few hours is not working, I will use another CNC to mill the boards.

Finally, it was just a hiccup, and in the afternoon, after booting the computer with a light version of linux, I was able to save my Mach3 config files, and get the old Windows XP up and running again. This is, by far, the largest PCB I have milled to date, and it went smoothly:

This time, stuffing the electronics went way better than previous weeks. I felt all the time way more confident about my skills, and I can clearly see an improvement from the first weeks.

Spiral development

Embedded programming

Once I had soldered the board, I started testing all four subsystems: LED, button, VL53L1X and bipolar stepper control. I did it in that order, since I figured it would go from easier to more complex.

Even I had the schmatic and the AT Tiny 1614 pinout at hand, I prepared the following table, to have all pins at hand:

UsePinArduino eq.
UPDIPA011
Not in usePA18
ButtonPA29
LEDPA310
Stepper 1APA40
Stepper 2APA51
Stepper 1BPA62
Stepper 2BPA73
SCLPB07
SDAPB16
TxPB26
RxPB37

But even before that, I uploaded Neil's 1614 echo.c, which went fine, but when I applied 12V through VBB, bad sign.. smoke came out of one of the 10uF capacitors, and then the voltage regulator started to get really hot... so I turned everything off, and checkd, just in case I had got wrong connections. After replacing the burnt capacitor, everything worked fine!!

Next, I uploaded this blinking code changing pin 4 for pin 10, and the delays, and it also worked:

After that, it was the turn of the button, using the switch code I wrote during week 9, but again changing the pins. It also worked fine:

Then was time for the VL53L1X sensor. Thanks to the first test with the hello.1614.echo, I already knew serial communication was working fine. I was kind of a bit afraid before testing it, since it gave me quite a hard time in the previous weeks. But besides adding an import sys line of code in Neil's hello.VL53L1X.py, probably because of my system settings, It also worked from the first try, with python3 hello.VL53L1X.py /dev/ttyUSB0.

Finally, the first moment of truth... the stepper driver... I tested first directly Neil's . Arduino library, apparently working under load, but not without it. Why?

What seemed to be working fine, was not, and took a quite long debuggin to figure out what the problem was. At first, I was getting erratic movements from the stepper:

I checked connctions, and then voltages. I observed that the voltage at Vbb dropped when the motor started, form 12v to around 8v. At that moment, I wondered if the power supply that I was using was powerful enough (12v 1.25A). I decided to use the oscilloscope, to check if the AT 1614 was sending signals and if the output of the A4953 corresponded to those signals. I found that for two pins, that corresponde to one of the A4953, the frequency was double.

I had no idea what could be going on. So after consulting with my local instructor Adrian, he suggested that it might be that the problem was that I was using two PWM pins in the AT 1614, and another regular digital pins. He asked Quentin, who quickly told him that the pins should behave identically, and spotted the problem in the code: there was a mistake in the step sequence I wrote, so a pair of pins remained high when they should be set to low...After the fix, al four signals in the oscylloscope were equal.

And in the motor datasheet, the order of operation for full steps is also stablished.

To further understand what is going on, I drew an scheme and step table by hand.

The movement was far from perfect, but it moved... The problem then was that afer a just a few seconds, it would start moving erratically again:

Even using a more capable power supply, 12v 3.5A, could not get the stepper to move more than just a few seconds. In an informal chat with my father, I told him what was I up to, and he pointed out that probably the problem was that I was not limitting the current, and that by appliying 12v in every pulse, it would try to ramp up to 4.44A, and I could be messing up the stepper. Later he sent me this post by Luis Llamas, where this is explained under chopping.

So next, I modified my code, to include sofware induced PWM, but at the rate required for the 2.7 ohm coils, which was 22.5% on vs. 77.5% off, the motor did not move. I finally set it to 60% on vs. 40% off, which worked fine even for PWM count as low as 15 cycles.

Next, I wanted to use the button to both turn on and off the stepper. At first I thougth it would be easy, just using a for loop after an if statement. But I what I had not taken into acount was that the event that would stop the for loop was outside it. So I ended up making a function that included the loop, and call it from the if statement, after simplifiying also the switch functionallity of the button:

I also added another function to turn off the stepper, by setting all pins LOW, and a delay of half a second, so the controller can read the state of the button and swicth it. There are probably more elegant ways to do it, but for now, it works:

The weekend before final presentations started, I travelled to about 320 kms and dropped the kids at my parent's, about half the way there. I was ready for a kidsfree final push!!! I was really happy of meeting all of my local instructors in person, Nuria, Pablo and Adrian, after so many on-line sessions. It was also great that two of my classmates, Lorena and Sergio.

Once in Fab Lab Leon it was time for another real momment of truth... check that the system could measure and send data to the computer.

I added to the code the Wire.h and VL53L1X.h libraries, set serial communication at 115200 bps, set the clock for I2C at 400 kHz, and stablished an if statement after a 500 ms timeout for the system to recognize the ToF sensor.

I also set the distance mode to short, with setDistanceMode(VL53L1X::Short);, and the timming butget to 50ms whith setMeasurementTimingBudget(50000). Note the value introduced is in microseconds, rather than milliseconds.

For the first spiral, I just wanted to check that after every move cycle of the device, it performed measurements and sent them through serial. Since the pause between movement is 500 ms long, I expect to get 10 measurments at each stop. Later, I found out that these settings are too ambitious, and I allowed a longer time budget, of 140ms.

The sketch used 8286 bytes, taking about 50% of program storage space, and the upload proccess went ok at the first run:

But unfortunanetly, I was not getting any reading in serial. It was a bit confusing, because both sensor and serial were tested with hello.VL53L1X.py and 1614.echo.c, and it had worked. I uploaded both programs and cheked that again, it was working. Then, comparing the codes, I realized Neil had used a longer time budget, of 140 ms, and this time got it working.

At first, I programmed it so it just took one read per stop. Later, I added a for loop, to make 10 reads per stop, and average them. Hopefully I will get better results. Probably I should take rid of the max and min and then average, but that will happen in further spirals.

I was a little dissapointed, because in every test I ran, the device would or wouldn't work, and I could not figure out what was wrong... until Pablo came along and observed that the order in which I plugged the device matters: I should first plug the 12 V to the main board and then plug the serial. I also noticed that it was not enough to just plug Tx and Rx to the computer: Gnd was also needed.

Interface and application programming

So, back home and with less than a week to go for my final presentation, and now that I can read both X and Y coordinates of each point through serial, I want to design and interface that draws a polyline with those points.

The task seems simple... but I have to remember that I am newbie to programming, and it will take time, even my ilocal instructors told me it was going to be piece of cake...

I am using Processing: I really liked it a lot during Interface and application programming week. So first thing I did was go back to Daniel Shiffman's books and video, and learned about array[] and listArray[]. Later, I found in the Processing language guide FloatList(), along its methods size(), clear(), get(), set(), append().

Every point sent through serial has two coordinates, separated by a comma. Every set of coordinates is separated by a carriage return. So my guess is that I can assemble two FloatList(), one for the X coordinates and another for the Y coordinates. Everytime a new pair of values comes in, it gets appended using append(). Then, with a for loop and beginShape(), the line can be drawn.

In order to test it, I first assembled by hand two FloatList() elements, with three items each:

Next, I defined a function that takes no arguments, polyline(), and which itself runs a for loop to get X and Y coordinates from both lists and assemble every vertex:

And got this result, even it is just two segments, to me is really meaningful!

The following step was to get the data from serial, and store it in each of the FloatList() created.As in the previous week, I first used Marta's snippet of code, with the modifications and comments I need. What it does is read each incoming line, and assemble an array with the values separated by commas. Then, you can assign those values to whatever variable is needed. In my case, the values stored in index [0] of each array will go to xCoord, wheras those stored in index [1], will go to yCoord. And that will happen for each pair of numbers, since they are separated by /n line breaks:

Finally, I added import processing.serial.*, set up serial port, and cleaned and comment the code:

Processing file: polyliner.pde

And the first run went [almost] well:

  1. The stepper moved
  2. The ToF sensor measured
  3. The microcontroller averaged the data
  4. The computer recieved data via serial
  5. The Processing snippet got the data and drew a polyline

But I forgot that in Processing, Y axis goes from top to bottom, so I got this polyline, which is the mirrored of the required one:

And here is a video segment of that first run:

And a last picture working in Fab Lab Leon. Thanks, Pablo!!!

I am truly amazed of how much I achieved in the last four weeks of the cycle. Honestly, during the previous weeks I was afraid I was not going to be able to get this far. So yes, I am really happy about what I have learned during the past five months!!!

Do not forget to have fun all along the journey!