Added some useful features to my Marlin fork

I maintain a separate fork of Marlin with some tweak that enabled features specifically for the PRNTRBoard. The code is located in .

Last weekend I spent some time adding some minor, but useful updates. First I finally got to enable support for the sd-card reader on the Nucleo-F407 board. It took a while because typically Marlin uses SPI to communicate with the sd-card. However the STM32 has much better hardware module (SDIO) which allows excellent transfer speed.

So it took some time to research what is the simplest way to add SDIO support to the Marlin firmware. There was already support for the STM32F1 series CPU, but it was written using a deprecated library (libmaple). Long story short it is working fine now. The code is in the f407 branch.

The second feature I wanted to enable is the ability to store the printer settings. Usually this is accomplished using I2C or SPI EEPROM chip. Alas I did not add one to the Nucleo-F407 board. I added an SPI flash instead.

The difference is small but significant. EEPROM chips are small, but can sustain millions of data re-writes. In contrast SPI flash chips are relatively large (the one I use is 2MB), but can only support around 100k re-write cycles.

There were two possible approaches, one use the sd-card as storage. This was already supported in the Marlin firmware, so I simply ported to code. The disadvantage is that it depends on the presence of an sd-card in the slot.

The second approach is called wear leveling – using the fact that I have relatively large storage and spread the writing operations across many locations in the chip. This way if I spread the write operation evenly across 100 separate locations I’ll achieve 10 million re-write cycles.

The error leveling code is relatively simple. For the curious you can find the changes here.

Next I finally decider to make a converter board for RAMPS style LCD controller modules. The files are checked in the main PRNTRBoard github repository. I placed and order for a few prototypes – they should be arriving in a week or so.

D2B reverse engineering info

Many people send me private messages about the D2B protocol. Here is some info how I managed to reverse engineer the data:

The D2B optical transceiver chip is called OCC8001 if you use google you can find basic information on it. The schematics for the Mercedes-Benz Audio 30 is available – just google for “BE3300 service manual” or “BE3300 schematics” you can see how the OCC8001 chip is connected to the optical transmitter; the DAC and the ADC.

The Benz CD-Changers have a separate bard on the back that does the D2B communication. The board contains the OCC8001 chip and optical transmitter and receiver. It also has 3 pin connector for 12V power, ground and “wake up” signal. The “wake up” signal is used to start the device from sleep, when the car is started.

Here is the pinout for the board’s flat cable connector.

Optical IO board
(contacts up) MC3010
17 pin connector

1 – Fsync (pin 12)
2 – SCLK (pin 13)
3 – SR0 (pin 14)
5 – GND
6 – OCREQ – Optical input AND gate (pin 1 on TC7S08F)
7 – i2c SCL
8 – i2c SDA
12 – RMCLK (pin 6)
13 – GND
14 – GND
15 – BAT +12V
16 – BAT +12V
17 – VCC +5V

On MC3198 Contacts are down and pin 1 = pin 17

1. Device Addressing

Addresses in the D2B network ring are 12-bit numbers. Each device in the D2B network has two addresses. One is the device position address, which describes the device position in the ring relative to the master – the master has position 0 and position address of 0x400. The first device has position 1 and position address 0x401 and so forth. The devices initialize their position address by a special procedure initiated by the master. This procedure is one of the first things that the master performs.

The second address is the device physical address. Each device assigns it’s own address. For example the master address is usually 0x1c8; The CD-Changer address is 0x190. The device starts with a particular address and probes the network if that address is already taken. If the address is not taken, the device assigns the address to itself, otherwise it tries the next value.

When the master starts the network, it assigns an address to itself. When a slave device is participating in the network it starts with a default physical address of 0xfff. When the slave device first sends a packet to the master, the master would “notice” the device has “unassigned” address and send an “Assign Device Address” command to the slave. The slave would then initiate the procedure to assign a physical address to itself and notify the master.

In addition to the physical and position address, there is a “broadcast” address 0x3c8 – a message sent to that address would be received by all devices in the ring. There is also a group cast address – any other address in the 0x300-0x3ff range. The device must be a member of that group to receive the message. Each device decides what group it is a member of – there is no set procedure for that. Each device is a member of only one group at a time (limitation of OCC8001). I have not observed any group cast messages being sent.

2. Message Format

Each message is up to 16 bytes long. Each message has a type and a length encoded in the message header. The receive and transmit buffer formats are:

<address><type|len><message data>

Where the address is the source or destination address (depending whether you are receiving or sending a message). The address is 2 bytes with the LSB byte first and the top 4 bits 0 on the second byte. The third byte contains the message type – 4 high order bits; and the message length – 1 in the low 4 bits. A message length of 0 means 1 byte long message. A message length of 0x0f means 16 bytes long message. A message is minimum 1 byte long.

The receive and send buffers are 19 bytes long total. I have not been able to decipher much of the data messages being exchanged, just enough so I can simulate a CD-changer being connected to the network.

3. Errors

A message transmission could fail. Usually because the target device’s receiving buffer is not free. Thus when sending a message one has to check for “successful transmission” flag. Luckily the chip handles the acknowledgement and errors automatically. All you have to do is check if the transmission succeeded or not. It is suggested that an app retries up to 5 times to send a message if the transmission was unsuccessful.

Errors due to loss of signal are very rare and usually indicate a problem with the cables. In this case a device detecting the error just shuts off breaking the ring. Eventually the master would shut off the whole ring. Momentary loss of carrier is tolerated if the loss is less than 20ms.

4. Chip communication

The D2B optical controller is called “Conan” the chip is labeled OCC8001 and sometimes OS8101. These are the same identical ship. There is a brief data sheet available for OCC9001 – but that chip was meant to be way more advanced. Anyway the chip can use i2c or SPI for communication in the Audio 30 it is connected via i2c.

The chip’s i2c address is 0x46. I used a logic analyzer to sniff the communication between the CPU and the chip. The chip uses a protocol similar to other i2c devices, when writing the first byte is a “register address” the second byte is the value that is written to that address. If more than one value is sent the next value goes to the next address etc. When reading the CPU first sends a “write” request with only an address – which is the address where it want’s to read; The the subsequent device read requests read first value from that address, next value from the next address etc. until the CPU terminates the transfer.

The chip receive and transmit buffers (19 bytes each) are located at i2c addresses 0x6b and 0xaa respectively.

Happy hacking.

Jaguar D2B CD-changer details

Many people ask how to build one. Let me tell you it is not very easy.

The device consists of two parts a D2B audio controller and a Raspberry PI which handles the Bluetooth streaming. The latest version of the unit user Raspberry PI Zero – the regular, not WiFi version.

The two boards connect together via 40 pin header. The D2B unit receives audio via I2S protocol from the Rapsberry PI. The two units also communicate via serial interface. The Raspberry PI is powered by the D2B audio unit. The D2B audio unit also can reset the Raspberry PI board if it is not responding to serial commands.

Here is the schematics of the D2B unit. Jaguar D2B board

The micro-controller is Cypress PSOC4 4100 series. Here is the firmware it is running.

The Gerber files that one can use to make the PCB.

The fiber optic connector is 3D printed. Here are the model files. There are 3models for the 3 parts of the connector. The optical receiver is EAPLRBA0 the transmitter is EAPLTBA0

Instructions how to built the software for the Raspberry PI board.

You would need a micro-sd card for the Raspberry PI and a Bluetooth USB dongle (The ones marked with CSR 4.0 work fine)

PRNTRboard update

The TMC2130 version of the PRNTRboard is working very well. I’ve been using it for over 6 months on my soldering robot project. It is very stable and reliable.

I didn’t have time polishing the Marlin firm ware for it. I wanted to make the SD-card work on the F407 Nucleo-64 replacement board. Alas every time I look at the Marlin code, I loose all hope and start doing something else.

A few months ago I started working again on the TMC2660 version. This was the first variant I routed successfully, but I ran into trouble with controlling the drivers over SPI and switched my effort to the TMC2130 version. Long story short, when the TMC2130 was in a good shape I started looking back at the TMC2660 version. It is on rev 5 now and I’m really happy with the layout. In my opinion it looks much better than the TMC2130.

I managed to produce a working Marlin firmware for the TMC2660 board and tested a few motors. So far it works like a charm.

My only gripe is that while the mate black finish looks awesome, it is absolute PITA to clean the solder residue from it. I washed this board 3 times and you can still see some spots on it.

As a kick all thru-hole pins on the Nucleo-F407 board underneath are soldered using my soldering robot. On the TMC2660 I soldered the two headers with the robot.

Last but not least I started working on a version with TMC2209 drivers – these are quite capable and low cost compared to other Trinamic offerings.

Google Coral TPU dev board power up

I decided that the new machine learning fad is worth exploring. So far I’ve learned very little about it, but I acquired some cool dev kits I wanted to show off.

I got the cool Google TPU dev kit – it is branded Coral. You can read the specs here. The really cool part is that it has the new TPU ML accelerator chip. Not the first such thing to hit the market. But being from Google one would expect some very good integration with TensorFlow.

Here is how my attempt to get it to work went down: You need not one, not two, but THREE USB cables to get the beast to work.

That was rather annoying. You need a micro USB cable for serial console – fair enough and nice of them to include the USB <–> serial adapter on the board. Then you need USB-C adapter for power. Hmm maybe power the thing from the serial console cable – just a though. Ok, I understand that one may need separate cable just for power. These boards suck 2-3 amps on full load. Still could have been nice option. Then you need a third USB-C cable to flash the OS image to the board and for general data communication.

Well I was out of cables :-(. A quick search on revealed this item – 5 pack USB to USB-C cables. Not the most economical solution, but can’t beat the one day shipping.

Here I was today all cable connected following trough the “Get Started” guide step by step.  The setup is mostly uneventful. I won’t bore you with repeating the steps in details – they are well documented:

      • boot in the serial console and enter fastboot mode
      • download the OS image – there are two: the mendel-chef seems to be newer version
      • flash the image using the provided shell script
      • “connect to the internet” part was not needed if you have Ethernet cable. The provided steps are to enable the onboard wifi.
      • the “install Mendel Dev Tool” step was confusing – this is something you have to do on your PC/Mac not on the dev kit itself. It was not obvious to me. Then you’ll have to add the pip local folder to the path or you won’t be able to find the mystery mdt command. The path is in the little blue note in the instructions. Ultimately I skipped that step and enabled SSH instead.
      • run the ML example

I won’t lie, the example is very impressive. You run a command on the dev kit then connect to the dev kit with a browser and it simulates image recognition on a running video stream. You can type “n” in the dev kit terminal to switch between CPU and TPU and marvel at the 10x speed improvement.

A few observations: The board has a 30mm fan which is vary loud, when it runs. The fan runs when you flash the board, then when the OS boots the fan stops. There appears to be some sort of thermal management running.

To me the heatsink gets really hot. According to it’s own temperature report it gets to 60C at idle. To read the temperature from the sensor run:

cat /sys/devices/virtual/thermal/thermal_zone0/temp

It would report a number, divide by 1000 to get the temperature in Celsius. The default threshold for the fan to turn on is 65C. If you want to change it run:

echo 57000 > /sys/devices/virtual/thermal/thermal_zone0/trip_point_4_temp

You’ll need to run the above command as root. This example would turn the fan on when the sensor temperature reached 57C. There is a hysteresis of 10C by default, so the fan would turn off, when the temperature reaches 47C.

The OS itself is some offspring of Debian, called Mendel Linux. Not many details are available on it.

I would recommend changing the default password. Then enabling SSH login by editing the /etc/ssh/sshd_config file. Change PubkeyAuthentication to “yes”; uncomment the AuthorizedKeysFile line and switch PasswordAuthentication to ‘yes’. Do the PasswordAuthentication change only after you have changed the default password or you risk strangers logging in your dev kit and compromising it. You can follow this guide how to enable logging in the dev kit without requiring a password. After that you can revert the PasswordAuthentication back to ‘no’ to improve security.

You can now reduce the cable clutter, by first disconnecting the serial console and then the USB-data cable. In my case I use USB-C for power and Ethernet cable. If you want really minimalistic setup, use the onboard WiFi.

The USB-data cable is used to enable Ethernet emulation over USB. You can use it in an environment where you don’t have Ethernet or wireless network.

Google has a mystery tool called Mendel Development Tool – seems it is some sort of wrapper over ssh to allow you to log in the dev kit and copy files. I personally prefer ssh, because I’m familiar with it. The MDT tool works only over the USB-data connection.

Here is a size comparison between the Coral TPU dev board an the small NVIDIA Jetson Nano:

I don’t know much about ML to give you a reasonable comparison which is better. I would suspect both have some strengths and it really depends on the particular use case.

One small observation is that NVIDIA has established community for the Jetson products line and one can easily find answers to all sorts of questions online. By contrast the community for the Coral dev kit is not there yet.


TMC2660 success at last

I was very frustrated with my failure to get the TMC2660 board variation running. I checked and double checked the connections, alas the steppers would not move at all.

I purchased one TMC2660-BOB kit from digikey and started experimenting with it, instead of my board. At first, I had the same failure – the stepper would not move at all. The software was a very simple Arduino sketch – what would be that wrong. Since the kit was designed by Trinamic, the hardware should be proper. Alas, no luck. I declared the TMC2660 chip cursed and moved to my soldering machine project.

Yesterday I decided to give the test jig one more try. After a few failed attempts. I spotted an error in the Arduino code – I was passing the incorrect CS pin in the driver setup. DUH!!! After a quick fix it was working.

Then I moved back to my original goal to test the thermal dissipation ability of my TMC2660 PrntrBoard design. I connected my board and started to torture test the motor driver. Unfortunately I was not able to run the driver past 1.5A RMS, which is a shame. I’ll try using a different motor with higher coli resistance. Anyhow here is an image from my thermal camera of the top of the ship:

The chip has no heat-sink and runs at 54C. This is not bad at all. much cooler than the TMC2130 version. The board seems to be dissipating quite a bit of the energy.

Here is a picture of the bottom of the board:

The bottom is at 45C in the center, which I think is quite good thermal conductivity of the board layers.

I feel good about the board thermal capabilities. If I add heat-sinks on the top and the bottom it should be able to run at 2A RMS and above with active cooling.

Soldering machine improvements

I was very confident in my soldering machine from the tests I conducted the previous week. I decided to program a whole board and try it out.

Alas the confidence was premature and multiple failures ensued. Here is an example

I tried many things, but the soldering wire was hitting the pin and was not melting. I tried re-aligning the needle to point to the solder iron tip instead of the pin. This did not produce improvements at all. I had to aim fairly high to avoid hitting the pin and now the solder was not flowing down and bulging.

I was getting frustrated and decided to look at a few videos of commercial soldering machines for inspiration.

After a few hours I devised a new mount for the soldering needle. The previous mount was allowing adjustments only in the angle of the soldering iron as well as the needle. This configuration seems quite limited. Applying maximum effort here is the new plan:

Now the syringe is mounted on this dual clamp. The clamp allows for both items to rotate. The other end of the clamp is connected to a 3mm steel rod, which adds another degree of rotation. Finally the rod is connected to the mount plate with a plank which allows both: XY movement as well as rotation.

Here is the final assembly after a few dozen failed 3D printing jobs

The new mounting system adds quite a bit of flexibility to the position of the needle that guides the solder wire. Hopefully I’ll be able to find a location which works in most cases.


Soldering machine tests

I’ve been running the soldering machine for about 2 weeks. I added a very ugly, but effective fume extractor to the machine head.

It has 40mm fan and a square piece of carbon-activated filter to absorb the fumes. The design is not my best work and is held together with hot glue. However it does work.

Some early failures of the soldering were quite comical:

But some tweaks of the G-Code and it is mostly working now

At this stage it is completely manual programming. No computer vision at all. I’m recording all soldering sessions so they can be used for training ML models later.

My test board is fairly straight forward, so programming the G-Code is not hard. I use a simple C++ program to send the commands to the 3D printer controller. This allows me to add the necessary delay and in the future integrate some processing of the camera image.

I also managed to find an M12 camera lens with much less distortion, to the point that the image no longer needs corrections.

Computer vision mishaps

I was planning to add a Raspberry Pi camera on my soldering machine. I used a camera board from China which has the M12 lens mount. There is a variety of M12 lenses and one can play with the focus.

This is the camera board mounted on the soldering head

I finally got everything set up. I discovered this very nice camera streaming web interface package here is a picture of the web interface

The UI is simplistic, but allows control of the camera settings and while streaming is consumes only 3-5% CPU. Well done to the Raspberry Pi foundation and the RPi Cam Web Interface team.

Here is an image I captured with the camera

The focus looks good and the image resolution is very nice. However the vertical blue edge of the plastic mount is supposed to be straight. Not so much on the image. The 3.6mm M12 lens I used on the camera adds quite a bit of distortion around the edged. My other lenses are more on the telephoto side: 6mm, 8mm, 12mm and 16mm. I tired the 6mm lens and the distortion was better, but the field of view was too narrow and wan not capturing the soldering head. I ordered some more lenses which claim “low distortion”. We’ll see it they produce better result.

My initial goal was to capture a series of images and then “stitch” them together with OpenCV. Initial experiments failed miserably. First the lens distortion was confusing the stitching algorithm. I know that OpenCV has camera calibration option which can correct lens distortion, but I’ll try better lens first.

The other issue with the stitching was inconsistent lighting. I tried using my LED photo light, which helped initially. Still the lighting on some spots was low and some spots were too bright and getting lots of reflection from the PCB board surface.

I constructed this new camera head, which allowed me to mount a small ring of LEDs close to the camera.

I seemed like a good idea at the time, however it makes terrible reflections onto the PCB. So back to square one. I’ll make some combination of external photo light as well as some white LED strips. The goals is to have uniform light with minimal reflection and not to obstruct the movement of the machine.

Soldering machine progress

I managed to put together the chassis of the soldering machine. The bulk of it is made from parts for a Prusa MK3 3D printer. It provides a good start point so I can experiment further.

This is what is looked like in the beginning

I also put this mounting plate to hold the connectors that I need to solder for my test board. With this plate I can insert the connectors, place the board over and get it soldered quickly, then move to the next one.

Here is a video how the head would move along the Y axis

And another one along the X axis. This one needs to hop over the pins.

I used my PrntrBoard controller to drive the motors. This is a picture of the machine in it’s current variation. I added the Prusa LCD display, but have not connected it yet.