#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
// WiFi credentials
const char* ssid = "SSID";
const char* password = "PASS";
// Prometheus Pushgateway
const char* pushgatewayHost = "https://pushgateway.example.com/metrics/job/voltage_monitor/instance/node-8266/sensor/voltage";
// Voltage divider resistors
const float R1 = 29000.0;
const float R2 = 7500.0;
// ADC config
const float ADC_RESOLUTION = 1023.0;
const float REF_VOLTAGE = 3.3; // Adjust depending on your board
float previousVoltage = -1.0;
void setup() {
Serial.begin(115200);
delay(1000);
WiFi.begin(ssid, password);
Serial.print("Connecting to WiFi");
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("\nConnected!");
}
void loop() {
float voltage = readVoltage();
if (abs(voltage - previousVoltage) > 0.01) { // send only if change > 10 mV
sendToPrometheus(voltage);
previousVoltage = voltage;
} else {
Serial.println("
Voltage unchanged. Skipping Pushgateway update.");
}
delay(20000); // Send every 20 seconds
}
float readVoltage() {
int adcValue = analogRead(A0);
float vOut = (adcValue / ADC_RESOLUTION) * REF_VOLTAGE;
float vIn = vOut * ((R1 + R2) / R2);
Serial.print("Measured Voltage: ");
Serial.println(vIn, 3);
return vIn;
}
void sendToPrometheus(float voltage) {
if (WiFi.status() != WL_CONNECTED) {
Serial.println("WiFi not connected!");
return;
}
//WiFiClient client; // for http
//HTTPClient http;
WiFiClientSecure client;
client.setInsecure();
HTTPClient http;
String metrics = "voltage_sensor " + String(voltage, 3) + "\n";
String url = String(pushgatewayHost) ;
// Encode Basic Auth manually
String base64Credentials = "Base64encoded Creds";
String authHeader = "Basic " + base64Credentials;
http.begin(client, url);
http.addHeader("Content-Type", "text/plain");
http.addHeader("Authorization", authHeader);
int httpCode = http.POST(metrics);
if (httpCode > 0) {
Serial.printf("Pushgateway Response: %d\n", httpCode);
} else {
Serial.printf("Failed to send data: %s\n", http.errorToString(httpCode).c_str());
}
http.end();
}
Author: Alok
DevSecOps
Voltage Sensor – with pico w 2
- R1 – 7.5K
R2 – 30K
from machine import ADC
from time import sleep
# Use ADC0 (GPIO26)
adc = ADC(26)
# Constants
VREF = 3.3 # Pico ADC reference voltage
ADC_RESOLUTION = 65535 # For read_u16() scale
DIVIDER_RATIO = 5 # Because 7.5k / (30k + 7.5k) = 0.2 → inverse is 5
def read_input_voltage():
raw = adc.read_u16()
v_out = (raw / ADC_RESOLUTION) * VREF
v_in = v_out * DIVIDER_RATIO
return round(v_in, 3)
# Main loop
while True:
voltage = read_input_voltage()
print("Measured Voltage:", voltage, "V")
sleep(1)
Since the Pico ADC max is 3.3V and you’re dividing by 5: Vin max=3.3V×5=16.5VV = 3.3V \times 5 = 16.5V
Vin max=3.3V×5=16.5V
So you can safely measure up to about 16.5 volts.
Pico 2 w – HC-SR04 ultrasonic distance sensor
Pins:
from machine import Pin, time_pulse_us
from time import sleep
# Define GPIO pins
TRIG = Pin(3, Pin.OUT)
ECHO = Pin(2, Pin.IN)
def get_distance():
# Ensure trigger is low
TRIG.low()
sleep(0.002) # Let sensor settle
# Send a 10µs pulse to trigger
TRIG.high()
sleep(0.00001)
TRIG.low()
# Measure time for echo
try:
duration = time_pulse_us(ECHO, 1, 30000) # 30ms timeout
except OSError as ex:
print("Pulse timed out")
return None
# Distance calculation: time (us) × speed of sound (cm/us) / 2
distance_cm = (duration * 0.0343) / 2
return round(distance_cm, 2)
# Main loop
while True:
dist = get_distance()
if dist:
print("Distance:", dist, "cm")
else:
print("No distance measured.")
sleep(1)

Pi Pico 2 W – UF2 flash – install
- While connect to your PC first press the BOOTSEL cutton on the pico 2 w and then connect the USB
- It will be connected as new drive(FS mode). you can view in “files”
- Drop the UF2 file(https://www.raspberrypi.com/documentation/microcontrollers/micropython.html) for pico 2 w from your PC to this FS
- It will automatically reboot
- And you will be able to see the Thonny editor

Pico W with MQ-135 air quality sensor – Prometheus pushgateway
If you want to make portable Air quality sensor this is very easy setup. Make sure to include you mobile hostspot wifi ssid so that you can easily collect data from anywhere on the go.
Gas sensor normal takes 2-3 min to normalized it’s output vaules.
- Pins
VCC = 3v3(OUT) - GP36
GND = GND -GP38
Input = ADC0 - GP26
- Code
import network
import urequests
import machine
import time
import ubinascii
#only needed if sending over public ip with https.
USERNAME_P = "basic-auth-username"
PASSWORD_P = 'basic-auth-pass'
# WiFi Credentials
SSID = 'WIFI-SSID'
PASSWORD = 'WIFI-PASSWORD'
# PushGateway Configuration
PUSHGATEWAY_URL = 'https://pushgateway.example.com/metrics/job/gas_sensor/instance/pico-1/sensor/mq135'
# ADC Setup for MQ-135 on GP26 (ADC0)
adc = machine.ADC(26)
def connect_wifi():
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
if not wlan.isconnected():
print('Connecting to WiFi...')
wlan.connect(SSID, PASSWORD)
while not wlan.isconnected():
time.sleep(0.5)
print('Connected, IP:', wlan.ifconfig()[0])
def read_gas_sensor():
raw_value = adc.read_u16() # 0–65535
voltage = raw_value * 3.3 / 65535 # Convert to voltage if needed
return raw_value, voltage
def send_to_pushgateway(value):
# Prometheus format (you can include labels if you want)
payload = f"gas_sensor_value {value}\n"
auth_string = "{}:{}".format(USERNAME_P, PASSWORD_P)
auth_encoded = ubinascii.b2a_base64(auth_string.encode()).decode().strip()
headers = {
"Content-Type": "text/plain",
"Authorization": "Basic " + auth_encoded
}
try:
res = urequests.post(PUSHGATEWAY_URL, data=payload, headers=headers, timeout=5)
print("Pushed to gateway:", res.status_code)
res.close()
except Exception as e:
print("Push failed:", e)
def main():
connect_wifi()
while True:
raw, voltage = read_gas_sensor()
print(f"Gas Sensor Raw: {raw} | Voltage: {voltage:.3f}V")
send_to_pushgateway(raw)
time.sleep(1) # Push every 10 seconds
main()
- timeout=5 is to fix the error code -110, [Errno 110] , ETIMEDOUT, [Errno 115] EINPROGRESS


- Read data from pico over USB tty
#find device
dmesg | grep tty
$ read X < /dev/ttyACM0
hello
$ echo $X
Gas Sensor Raw: 2496 | Voltage: 0.126V
- Read using screen command
screen /dev/ttyACM0
#with Baud rate
screen /dev/ttyACM0 9600
check LAN max speed- iperf3
apt install iperf3
#on server 192.168.0.10
iperf -s
#on client
iperf -c 192.168.0.10
root@lp-arm-3:~# iperf3 -c 192.168.0.10
Connecting to host 192.168.0.10, port 5201
[ 5] local 192.168.0. port 50976 connected to 192.168.0.10
port 5201
[ ID] Interval Transfer Bitrate Retr Cwnd
[ 5] 0.00-1.00 sec 11.4 MBytes 95.6 Mbits/sec 248 48.1 KBytes
[ 5] 1.00-2.00 sec 10.9 MBytes 91.2 Mbits/sec 260 38.2 KBytes
[ 5] 2.00-3.00 sec 10.9 MBytes 91.7 Mbits/sec 251 38.2 KBytes
[ 5] 3.00-4.00 sec 11.2 MBytes 93.8 Mbits/sec 245 48.1 KBytes
[ 5] 4.00-5.00 sec 10.8 MBytes 90.7 Mbits/sec 277 36.8 KBytes
[ 5] 5.00-6.00 sec 11.3 MBytes 94.9 Mbits/sec 247 38.2 KBytes
[ 5] 6.00-7.00 sec 11.1 MBytes 92.8 Mbits/sec 231 52.3 KBytes
[ 5] 7.00-8.00 sec 10.9 MBytes 91.7 Mbits/sec 260 46.7 KBytes
[ 5] 8.00-9.00 sec 10.8 MBytes 90.7 Mbits/sec 241 50.9 KBytes
[ 5] 9.00-10.00 sec 10.9 MBytes 91.7 Mbits/sec 245 46.7 KBytes
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval Transfer Bitrate Retr
[ 5] 0.00-10.00 sec 110 MBytes 92.5 Mbits/sec 2505 sender
[ 5] 0.00-10.05 sec 110 MBytes 91.9 Mbits/sec receiver
iperf Done.
Ref- https://www.jeffgeerling.com/blog/2025/exploring-wifi-7-2-gbps-on-raspberry-pi-5
Adafruit_DHT22 python3 issue fixed – RuntimeError: Unknown platform
git clone https://github.com/adafruit/Adafruit_Python_DHT.git
cd Adafruit_Python_DHT
if [ $(cat /proc/cpuinfo | grep Hardware | wc -l) != "1" ] ; then
cat /proc/cpuinfo > /etc/cpuinfo
echo -e "\nHardware : BCM2709" >> /etc/cpuinfo
mount --bind /etc/cpuinfo /proc/cpuinfo
echo "Mounted cpuinfo with Hardware info"
fi
python3 setup.py install
Ubuntu – Linux thermal / temperature sensor
#!/bin/bash
cpu=$(</sys/class/thermal/thermal_zone6/temp)
cpu_temp=$(echo "$cpu/1000" | /usr/bin/bc -l)
echo "CPU_temp $cpu_temp"
root@lp-knode-2:~# cat /sys/class/thermal/thermal_zone*/type
INT3400 Thermal
SEN1
SEN2
SEN3
SEN4
SEN5
pch_cannonlake
B0D4
iwlwifi_1
x86_pkg_temp
root@lp-knode-2:~# cat /sys/class/thermal/thermal_zone*/temp
20000
41050
47050
41050
45050
50
54000
46050
48000
46000
https://askubuntu.com/questions/1110943/what-do-the-different-thermal-zones-actually-correspond-to
Ubuntu desktop sharing
grdctl status
grdctl rdp enable
grdctl rdp set-credentials username pass
grdctl --system status --show-credentials
#connect
rdesktop -u USERNAME -p PASS 192.168.0.210
wake on lan – wol – ubutnu
https://help.ubuntu.com/community/WakeOnLan
apt install ethtool
ethtool eth
root@home:/home# ethtool enp3s0
Settings for enp3s0:
Supported ports: [ TP MII ]
Supported link modes: 10baseT/Half 10baseT/Full
100baseT/Half 100baseT/Full
1000baseT/Full
Supported pause frame use: Symmetric Receive-only
Supports auto-negotiation: Yes
Supported FEC modes: Not reported
Advertised link modes: 10baseT/Half 10baseT/Full
100baseT/Half 100baseT/Full
1000baseT/Full
Advertised pause frame use: Symmetric Receive-only
Advertised auto-negotiation: Yes
Advertised FEC modes: Not reported
Speed: Unknown!
Duplex: Unknown! (255)
Auto-negotiation: on
master-slave cfg: preferred slave
master-slave status: unknown
Port: Twisted Pair
PHYAD: 0
Transceiver: external
MDI-X: Unknown
Supports Wake-on: pumbg
Wake-on: g
Link detected: no
wol p|u|m|b|a|g|s|d...
Sets Wake-on-LAN options. Not all devices support this.
The argument to this option is a string of characters speci‐
fying which options to enable.
p Wake on PHY activity
u Wake on unicast messages
m Wake on multicast messages
b Wake on broadcast messages
a Wake on ARP
g Wake on MagicPacket™
s Enable SecureOn™ password for MagicPacket™
d Disable (wake on nothing). This option
clears all previous options.
wake command
apt install etherwake
etherwake MAC-ADDRESS