Tag Archives: hardware

First tests with 360 Lidar

In the past, I’ve played with a standard lidar device.

Now it is time to check out a 360 version.

This one is very small (40mm x 40mm x 35mm)

Provided examples didn’t work. (People with same error on the Github issues tracker page had the same)

I changed the python script so it worked also with this YDLidar T-mini Plus version.

Next to-do, put this on my robot car.

Code:

import os
import ydlidar
import time
import sys
from matplotlib.patches import Arc
import matplotlib.pyplot as plt
import matplotlib.animation as animation
import numpy as np

RMAX = 32.0

fig = plt.figure()
lidar_polar = plt.subplot(polar=True)
lidar_polar.autoscale_view(True,True,True)
lidar_polar.set_rmax(RMAX)
lidar_polar.grid(True)
ports = ydlidar.lidarPortList();
port = "/dev/ttyUSB0";
for key, value in ports.items():
    port = value;
    
laser = ydlidar.CYdLidar();

laser.setlidaropt(ydlidar.LidarPropSerialPort, port);
laser.setlidaropt(ydlidar.LidarPropSerialBaudrate, 230400);
laser.setlidaropt(ydlidar.LidarPropLidarType, ydlidar.TYPE_TRIANGLE);
laser.setlidaropt(ydlidar.LidarPropDeviceType, ydlidar.YDLIDAR_TYPE_SERIAL);
laser.setlidaropt(ydlidar.LidarPropScanFrequency, 10.0);
laser.setlidaropt(ydlidar.LidarPropSampleRate, 4);
laser.setlidaropt(ydlidar.LidarPropSingleChannel, False);
laser.setlidaropt(ydlidar.LidarPropMaxAngle, 180.0);
laser.setlidaropt(ydlidar.LidarPropMinAngle, -180.0);
laser.setlidaropt(ydlidar.LidarPropMaxRange, 16.0);
laser.setlidaropt(ydlidar.LidarPropMinRange, 0.02);
laser.setlidaropt(ydlidar.LidarPropIntenstiy, True);

scan = ydlidar.LaserScan()

def animate(num):
    
    r = laser.doProcessSimple(scan);
    if r:
        angle = []
        ran = []
        intensity = []
        for point in scan.points:
            angle.append(point.angle);
            ran.append(point.range);
            intensity.append(point.intensity);
        lidar_polar.clear()
        lidar_polar.scatter(angle, ran, c=intensity, cmap='hsv', alpha=0.95, marker=".")

ret = laser.initialize();
if ret:
    ret = laser.turnOn();
    if ret:
        ani = animation.FuncAnimation(fig, animate, interval=50)
        plt.show()
    laser.turnOff();
laser.disconnecting();
plt.close();

Mattermost notification thingy

3D printed a little light case for a wemos and a piece of WS2812 led strip I had lying around.

Schematic:
NOTE: The resistor is 100-500 ohm (I forgot, just try)
You can only use this trick for a few leds (I used 4), else you better can use the sacrifice a led to make a level shifter trick.
(Wemos logic is 3.3V and the led strip is 5V)

I flashed ESPHome on the wemos using the flasher in Home Assistant.

Code:

esphome:
  name: matternotification
  friendly_name: matternotification

esp8266:
  board: d1_mini

# Enable logging
logger:

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

ota:
  - platform: esphome
    password: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"

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

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "Matternotification"
    password: "rxxxxxxxxxxxxxxx"

captive_portal:

light:
  - platform: neopixelbus
    type: GRB
    variant: WS2812
    pin: D4
    num_leds: 4
    name: "NeoPixelMattermost"        

To get the status of messages and controlling the HA entity, I made a bash script.

First curl command to get a token from Mattermost using the API.
Second curl command to get messages states from Mattermost.

Bottom two curl command turn a light entity on or off in your Home Assistant server using a API

#!/bin/bash
#set -x
# change : mattermost username and password (and server)
# change : mattermost userid and teamid
# change : home assistant long time token (and HA server) 
# change : light entity
#
while true; do
# Get token using login
#token=$(curl -s -i -X POST -H 'Content-Type: application/json' -d '{"login_id":"username","password":"password"}' https://mattermostinstance.com/api/v4/users/login | grep ^Token | awk '{ print $2 }' | tr -d '\r' )
#using a MM auth token (see below)
token=xxxxxxxxxxxxxxxxxxxx

# Get messages 
# Gives you something like
# {"team_id":"j3fd7gksxxxxxxxxxxxxxjr","channel_id":"rroxxxxxxxxxxxxxxtueer","msg_count":0,"mention_count":0,"mention_count_root":0,"urgent_mention_count":0,"msg_count_root":0}
# We need to count ":0" 

messages=$(curl -s  -i -H "Authorization: Bearer ${token}"  https://mattermostinstance.com/api/v4/users/ou5nz5--USER-UUID--rbuw4xy/channels/rropejn--TEAM-ID--tueer/unread | grep channel 
| grep -o ":0" | wc -l)

# If 5 times ":0" then no messages
if [ $messages == 5 ] ; then
# Turn off
curl -s -X POST -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cC--HOME-ASSISTANT-LONG-TIME-TOKEN-CBusTgTUueWpPNdH5WAWOE" \
       -H "Content-Type: application/json" \
       -d '{"entity_id": "light.matternotification_neopixelmattermost_2"}' \
       http://192.168.1.2:8123/api/services/light/turn_off > /dev/null
else
# Turn on
curl -s -X POST -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cC--HOME-ASSISTANT-LONG-TIME-TOKEn--CBusTgTUueWpPNdH5WAWOE" \
       -H "Content-Type: application/json" \
       -d '{"entity_id": "light.matternotification_neopixelmattermost_2"}' \
       https://192.168.1.2:8123/api/services/light/turn_on > /dev/null
fi
sleep 5
done

Get a Long-lived access token from HA:

Profile > Security and Create Token

Create a token in Mattermost:

Display work

While working on a client project, I tested multiple displays.

  • ILI9341
  • 1.3inch SPI TFT LCD Display RGB (ST7789)
  • Waveshare 4.2 Epaper with ESP32 Controller

I thought it was fun to connect the Epaper to ESPHome.

This probably ends up being a Quote displayer
Universal e-Paper Driver Board with WiFi / Bluetooth SoC ESP32 onboard, supports various Waveshare SPI e-Paper raw panels

It was not without problems. For example, the ESPHome editor gave squiggly lines under type.
This has to be changed in the libraries.
(Already notified developers)

model: 4.20in-V2 does not work .. use model: 4.20in-v2

esphome:
  name: epaperqoute
  friendly_name: epaperqoute

esp32:
  board: esp32dev
  framework:
    type: arduino

# Enable logging
logger:

# Enable Home Assistant API
api:
  encryption:
    key: "tzRSzZky3Jk+hUYtiybzT90kxxxxxxxxxxxxxxxxxxxxx="

ota:
  - platform: esphome
    password: "4f127e114a7a44fxxxxxxxxxxxxxxxxxxxxx"

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

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

captive_portal:


external_components:
  - source: github://pr#6209
    components: [ waveshare_epaper ]

text_sensor:
  - platform: homeassistant
    entity_id: input_text.epaper_display_text
    id: epaper_display_text
    on_value:
      then:
        - component.update: epaperdisplay
    
spi:
  clk_pin: GPIO13
  mosi_pin: GPIO14

# Upload own ttf to a directory in esphome/fonts using file editor in Home Assistant
font:
  - file: "fonts/newspaper.ttf"
    id: tahoma
    size: 64

http_request:
  verify_ssl: false

# image test
online_image:
  - url: "https://www.henriaanstoot.nl/epapertest.png"
    id: example_image
    format: PNG

#it.image(0, 0, id(example_image));

display:
  - platform: waveshare_epaper
    id: epaperdisplay
    cs_pin: GPIO15
    dc_pin: GPIO27
    busy_pin: GPIO25
    reset_pin: GPIO26
    model: 4.20in-v2
    reset_duration: 200ms
    update_interval: never
    lambda: |
           it.printf(0, 0, id(tahoma), "%s", id(epaper_display_text).state.c_str());  

BLD-305S and Arduino

Part of a client’s build for powerful DC motors, so no details

Controlling this with an Arduino is straightforward, except for the SV signal.

This controls the speed using a voltage level.
A Uno has analog inputs, no outputs.

The trick is using a digital potmeter.

256 steps potmeter MCP41100

#include <SPI.h>
int svpin = 5;
setup:
  pinMode(svpin, OUTPUT);

loop:
// SPI Digital potmeter
  digitalPotWrite(0x20);

New tests for animatronics

Controlling windscreen wipers with Arduino for animatronics.

I was looking for a cheap solution to control movement, for example Halloween puppets.

I used a XY-160D dual 7A high amperage 12V controller to control a windscreen wiper.

Using a Arduino Uno and some simple code, I got movement out of the 12V motor.

Pins used:
Vcc – Arduino 5V
GND – Arduino GND
ENA – Arduino PWM pin
IN1 & IN2 (controls direction) – Two arduino output pins

Mega PC tower and Book

I’ve printed two books using the Lulu service. (One for Tyrone)
When they arrived, I noticed some faults.
Lucky Lulu will be printing them again for me.

The book has over 500 pages and has a nice hardcover.

And I’ve been busy building a Mega Tower with 4 Motherboards.
This will have a superb processing power! .. not.
It houses some old motherboards for hardcore machine coding on real old hardware.

From top to bottom: 8088, 8086, 80386, 80484

Todo:

  • Rework on the cables
  • 3D print an information plaque on the front of each board
  • Add a control panel on each board
  • Maybe some dust cover would be nice

I can remove the boards, and place them on a table.
I’ve made some custom feet for them. Twist and lock by my own design.

Padded feet

The openscad files:

The locking is done by making the cylinder slightly oval by 0.5mm

difference(){
	difference(){
		difference(){
			difference(){
				rotate([90,30,0])
				cylinder(r=30, h=10, $fn=3);
				translate([-20,-20,0])
				cube([40,40,40]);
				}
			rotate([90,0,0])
			translate([0,0,-10])
			cylinder(r=5, h=30, $fn=200);
			translate([0,-5,-10])
			cylinder(r=7, h=30, $fn=200);
			}
		translate([18,-5,-12])
		cylinder(r=4, h=30, $fn=200);
		translate([18,-5,-22])
		cylinder(r=2.2, h=30, $fn=200);
		translate([-18,-5,-12])
		cylinder(r=4, h=30, $fn=200);

		translate([-18,-5,-22])
		cylinder(r=2.2, h=30, $fn=200);
		}
	translate([9,-20,-20])
	cube([40,40,40]);
}

Note the resize for the oval effect

resize([14,14.5,10])
cylinder(r=7, h=10, $fn=200);
translate([0,0,0])
cylinder(r=9, h=3, $fn=200);

When designing above, I also made new knobs for our stove.
Using the white dot, you can see which burner has which knob.

Old and new chips SMD or THT?

I’ve got two friends who make old retro computers.

They like to use old chips and use only THT.

What is my take on this?

I like to use THT when possible. Exceptions are:

  • Size constrains
  • No THT parts available
  • New gadgets

Old versus new chip solutions

  • CPU : never a new alternative
    (I’m not going to replace a 6502 using Arduino emulation, for example)
  • Yes, I’m using static ram instead of dynamic
  • Address decoder using 74xx ? Yes, I want to test at least once.
    But using a ATF22v10 has my preference. (Not using GALs anymore)

I only replace with newer alternatives when it does NOT interfere with how a system is performing. CPU has its own quirks, also chips like the SID. I never emulate when it can be avoided.
Address decoding, RAM or ROM yes please 🙂
Old untrusted UV Eproms are sh*t. Give me the new flash-able alternatives any time

I can emulate everything, but I need real hardware.

  • Real 6502
  • Real 68000
  • Real 8088
  • Real 8086
  • Real 80386

I still want a real VGA monitor because I used to write VGA manipulation programs which only work on CRTs.

68000 Progress

UPDATE 20240927 PCBs are in

While testing on a breadboard is fast, I still want my 68000 on PCBs.

Breadboards are nice for testing, and I use them in the design stage.
But they will fail in the end.
Loose wires, oxidated contacts and alike.

So when I was testing using breadboard, I drew the schematics in KiCad.

I wanted to use Eurocards for this one. If I divide the whole system in system blocks, I can exchange and experiment parts.
(My 6502 uses another method to connect different cards)

  • CPU and Clock (Plus power-on reset and step mode)
  • Memory and ROM
  • Storage
  • Address decoding
  • Sound
  • IRQ Handlers
  • Led Blinkenlights 🙂

I wrote about Eurocards in the past.

So I’m using the VMEbus standard for my new design.
(Using the recently bought book I mentioned)

Backplane design is done. And currently being autorouted.

PowerLeds for 5 and 12V. On/Off switch and MOLEX power connector.

Kicad sources will be uploaded

Freerouter with in the background a part of the CPU Card I am redesigning.

In the past, I dumped my old eurocards and even a nice case I had.

UPDATE 20240927 PCBs are in

Made a Meatloaf device for C64

Awesome opensource project

https://github.com/idolpx/meatloaf-specialty/tree/main

  • Emulates a floppy drive: Meatloaf plugs into the Commodore 64’s IEC serial port and acts like a virtual floppy drive. This allows you to load software and data stored on its internal flash memory, sd card, or stream it via WiFi using various protocols from servers all over the world.
  • Supports multiple virtual drives: Unlike a single floppy drive, Meatloaf can be configured to emulate up to 26 virtual drives (IDs 4-30). Each virtual drive can have a different disk image loaded, essentially offering the equivalent of having thousands of floppies connected to your C64.
  • Supports additional virtual device types: Printers, a network interface, and more.
  • Connects to the internet: Meatloaf also functions as a WiFi modem, enabling your Commodore 64 to connect to Telnet BBS (bulletin board systems) for communication and sharing information.

https://meatloaf.cc/sc/s/shortcodes.php

Load a prg using a url

LOAD"HTTP://C64.ORG/GAMES_AZ/H/H.E.R.O.PRG",8

Or from a D64 image on your own Windows/Samba server (all known CBM image formats supported):

LOAD"SMB://STORAGE/C64/FAVORITES/PIRATES_A.D64/*",8

Load a random game from the internet

LOAD"ML:ARCADE*",8