Raspberry Pi Pico Ionising Radiation Sensor
I'm recording CO2 levels, motion, temperature, humidity and atmospheric pressure, so what's left to detect? Ambient ionising radiation, of course! ☢️ As with the other Raspberry Pi Pico sensors, this one will report back to Home Assistant to allow plotting the radiation over time in μSv/h (microsieverts per hour).
To contextualise this value, the EU has a radiological map which includes the UK. At the time of writing, the monitoring station closest to me was reporting an average of around 110 nSv/h (nanosieverts per hour). My measurement above shows 150 nSv/h, which is slightly above this value. This discrepancy is probably due to the sensor not being calibrated.
⚠️ This project is for hobby use only, it is not accurate enough for safety applications ☢️
Components
I'm using the Gravity Geiger Counter Module, which includes the M4011 Geiger Tube. The approach to measuring in this post should work for any tube though; after all the code just needs to measure pulses on a GPIO pin. The M4011 tube is compared against similar tubes here, which discusses its sensitivity to direct sunlight (also noted on the product documentation). I'm also using a Raspberry Pi Pico W with MicroPython to process the data and respond to pulses from the geiger tube.
Code
The code needs to do a few things:
- Process clicks as they're coming in from the Geiger tube
- Sample the clicks every so often, and convert them to a μSv/h value
- Report this value to Home Assistant
Processing Clicks via GPIO
from machine import Pin
clicks = 0
pin = Pin(0, Pin.IN)
def click(pin):
clicks += 1
pin.irq(trigger=Pin.IRQ_RISING, handler=click, hard=True)
The above code uses a hardware interrupt on GPIO pin 0 to increment the clicks
variable, in response to a pulse from the geiger tube. See Writing interrupt handlers for more information about hardware interrupts and the limitations of them.
Sampling Microsieverts
I created geiger.py to wrap the above logic, and deal with the sampling of the clicks on a regular basis. To use the code, see the below example:
import utime
from machine import Pin
from geiger import Geiger
pin = Pin(0, Pin.IN)
geiger = Geiger(153.8, pin, Pin.IRQ_RISING, 60_000)
while True:
geiger.update()
if geiger.datapoint.get_needs_update():
print(geiger.datapoint.get_value(), "μSv/h")
geiger.datapoint.set_value_updated()
utime.sleep(1)
This code will print the μSv/h value every 60_000 milliseconds. You can increase or decrease this value depending on how frequently you want to sample the clicks (but less frequent samples mean more variability).
Reporting Results to Home Assistant
For the previous sensor projects, I created hass.py which wraps the POST /api/states/<entity_id> API. Putting it all together, the logic looks like this:
import utime
from machine import Pin
from geiger import Geiger
from hass import Hass
pin = Pin(0, Pin.IN)
geiger = Geiger(153.8, pin, Pin.IRQ_RISING, 60_000)
hass = Hass("http://assistant.home", "ey....")
while True:
geiger.update()
if geiger.datapoint.get_needs_update():
hass.send_update(geiger.datapoint.get_value(), "μSv/h", None, "Radiation Sensor", "sensor.radiation")
geiger.datapoint.set_value_updated()
utime.sleep(1)
This logic is available in the main.py code, which includes configurable support for all of the other sensors, and WiFi connection handling.
🏷️ code value geiger tube sensor clicks sample raspberry pi pico radiation assistant μsv gpio logic
Please click here to load comments.