Node 8266 EPS – voltage sensor – pushgateway

#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();
}

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”

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