Category Archives: Computer

Wireless ping tester with beeps using Wemos

While I’ve used a Laptop with a ping script I made in the past, I needed something more portable.

So I build:

  • Scan for wifi networks
  • Connect
  • Enter IP to ping
  • Buzzer beeps when ICMP packet received
  • Gateway not reachable ? Sound alarm note

This way I can use both hands, hanging upside-down in a hard-to-reach place, without turning my head to a screen or my phone.

CODE (Below code is for D6)

#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include <WiFiManager.h>
#include <ESP8266Ping.h>

ESP8266WebServer server(80);
String pingHost = "";
bool startPinging = false;
unsigned long lastPingTime = 0;
bool gpioState = false;

void setup() {
  Serial.begin(115200);
  pinMode(D6, OUTPUT);  

  // WiFiManager captive portal
  WiFiManager wm;
  if (!wm.autoConnect("ESP_SetupAP")) {
    Serial.println("Failed to connect, restarting...");
    ESP.restart();
  }

  Serial.println("WiFi connected. IP:");
  Serial.println(WiFi.localIP());

  // Web UI
  server.on("/", HTTP_GET, []() {
    String html = "<html><body><h2>ESP Continuous Ping</h2>"
                  "<form action='/start'>"
                  "Host/IP to ping: <input name='host' type='text'>"
                  "<input type='submit' value='Start Pinging'>"
                  "</form></body></html>";
    server.send(200, "text/html", html);
  });

  server.on("/start", HTTP_GET, []() {
    if (!server.hasArg("host")) {
      server.send(400, "text/plain", "Missing 'host' parameter.");
      return;
    }
    pingHost = server.arg("host");
    startPinging = true;
    server.send(200, "text/plain", "Started pinging " + pingHost);
  });

  server.begin();
}

void loop() {
  server.handleClient();

  if (startPinging && millis() - lastPingTime > 2000) {
    lastPingTime = millis();
    bool success = Ping.ping(pingHost.c_str(), 1);

    if (success) {
      gpioState = !gpioState;
      digitalWrite(D6, HIGH);
      delay(500);
      digitalWrite(D6, LOW);
      delay(500);
      Serial.println("Ping success, toggled D6.");
    } else {
      Serial.println("Ping failed.");
      digitalWrite(D6, LOW);
    }
  }
}

Further ideas

D2 pin because easier soldering

New project : Find nearest booze shop.

Or anything else. ( idea from a reddit post )

UPDATE: 20250523

Combining a GPS module, compass, a LED ring and some code, I want to make a little device which shows you the way to the nearest … something.

To make it completely standalone, I have to use a SIM module. (Same as I have used before) This POC will use my phone as hotspot.

The LED ring will show the direction to go.

Edit: Maybe not a LED ring but a little display.

As previously posted, I was playing with Overpass turbo.
Using an API, I can use code to query this.

  • Arduino sends latitude, longitude to my webserver
  • Webserver queries API for neastest POIs and calculates distance.
  • Send data from webserver to arduino
  • Arduino uses heading data to light up direction LED
    (also on secondary display with distance info?)
    edit: and shop info

Test code for my web server to query the data

import overpy
import math

api = overpy.Overpass()

# This location will be filled with data from GPS module on Arduino.
latitude = 52.2270745        # Center latitude (e.g. Berlin)
longitude = 5.177519      # Center longitude
box_size = 0.05         # Box size in degrees (about ~5 km)

south = latitude - box_size
north = latitude + box_size
west = longitude - box_size
east = longitude + box_size

def haversine(lat1, lon1, lat2, lon2):
    R = 6371  # Earth radius in km
    phi1 = math.radians(lat1)
    phi2 = math.radians(lat2)
    d_phi = math.radians(lat2 - lat1)
    d_lambda = math.radians(lon2 - lon1)

    a = math.sin(d_phi / 2)**2 + math.cos(phi1) * math.cos(phi2) * math.sin(d_lambda / 2)**2
    c = 2 * math.atan2(math.sqrt(a), math.sqrt(1 - a))

    return R * c  # Distance in kilometers

# Calculate bearing in degrees (0-360)
def bearing(lat1, lon1, lat2, lon2):
    phi1 = math.radians(lat1)
    phi2 = math.radians(lat2)
    delta_lon = math.radians(lon2 - lon1)

    x = math.sin(delta_lon) * math.cos(phi2)
    y = math.cos(phi1) * math.sin(phi2) - math.sin(phi1) * math.cos(phi2) * math.cos(delta_lon)

    initial_bearing = math.atan2(x, y)
    compass_bearing = (math.degrees(initial_bearing) + 360) % 360  # Normalize to 0–360

    return compass_bearing

# Overpass QL query
query = f"""
[out:json];
node
  ["shop"="alcohol"]
  ({south}, {west}, {north}, {east});
out body;
>;
out skel qt;
"""

try:
    result = api.query(query)

    # Collect and sort places by distance
    places = []
    for node in result.nodes:
        node_lat = float(node.lat)
        node_lon = float(node.lon)
        distance = haversine(latitude, longitude, node_lat, node_lon)
        direction = bearing(latitude, longitude, node_lat, node_lon)
        name = node.tags.get("name", "Unnamed")
        places.append((distance, direction, name, node_lat, node_lon))

    places.sort()

    print(f"Found {len(places)} alcohol-related places sorted by distance:")
    for dist, dir_deg, name, lat, lon in places:
        print(f"- {name} at ({lat:.5f}, {lon:.5f}) — {dist:.2f} km, {dir_deg:.0f}°")

except Exception as e:
    print(f"Error: {e}")

Output:

Found 10 alcohol-related places sorted by distance:
- The Skiff at (52.22583, 5.17860) — 0.16 km, 152°
- Onzewijnen at (52.22612, 5.17045) — 0.49 km, 258°
- Gall & Gall at (52.23244, 5.19204) — 1.15 km, 59°
- Gall & Gall at (52.21536, 5.16735) — 1.48 km, 208°
- Eric's Beer Craft at (52.21549, 5.16632) — 1.50 km, 211°
- Slijterij at (52.21082, 5.15692) — 2.29 km, 218°
- Gall & Gall at (52.21590, 5.14074) — 2.80 km, 244°
- Gall & Gall at (52.25422, 5.22705) — 4.53 km, 48°
- Gall & Gall at (52.26808, 5.18348) — 4.58 km, 5°
- Il DiVino at (52.27507, 5.16414) — 5.41 km, 350°

Example using Overpass Turbo to find breweries

Other ideas

  • Geocaching (Thanks Vincent)
  • Find each other at festivals?

UPDATE

Building the hardware : First design

Screen programming (First setup)

Some test code

#include "SPI.h"
#include "Adafruit_GFX.h"
#include "Adafruit_GC9A01A.h"

// Overrule stuff
#define TFT_CS 18   // Chip select
#define TFT_DC 5    // Data/command mode
#define TFT_BL 4    // Backlight control
#define TFT_MOSI 12 // SPI Out AKA SDA
#define TFT_SCLK 13 // Clock out AKA SCL 
#define TFT_MISO -1 // pin not used
#define TFT_RST 23  // Reset ################# IMPORTANT, won't work without!! Took me a hour!

// Need this changed from example also
Adafruit_GC9A01A tft(TFT_CS, TFT_DC,TFT_MOSI,TFT_SCLK,TFT_RST,TFT_MISO);

float angle = 0;

void setup() {
  tft.begin();
  tft.setRotation(0);
  tft.fillScreen(GC9A01A_BLACK);
  drawCompassFace();
}

void loop() {
  drawNeedle(angle, GC9A01A_RED);
  delay(1000);
  drawNeedle(angle, GC9A01A_BLACK);  // Erase previous needle
  angle += 15;
  if (angle >= 360) angle = 0;

  tft.setCursor(60, 100);
  tft.setTextColor(GC9A01A_WHITE);  tft.setTextSize(2);
  tft.println("230 Meters");

}

// Draw static compass face
void drawCompassFace() {
  int cx = tft.width() / 2;
  int cy = tft.height() / 2;
  int radius = 100;

  tft.drawCircle(cx, cy, radius, GC9A01A_WHITE);
  tft.setTextColor(GC9A01A_WHITE);
  tft.setTextSize(1);
  tft.setCursor(cx - 3, cy - radius + 5); tft.print("N");
  tft.setCursor(cx - 3, cy + radius - 10); tft.print("S");
  tft.setCursor(cx - radius + 5, cy - 3); tft.print("W");
  tft.setCursor(cx + radius - 10, cy - 3); tft.print("E");
}

// Draw compass needle
void drawNeedle(float angleDeg, uint16_t color) {
  int cx = tft.width() / 2;
  int cy = tft.height() / 2;
  float angleRad = angleDeg * DEG_TO_RAD;
  int x = cx + cos(angleRad) * 90;
  int y = cy + sin(angleRad) * 90;
  tft.drawLine(cx, cy, x, y, color);
}

UPS Load in Home Assistant using Curl

Example is for a UPS, but other generic uses can be setup in same manner.

Create helper (1-100 unit %)

input_number.uspload

Create curl command in configuration.yaml

(Fix grep/cut accordantly )

shell_command:
    getups: curl -s  "http://x.x.x.x/cgi-bin/apcupsd/upsstats.cgi?host=127.0.0.1&img1=5&img2=6&img3=5&temp=C&refresh=30" | grep "UPS Load" | grep img  | cut -f4 -d= | cut -f1 -d. | head -1

    

Automation

alias: UPStest
description: ""
triggers:
  - trigger: time_pattern
    minutes: /5
conditions: []
actions:
  - action: shell_command.getups
    metadata: {}
    data: {}
    response_variable: upsload
  - action: input_number.set_value
    metadata: {}
    data:
      value: " {{ upsload['stdout'] }} "
    target:
      entity_id: input_number.uspload
mode: single

Found a rogue AP in my house

Where is it, what device could it be?

Its SSID started with ESP. So I probably am the one responsible for its existence.
I’ve got a sh*tload of ESPs/NodeMCUs/8266 turned on 24-7.

Using a Wifi analizer I could narrow it down to my livingroom.
Checked all devices, and they are all connected to my AccessPoint.
(So no fallback AP mode)

The problem with this method is that you can’t figure out a direction.

So I used this on my Laptop.

See graphs on the left

This is a directional antenna.

Using Wireshark and wavemon, I could find the direction.

There were only two devices in the direction with the strongest signal.
My photo viewer remote, and my mini turntable controller with RFID.

But these devices are working just fine! .. So lets disconnect the power.
So it IS the mini recordplayer!

Lets look at the code. (part of)

WiFi.mode(WIFI_AP_STA); 

I should have used

WiFi.mode(WIFI_STA); 

Now it was a client AND an Access Point!

Mystery solved!

Ben Eater Clock Module on steroids

My previous build of the clock module is as Ben designed. Wellll . Not really, I added some components to change the clock range.

Okay, Ben’s design is awesome. Not because of its technical design. No, you will learn to use the NE555 chip in three ways!
Variable freq, debounce with delay and a flip-flop like switch
I added another function to it. While making my version.
I added a 555 power-on reset pulse part.

I used a perm board (which is shorter than a regular breadboard)
And I moved some components over and added some LEDs/pin headers.
While doing so, I only used 3/4 of the board.

So I added a power-on reset part with a manual push-button. (Partly like the C64 power-on)
I also added the 1Mhz crystal.

Rest of the boards will use JST connectors for the bus-connections.

I am working on big motor controllers and 3D print modelling for clients.

Busy .. work and play

While working on my clients projects, I’ve been busy with other Fun stuff.

All will be posted more about soon

  • Designing 3D models for printing
  • Testing Arduino Code for RS485!
  • Creating T-shirt prints using 3D printing and bleach/paint with Vincent !
  • Transforming my Lab
  • Testing UM25C logging possibilities
  • Testing queries on overpass-turbo.eu (So much fun)
  • Playing chiptune music using Synthcart + Midi
  • Made V2 displayer on my 64×64 HUB75 led display
  • Bought a directional Wi-Fi antenna, tweaking wireshark to pinpoint rogue access points and clients.

New C64 Cartridges

New cartridges stuff.
I’ve bought some in the past, and was gifted some.

Made a case for an own made 8085 cartridge.
In this case, I used a gifted PCB from Bigred (thanks).
This was designed by Venneker.

With a gap for a 40 pins socket to piggyback signals.

https://media.henriaanstoot.nl/c64-cartridge-gap.tgz

Then a new Nordic Replay, this is a new version of the Retro Replay.

Today the TeensyRom, this came without case, so I printed one in fancy dual silk color.

Demos and hacks soon

March stuff, being busy

Working for clients, so fragmented personal stuff.
New workplace setup so even more space!

My BBQ monitor V3

As posted before, but now an esphome version, with big-ass buzzer

Code available soon, when made generic.

4Button controller using ESPHOME

Code allready posted

STL FILE https://media.henriaanstoot.nl/4buttons.stl

Flash trick for XYUSB

Flashing this to ESPHOME, use sowing pins!

CODE

substitutions:
  name: usb-relay
  friendly_name: "USB Relay"
  default_state: "RESTORE_DEFAULT_OFF"


esphome:
  name: xyusb1
  friendly_name: xyusb1

esp8266:
  board: esp01_1m

# Enable logging
logger:

# Enable Home Assistant API
api:
  encryption:
    key: "ndm8xxxxxxxxxxxxxxxxxjlvrggJv3a1BkY="

ota:
  - platform: esphome
    password: "12cc9xxxxxxxxxxxxxxxxfb6a01e672"

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "Xyusb1 Fallback Hotspot"
    password: "xxxxxxxxxxx"

captive_portal:

time:
  - platform: homeassistant

# Blue LED
status_led:
  pin:
    number: GPIO16

# Relay
switch:
  - platform: gpio
    id: switch_relay
    pin: GPIO5

  # Green LED
  - platform: gpio
    pin: GPIO14
    id: green_led
    inverted: true # start on

  # Switch template to link relay and green LED states
  # LED is on when relay is off
  - platform: template
    id: relay
    name: "${friendly_name}"
    lambda: |-
      if (id(switch_relay).state) {
        return true;
      } else {
        return false;
      }
    turn_on_action:
        - switch.turn_on:
            id: green_led
        - switch.turn_on:
            id: switch_relay
    turn_off_action:
        - switch.turn_off:
            id: green_led
        - switch.turn_off:
            id: switch_relay

# Button
binary_sensor:
  - platform: gpio
    id: hardware_button
    pin:
      number: GPIO04
      mode: INPUT_PULLUP
      inverted: True
    on_press:
      - switch.toggle: relay

# WiFi Signal Sensor
sensor:
  - platform: wifi_signal
    name: "WiFi Status"
    update_interval: 60s

# Restart button
button:
  - platform: restart
    name: "Restart"

Reflashed my USB Volume button and added a LED-Ring.

Example is green and blue.

Funny text on box

What is a termianl assortment? LOL

Wireless Temperature/Humidity sensor for ESPHome.

Wemos D1 mini with deep sleep, voltage monitoring using A0 line.
BME280 Temperature/Humidity sensor.
And a 18650 battery with TP4065 battery manager.
Now 3D print a little case.

Made a PCB for a 24 Channel Logic analyzer

See post: