Tag Archives: electronics

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 Alarm with ESP Siren

I used to have a “professional” alarm system, but it was too limited.

But when making a new alarm system using Home Assistant I thought I could reuse some sensors and the very loud alarm.

Setting up the Alarm within HA was as described on the HA website.
I made a group for door and motion sensors.
Then I made groups for lighting and switches.

Now I can “ARM” the house.

  • Motion sensors like PIR and camera sensors are being used for detection.
  • Lights and sound will be turned on when motion is detected.
  • When arming the system, the siren mode of the camera’s is also turned on.
  • When intrusion is detected I get a pushover notification on my phone and watch.

The siren is about 4-5 Euro’s on Ali
https://nl.aliexpress.com/item/1005006066524139.html

Schematic of the wemos controller

(I don’t have a Siren Fritzing part .. hence the speaker)

Used mosfet is a N-Channel 30N06L, resistor is 10K

ESPHome code

esphome:
  name: bigalarm
  friendly_name: BigAlarm

esp8266:
  board: d1_mini

# Enable logging
logger:

# Enable Home Assistant API
api:
  encryption:
    key: "1xxfIYKv6tpzt7HQKYOxxxxxxxxTBETHkmy7cwDE="

ota:
  password: "5d23a3af438fe0xxxxxxxx2ff29ab6"

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

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

captive_portal:

output:
  - platform: gpio
    pin: 0
    id: 'generic_out'
switch:
  - platform: output
    name: "BigAlarm"
    output: 'generic_out'

Started working on C64Pico with Bigred

A week ago I got the last components delivered to my doorstep.

This project was made by Silvervest and it’s f*ckin awesome.

https://github.com/silvervest/c64pico

I was afraid to start this myself, SMD is on another level for me.
But my good friend Marco said … No problem!

So I ordered components online, which was not easy.
Selecting the correct parts, sizes and options.

These things are really really small

Using tweezers to place the components was even difficult.
The slippery tiny bastard got catapulted everywhere. (Or got stuck on fingers, soldering iron and alike)
Many small components got lost into the 7th dimension. Never to be found again.

Awesome to work on this together, but Marco said that I have to try it myself.
Welllll, I got 3/4 of the ATmega328PB-A perfectly soldered, then I notished that it was crooked.
Desoldering was a mess, and I heated the PCB TOO much with the heatgun.

My messed-up PCB, and f*cked-up IC. Leave it to the professionals.

Next step for me is soldering the 75 mini buttons!

Got a Trinitron display from him, I was looking for this for a long time.

Three channel mixer for ay-3-8910 is almost done.

At the back the 8 pin single channel lm368 amplifier.
At the front the 3 channel setup.
I still have to tweak the resistors, and potmeters.
Then I can make a permanent PCB, and figure out the connections to the 6502.

At the moment, the Arduino Nano is playing some real sound samples by using the registers of the sound chip.
The music is being played by sending the register dumps directly to the chip.

Much like i’ve been using SID register dumps to play songs in another project.

This is version 0.1 .. do not use.
If its wrong, or can do better please mail me.
Oh it needs a 1k resistor from the 20K’s to ground I think.

Pico with SPI troubles, but a Rigol helps a lot.

I was working on a MCUME proof of concept, with my own compiled version.
But my combination of a Pico and an ILI9341 display didn’t work.

Luckily, a package arrived.
My new scope!

A Rigol DS1074Z+ oscilloscope!
The replacement of my CRT version.

This new oscilloscope has 4 channels AND there is a add-on for a 16channel logic analyser.

For my next birthday?!? 🙂

The Rigol can be connected to a wired network.
So that’s one of the first things I did.
(It came with all software options enabled, so no need to ‘fix’ those)

Using the ISCP protocol, you can remotely control the device.
( see my Onkyo web hack https://www.henriaanstoot.nl/2009/10/23/onkyo-web-control-hack/ )

See https://www.batronix.com/pdf/Rigol/ProgrammingGuide/DS1000DE_ProgrammingGuide_EN.pdf for commands.

So I created a capture script using bash

capture-rigol.sh
# ./capture-rigol.sh fft
echo ':display:data?' | netcat -w 20 my-rigol-static-ip 5555 | tail -c +12 > $1.bmp


Below a screen of DSremote

But back to the problem:

My SPI setup didn’t work, display broken?

Lets try a micropython setup.

Nope, the display is fine, my compiled version is borked.

See protocol decode in above gallery, so I have to check my sources:(

Last week’s stuff

Update: https://www.henriaanstoot.nl/2024/01/14/hlk-ld2410b-with-a-wemos-mini-d1-v4-connected-to-home-assistant-using-esphome/

Case for presence detector

Update: BBQ watch

Not posted in the past, new version using ESPHOME and a m5stickc

Previous version using a ESP12
A “watch” with core and environment temperature of my smoker with a alarm, and button for timers.

ESP32 dac’s drawing on oscilloscope ( no additional components)

ESP32 in front of scope, two clips for x and y

For above i used sin/cos functions 2:3, which creates Lissajous figures.
See: https://www.henriaanstoot.nl/1992/01/01/oscilloscope-graphics-using-a-amiga-bonus-vectrex/

3 battery operated buttons (no wires needed) to control my shelly dimmer at the dinner table.

left button on, middle steps per 20% and 3rd button off.
(This cheapass button only sends ON commands)

Node red code

[
    {
        "id": "8190a851.8d02b8",
        "type": "mqtt in",
        "z": "44d7a4fb.e41a5c",
        "name": "domoticz-out",
        "topic": "domoticz/out",
        "qos": "0",
        "broker": "8c74c5f6.9a7a48",
        "inputs": 0,
        "x": 190,
        "y": 600,
        "wires": [
            [
                "543a2fa3.af27c",
                "c70d463.da52ab8",
                "ffa2f6be.afe618"
            ]
        ]
    },
    {
        "id": "543a2fa3.af27c",
        "type": "function",
        "z": "44d7a4fb.e41a5c",
        "name": "Filter IDX + nvalue",
        "func": "var varPayload = JSON.parse(msg.payload);\nvar varidx = varPayload.idx;\nvar varnvalue = varPayload.nvalue;\nif(varidx == 2473)\n{\nmsg.payload = {};\nmsg.payload.turn = \"on\";\nmsg.payload.brightness = 50;\nreturn msg;\n}",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 410,
        "y": 600,
        "wires": [
            [
                "d7b0f308db912817"
            ]
        ]
    },
    {
        "id": "c70d463.da52ab8",
        "type": "function",
        "z": "44d7a4fb.e41a5c",
        "name": "Filter IDX + nvalue",
        "func": "var varPayload = JSON.parse(msg.payload);\nvar varidx = varPayload.idx;\nvar varnvalue = varPayload.nvalue;\nif(varidx == 2474)\n{\nmsg.payload = {};\nmsg.payload.turn = \"on\";\nvar count = context.get(\"counter\") || 0;\ncount = (count+1) % 6;\ncontext.set(\"counter\", count);\ncount = count * 20; \nmsg.payload.brightness = count;\nreturn msg;\n}",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 410,
        "y": 680,
        "wires": [
            [
                "d7b0f308db912817"
            ]
        ]
    },
    {
        "id": "ffa2f6be.afe618",
        "type": "function",
        "z": "44d7a4fb.e41a5c",
        "name": "Filter IDX + nvalue",
        "func": "var varPayload = JSON.parse(msg.payload);\nvar varidx = varPayload.idx;\nvar varnvalue = varPayload.nvalue;\nif(varidx == 2475)\n{\nmsg.payload = {};\nmsg.payload.turn = \"off\";\n//msg.payload.brightness = 0;\nreturn msg;\n}",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 410,
        "y": 760,
        "wires": [
            [
                "d7b0f308db912817"
            ]
        ]
    },
    {
        "id": "35f35737.b4f2c8",
        "type": "comment",
        "z": "44d7a4fb.e41a5c",
        "name": "Living Dinner Table Shelly 2024",
        "info": "",
        "x": 250,
        "y": 560,
        "wires": []
    },
    {
        "id": "b080c84e.2c3968",
        "type": "comment",
        "z": "44d7a4fb.e41a5c",
        "name": "butt1 on / (butt2 off)",
        "info": "",
        "x": 510,
        "y": 560,
        "wires": []
    },
    {
        "id": "ac892b87.1c7358",
        "type": "comment",
        "z": "44d7a4fb.e41a5c",
        "name": "butt3 toggle",
        "info": "",
        "x": 390,
        "y": 720,
        "wires": []
    },
    {
        "id": "b5bdbd65.c4e1c",
        "type": "comment",
        "z": "44d7a4fb.e41a5c",
        "name": "butt 2 step dimmer",
        "info": "",
        "x": 410,
        "y": 640,
        "wires": []
    },
    {
        "id": "d7b0f308db912817",
        "type": "mqtt out",
        "z": "44d7a4fb.e41a5c",
        "name": "",
        "topic": "shellies/shellydimmer-D0DF15/light/0/set",
        "qos": "",
        "retain": "",
        "respTopic": "",
        "contentType": "",
        "userProps": "",
        "correl": "",
        "expiry": "",
        "broker": "8c74c5f6.9a7a48",
        "x": 860,
        "y": 600,
        "wires": []
    },
    {
        "id": "8c74c5f6.9a7a48",
        "type": "mqtt-broker",
        "name": "MQTTSERVER",
        "broker": "MQTTSERVER",
        "port": "1883",
        "clientid": "",
        "usetls": false,
        "compatmode": true,
        "keepalive": "15",
        "cleansession": true,
        "birthTopic": "",
        "birthQos": "0",
        "birthPayload": "",
        "closeTopic": "",
        "closePayload": "",
        "willTopic": "",
        "willQos": "0",
        "willPayload": ""
    }
]

Vector graphics on my demo arduino nano.

Raspberry Pico with st7789v2 display 3D control

While ordering components for a mini C64 project I’m doing with my friend Bigred, I ordered a cheap ST7789-v2 display.

I want to make a generic pico gadget with a display, buttons and sound.
This to make a mini device for writing micropython demos.

The 3 tactical buttons are controlling the X,Y and Z axis of the rotating Cube.

Pinout:

PICODISPLAY
GP2Tactical switch (other side to 3v3)
GP3Tactical switch (other side to 3v3)
GP4Tactical switch (other side to 3v3)
GP9CS1
GNDGND
3v3VCC
GP18SCL (SPI clock)
GP19SDA (MOSI / SPI Data)
GP20RES (reset)
GP17DC (data command)
GP16BLK (backlight)

I know it says SCL/SDA (i2c) but it’s SPI controlled.

Used library : https://github.com/russhughes/st7789_mpy/tree/master

Some 3D explanation I drew a long time ago.

Using python you can use the Math funtions. (sin/cos)
Note: these are in radians!
print(math.sin(math.radians(30))) # 30 degrees

When using MachineCode you can use lookup tables.
These are generated tables which hold precalculated sin data for every degree.
You don’t have to use both cos and sin! (these are just 90 degrees shifted!)

Erik and I used a little basic program to generate an ASM include file like this

Costab LABEL BYTE
DB 0B4h,0B4h,0B4h,0B4h,0B4h,0B3h,0B3h,0B3h,0B2h,0B2h,0B1h,0B1h,0B0h,0AFh,0AFh
DB 0AEh
DB 0ADh,0ACh,0ABh,0AAh,0A9h,0A8h,0A7h,0A6h,0A5h,0A4h,0A2h,0A1h,0A0h,9Eh,9Dh,9Bh
DB 9Ah,98h,96h,95h,93h,91h,90h,8Eh,8Ch,8Ah,88h,86h,84h,82h,80h,7Eh
DB 7Ch,7Ah,78h,76h,74h,72h,70h,6Eh,6Ch,69h,67h,65h,63h,61h,5Eh,5Ch
DB 5Ah,58h,56h,53h,51h,4Fh,4Dh,4Bh,48h,46h,44h,42h,40h,3Eh,3Ch,3Ah
DB 38h,36h,34h,32h,30h,2Eh,2Ch,2Ah,28h,26h,24h,23h,21h,1Fh,1Eh,1Ch
DB 1Ah,19h,17h,16h,14h,13h,12h,10h,0Fh,0Eh,0Dh,0Ch,0Bh,0Ah,09h,08h
DB 07h,06h,05h,05h,04h,03h,03h,02h,02h,01h,01h,01h,00h,00h,00h,00h
DB 00h,00h,00h,00h,00h,01h,01h,01h,02h,02h,03h,03h,04h,05h,05h,06h
DB 07h,08h,09h,0Ah,0Bh,0Ch,0Dh,0Eh,0Fh,10h,12h,13h,14h,16h,17h,19h
DB 1Ah,1Ch,1Eh,1Fh,21h,23h,24h,26h,28h,2Ah,2Ch,2Eh,30h,32h,34h,36h
DB 38h,3Ah,3Ch,3Eh,40h,42h,44h,46h,48h,4Bh,4Dh,4Fh,51h,53h,56h,58h
DB 5Ah,5Ch,5Eh,61h,63h,65h,67h,69h,6Ch,6Eh,70h,72h,74h,76h,78h,7Ah
DB 7Ch,7Eh,80h,82h,84h,86h,88h,8Ah,8Ch,8Eh,90h,91h,93h,95h,96h,98h
DB 9Ah,9Bh,9Dh,9Eh,0A0h,0A1h,0A2h,0A4h,0A5h,0A6h,0A7h,0A8h,0A9h,0AAh,0ABh,0ACh
DB 0ADh,0AEh,0AFh,0AFh,0B0h,0B1h,0B1h,0B2h,0B2h,0B3h,0B3h,0B3h,0B4h,0B4h,0B4h
CosTabE LABEL BYTE


Basic:
0 DEF SEG = &H7000: c = 0
1 pi = 3.14159265#
2 FOR x = 0 TO 2 * pi STEP 2 * pi / 256
3 d = COS(x) * 127 + 127
4 POKE c, d: c = c + 1: NEXT

Most i learned from a book called “Art of Graphics”
(This is image of the book from the internet, i don’t think I still got my copy somewhere.

A “new” sound chip for 6502

UPDATE: 20240225

I’ve written about General Instrument AY-3-8910 before, here is some work I did today.

This sound chip i wanted to implement in my amiga, and now it’s a alternative for my 6502 computer. ( As an alternative setup for the SID chip. )
Btw this is the same kind of chip used in the Atari ST.

A clean setup … I’ve got the sound chip and a Amplifier chip.

Above a Kicad drawing I made today, a little different from my design from the 90’s.

Below a movie clip I recorded today. Running a test setup using an Arduino nano and a sdcard reader.
The sound is bad, this is due to clipping and the absence of multiple resistors and capacitors.
Music is a register dump from a YM music file.
Amplifier is a bare LM386.

UPDATE: 20240225

I don’t like tying those three outputs together, and amplifying those.

So I’m going to use a LM324 i’ve got left from my 8085 interface, and make a 3-channel amplifier.

Something like this

SDK-85 interface PCB soldered

Using spacers, I can use the existing holes in the SDK to hold the interface PCB in place. Now I have to move my information sheet. 🙂

My scope didn’t save the test capture .. Next time.
But I could see the clear ones and zeros.

You can faintly see the data, stop start of a program is visible.

Dirk cleaned up a OCR version of the program, which I cleaned up some more, and found some errors.
So that should be okay now.

Flute note detection with leds

Yesterday I got my MAX9814 in, last night I got it working.
Used the leds from a lightpainter project to test controlling the leds.

Why is it, that it doesn’t matter how much components and ledstrips you buy, you alway need more.

First parts of the Scale, then a part of Farewell to Uist

Arduino Nano, using FastLeds library and FFT.
Ledstrip is WS2812, and the MAX8914 microphone