[ESP32] A tiny WiFi/BT to (true) RS232 adapter

Ages ago I received a defective Keithley SourceMeter 2400 that I could easily repair. I also have an old AOR A5000. Both are remotely controllable using their RS232 interface. But nowadays long RS232 cables aren’t quite state of the art and placing USB cables through my office is neither. As my computer and those devices are some meters apart, I needed a proper solution.

Unfortunately it doesn’t always work to fake RS232 using 3.3V lines directly off an ESP32, so I decided to make a custom PCB that features an ESP32 plus a true RS232 Transceiver regarding voltage levels.

Rs232 oscilloscope trace.svg(Source)

My PCB named ESP232 is designed to be quite compact, merely bigger than the footprint of the ESP32 itself. Rotating the ESP32 could have made the PCB a millimeter narrower but a bit longer. But the design intentionally has the USB power plug and antenna on the side as the devices usually are quite long and bump the wall behind anyway.

This time I decided to use an inefficient AMS1117 and not the TPS62291 for the 3.3V supply. It wouldn’t run all day long or drain a battery, so KISS. Maybe I could have saved some mm² space, but the size is dictated by the ESP32 anyway.

The software is built using arduino and supports OTA updates – if you enter update mode by bridging Rx and Tx in the connector (loopback). The bridge gets detected on startup and the firmware enters OTA-only mode.

Why that complicated? I found that the OTA module crashes quite often in my network. (AFAIR it fails to allocate somewhere around the common 1400 bytes using new[] in some UDP receive func). To work around that, I just disable OTA by default. Additionally, this is safer to not accidentally flash the wrong device when updating some other device in hurry.
Of course there is also a rudimentary web interface to select baud rate that gets saved via arduino/ESP32 EEPROM driver.

The serial port is exposed via TCP on the telnet port (23), so you can either connect from your application which supports TCP transport. Or you connect a second ESP32-Board to your computer with a firmware that simply bridges its serial data to the TCP-port of the adapter (USB <-> WiFi <-> RS232).
So your computer sees a COM-port that magically forwards data to the remote (real) RS232. Did a similar thing with one of my 3D printers so cura can print over network.

Unfortunately SmuView doesn’t support the SourceMeter 2400’s SCPI flavour out of the box, so I would have to patch it manually. Sigh :( Maybe somewhen later.

This PCB is not a big thing. Literally. But does its job and it’s cheap.

Schematic/PCB: https://oshwlab.com/EFS-GH/esp32-rs232
Sources: https://github.com/g3gg0/ESP232

[3D-Print] Geeetech prusa i3 – improvements

Last year i bought a cheap chinese prusa i3 clone for €270 including VAT and shipping which performs very good overall.

After assembling it – which took me about 8 hours – its print results was.. well.. quite okay.
As expected, because reading forums and blogs already explained Z wobble to be a serious problem with this printer.

So the first thing I’ve printed the already posted “Z wobble fix” which came out wobbly of course, but works well :)
I’ve also decoupled the Z axis from the frame by (gently) drilling a bigger hole in the top part of the printer so it can move freely.


anti wobble z axis screw

Then I also added a ball bearing (608Z) “decoupler” to the top end of the thread so it is not moving too much and is guided a bit better.

Aside of that, I replaced the too small Z axis rods with a proper one and the Z axis threaded rod with a TR8 trapezoid one.

After some printing, i wondered why the MOSFETs get so hot. They used P55NF06 with a quite okay R_DS(on) of 0.018 Ohms. But more problematic is the V_GS which is with 5V just barely above the threshold voltage.
This causes an resistance of far more than the 0.018 Ohms which you will only get at a V_GS of 10V. The result – the MOSFETs get hot.


The P55NF06 is at it’s minimum switching voltage when driving it with 5V on gate

Solution? Buy some IRFB7430 which have only 0.001 Ohms R_DS(on) at 10V and ~0.013 Ohms at 5V.

Hard to see, but the second curve from bottom (4.8V) tells us that when driving a 20A load, the voltage drop at the MOSFET will be ~0.25 Volts. Thats approx. 0.013 Ohms internal resistance

As these parts are a bit pricey, I’ve chosen to take the cheaper IRF2804 for the hotends. They still provide a low resistance with ~0.015 Ohms and are good enough for hotend heaters.
Probably also good enough for the heated bed :)


before I was able to swap them, a really bad thing happened – my printer heated permanently until it smoked and i powered it off.

First let’s see how the GT2560 board looks like:


Now when looking at the heat sink of the MOSFET, one will realize that they have

a) a sharp corner
b) are electrically connected to the MOSFET with a metal screw and without any insulation pad
c) (no, you can’t see that on the photos) there is a PCB trace *exactly* below the sharp corner of the heat sink, prone to get scratched


Please ignore the insulation tape I placed there just as a quick hack to get things done.

After a while the PCB was scratched and the heatsink made a short circuit with a trace on PCB, permanently heating the hotend.
Yay. worst case. Even marlin’s “thermal runaway”-protection couldn’t do anything as they are short-circuited on board.
So the result was an overheated hotend with damaged PTFE inliner, died MOSFETs and me, a bit scared of this really bad engineering.

No fire tho, but there was smoke at least.

Okay to be honest, when paying 270€ for a whole box full stuff you can build a printer of, don’t be surprised if that is not at IBM quality level.
But there is a difference if a connector is of cheap quality or a rod is bent, or if a PCB designer doesn’t realize that a sharp-edged aluminum block just micrometers above a PCB trace that might cause malfunction and finally a fire is a frickin’ bad idea.

a) now really buy the MOSFETs i already had chosen
b) along with insulation pads and plastic screws
c) and put some {glue, hot glue, epoxy, cyanacrylate, whatever} on the PCB below the heat sinks (i used a special solder mask pen)
d) put a smoke detector above the printer

Recommendation to all users of a GT2560: ALSO FIX THIS ISSUE, it might cause the printer to catch fire.

The wonderful side effect: you don’t need the devilish loud mainboard fan anymore.

After these changes, my printer works like a charm :)
It happened in october ’16 and geeetech sent me a second mainboard just days later so I could fix the other one properly.
(thanks for this really fast response and good service)


I hope this warning reaches out to all “cheap chinese printer” users out there.

[3D-Print] Custom geeetech i3 printhead

[Update: 04/2018]

Summer ’16 I bought a prusa i3 clone from geeetech, a cheap chinese printer manufacturer.
With 270€, including VAT and shipping, the DIY-kit is quite cheap and 8 hours later i had a prusa i3 clone that prints “quite okay”.

[more about preventing your house burning down here]

This printer has a direct drive, bowdenless MK8-style extruder. While it prints really good, I wanted to have more flexibility.

So I started to design my own printhead with these constraints:

  • exchangeable modules for: E3D v6 hotend, dual E3D v6 hotend, E3D Cyclops, plotter, laser cutter (more laserz, even more), …
  • modules should be easy to change (no soldering, no screws, no levers)
  • no rewiring when changing a module
  • lightweight design
  • easy to service

These lead me to a three-component setup, I designed in OnShape.


a) The X-Axis carrier.
Into this thing go all the screws. The SC8UU housings for the LM8UU linear bearings get mounted there, the belt attachment and the other printhead parts are mounted onto it.


The X-Plate with a lot of holes for M4 screws in all variants

The plate just connects the three ball bearings and provides a stable mount for the more complex baseplate with magnets, contacts and stuff.


b) The thing, I call “Baseplate”
It is the electrical connector that holds the printhead in place with magnetic force.


The Baseplate with Ingun pogo pins and neodymium magnets

The Baseplate holds 30 pogo pins “GKS-967” from Ingun and each two “Q-10-04-02-N” and “Q-15-15-03-N” neodymium magnets from supermagnete.de.
While the magnets are quire cheap to get, the pogo pins and the counterparts were approx. 80€ , which is about 30% of the printer’s initial cost.
Not quite a el-cheapo design, but worth the money. Cost can for sure be reduced, but the first designs are not meant for this kind of experiments.

The layout of the connector is designed so printheads can be plugged in either of the two connectors, having the same pinout on both.


This EAGLE PCB was later redrawn in Altium by a friend who ordered a larger panel anyway

The pinout for every module has 9 “center” pins that are for the important lines – heater, thermistor and fan supply, where the high current traces and pogo pins are used in parallel.
The “outer” pins are for the (extruder) stepper motors and some spares for future use.
But there is a small caveat though – the fan pins are not equal. While one of them is PWM controlled, the other is always-on only. I can’t change this, as there is only one PWM capable output on the GT2560 mainboard.

Sure, could modify the board and add a MOSFET, but thats another story.

Also made a proper mount for the original MK8 extruder that gets snapped into the base plate.


The pads you can see in the upper part of the PCB are the solder pads for the flexband I harvested from Audi/Volkswagen steering angle sensors.
One of the next steps is to use five flexbands and solder them onto the PCBs. I have the same PCB twice, one in the baseplate and one next to the printer’s main PCB.


No idea where to get such flexbands from officially – scrapyard?


c) The printhead modules

The print heads are designed for various purposes, mainly for FFF print heads, but also some other tools.
Meanwhile I designed various print heads, some are listed here:

Mk8 extruder


One module – a classic E3D v6 – plugged into the baseplate. Slim enough for two in parallel.


Two E3D v6 modules and a E3D Cyclops above them for size comparison

An experiment with a BLTouch clone made me realize that strong neodymium magnets are not good for its sensitive GMR sensor (BR, cpt. obvious)

Very valuable helper if you have wedding invitation cards – a plotter :)


Here a video of the current status, feels quite stable thanks to dasfilament PETG which I can absolutely recommend.

This video shows how well the printheads snap into the base plate. The four neodymium magnets leave no play and deliver a solid mechanical feeling.


Here photos of the printhead with flex bands attached

The printhead system prior to mounting. In front there is a spare PCB for the spring loaded Ingun fixtures.


Here the print head system after mounting. The status LEDs (WS2812) which glow dependent on printhead status and temperature are controlled by a separate digispark on the other end.


This photo shows some of my printheads in real hardware:

1. MK8 Extruder
2. Laser 450nm, 1.6W
3. ball pen plotter head
4. E3D  v6 hotend for bowden
5. micrometer dial indicator


After more than a year of use, I am so statisfied with the result. Swapping from the Mk8 extruder to the laser head within 5 seconds and then lasering a piece of wood with ease makes this piece of hardware much more usable.
So my printer is not only for squeezing hot plastic through a brass nozzle anymore, but also for engraving wood using a mill.
Sure, milling with that acrylic frame and wobbly axis will not give the best results (not to speak about the dust this hardware isn’t designed for), but are at least a funny experiment.

The best decision was to use the flex cable, which is not easy to get unfortunately. It really is a good feeling when you don’t have to fear broken cables.
No need for a drag chain, no sloppy cables, helping to reduce the risk of serious fail that could burn your house down.

[UM2] Laser Addon – Part 2

As previously described, I made a simple adapter to mount a 405nm blue laser diode to expose PCBs. There are for sure other methods that seem simpler, like separating the laser toner from a print or printing on transparent film, but our goal was to make it a “just press start” method using things we had lying around. No “process” that may vary with laser toner properties, chemicals, time involved. Just place it in printer and get a perfectly exposed PCB. Hopefully.

The first print of the laser mount was quite usable as you can see. Just the image is a bit blurry. Module sits tight, mount sits tight, looks proper. Just the “fixation” tab you can see on the 3D sketch was a bit clumsy and I just broke it off.

LaserMount LaserMount2

I searched for some EAGLE script that will output already usable G-code and was successful with PCB-GCODE. Some minor modifications were to do, then it was able to output G-code that switches the fan output whenever a line was to draw and so switch the laser on when exposing and off when moving across the PCB.

Some very careful tests of that G-code later, it showed that all is doing well. I set up the code to just home the Z axis and use the X/Y positions of the current head position as zero. This allows me to move the head manually to the board’s origin before starting, as I just fixate it with scotch tape for now. Played a bit to find the right Z position where the focus of the lens is best. In my case 12.5 mm above the glass plate. Just wrote that into the PCB-GCODE setup dialog, added PCB thickness and ready was the first G-code we ran on a real photosensitive PCB.

After exposing the first PCB, my colleague developed and etched it. The first try was a quite okay. A bit overexposed, but the technique seems to work. Fan output is driving the laser module’s enable pin correctly and it’s perfectly (over-)exposing areas.


This exposure was using 100mm/min at ~80mA laser power. Next time less current.

Also added an aperture plug to reduce the reflections the laser is causing in the metal on its way down. Now the spot is very clear and small, no scattered light. Just some reflections of the light coming back from the PCB, hitting the metal fan shroud and reflecting back to the PCB.


While experimenting with the laser output power, I used a Keithley SourceMeter 2400 for providing stable 3.0V. Using the Ultimaker 2 menu, I played with the fan speed. What I didn’t think of, was the dynamic behavior of both SourceMeter and the constant current driver of the laser module. A few “fan speed” sweeps up and down later, the laser started to blink and go off.

Shock. Did the laser module die? Power consumption went up from ~580mW to > 1W and the SourceMeter limited the current. A short test by driving the laser module directly, showed that the laser itself is still functional. Phew. So the constant current module died. I am quite sure that the (measured) 490Hz PWM of the UM2’s fan output caused the whole setup to oscillate and the RT8285B to catastrophically die.

Well, picked up a AQY221R2V solid state relay from our laboratory and used this to drive the laser module directly with the PWM output. For now I will not use the PWM to control its power, just use 0% and 100% :)

After doing some calculations, based on experiences of other people on the net, some estimations of the laser module’s power (using SLD3132VF as reference) I came to some approximated values of movement speed and laser current. Basically I am trying to get the same amount of energy to the ~50µm focused spot as some people who had success exposing with a 300W halogen lamp all at once. Interesting number: with the laser we have about 8 MW per m² energy concentration.

Here are the first tries with varying speed and current to find out where the sweet spot lies.


The result with 1000mm/min at 40mA laser current is really overwhelming for such a cheapo 2,50€ extra cost setup.


So this was quite successful. A bit more fine tuning to find where the limits are, e.g. the minimum laser current, the perfect focus plane level, the minimum line width and a bit of tool-tuning to get the drill holes laser-marked too. Then design and print some mounting frame to repeatedly hit the same zero offset when fixating PCBs and thus be able to expose two-sided PCBs.

The cool thing is – I just poweroff the laser and am able to print ABS just the minute after, without any de-/setup procedure.
Thanks to my colleague Franz for his support, especially for etching the PCBs.

Next stop: drilling ;)

Update: And here a close-up zoom with a macro lens:


And currently i am uploading a video that shows the setup being in action with a dry-run on paper.

[UM2] Laser Addon

I am currently thinking about adding a laser to our Ultimaker 2 at work. Primary use case would be exposing PCBs to etch them on our own.

For this task we need some UV laser on the printhead. Well the chinese sellers on aliexpress.com sell them for less than 2€ including P&P, why not use them?
So i disassembled a standard 405nm blue-ish purple laser i had lying around and checked what is in there.

Ideal would be if these cheap laser pointers had a 24V capable constant current driver that allows PWM dimming using the UM2’s cooling fan output. Yeah that would be a bit too much to expect, but we are not far away. In mine I found a SOT-23-6 with marking “AN=P1U” which seems to be a Richtec RT8285B. The website tells me that the marking should be “AN-P1U” and not “AN=P1U”. But the circuit fits just well.

Here the hand-drawn “DaveCAD” compatible circuit.


As i didn’t unsolder the trimmable resistor, i couldn’t measure its resistance. This would be needed to really know the max current etc. Edit: It was trimmed to 400 Ohm and its total resistance was 4.7 kOhm or 47 kOhm, don’t exactly remember.
But it’s already enough to build what we need. The datasheet explains that the EN pin of the B-version, which is thankfully active high, allows to dim the current by applying a PWM. Yay.
So just add a 56kOhm / 10kOhm voltage divider to get from 24V PWM to <5V and we can use the UM2’s fan speed control to dim the laser power.

Just the supply voltage with 5V maximum rating needs some extra circuitry. Perhaps its a good idea to low-pass filter the PWM signal, buffer it with a capacitor and use some cheap step down (like the LM2596) to get a good 5V supply.

But for the first tries, 3V batteries will to their job ;)

This is where I plan to put the laser (yellow). The UM2 guys initially wanted to add dual extrusion support, dropped that idea afterwards due to temperature issues that were to expect. So let’s use that hole for our plans.



I designed that mount using OnShape, a free-for-makers online CAD tool which is absolutely easy to use by the way. I am going to print it that week and test a bit. Idea is to place the laser above the hotend area where it will – surprise – get hot during normal prints. So the diode can be left mounted during prints – or unmounted with the ease of just unplugging the adapter (light blue).

Then only the software thing is remaining. I am wondering if i should create a 1-layer 3D object from the PCB and let a slicer like cura do its job. After the slicer router the “ideal” print head movement, post process the g-code to disable material feeding and insert fan speed commands that corellate to the feeder speed.

Or should i just export the PCB into a bitmap(BMP/PNG/…) and code a custom tool that read the bitmap, raster-scans it and creates g-code from it.
Of course it should be intelligent to follow the paths with “laser on” pixels first until it cannot go further anymore, turn off laser and move to the next position where we need to expose and do the same here. This looks necessary to me because i don’t know how long the PWM stuff will take until the laser reaches the desired power. For fast head movements and thin lines i am sure miliseconds will matter.

It wouldn’t be as intelligent as a slicer that knows outlines and will draw continuous lines and uses zig-zag for infill. But it allows us to generate g-code from just a bitmap and gives us fine grained control over things like z position etc. Just imagine we could shift the z-offset to draw thicker lines ;)

We will see how far this will get.


[ESP8266] Xmas tree lights


This year I improved my christmas tree LED lights from last year (https://plus.google.com/106975890398198714969/posts/EaUEFXzoxED)

I removed the Infineon MCU (XMC1100) which already was at it’s limits and replaced it with an ESP8266.
So i put the cool and versatile WiFi enabled MCU under my xmas tree, featuring an ugly, crude web interface using ESP8266WebServer (i am no web dev at all) and ported the old code from the XMC1100 over.
Porting was just a task of ten minutes to be honest.

The most time consuming part was all the stuff like adding SPIFFS+JSON based configuration saving, configuration parameter web interface, NTP time sync with ON/OFF times, and a dozen hours of debugging resets.

Using the Arduino port for ESP8266 development is very easy, but be warned:
Even if you just use 70% of your RAM, all the new/delete stuff of C++ will
fragment that memory so fast that you might face reboots every day.

In my case using the webinterface’s setup screen once allocated so many objects that all further allocations led just one step further to heap exhaustion.
then weird things happen.

Anyway, it was a nice this year’s xmas project and looks very appealing.
A beautiful purple light with smooth transitions fading slowly up and down from time to time makes it very special.

Here a short video showing some different modes (more or less pretty ones)

(and it uses the same code base as my kitchen floor lights https://youtu.be/ea7AFVHCEq0)
Here some screenshots:

[GSM] Source code of RX-FFT and GSM-Analyzer

Long time ago I coded tools to capture, demodulate, decode and decrypt data from an Software Defined Radio (SDR).
As i dont see any reason to keep it private, i decided to release the source code.

I mainly used a device that is comparable to the USRP, but designed by a friend of mine. Still these tools can work with .cfile that are saved from USRP. There is also a prototypic implementation for the HiQ-SDR device that is not tested a lot.

Nearly all the code is written by myself with these exceptions that come into my mind right now:
– Viterbi decoder (OpenBTS)
– FireCRC (GNU Radio)
– CryptA5 (Marc Briceno et al)

The two main tools in this project are:
RX-FFT, a windows (DirectX) based broadband FFT visualizer and
GSM-Analyzer that can decode (and with kraken-win32 even decrypt) GSM data live from the air or from/to files

You may use it for your own projects (non-commercial, commercial) after you informed me about your project.
If you have use for this code, you can also send some money to [email protected] to show me how much you liked it.

How to use it with USRP .cfile files?
1. Get some information about your used .cfile: crystal frequency: 64MHz, 100MHz,  decimation rate (usually visible in the filename as …_d174_… for decimation rate 174) (sample file)
2. Select “Open”, “IQ Wave file” in GSM Analyzer
3. If the fields are not correctly autodetected, correct them
4. Go into “Options” and press “A” or “B” in “Burst length correction type”. One of them is the correct one for your provider (O2 sometimes uses B)
5. Press “Play”
6. You should see now all traffic happening on the channel
7. In “Filter” menu select those entries that shall be ignored to prevent flooding the log

source: http://svn.g3gg0.de/svn/default/trunk/EZ-USB/RX-FFT/
user: rx-fft
pass: rx-fft

it’s on bitbucket: https://bitbucket.org/g3gg0/rx-fft
just like Kraken-win32: https://bitbucket.org/g3gg0/kraken-win32

it’s on bitbucket: GitHub – g3gg0/rx-fft
just like Kraken-win32: GitHub – g3gg0/kraken-win32

[EOS] TimerGen Tool

Since last year I helped a little developing Magic Lantern, a Firmware mod for Canon EOS DSLRs.
I reverse engineered some interesting registers and memory structures that make frame rate patching possible.

(yeah, as always I couldn’t resist reverse engineering the next device I bought :) )

Now I’ve coded a little tool that makes it possible to:
a) Calculate the exact timer frequency that generates frame rate
b) generate custom frame rates

The tool is available here.
Here some screenshot.