GeistHaus
log in · sign up

jacob's Web

Part of wordpress.com

Technology, Music, Philosophy

stories
Reverse Engineering a 27MHz RC Toy communication using RTL SDR
FunHobbyTeardownTechgnuradioRC ToySDR
My kids have this RC fire engine that works in the 27MHz band. I got curious how the communication is, with objective to control the toy from laptop. I had an RTL SDR in my toolbox. I have used it with gnuradio software for a couple of analog reception tasks. Not for anything serious so […]
Show full content

My kids have this RC fire engine that works in the 27MHz band. I got curious how the communication is, with objective to control the toy from laptop. I had an RTL SDR in my toolbox. I have used it with gnuradio software for a couple of analog reception tasks. Not for anything serious so far. So I started simple and kept building on top.

Following is the final block diagram I arrived at. Seems complex right?. I will walk you through the steps involved in reverse engineering the communication.

Though the toy says it uses 27MHz, the exact frequency can be anywhere in the 26-28MHz range. Identifying the exact frequency and visualizing the signal in a waterfall diagram is the first step. Created a gnuradio project and added RTL-SDR Source block and QT GUI Sink block connected to its output to do this. Also added a QT GUI Range block to vary the RF frequency. Executed the flow graph. After playing a bit with the slider at bottom of the output window, I could visualize the RF signal as shown below. Note the strong red indicates the time when i was pressing the key on remote control.

Now that we understood the frequency to be 27.1MHz, we need to find out the modulation scheme. Modulation can be on Amplitude, the frequency or the phase, or a combination. To figure if there is any amplitude modulation, we need to look at the RF time domain with a large observation window. So I added a time domain visualisation by configuring the QT GUI sink block. During execution, increased the FFT size (observation window) from default 1024 to 16384

It appears like it is some form of Amplitude Shift Keying (ASK). (It can be a combination of Amplitude and phase modulation also. But we build on this assumption, and see whether we can differentiate all the RC keys with just the ASK). Next step is to demodulate the ASK signal with the help of an AM Demod block. From my experience with analog reception, I added an AGC2 and Decimating FIR Filter blocks to improve the signal to noise ratio. The demodulator output was then visualised using a QT GUI Sink. Also the output was taken to an Audio Sink to hear the message, after passing through a Low Pass Filter to reduce the sample rate to 32kHz required for the Audio Sink.

The time domain output of the QT GUI Sink is shown above while pressing one of the keys. Shows repeating Ones and Zeros last for 0.5 ms each. I changed the FFT size parameter on bottom to get idea about the larger frame structure.

At observation window of 32768, a repeating sequence of low frequency (111011101110) pattern followed by high frequency (10101010…) pattern is evident. The envelope change is an artefact of the AGC, so just ignore that. Tried a different switch on the remote.

Here we have a shorter high frequency (1010…) pattern. So the switches are encoded using the length of high frequency region. Now we need to estimate the length of each of the frames. For this we need to downsample it such that each sample represents 1 bit. A Symbol Sync block is required for this downsampling. Then with a Threshold block the amplitudes were converted to the [0,1] range. To count the bits after the preamble pattern (111011101110) I tried using many built in blocks like “Correlate Access Code – Tag” block etc. But did not work as per expectation. So I added a Python Block and decided to write the python code to count it, and renamed it to Custom Decode Block. The code used to count the frame length is shown below

The code was arrived at after a few trials and errors. It just correlates the 110110110 pattern with the datastream to identify the frame starts, and calculate the distance between the frame starts. Now it prints the frame length to the console. And also shows that as height of spike in an output visualization.

Almost done. But one more problem. Some keys especially those that had the long sequence of 1010.. were not showing up. I had to solve one more issue that is rooted on the gnu radio implementation to get all the frame length. The reason is the buffers passed to the code were very small and insufficient to hold a full frame in case of the long frames. So I had to add this Stream to Vector and Vector to Stream block pairs to aggregate multiple block and make a bigger block before passing to my Python block.

After all this exercise, I arrive at the following table. First 2 columns are experimentally obtained and other two are calculated.

Key CombinationFrame Length (bits)Data Length (Frame Length – 12) (bits)Data Length/12^13212010V1201089<24121>84726^,<72605^, >96847V, <60484V, >108968

A video tutorial on the above is available at https://youtu.be/SOK6BxCaqKs

The .grc file is avilable at https://github.com/nitrojacob/gr-flows/blob/main/rtlsdr/27mhz_fire_engine_remotecontrol_decoder.grc

http://nitrojacob.wordpress.com/?p=633
Extensions
Summarizing the Frontier: What Happens When Everyone Can See the Cutting Edge?
ViewpointsAgentic AIAIfrontierliterature searchLLMresearchscience
Impact of LLMs for research summarization is an under-appreciated. This is going to accelerate science.
Show full content

For decades, navigating the vast ocean of scientific literature required a near-monastic commitment. Researchers and students often spent months — sometimes years — combing through journal articles, conference papers, and dense reviews just to understand the current state of the art in a field. It was a high barrier to entry: you needed access, training, time, and often a formal research environment. In many cases, you needed to do a PhD just to know what questions to ask.

But that barrier has started to crack.

Large language models (LLMs) like GPT-4, Claude, Perplexity, and Consensus are fundamentally reshaping how we approach research. With the right prompts or queries, these tools can ingest hundreds (or thousands) of papers and return structured summaries, highlight key ideas, compare methodologies, and point out gaps — often in minutes.

What once took weeks of literature review can now be prototyped in an afternoon.

This shift has major implications:

  • Working professionals can keep up with fast-moving fields like AI, biotech, and quantum without stepping away from their careers.
  • Researchers can more easily explore adjacent domains, fostering cross-disciplinary innovation.
  • Tech recruiters can better evaluate candidate expertise or connect job roles with emerging trends in research.
  • Students can access expert-level overviews, gaining confidence and orientation early in their academic journeys.

But perhaps the most transformative effect lies in who now gets to participate.

For every celebrated researcher, there are thousands of brilliant minds whose ideas never made it to the surface — not because they lacked insight, but because they lacked access. Many never followed the formal path of academic research, and without the time or resources to conduct exhaustive literature surveys, their contributions were never fully formed, recognized, or published.

Not every Ramanujan finds a Hardy.

The world has likely missed out on countless innovators simply because they weren’t in the right place, with the right network, at the right time. Until now, the frontier of science was guarded not just by knowledge, but by gatekeeping — institutional, informational, and logistical.

LLMs are changing that.

By making the current frontier of knowledge visible and navigable, these tools are removing a silent filter that has long excluded capable thinkers. When you no longer need institutional affiliation, journal access, or years of immersion to get oriented, you open the door to innovation from unexpected places.

This isn’t about replacing deep expertise — it’s about lowering the barrier to entry, leveling the playing field, and democratizing access to discovery. It’s about letting the experts focus their energy on solutions.

What happens when everyone can see the edge of human knowledge?
We might just find that the next great leap doesn’t come from a lab — but from someone who, until now, couldn’t afford to join the conversation.

http://nitrojacob.wordpress.com/?p=613
Extensions
Time Leverage
PhilosophyTechAgentic AILeverageLLMProductivityStar PerformerTime
There used to be two ways in which capable individuals at organizations traditionally got more things done. For both the above the multiplication factor was very limited, as both delegation and coding required efforts to either manage people or computer systems, which beyond a point saturates the full available mental bandwidth of the high performer. […]
Show full content

There used to be two ways in which capable individuals at organizations traditionally got more things done.

  1. Delegation – If you have a great idea, delegate the execution to other capable individuals.
  2. Technology – If you have a great idea, write code/software to automate many of the boring aspects of the implementation.

For both the above the multiplication factor was very limited, as both delegation and coding required efforts to either manage people or computer systems, which beyond a point saturates the full available mental bandwidth of the high performer. Team sizes beyond 10-20 and you end up being just a people manager. Developing automation, customizing them and maintaining them can easily shift your focus away from your core idea. Once in a while things that used to work well breaks. As you have more of these automation, chance that every day you have to work on one of these increases. Increasing the multiplication factor beyond like 20x came with and exponentially rising cost — You need to hire people smarter than you. You need to deploy automation managed by external teams.

But now there is one new lever that is coming up that seems to provide a higher multiplication factor for your time. – Large Language Models (LLMs) and their use in Agentic Systems. The way this can build you automation in an automated fashion with AI managed build – test – refine loops, taking up just a fraction of the time that traditional software automation consumed.

http://nitrojacob.wordpress.com/?p=606
Extensions
‘unshare -r’ on ubuntu 24.04, 23.10
TechTipsUbuntu
unshare -r used to work in older versions of ubuntu and stopped working in recent releases and returns the message unshare: write failed /proc/self/uid_map: Operation not permitted The -r option is quite useful in many cases like if you want to prevent an application access to the internet but allow a client-server communication that uses […]
Show full content

unshare -r used to work in older versions of ubuntu and stopped working in recent releases and returns the message

unshare: write failed /proc/self/uid_map: Operation not permitted

The -r option is quite useful in many cases like if you want to prevent an application access to the internet but allow a client-server communication that uses localhost to communicate inside the network namespace. New network namespaces don’t have the localhost loopback up.You need to run ifconfig lo up from the namespace as root user. To enable root access within the new namespace you need -r option.

Reason for the same is ubuntu has enforced Apparmor to not let unprivileged users switch to root user in the newly created namespace. A way to disable such protection is described here. Reason for the same is described here[https://github.com/YoYoGames/GameMaker-Bugs/issues/6015], by using command

sudo sysctl kernel.apparmor_restrict_unprivileged_userns=0

But this is not recommended. As the reason stated[https://discourse.ubuntu.com/t/spec-unprivileged-user-namespace-restrictions-via-apparmor-in-ubuntu-23-10/37626] by ubuntu for enabling the Apparmor protection is very sensible (Read it thoroughly before continuing!).

A better way to make unshare -r work is by creating an apparmor rule in /etc/apparmor.d/ on a per-application/ per-script basis, and wrapping the unshare command in a script.

#!/bin/bash
unshare -uUnrf path.to.application

Replace path.to.application with your application path, save the above script to a location. eg. /home/$USER/scripts/runJailed.sh. Then create a /etc/apparmor.d/runJailed file with following contents

# This profile allows everything and only exists to give the
# application a name instead of having the label "unconfined"

abi <abi/4.0>,
include <tunables/global>

profile runJailed /home/$USER/scripts/runJailed.sh flags=(unconfined) {
  userns,
}

After that sudo systemctl reload apparmor.service to reaload the new rule. More details on apparmor usage at https://ubuntu.com/server/docs/apparmor

http://nitrojacob.wordpress.com/?p=603
Extensions
Connect to FPGA boards from Xilinx ISE / iMPACT on Linux
TechTipscable drivercable serverdriverhardwareLinuxwindrvr6xilinx ise
Trying to connect to FPGA boards from iMPACT tool under linux throws error that the cable driver is not present. Searching the ISE install directory yields you some configure and setup scripts related to the various cable drivers. Running the script throws out another error related to the linux header files (linux/config.h not found). In […]
Show full content

Trying to connect to FPGA boards from iMPACT tool under linux throws error that the cable driver is not present. Searching the ISE install directory yields you some configure and setup scripts related to the various cable drivers. Running the script throws out another error related to the linux header files (linux/config.h not found).

In Xilinx ISE, the cable drivers are designed as kernel driver modules. But such kernel modules are dependent on the specific kernel you are using and needs to be compiled with the corresponding kernel headers. The cable driver source code packaged with ISE is so old that it expects the kernel header structure that existed in the pre 2.6.x kernels. So building the kernel modules is a high effort task.

Solution was to install the Vivado Lab Edition software, which uses a different driver architecture, and doesn’t need a kernel module for each cable. The Vivado Lab edition can start a cable server in the localhost. From the ISE we can then connect to the cable server and access the connected board from iMPACT.

http://nitrojacob.wordpress.com/?p=582
Extensions
Covid-19 and the Sharing Economy
PhilosophyViewpoints
The key idea behind the sharing economy is “better utilization leads to better economic efficiencies”. We are witnessing an increase in efficiencies with the help of cloud and IoT techniques, that reduce the need for excess inventories at the manufacturer, leading to better utilization of capital. One step further is the concept of sharing economy […]
Show full content

The key idea behind the sharing economy is “better utilization leads to better economic efficiencies”. We are witnessing an increase in efficiencies with the help of cloud and IoT techniques, that reduce the need for excess inventories at the manufacturer, leading to better utilization of capital. One step further is the concept of sharing economy where capital intensive items like automobiles, and buildings are shared across a pool of people. Let’s rethink the idea of economic efficiencies with the realities that were thrown at us by the Covid-19 pandemic.

This pandemic has placed lot of strain on the supply chain of medical devices. Firstly we had to build the capacity for ventilators, oxygen concentrators, diagnostic kits and equipments. Later it turns out that there is a supply glut, and many of the added capacities won’t ever breakeven. In some cases luckily, there were similar equipments used for other purposes, that could easily be repurposed for emergency uses. Same now goes with the vaccine production and administration related items. There was a lean stockpile, and production were running at close to 100% capacities. Now the one time event of vaccination requires fresh capacity addition for everything from vaccine bottles to syringes to PPE kits. Once the vaccination demand subsides, we may see a supply glut of these items, and many of the added capacities may end up not even breaking even.

With hindsight, one can propose two solutions for such surge in demands. 1) To keeps capacity utilization below 50% during normal times, so that the additional manufacturing facility can be pushed into action when there is spike in demand. 2) To keep additional inventory of PPE Kits, and Syringes and bottles, so that a surge in demand can be met while the installed capacity is utilized at 80% to 100% at all times.

But without hindsight, you never know where such excess capacity needs to be kept. Whether you all need to keep an automobile with 10% utilization, or just use a uber taxi that has 80%+ utilization. Whether you need to build excess capacities in terms of electricity productions, or climate control, until you see the demand spike.

My argument is that systems that are at near 100% utilization are unable to meet a surge in demand, be it induced by a pandemic or some other natural calamity. The sharing economy that we are currently seeing a lot of traction, may be increasing the economic efficiencies, but sure it is making the economy ill prepared to meet a surge in demand. There is a certain relevance of ‘Anti-fragility’ concept proposed by Nassim Taleb.

http://nitrojacob.wordpress.com/?p=576
Extensions
Cross compiling linux libraries and applications with large dependencies
Techchrootcross-compileemulationlarge dependencyopencv
Cross compile is the only option for building applications for tiny embedded systems. But once you have a hardware capable of running Linux, you have multiple options. Cross compilation Native compilation on target Compile from host using a target emulator. We will look at the various options and figure out the relative strengths Cross-Compilation If […]
Show full content

Cross compile is the only option for building applications for tiny embedded systems. But once you have a hardware capable of running Linux, you have multiple options.

  1. Cross compilation
  2. Native compilation on target
  3. Compile from host using a target emulator.

We will look at the various options and figure out the relative strengths

Cross-Compilation

If you have a non-linux OS, or if you have a very stripped down linux system, and all the dependenices of your software are going to be built by you then this is an excellent option (sometimes the only option). Though it takes some extra effort to get the flow working; the build can be the fastest it can get. But if your library or applications has dependency on many dynamic libraries, you have to provide the target specific library header files for each of the dependencies. This is mostly un-supported workflow on most linux enviroments (hosts as well as targets) and can prove very hard to setup.

Native Compile on target

If your application is small and your linux based target provides a command line interface, login to the target’s command line, and build the application natively. For large and complex libraries or applications this can take significant time due to the low CPU performance of typical non-x86 platforms. Sometimes build on target can take days. (eg. Building the popular computer vision library OpenCV for even the somewhat powerful Raspberry Pi takes around 1.5 to 2 days). Sometimes such native compile may not be possible due to compiler facing out-of-memory on the target.

Compile from host using a target emulator

Compiling on your PC with qemu emulation of the target is the easiest approach for building linux libraries/applications with lot of dependencies. The compile speed will be in-between the other two approaches due to the instruction set emulation. The more important point is that it helps to use the large memory available on your PC for the build. Applications that doesn’t compile due to OOM on native compile can be built this way. In this flow you take a copy of the target’s root (/) file-system to your PC; and chroot into that filesystem. Modern linux desktops have pre-configured binfmt availalble from the package manager. If you attempt to run an ARM binary on x86_64 PC, you OS will automatically invoke qemu to do the emulation. Hence if you have qemu-user-static (Ubuntu Package name) installed, then you can chroot straight into the filesystem without any configuration of binfmt.

A comprehensive document on the setting up emulation and chroot is available here. On a modern ubuntu system you can skip most of the document, and just read and follow steps in “Chroot to Arm root directory” section. You can also invoke the target’s package manager from within the chroot environment, if you figure out that you need some extra headers.

Other options

There are many other techniques like setting up docker containers with close distributions for x86_64 that are very close to the target, and doing cross compile. Setting up full-fledged Virtual Machines with device virtualisation etc. for the target, and compile from within the virtual machine. etc. But these are all difficult to setup and mostly wasteful when you have a more foolproof and simple method available using chroot.

http://nitrojacob.wordpress.com/?p=566
Extensions
1kVA Square Wave Inverter Teardown
Teardowninverter circuit diagramsimple inverter circuitSquare Wave Inverterteknix
Teardown of an un-branded 1kVA Square Wave Inverter. The only form of identificaton was a name TEKNIX/D12-V2 on the PCB. The box is screw fit, and can be opened easily. Inside there is a large transformer used for both up conversion in inverter mode and down conversion in charger mode; a single side PCB with […]
Show full content

Teardown of an un-branded 1kVA Square Wave Inverter. The only form of identificaton was a name TEKNIX/D12-V2 on the PCB. The box is screw fit, and can be opened easily. Inside there is a large transformer used for both up conversion in inverter mode and down conversion in charger mode; a single side PCB with MOSFETS on one side, and all the AC switching relays; and a discrete power Capacitor.

Jpeg

The circuit is centred around a PIC16F676, which senses the battery voltage, mains and overload and generates the drive signal for the transitors and blinks the LEDs that are part of the user interface.

Jpeg

I have attempted to reverse engineer the schematic, inorder to fix the charging circuit overcharging the battery; and have arrived at following schematic, which is mostly complete except for a few trival relay flyback diodes, and some component annotatons. The schematic is not very neat, and as it served me the purpose, I don’t plan on cleaning it up.

The charging circuit is very bad – sort of a constant voltage charge with current limited by the resistance in the path only – battery internal resistance, cable resitance, and PCB trace resistance. The PIC16F676 senses only the voltage at the PCB for charger cut off/enabling. As the battery ages, the charge current reduces, and hence the charger will cut-off only at a higher battery voltage (As charge current is less, voltage drop on cable and PCB are lower, and sensed voltage is very close to battery terminal voltage). This leads to continuous(charge never cutting-off) electrolysis (gassing) within the cells, and the battery ageing will get accelerated.

The orignal KiCad Schematic file is uploaded here

http://nitrojacob.wordpress.com/?p=554
Extensions
Simulavr with Codeblocks
Techtoolsavr simulatorCode::Blockscodeblockssimulavr
Simulavr is a simulator for processors using the AVR intructon set from Atmel (now Microchip). Its handy if you have a complex bug and don’t have a JTAG emulator. Code::Blocks is an easy to learn and use cross-platform IDE for C/C++ development. The following is targetted at embedded development under ubuntu/linux. The version provided by […]
Show full content

Simulavr is a simulator for processors using the AVR intructon set from Atmel (now Microchip). Its handy if you have a complex bug and don’t have a JTAG emulator. Code::Blocks is an easy to learn and use cross-platform IDE for C/C++ development. The following is targetted at embedded development under ubuntu/linux.

The version provided by ubuntu package manager is somewhat old. Always install the latest version of simulavr from https://savannah.nongnu.org/projects/simulavr. v1.1.0 is the latest as of this writing. Hence the following steps.

wget http://download.savannah.nongnu.org/releases/simulavr/libsim_1.1.0_amd64.deb
wget http://download.savannah.nongnu.org/releases/simulavr/simulavr_1.1.0_amd64.deb

And install them in that order by double clicking each of the .debs.

To run the simulator, simulavr --device atmega --file blinky -p1028 -g. The simulator provides a gdb server like interface listening on port specified by -p<port> (port=1028 for this example). blinky is the binary with debug symbols after linking(symbols can be enabled using -g opton of gcc). An avr-gdb commandline can be attached to simul avr by running the following (for understanding only. Not required for connection with code::blocks).

avr-gdb blinky
(gdb) target remote localhost:1028
(gdb) load

To attach Code::Blocks to simulavr, Configure under Code::Blocks > Settings > Debugger as follows:

After that set Code::Blocks > Select Debuggers > Active Debugger as simulavr.

To perform debug.

  1. Run simulator simulavr --device atmega --file blinky -p1028 -g
  2. Press Debug button
  3. Set breakpoint in main() and continue till this point. This is very important as halting the simulavr at points before the stack gets initialized will throw following error. Stack gets initialized in __ctors_end(). Stepping before that point will throw following abort message.
simulavr: /home/buildbudy/simulavr/libsim/hwstack.cpp:286: void ThreadList::OnSPRead(int): Assertion'0 != SP_value' failed.

http://nitrojacob.wordpress.com/?p=546
Extensions
What the corona virus outbreak teaches us?
PhilosophyViewpointsCoronaCOVID-19drug discoveryeconomic modelfinancing pharma r&d costs
We need to rethink the financing model of Pharma R&D to accelerate drug discovery during future outbreaks.
Show full content
Photo by Pixabay on Pexels.com

This post in in continuation to my article “True Economics of Consumerism”

Let us take a closer look at how consumption subsidises the cost of technology improvement. A very good example for this is the electronics industry. The industry as a whole is progressing forward and we have reached levels of sophistication un-imaginable 20 years back. Retrospectively there were two choices.

  1. To get a large amount of capital funding and develop an extremely good processor every 10 year. Sell it in ultra-large volumes for the next 10 years. Then get the next big increment and so on..
  2. To release a product every year or so with smaller increments, so that we get the same level of improvements as 1st choice in 12-15 years time instead of 10years there.

The electronics industry chose the 2nd option of frequent small increment and volume production of each increment to support the R&D costs of the next iteration. The second option requires far less amount of initial investments. This is a very clever financing model for a high investment technology that has potential for mass adoption.

Drug development and Pharmaceuticals is a similarly large capital intensive areas as electronics R&D. Yet it is hard to apply the financing model that the electronics industry took. The lessons from COVID-19, and potential for more lethal future outbreaks points to a need to speed-up Pharma R&D. But unlike the electronics industry, we haven’t found a suitable financing model for the Pharma industry. Here we would be looking at a few alternate models to finance the additional capital required to speed up Pharma R&D.

  1. A socialist approach – Governments should fund the Pharma R&D capital. The government taxes people for all such unforeseen outbreaks; and funnels that money into funding R&D. The government in return provides free healthcare for all tax-payers.
  2. Health insurance premiums should pay for pharma R&D. Advances in pharma R&D leads to fewer claims or less claim amount. Hence financing R&D for cheaper, more effective drugs is in the interest of health insurance. But the people running these health insurances may not be seeing the big picture and may be focused on the immediate financial gains. Hence nudges/regulations from governments will be required to make this happen.

Share if you have got better ideas on this topic.

http://nitrojacob.wordpress.com/?p=528
Extensions