[ESP32] LegoRemote v1.2 – a BLE/WiFi remote control for motors using a Steam Controller

Some years ago when I was young, I always wanted to have technic bricks to build some cool stuff with it. Self driving tanks, rotating cannons and shooting smaller bricks around. But back then I had no technic.

Well, not even bricks. Just a friend whose brother had this expensive stuff.

Now I have a son in this age and well… he builds tanks that… stupidly drive until they crash into a wall :)
Time for some ESP32 and soldering wizardry to build a proper REMOTE CONTROL!

No no, I know there are some remote controls around there. But none fits really well. Either 80’s infrared or bulky. Or too expensive.
And most important – none of them of which I can say to my son: “I built it for you!

So lets build a new, better one to rule them all!




  • ESP32-WROOM-32D  |  WiFi, BLE and enough processing power and IOs to control two motors and a LED light
  • DRV8833  |  dual H-bridge for enough power to drive the motors
  • TPS62162  |  step down for up to 17V input voltage, and also for having fun soldering the 2×2 mm WSON-8 package
  • CP2104  |  just for programming the ESP32
  • Power functions connectors to connect the motors and lights.
    Will cut the wire and solder them to the bottom side and glue the brick/connector to the top side

All this in a rather small footprint, here as shown in EasyEDAs 3D view:

The wire you can see on the PCB photo at the top of the article is not to patch some bug, but to feed the USBs 5V to the power supply. It will probably not be enough to power a motor, but unfortunately the connectors from china didn’t arrive yet. So I was testing with LEDs only in the first place. For the photo I just placed the motor connector losely onto the PCB without function.

To see what the motor driver does, the v1.1 had (unlike the v1.2 now on EasyEDA) no LEDs designed onto the PCB, so I soldered two antiparallel diodes to the outputs so I can see whats happening. If you look closely in the video you can see the two 0603 diode pairs alternating, which are indicating forward/backward motion.


For the control I first wanted to build an extra PCB with buttons and another ESP32, a classic remote control.

But I somewhen remembered that the Steam Controllers have a BLE mode. So sat down and a few hours later I was able to receive packets from the controller :D
Basically you just search for a HID device that announces as “SteamController” and connect to it. Then just use some undocumented Valve service and some undocumented command with it to enable packet transmission.

Then there was some also undocumented report format (is this even a HID like report? didn’t make sense to me) which I reverse engineered manually.

After a hour or so, all flags and values made sense and I was able to blink LEDs using a Steam controller and an ESP32. ¯\_(ツ)_/¯
I will upload the sources and update this post later.


Project files:

v1.0: “first try”
– first revision, but had chosen the wrong voltage regulator. TPS62291 only goes up to 6V. had few projects in parallel and simply forgot that this device had to cope with 9V

v1.1: “good enough”
– the version you see in the videos with everything working fine

v1.2: “final”
– added indication LEDs to driver output and optimized layout and PCB size


Here a short video showing the connection phase (1-3 seconds after switching power on) and controlling the motor outputs. The LEGO connector for the headlight was not populated there.
It will go to the empty space marked with the white rectangle right next to the other connectors.


Meanwhile my son uses this device on a regular basis to control his tank like constructions.

During his stress tests, I faced only one issue – the driving mode of the motor I expected to work best – fast decay – caused some serious speed drop after a few seconds of driving.
So I changed to code to use the slow decay mode

I will have to dig deeper into what the DRV exactly does and try to understand why the motor first runs at high speed and gradually slows down after maybe 10 seconds. Maybe MOSFETs are heating up and their resistance is raising a bit too much. Not sure.
But for now this is bypassed by using slow decay.


Maybe this is some inspiration to other people what you can use your arduino playground for without too much effort and get your kids interested in electronics also.


[ESP8266] CAN library for Arduino

Recently I needed a CAN <-> WiFi router at work. As I didn’t want to use a several thousand euro hardware that sucks a few amps at 12V,
I decided to implement that using the ESP8266 and a CAN transceiver.

The current setup

The current setup

Sending CAN messages with the ESP8266, decoded with PicoScope.

Sending CAN messages with the ESP8266, decoded with PicoScope.

Well, it works quite stable, just a few things here and there. E.g. I cannot ACK messages as I am using I2S to sample the CAN Rx path.
Also the I2S seems not very stable and goes crazy every 20 minutes at 1.5 MHz sampling rate, so that I implemented a detection and restart procedure.

Here is a picture of the ISR execution time – it is quite stable at 725µs – 765µs

Tracing the ISR execution time using a GPIO. When the ISR is active, the signal is high.

Tracing the ISR execution time using a GPIO. When the ISR is active, the signal is high.

But aside of these minor issues, the ESP8266 is now ready for its use case – routing between WiFi and CAN :)

Here is the library: GitHub – g3gg0/esp8266can

[GSM] Kraken

currently i am porting Kraken, the fantastic A5/1 cipher cracker to win32/x64.
it seems that i am done with most of the steps.

it starts, cracks the keys, supports ATI cards as the linux version does and is even able to run as a multi-client server application.

i also added support for older cards like the Radeon HD 3870 which will speed up the key search by maybe 10% depending on your HDD setup.

unfortunately its no GPL or even a more free license like MIT or BSD.
so i may not publish my changes. instead i will try to get them added to the original repository.
since i also changed a lot (!) in the internals of kraken, i am not sure if it will get added :)

but we will see….

[CEntrilo] no support for ventrilo v3.0 for now

hi again.

just want to let you know that i will not support ventrilo v3.0.
the reason is, the ventrilo guys are authenticating the server against some of their servers.
just have a look at port 6100 when you start ventrilo…

as stated on: http://ventrilo.com/forums/showthread.php?t=23257
they require you to let the client authenticate the server.
if you are behind a firewall, so u’re fucked.

  • server calculates some seed (?) and sends this to the client (UDP)
  • client contacts flagship-servers and gets some other token (UDP)
  • client calculates encryption keys from this
  • server sends 0x34 command during TCP-handshake
  • client receives 0x34 command
  • server modifies encryption lookup tables using the keys from above
  • client modifies encryption lookup tables using the keys from above
  • both communicate with modified tables now

i hate that “we want control everything”-way everyone goes.

well, i was able to let the win32 client authenticate my server and then use that authentication token to decode the protocol without any problems.
that token seems just to change when the server is restarted – but neither i want to make a dumper for that token nor do i want to re-implement their authentication procedure.
maybe i’ll find another way like bruteforcing the encryption while the server sends pings and information blocks, but i dont think its the right way.

P.S.: these guys really suck!



[CEntrilo] ventrilo 3.0 issues

well, first i want to thank the guy i wrote about there:



more than half a year later he contacted me and sent twice the money he promised before.
obviously he really was busy for long time ;)
thanks Mr. S.C. ;)
okay now about Ventrilo v3.0.x:

i had a look at the protocol. the connection setup is nearly the same. but right after the sever sends the command 0x34, both client and server modify their encryption tables. This results in totally wrong en/decryption.

see http://g3gg0.de/projects/CEntrilo/modify_crypt_buffer.html
and http://g3gg0.de/projects/CEntrilo/modify_crypt_buffer_c.html
its from Ventrilo Server for Linux v3.0.1

i’m not exactly sure what sense this change makes. it’s re-allocating the buffer with a minimum size of 0x40, fills it up with [length]+pos byte values and adds up the old values.
that looks like some weird try to prevent another reversing?!

anyone an idea whats the sense of this code?

[ARMada] Big fat update!

i had some free minutes and wanted to catch up some changes i always wanted to make.
and since a friend was hacking around with 32bit ARM opcodes using stupid
“.dd E1234567”-opcodes, i knew its time to fix this. :)

it took some hmm 10 hours to implement nearly(!) the whole ARM32 instruction set.
now you can code like this:

.sub useless
.org 0xDEAD1000
.inj 0x00001000
.imp some_call 0xDEAD0100
.code 32

MOVCSS R0, 0xDE000000
ADDCS R0, R0, 0x00AD0000
TST R0, R0 LSR 2
BEQ @loop
BL @some_call


this example would inject the generated ARM32-code at offset 0x1000 into the loaded file,
doing some nonsense-operations and after that it will call the function ‘some_call’ at address 0xDEAD0100.
since the code is told to be at 0xDEAD1000 (the ‘.org 0xDEAD1000’), the BL will automatically
get calculated to jump about 0x0E00 bytes backwards, where the function ‘some_call’ is said to be.

now its not just useful for hacking firmwares, but also very good for crack..erh customizing e.g. symbian apps.

just one note…
ARMada sometimes crashes when typing too long. i dont know why – that happens during the GUI update,
but i really cannot figure out why. but simply use a notepad to code in a clean style, then copy paste it into ARMada ;)
i will try to fix in an upcoming release in which i will also include the last two missing opcodes (coprocessor data and register transfers)

to download, click Projects->ARMada

[usb_rx] Current Project

i didnt post much lately.
this is because im working on a little project for a Cypress CY7C68013A. thats a USB2.0 chip with a 8051 microcontroller for setup and firmware.

really an interesting project :)
won’t tell you exactly what its for, but its used to stream RF radio data with speeds up to 32MB/s to a Win32 program used for recoring and decoding etc.

i’m using Microsoft Visual C++ together with SDCC (Small Devices C Compiler) to compile the firmware for the Cypress chip. the used Win32 driver is the standard Cypress driver for those chips, but interfaced with a DLL i wrote.

i’m using shared memory for distributing data to one or more applications which may preprocess the data stream they get. they redistribute it again over shared memory areas. made also TCP Client/Server tools so that whole thing works via network too.

that project looks quite mature now.
at least everything is working as intended ;)

USB Receiver