Example: Cellular Telemetry with Raspberry Pi
This walkthrough demonstrates a complete end-to-end example using the M-Hat: the Raspberry Pi reads its own CPU temperature using a built-in Linux interface and publishes it to the Particle Cloud over cellular every 60 seconds. No additional hardware is required beyond the M-Hat kit.
What You'll Need
- Raspberry Pi 4 or 5 with Raspberry Pi OS Bookworm installed
- M-Hat with B504e or B524 SoM, set up per the Install and Setup Guide
- Tethering active (
ppp0interface up and running)
Part 1: Verify Tethering is Active
If you have not already done so, follow the Install and Setup Guide to flash the tethering firmware and bring up the ppp0 interface. Once ppp0 is active, the Pi has cellular internet access and can reach the Particle Cloud.
Tethering has been tested and validated on the B504e and B524. Tethering support for M-Series SoMs is coming soon.
Part 2: Read the CPU Temperature
The Raspberry Pi exposes its CPU temperature through the Linux kernel at a standard path - no library or external sensor required:
# Read CPU temperature (returns value in millidegrees Celsius)
cat /sys/class/thermal/thermal_zone0/temp
A reading of 52000 means 52.0°C. In Python:
def read_cpu_temp():
with open("/sys/class/thermal/thermal_zone0/temp", "r") as f:
temp_mc = int(f.read().strip())
return round(temp_mc / 1000.0, 1)
print(f"CPU temperature: {read_cpu_temp()}°C")
This works on all Raspberry Pi 3, 4, and 5 models with no additional setup.
Part 3: Publish to the Particle Cloud
Once ppp0 is up, the Raspberry Pi can reach the Particle Cloud using the Particle REST API over cellular. No Particle SDK is required on the Linux side.
Install the requests library:
sudo apt install -y python3-requests
Create a file named publish_temp.py:
import requests
import time
DEVICE_ID = "<your-device-id>"
ACCESS_TOKEN = "<your-access-token>"
def read_cpu_temp():
with open("/sys/class/thermal/thermal_zone0/temp", "r") as f:
temp_mc = int(f.read().strip())
return round(temp_mc / 1000.0, 1)
def publish_event(event_name, data):
url = "https://api.particle.io/v1/devices/events"
headers = {"Authorization": f"Bearer {ACCESS_TOKEN}"}
payload = {"name": event_name, "data": str(data)}
response = requests.post(url, headers=headers, data=payload)
return response.status_code
while True:
temp = read_cpu_temp()
status = publish_event("cpu_temperature", temp)
print(f"Published {temp}°C - HTTP {status}")
time.sleep(60)
Run it:
python3 publish_temp.py
Replace <your-device-id> and <your-access-token> with your values from console.particle.io. Your access token is available under User Settings - Access Tokens.
Part 4: Verify in the Particle Console
Navigate to console.particle.io, find your device, and open the Events tab. You should see cpu_temperature events arriving every 60 seconds.
Going Further
Run as a background service:
sudo nano /etc/systemd/system/particle-temp.service
[Unit]
Description=Particle CPU Temperature Publisher
After=network.target
[Service]
ExecStart=/usr/bin/python3 /home/pi/publish_temp.py
Restart=always
User=pi
[Install]
WantedBy=multi-user.target
sudo systemctl enable particle-temp
sudo systemctl start particle-temp
Off-grid deployment: Add a solar panel connected to the DC IN screw terminals (5-12V) and rely on the included LiPo battery as a buffer.
Ultra-low power operation: Use the SoM's power control (D8) to cut power to the Pi between readings:
void powerDownPi() {
pinMode(D8, OUTPUT);
digitalWrite(D8, LOW);
System.sleep(D8, RISING, 60s);
digitalWrite(D8, HIGH);
}
PoE-powered fixed installation: Stack a PoE HAT below the M-Hat and set the HAT power jumper to 5V_IN.
Webhook integration: Set up a Particle Webhook in the console to forward cpu_temperature events to an external service. See Integrations for details.