Introduction
Recently, I acquired a fascinating scientific instrument: the Radiacode 102 (note: This is an Amazon affiliate link, this pages author profits from qualified purchases) pocket gamma spectrometer featuring an Cesium Iodine (CsI(Tl)) scintillator with digital readout. Note that at the time of writing, a new versionāthe Radiacode 103 (note: This is an Amazon affiliate link, this pages author profits from qualified purchases) ā is already available, offering better spectral resolution at $8.4% \pm 0.3%$ FWHM compared to $9.4% \pm 0.4%$ FWHM of the 102. Additionally, a high-resolution variant exists: the Radiacode 103G, which achieves an impressive $7.4% \pm 0.3%$ FWHM. Despite this, the Radiacode 102 remains a compact and affordable gamma spectrometer designed for both amateur and professional radiation detection. Unlike typical Geiger counters, which only measure radiation levels, this device provides detailed spectral information, allowing users to identify specific radioactive isotopes in their environment.
In this post, I want to walk you through what makes this device so useful, the key differences between gamma spectrometry and Geiger counting, and how it performs in real-world scenariosāfrom mapping radiation levels in the field to analyzing fixed radioactive sources in a lab. I will also cover its mobile integration and show how it can be controlled programmatically using Python via USB and Bluetooth connection.
Gamma Spectrometer vs. Geiger Counter: Why Spectrometry Matters
Geiger counters are widely known for their simplicity and affordability. They provide a basic count rate (in counts per second or microsieverts/hour) without distinguishing between the types or energies of the detected radiation. While useful for identifying the presence of radiation, they fall short when it comes to identification.
Gamma spectrometers like the Radiacode 102 go much further. They measure the energy spectrum of incoming gamma rays, allowing one to identify characteristic emission lines from specific isotopes such as Potassium-40, Cesium-137, or isotopes in the uranium and thorium decay chains. This makes them vastly superior when the goal is isotope identification, environmental monitoring, or educational demonstrations.
How it works
Gamma spectrometers like the RadiaCode 102 are based on scintillation detectors - specifically, a thallium-doped cesium iodide crystal, or CsI(Tl). When a gamma ray enters the detector, it interacts with the crystal material . These interactions deposit energy in the crystal, which is then re-emitted as visible light (scintillation photons). Gamma photons interact with matter primarily through three mechanisms, depending on their energy: the photoelectric effect, Compton scattering, and pair production.
- Photoelectric effect: A low-energy gamma photon is absorbed by an atom, causing the ejection of an inner-shell electron. The photonās energy is transferred entirely to the electron, minus the electronās binding energy. This effect dominates at low photon energies and in high-Z materials. The cross-section roughly scales as $\frac{Z^n}{E^3}$ where Z is the atomic number and E is the photon energy.
- Compton scattering: At intermediate energies, gamma photons interact with loosely bound electrons, scattering off them and losing part of their energy. The energy of the scattered photon $Eā$ is described by the Compton equation, where $E$ is the incident photon energy, $\theta$ is the scattering angle, and $m_e c^2 \approx 511 keV$ is the electron rest mass energy.
[
\begin{aligned}
E' &= \frac{E}{1 + \frac{E}{m_e c^2} (1 - \cos(\theta))}
\end{aligned}
]
- Pair production: At high photon energies (above 1.022 MeV), a gamma ray can convert into an electron-positron pair in the vicinity of a nucleus. The excess energy is distributed as kinetic energy among the two particles. This process becomes more significant at higher gamma energies and higher-Z materials.
For charged particles like electrons, protons or positrons on the other side the energy loss in matter is governed by the Bethe-Bloch equation, which describes how much energy they lose per unit distance through ionization:
[
\begin{aligned}
-\frac{dE}{dx} &= \frac{4 \pi n z^2}{m_e c^2 \beta^2} \left(\frac{e^2}{4 \pi \epsilon_0}\right)^2 \left(\ln\left(\frac{2 m_e c^2 \beta^2}{I(1-\beta^2)}\right) - \beta^2\right)
\end{aligned}
]
- $\beta = \frac{v}{c}$ is the velocity factor
- $v$ is the velocity of the particle, $c$ the speed of light
- $E$ the energy of the particle
- $x$ is the path length over which the energy is deposited
- $z$ is the charge number of the particle so the charge is $q = z * e$
- $\epsilon_0$ is the electric field constant
- $e$ is the electric charge, $m_e$ the mass of the electron
- $n$ is the electron density of the target material where $n = \frac{Z \rho}{A u}$ with $Z$ and $A$ being charge and mass number of the atom in the periodic system and $u$ the atomic mass number as well as $\rho$ being the density of the material
For a gamma spectrometer the effects that are relevant are the Photoelectric effect and Compton Scattering. The emitted light is then collected by a photodetector, usually a silicon photomultiplier (SiPM) or photodiode, and converted into an electrical pulse. The pulse height (amplitude) is proportional to the energy of the incident gamma photon. By digitizing and sorting these pulses into a histogram of counts versus pulse amplitude, the spectrometer reconstructs a gamma energy spectrum.
The energy resolution of such a detector - the ability to distinguish closely spaced spectral lines - is limited by several physical and electronic factors:
- Statistical fluctuations in the number of scintillation photons produced per event.
- Non-uniform light collection due to imperfections in optical coupling between the crystal and the photodetector.
- Electronic noise from the readout circuitry, especially in compact, battery-powered devices.
- Intrinsic properties of CsI(Tl), such as its relatively long decay time and modest light yield compared to other scintillators like $LaBr_3$.
In practice, CsI(Tl) is chosen for its robustness, low cost, and non-hygroscopic behavior, even though its resolution is inferior to high-end materials. A typical CsI(Tl)-based detector like the RadiaCode 102 achieves energy resolutions around 7ā10% FWHM at the 662 keV line of Cesium-137.
There actualls exists a Geant4 digital twin model on GitHub for the crystal used in the Radiacode devices.
This method enables the identification of specific isotopes based on their characteristic gamma emission energies, giving spectrometers an advantage over simpler detectors like Geiger counters. Other detectors that are actually capable of doing spatial and energy resolved detection of particles would be semiconductor particle detector like the ones used during my diploma thesis.
The Versatility of the Radiacode 102: Mapping and Fixed Analysis
The Radiacode 102 excels in two very different use cases:
- Mobile Mapping: Paired via Bluetooth with a smartphone app (available for Android and iOS), it can record GPS-tagged radiation data while youāre on the move. This is perfect for scanning terrain, checking building materials, or surveying historical sites with known contamination. You can also carry the device with you all the time and passively search for contaminated sites while hiking or exploring. Keep in mind that small radioactive sources actually require pretty long integration times on the scale of hours so you will only spot larger or spread out contaminations.
- Stationary Measurement: The device can also be used as a static detector to measure sources over time. The internal spectrum accumulation allows detection of weak sources with long integration times. This makes it suitable for indoor lab use or monitoring fixed installations.
Note that of course the mobile use case is very limited to more active radiating samples since one needs to perform proper background compensation and long term integration for low activity samples.
Mobile Connectivity: Bluetooth and Android/iOS App
One of the key strengths of the Radiacode 102 is its Bluetooth connectivity. In addition, the device fits every pocketāand is usually delivered with a bag for runners and bikers. The Android app allows you to view radiation levels in real-time, access the spectral data, and even visualize radiation maps by combining GPS data with the measured gamma spectrum. It takes a while to get used to the app though since it exposes about every feature simply accessible - one has to play for a few days to really get all features.
Hereās an example screenshot of the mapping mode, showing a survey route with overlaid dose rates and spectral features.

Real World Examples
To demonstrate its capabilities, here are a few spectrum images acquired from common sources. Note that this section will (hopefully) grow over time as I get access to and enough integration time with different samples (for obvious reasons dangerous resources cannot be measured at home or at an arbitrary location).
Potassium-40
The first experiment was to gather data using the Android App and measure Potassium-40 decay.This is actually a background measurement - Potassium-40 offers a single 1460.8 keV gamma photon peak. Since potassium was created during the creation of the early solar system and exists in soil, concrete, bricks, humans and somewhat enriched in bananas with a $\tau_{\frac{1}{2}} \approx 1.248 * 10^{9}$ years it offers a very prominent decay line to check functionality of the gamma spectrometer since one expects it to be present.

Even after short integration time of around 20 hours one can easily spot the K-40 line in the above screenshot of the Android Application.
Thorium-232
The second example is Thorium-232 in a 2% doped WIG welding rod. The following graphics shows a 1 week integration without smoothing and no background subtraction. The overlay shows the location of the peaks of the Thorium-232 decay chain which are clearly visible in the spectrum.

Using Python to Analyze Spectra via USB
Beyond the mobile app, the Radiacode 102 can also be remotely controlled using a Python library. This works reliably via USB, and on supported operating systems even wirelessly via Bluetooth LE, enabling flexible integration into mobile or automated platforms. This opens up the possibility for programmatic control and data analysis. An open-source Python library allows access to raw spectral data, real-time measurements, and even configuration of the device.
The library is available via PyPi and can simply be installed via
Itās source code is available on GitHub.
After attaching the device to the USB port it should be recognized as USB device with vendor ID 0x0483 and product ID 0xF123. Unfortunately all RadiaCode devices have like many cheaper devices the same serial number for all devices - itās not simply possible to distinguish multiple attached spectrometers and assign unique symlinks for them. The following shows the dump of the USB descriptors by usbconfig:
ugen5.2: <RadiaCode RadiaCode-102> at usbus5, cfg=0 md=HOST spd=FULL (12Mbps) pwr=ON (400mA)
bLength = 0x0012
bDescriptorType = 0x0001
bcdUSB = 0x0201
bDeviceClass = 0x0000 <Probed by interface class>
bDeviceSubClass = 0x0000
bDeviceProtocol = 0x0000
bMaxPacketSize0 = 0x0040
idVendor = 0x0483
idProduct = 0xf123
bcdDevice = 0x0200
iManufacturer = 0x0001 <RadiaCode>
iProduct = 0x0002 <RadiaCode-102>
iSerialNumber = 0x0003 <RC-102-009455>
bNumConfigurations = 0x0001
Configuration index 0
bLength = 0x0009
bDescriptorType = 0x0002
wTotalLength = 0x0020
bNumInterfaces = 0x0001
bConfigurationValue = 0x0001
iConfiguration = 0x0004 <Custom Config>
bmAttributes = 0x00c0
bMaxPower = 0x00c8
Interface 0
bLength = 0x0009
bDescriptorType = 0x0004
bInterfaceNumber = 0x0000
bAlternateSetting = 0x0000
bNumEndpoints = 0x0002
bInterfaceClass = 0x00ff <Vendor specific>
bInterfaceSubClass = 0x00ff
bInterfaceProtocol = 0x00ff
iInterface = 0x0005 <Custom Interface>
Endpoint 0
bLength = 0x0007
bDescriptorType = 0x0005
bEndpointAddress = 0x0081 <IN>
bmAttributes = 0x0002 <BULK>
wMaxPacketSize = 0x0040
bInterval = 0x0000
bRefresh = 0x0000
bSynchAddress = 0x0000
Endpoint 1
bLength = 0x0007
bDescriptorType = 0x0005
bEndpointAddress = 0x0001 <OUT>
bmAttributes = 0x0002 <BULK>
wMaxPacketSize = 0x0040
bInterval = 0x0000
bRefresh = 0x0000
bSynchAddress = 0x0000
On FreeBSD one can use devd to assign proper permissions to all radiacode devices though as usual via a custom devd rule in /usr/local/etc/devd/radiacode.conf after creating a new group and adding your user to it:
notify 1000 {
match "system" "USB";
match "subsystem" "INTERFACE";
match "type" "ATTACH";
match "vendor" "0x0483";
match "product" "0xf123";
action "chgrp radiacode /dev/$cdev && chgrp -h radiacode /dev/$cdev";
};
To crete the group and add a user to it on FreeBSD:
sudo pw groupadd radiacode
sudo pw usermod ${USER} -G radiacode
The first thing to try is of course to dump the spectrum. Here is a simple snippet showing how to do this and display it as a matplotlib plot:
from radiacode import RadiaCode
import matplotlib.pyplot as plt
# Connect to device using USB connection
device = RadiaCode()
# Fetch current spectrum from the device
spectrum = device.spectrum()
# Plot using matplotlib
fig, ax = plt.subplots()
ax.plot(spectrum.counts)
ax.set_title(f"Gamma spectrum ({spectrum.duration})")
ax.set_xlabel("Channel")
ax.set_ylabel("Counts")
ax.grid()
plt.show()
The example script should fetch the current spectrum from the device:

By switching the scale to logarithmic one can get more insight about the peaks:

This capability enables long-term monitoring, automated isotope identification, and integration with other systems or research software. It also allows simple integration of the Radiacode into mobile platforms like drones or robots.
Drawbacks
While the Radiacode 102 does feature a built-in display capable of showing basic dose rate information and local alarms, its standalone usability is limited. Although it logs data even without a smartphone connection - except GPS position - and includes a rudimentary spectrum view, meaningful use truly begins when paired with a mobile or desktop application for full-spectrum analysis and interpretation. In addition the use of background subtraction in the Android application at time of writing this blog article is pretty limited since it lacks normalization from counts to dose rates.
A noteworthy issue is the lack of any authentication mechanism for the Bluetooth interface. This means that, in principle, any nearby device with the Radiacode app could connect to your spectrometer without prior pairing or permission, which may raise privacy or data integrity concerns in shared or public environments.
Another practical limitation arises not from the spectrometer itself but from the Android ecosystem. On some devices, particularly older or budget models, aggressive power management can terminate the appāeven when explicitly excluded from optimization. Situations such as running out of memory during photography or phone calls may also cause the app to be killed, interrupting data acquisition unexpectedly.
Conclusion
The Radiacode 102 is an exceptional tool for anyone interested in radiation science, environmental monitoring, or amateur radioactivity exploration. Its combination of spectral detail, portability, Bluetooth connectivity, and open USB interface makes it one of the most versatile and user-friendly gamma spectrometers in its class.
In future posts, I might dive deeper into automatic isotope identification or custom logging and mapping software. But for now, this device is already an impressive bridge between citizen science and professional-grade instrumentation.
References
This article is tagged: