I tried to recreate an optical illusion

My friend Tyrone posted something he recorded from TV.
It was an illusion, using rotated images.

The effect is that it seems that the card is rotating at different speeds, when pressing the s (show/unshow) key, you see the card rotating at the same speed as before.

So I wanted to try to recreate this using python.
The effect is there, but a little less.
What can I improve?

Mine:

Around the 30 seconds mark I disable the background, you’ll see the card rotating as before.

Original:

Better version, larger and using s key to toggle water off, to see the card rotating

import pygame
import math

# 20240409 added s to toggle 

pygame.init()
screen = pygame.display.set_mode((1600, 900))
clock = pygame.time.Clock()

def blitRotate(surf, image, pos, originPos, angle):

    image_rect = image.get_rect(topleft = (pos[0] - originPos[0], pos[1]-originPos[1]))
    offset_center_to_pivot = pygame.math.Vector2(pos) - image_rect.center
    rotated_offset = offset_center_to_pivot.rotate(-angle)
    rotated_image_center = (pos[0] - rotated_offset.x, pos[1] - rotated_offset.y)
    rotated_image = pygame.transform.rotate(image, angle)
    rotated_image_rect = rotated_image.get_rect(center = rotated_image_center)
    surf.blit(rotated_image, rotated_image_rect)

try:
    image = pygame.image.load('cards.png').convert_alpha()
    image2 = pygame.image.load('clear+sea+water-2048x2048.png').convert_alpha()
except:
    text = pygame.font.SysFont('Times New Roman', 50).render('imagemissing', False, (255, 255, 0))
    image = pygame.Surface((text.get_width()+1, text.get_height()+1))
    image2 = image
    image.blit(text, (1, 1))

w, h = image.get_size()
angle = 0
angle2 = 0
done = False
while not done:
    clock.tick(60)
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            done = True

    pos = (screen.get_width()/2, screen.get_height()/2)
    
    screen.fill(0)
    keys = pygame.key.get_pressed()
    if (not keys[pygame.K_s]):
        blitRotate(screen, image2, pos, (900, 900), angle2)
    blitRotate(screen, image, pos, (w/2, h/2), angle)
    angle += 1
    angle2 += math.sin(math.radians(angle))
    pygame.display.flip()
    
pygame.quit()
exit()

Music Cover Art Display using ILI9431

Little Sunday afternoon project.

Two PHP scripts.

Install on your webserver (see previous post)

Resizes images and removes the onkyo header.
(See previous posts)

<?php
// onkyo.php
// write jpeg header
header('Content-type: image/jpg');

$lines = file_get_contents('http://IP-ONKYO-AMPLIFIER/album_art.cgi', false);
$lines = explode("\n", $lines);
// remove weird Onkyo header (3 lines)
$content = implode("\n", array_slice($lines, 3));
print $content;
?>

CoverArt from a squeezeboxserver

<?php    
// squeezebox.php
// leave playerid as is, for the default.
// change to MAC address of player to get coverart specific player
$img = file_get_contents('http://IP-LOGITECH_MEDIA_SERVER:9000/music/current/cover.jpg?player=<playerid>');
$im = imagecreatefromstring($img);
$width = imagesx($im);
$height = imagesy($im);
$newwidth = '240';
$newheight = '240';
$thumb = imagecreatetruecolor($newwidth, $newheight);
imagecopyresized($thumb, $im, 0, 0, 0, 0, $newwidth, $newheight, $width, $height);
//imagejpeg($thumb,'small.jpg'); //save image as jpg
header('Content-Type: image/jpeg');
imagejpeg($thumb);
imagedestroy($thumb); 
imagedestroy($im);
?>

Arduino install:

Start IDE
Install TJpg_Decoder library
Open examples>Tjpeg_decoder>SPIFFS>SPIFFS_web_spiffs
change wifi credentials
and the url to your php script.
  bool loaded_ok = getFile("https://myserver/onkyo.php", "/M81.jpg"); // Note name preceded with "/"

replace bottom part with

 // while(1) yield();
 delay(5000);
     SPIFFS.remove("/M81.jpg");

Media control automation in HA revisited

I was not happy with my old setup to control all media devices in my living room.

Controlling all devices using a single button and automations was not easy.

Problems encountered :

  1. Switching from one device to another toggled a device used by both.
  2. Switching from TV to Spotify (using my Onkyo), turned off the TV and cec turned off the Onkyo
  3. Using the Home Assistant Onkyo integration, I could select NET but not NET>Spotify
  4. The Harmony hub I’m using for Infrared Control didn’t expose all buttons.
  5. My Set-top box only power toggles. No way of reading the state.

Addressing problems:

Number 1 & 2 : Disable CEC, and manual add all that cec tried to do for me. (https://en.wikipedia.org/wiki/Consumer_Electronics_Control)

Number 5 :
(See post : https://www.henriaanstoot.nl/2024/04/01/multipurpose-rgb-sensor-esphome/)

Number 3 & 4 : Two options, integrate my web controller for onkyo.
(https://www.henriaanstoot.nl/2009/10/23/onkyo-web-control-hack/)
Or give HA more functionality.

Lets add an Onkyo python script to HA.
Open a webterminal and enter following command

pip install onkyo-eiscp

This will give you:
(Hint: want to copy text from the web terminal? Hold shift while selecting text)

➜  ~ pip install onkyo-eiscp   
Looking in indexes: https://pypi.org/simple, https://wheels.home-assistant.io/musllinux-index/
Collecting onkyo-eiscp
  Downloading https://wheels.home-assistant.io/musllinux-index/onkyo_eiscp-1.2.7-py3-none-any.whl.metadata (9.9 kB)
Collecting docopt>=0.4.1 (from onkyo-eiscp)
  Downloading https://wheels.home-assistant.io/musllinux-index/docopt-0.6.2-py2.py3-none-any.whl.metadata (17 kB)
Collecting netifaces (from onkyo-eiscp)
  Downloading https://wheels.home-assistant.io/musllinux-index/netifaces-0.11.0-cp311-cp311-musllinux_1_2_x86_64.whl.metadata (8.9 kB)
Downloading https://wheels.home-assistant.io/musllinux-index/onkyo_eiscp-1.2.7-py3-none-any.whl (45 kB)
   ━━━━━━━━━ 45.7/45.7 27.8     eta 0:00:00
             kB        MB/s                
Downloading https://wheels.home-assistant.io/musllinux-index/docopt-0.6.2-py2.py3-none-any.whl (13 kB)
Downloading https://wheels.home-assistant.io/musllinux-index/netifaces-0.11.0-cp311-cp311-musllinux_1_2_x86_64.whl (13 kB)
Installing collected packages: netifaces, docopt, onkyo-eiscp
Successfully installed docopt-0.6.2 netifaces-0.11.0 onkyo-eiscp-1.2.7
WARNING: Running pip as the 'root' user can result in broken permissions and conflicting behaviour with the system package manager. It is recommended to use a virtual environment instead: https://pip.pypa.io/warnings/venv
➜  ~ onkyo
Usage:
  onkyo [--host <host>] [--port <port>]
        [--all] [--name <name>] [--id <identifier>]
        [--verbose | -v]... [--quiet | -q]... <command>...
  onkyo --discover
  onkyo --help-commands [<zone> <command>]
  onkyo -h | --help
➜  ~ which onkyo
/usr/bin/onkyo

Now we can integrate shell commands in HA!

NET > Spotify
onkyo --host 192.168.1.2 NSV0A0

Spotify > track info
onkyo --host 192.168.1.2 NTIQSTN

Spotify > Artist
onkyo --host 192.168.1.2 NATQSTN

Turn Onkyo ON/OFF
onkyo --host 192.168.1.2 PWR01
onkyo --host 192.168.1.2 PWR00

Get Power state
onkyo --host 192.168.1.2 PWRQSTN

Mute on/off
onkyo --host 192.168.1.2 AMT01 or AMT00

Volume Level
onkyo --host 192.168.1.2 MVLQSTN

Home Assistant Shell Command example

  - platform: command_line
    switches:
      onkyo_mute:
        command_on: "/usr/bin/onkyo --host 192.168.1.2 AMT00"
        command_off: "/usr/bin/onkyo --host 192.168.1.2 AMT01"

Getting album art:

Get image from below url.
Note! .. its a static non refreshing image!

http://192.168.1.2/album_art.cgi

Note: This gives me a file which shows fine in a browser, but being a http feed you cannot embed this in a https site.
Another ‘problem’ with this image is that it includes headers, rendering this a invalid jpg when processing!
(remove first 3 lines programmatically)
I also want to have it updated, so I could make a mjpeg streamer for this.
Probably i’m going to use my reverse proxy which uses SSL offloading to access cover art over https.
(Then I can push this cover image on this webblog so you guys can see what we are listing to)

Another idea is to push this to an arduino display.

Not using https?

You can embed the album art in a dashboard. This won’t refresh, but the added time code will stop caching problems.

type: picture<br>image: http://192.168.1.2/album_art.cgi?v={{now().timestamp()|int }}")

Todo:

Make the automations foolproof.

Watching TV and want to listen to Spotify?

  1. Turn TV off
  2. Switch Onkyo to Net and Spotify
  3. (Adjust volume)
  4. Toggle TV set-top box off

etc

Next todo:
Cover art embed in HA.
Maybe in embed in this blog.
Make a small cover art display.

PHP code to strip lines and put behind a reverse proxy

<?php
header('Content-type: image/jpg');
$lines = file_get_contents('http://192.168.1.2/album_art.cgi', false);
$lines = explode("\n", $lines);
$content = implode("\n", array_slice($lines, 3));
print $content;
?>

You can use Generic Camera to refesh!

https://www.home-assistant.io/integrations/generic

Current Cover Art

Get cover art from Logitech Media Server

http://192.168.1.3:9000/music/current/cover.jpg?player=<playerid>

64×64 Matrixrgb plus Conway’s Game of Life

Yesterday I got this nice led matrix I mentioned before.

I wanted to control this display using Circuit Python and a Raspberry Pico.

Pico  Matrix
GP0   R1
GP1   G1
GP2   B1
GP3   R2
GP4   G2
GP5   B2
GP6   A
GP7   B
GP8   C
GP9   D
GP10  Clock
GP11  E
GP12  Latch
GP13  Output Enable

GND   GND ( I did both )

I installed Circuit Python and the following libraries.

adafruit_imageload, adafruit_display_text.label (the rest was already in the uf2 firmware.)
(Check this link : https://circuitpython.org/board/raspberry_pi_pico/ )
I could not install the Wifi uf2 file, then I got a out of storage space when installing the adafruit libraries.

importing libaries and init display

import board, digitalio, busio, time, displayio, rgbmatrix, framebufferio
import adafruit_imageload, terminalio, random
import adafruit_display_text.label

displayio.release_displays()
matrix = rgbmatrix.RGBMatrix(
    width=64, bit_depth=2, height=64,
    rgb_pins=[board.GP0, board.GP1, board.GP2, board.GP3, board.GP4, board.GP5],
    addr_pins=[board.GP6, board.GP7, board.GP8, board.GP9, board.GP11],
    clock_pin=board.GP10, latch_pin=board.GP12, output_enable_pin=board.GP13)
display = framebufferio.FramebufferDisplay(matrix)

I became interested in Conway’s “Game of Life”, in 1983. Reading a article in the Dutch Magazine Kijk.

The Game of Life, also known simply as Life, is a cellular automaton devised by the British mathematician John Horton Conway in 1970. It is a zero-player game, meaning that its evolution is determined by its initial state, requiring no further input. One interacts with the Game of Life by creating an initial configuration and observing how it evolves. It is Turing complete and can simulate a universal constructor or any other Turing machine.

https://en.wikipedia.org/wiki/Conway%27s_Game_of_Life

I found these on my server. Bad quality, I know. Scanned these many years ago.

The rules are:

  1. Any live cell with fewer than two live neighbours dies, as if by underpopulation.
  2. Any live cell with two or three live neighbours lives on to the next generation.
  3. Any live cell with more than three live neighbours dies, as if by overpopulation.
  4. Any dead cell with exactly three live neighbours becomes a live cell, as if by reproduction.

When playing with the Basic code as a kid, I wanted to try if it was possible to make a 3D version of this.

I came up with the following rules:

  1. Birth : 4 alive neighbours needed
  2. Survive : 5 or 6 neighbours
  3. Dead : below 4 and over 6

I think there should be a BBC Acorn basic version I wrote somewhere.

Back to the display

Greetings to my friends
Game of Life starting with my Logo plus a glider
A single Gosper‘s glider gun creating gliders

Code for the glider gun

    conway_data = [
        b'                        +           ',
        b'                      + +           ',
        b'            ++      ++            ++',
        b'           +   +    ++            ++',
        b'++        +     +   ++              ',
        b'++        +   + ++    + +           ',
        b'          +     +       +           ',
        b'           +   +                    ',
        b'            ++                      ',
    ]

Next todo:

  • Line functions
  • Design a Chip tune hardware add-on
  • Make a Game of Life start situation selector
  • Make a new Maze game!

Home Assistant – Reboot, start,shutdown and switch OS

This is my short log about (re)starting booting machines.

configuration.yaml

#WOL to start a machine
  - platform: wake_on_lan
    name: "wakeserver"
    mac: ec:be:5f:ee:11:78

#SHELL command to remote start reboot2windows script (multiboot machine)
shell_command:
    ssh_reboottowindows: ssh -i /config/ssh/id_ed25519 -o 'StrictHostKeyChecking=no' root@192.168.1.2 '/root/reboot2windows'
shell_command:
    ssh_haltlinux: ssh -i /config/ssh/id_ed25519 -o 'StrictHostKeyChecking=no' root@192.168.1.2 'halt -p'

reboot2windows linux script (on the remote server)

#!/bin/bash
#place in /root/
#chmod +x /root/reboot2windows
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
WINDOWS_TITLE=`grep -i "^menuentry 'Windows" /boot/grub/grub.cfg|head -n 1|cut -d"'" -f2`
grub-reboot "$WINDOWS_TITLE"
reboot

install https://iotlink.gitlab.io/ on your windows instance

scripts.yaml (with a helper button rebootwindows2linux, shutdownwindows)

#Reboot windows, linux is the default
windows2linux:
  alias: rebootwinserver
  sequence:
  - service: mqtt.publish
    metadata: {}
    data:
      qos: 0
      retain: false
      topic: iotlink/workgroup/winserver/commands/reboot
  mode: single
shutdownwindows:
  alias: shutdownwinserver
  sequence:
  - service: mqtt.publish
    metadata: {}
    data:
      qos: 0
      retain: false
      topic: iotlink/workgroup/winserver/commands/shutdown
  mode: single

automation rebootlinux2windows

(using a helper button rebootlinux2windows)

alias: rebootlinux2windows
description: ""
trigger:
  - platform: state
    entity_id:
      - input_button.rebootlinux2windows
condition: []
action:
  - service: shell_command.ssh_reboottowindows
    data: {}
mode: single

Configuring ssh keys

Open HA terminal

cd
ssh-keygen (enter) (enter) (enter) (enter) 
mkdir -p config/ssh
cp ~/.ssh/id* config/ssh/ 

Arduino Tiny Machine Learning Kit

A while ago I bought a little machine learning kit.

I’ve been reading at listening to ML podcasts and websites.

One on Spotify I liked was:

Also, the following Coursera was interesting
https://www.coursera.org/learn/machine-learning

I’ve been testing using Python on my Laptop.
(see other posts)

And a camera with esp32 using face detection.

See here multiple posts about these experiments.

https://www.henriaanstoot.nl/tag/machinelearning/

Today the first experiments using this kit.

  • Arduino Nano 33 BLE Sense board
  • OV7675 Camera
  • Arduino Tiny Machine Learning Shield
  • USB A to Micro USB Cable
  • 9 axis inertial sensor: what makes this board ideal for wearable devices
  • humidity, and temperature sensor: to get highly accurate measurements of the environmental conditions
  • barometric sensor: you could make a simple weather station
  • microphone: to capture and analyse sound in real time
  • gesture, proximity, light color and light intensity sensor : estimate the room’s luminosity, but also whether someone is moving close to the board
  • Microcontroller nRF52840
  • Operating Voltage 3.3V
  • Input Voltage (limit) 21V
  • DC Current per I/O Pin 15 mA
  • Clock Speed 64MHz
  • CPU Flash Memory 1MB (nRF52840)
  • SRAM 256KB (nRF52840)
  • EEPROM none
  • Digital Input / Output Pins 14
  • PWM Pins all digital pins
  • UART 1
  • SPI 1
  • I2C 1
  • Analog Input Pins 8 (ADC 12 bit 200 ksamples)
  • Analog Output Pins Only through PWM (no DAC)
  • External Interrupts all digital pins
  • LED_BUILTIN 13
  • USB Native in the nRF52840 Processor
  • IMU LSM9DS1 (datasheet)
Gesture test ( yes on a windows surface tablet, but Vincent and I installed linux on it!)

I just started and will update this page, with other experiments.

Note: displaying Arduino output without installing the IDE

stty -F /dev/ttyACM0 raw 9600
cat /dev/ttyACM0
................................
................................
................................
................................
................................
................................
................................
................................
................................
................####............
...............##..#............
..............##...##...........
..............#.....#...........
..............###...#...........
..............##.....#..........
..............##.....#..........
...............#....##..........
...............######...........
................................
................................
................................
................................

Multipurpose RGB sensor (ESPHome)

A few years ago, I made a little light metering sensor using a light resistor and a NodeMCU (using analog read).
This would measure if a Led was turned on from my Alarm system. (I had no other way to read this state.
(I also had it connected to our washing machine for a while, to read the state.)

Now I wanted to read the state of the TV set-top box.
This Arcadyan hmb2260 has a green/led state LED, so measuring light is not enough.
(I can only toggle the device from Home Assistant, so there is no way to know the current state!)
Toggling on/off and portscanning the device gave me not another way to get the state (no extra open ports/web state pages) than using an RGB Sensor.

Flashing this with ESP Home and integrating it in HA was a breeze.

I wanted to turn the Illuminance LED also off, because the Set-top box already emits light.

Now I’m going to 3D print a holder which can be used to press the button manually when needed.

The yellow part needs to be 3D printed.
Output of the sensor

ESPHome Code

esphome:
  name: rgbsensor
  friendly_name: RgbSensor

esp8266:
  board: d1_mini

# Enable logging
logger:

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

ota:
  password: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"

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

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

captive_portal:

i2c:
  sda: 4
  scl: 5

sensor:
  - platform: tcs34725
    red_channel:
      name: "TCS34725 Red Channel"
    green_channel:
      name: "TCS34725 Green Channel"
    blue_channel:
      name: "TCS34725 Blue Channel"
    clear_channel:
      name: "TCS34725 Clear Channel"
    illuminance:
      name: "TCS34725 Illuminance"
    color_temperature:
      name: "TCS34725 Color Temperature"
    glass_attenuation_factor: 1.0
    address: 0x29
    update_interval: 5s

light:
  - platform: binary
    name: "RgbSensorVerlichting"
    output: light_output

output:
  - id: light_output
    platform: gpio
    pin: 2

Automation in HA:

If Red Channel > 60% then device is OFF.

Other ideas:

Measure the dishwasher machine LED.

Using color cards to (program) the wleds I’m using.


LCD matrix idea’s

In previous post I was talking about an esp32 with display for demo’s.
But my friend Erik mentioned a cheap LCD matrix from Ali.

What about creating something cool with that!

My Maze project would look amazing on this!
I can draw walls now!

Or I could make a cool audio visualiser, like the posted WLED version

Ehh .. not posted (well I can’t post everything)

What about a game of life display?
Using a web interface for inputting the start situation of the cells

Conway’s Game of Life is a cellular automaton. It consists of a grid of cells, each of which can be alive or dead. The state of each cell evolves based on simple rules: any live cell with fewer than two live neighbours dies (underpopulation), any live cell with two or three live neighbours survives, and any live cell with more than three live neighbours dies (overpopulation). Additionally, any dead cell with exactly three live neighbours becomes alive (reproduction). This simple set of rules can lead to complex patterns and behaviours.

But back to the demo …

What about a 6502 with 64×64 pixel display!

What would be needed?

  • 6502, with rom and ram
  • Some IO chip, don’t know which one yet
  • The 64×64 pixel matrix
  • A sound solution (simple chip tune player)
  • 3D printed enclosure

Using some libraries and a framework setup, maybe there is a way to make a cool and cheap demo machine

Do you have any suggestions ideas?
Comment or email me!

Uilleann Pipe recordings

Best Uilleann recordings I own or listen to.

Do you know any other good recordings? Let me know.

Uilleann CDs (no order)

  • Liam O’Flynn – The Pipers Call
  • Davy Spillane – Atlantic Bridge, Pipedreams, Out of the Air
  • Paddy Keenan – The Long Grazing Acre
  • Sean McKeon – The Dusty Miller ( Multiple players playing harmony)

Calum Stewart (I know him from his Flute playing)
I play “Am Monadh Ruadh” from this CD, also Randolph’s Leap is awesome.
Look up “Randolph’s Leap”. I’ve been there, beautiful.
(A better name should be Cummings Leap)

Brian McNamara

He plays a ‘flat’ set pitched in ‘C’ made by Geoff Wooff in 1997 and a ‘concert-pitched’ set of pipes made by Peter Maguire, I was lucky enough to have him as my teacher in Drumshanbo.

Single tracks I like

High energy playing of Blackie O’Connoll. He was my tutor when I attended Tionol 2011

Fred Morrison‘s Kansas City Hornpipe

Paddy Keenan – Harvest Home & Boys of blue hill
(Check The Pipering Of Willie Clancy Vol II)

Doinna by John McSherry (I play this one also, but it is nothing compared to his pipe-sound, melodic virtuosity and feeling he puts in this relatively easy piece of music)

Another often played CD with Uileann, Borderpipes and Low Whistles is:

Partners in Crime by Jarlath Henderson and Ross Ainslie.
A very nice combination of two different pipes together.
Coline and I try to have at least one set with both instruments.

Some others:

  • Some tracks of Bad Shepherds
  • Some tracks of Afro Celt Sound System
  • Some tracks of Enya (See Sun in the stream post)

List of Artist i’ve got recordings from:

Cillian Vallely, Finbar Furey, Ronan Browne, Willie Clancy, Seamus Ennis, Johnny Doran, Leo Rowsome, Liam O’Flynn,Davy Spillane, Paddy Keenan, Finbar Furey, Brian McNamara, Paddy Moloney, Jerry O’Sullivan, Gay Conor, Sean McKeon, Declan Masterson, Michael McGoldrick I probably missed several

Female pipers

"If something is worth doing, it's worth overdoing."