Tag Archives: electronics

LMS Record player V.something .. final? No

But it works! Many iterations .. almost perfect

Recordplayer model by kriswillcode, but heavily remixed

Record player is going to be re-printed at a higher quality.

  • Put a printed image on the player, and it plays the album
  • Move the arm, and the next track will be played
  • Press upper white button, and the music will pause/resume
  • Press lower button … ??? Don’t know yet

Updated python client (see previous posts)

import paho.mqtt.client as mqtt
import urllib.request
from time import sleep

def on_connect(client, userdata, flags, rc):  # The callback for when the client connects to the broker 
        print("Connected with result code {0}".format(str(rc)))  
        client.subscribe("spotify/rfid/idlms")  
        client.subscribe("spotify/rfid/but1")  
        client.subscribe("spotify/rfid/but2")  
        client.subscribe("spotify/rfid/arm")  

def on_message(client, userdata, msg):  # The callback for when a PUBLISH message is received from the server. 
        print("Message received-> " + msg.topic + " " + str(msg.payload))  # Print a received msg
        if msg.topic == "spotify/rfid/idlms":
            urllib.request.urlopen("http://LMS-SERVER-IP:9000/anyurl?p0=playlistcontrol&p1=album_id:" + msg.payload.decode() + "&p2=cmd:load&player=00:04:20:16:d9:04")
        if msg.topic == "spotify/rfid/but1":
            urllib.request.urlopen("http://LMS-SERVER-IP:9000/anyurl?p0=pause&player=00:04:20:16:d9:04")
            sleep(1)
        if msg.topic == "spotify/rfid/but2":
            urllib.request.urlopen("http://LMS-SERVER-IP:9000/anyurl?p0=pause&pt=1&player=00:04:20:16:d9:04")
            sleep(1)
        if msg.topic == "spotify/rfid/arm":
            urllib.request.urlopen("http://LMS-SERVER-IP:9000/status.html?p0=button&p1=jump_fwd&player=00:04:20:16:d9:04")
            sleep(1)

client = mqtt.Client("lmsclient")  # Create instance of client with client ID “digi_mqtt_test”
client.on_connect = on_connect  # Define callback function for successful connection
client.on_message = on_message  # Define callback function for receipt of a message
client.connect('MQTTSERVER', 1883)
client.loop_forever()  # Start daemon

Wemos INO file

#include <Arduino.h>
#include <SPI.h>
#include <MFRC522.h>
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <PubSubClient.h>
#define SS_PIN 15
#define RST_PIN 0

const int buttonPin1 = D1;  
const int buttonPin2 = D2;   

int buttonState1 = 0; 
int buttonState2 = 0; 

MFRC522 mfrc522(SS_PIN, RST_PIN);
  MFRC522::StatusCode status; //variable to get card status
  
  byte buffer[18];  //data transfer buffer (16+2 bytes data+CRC)
  byte size = sizeof(buffer);

  uint8_t pageAddr = 0x06;  //In this example we will write/read 16 bytes (page 6,7,8 and 9).
                            //Ultraligth mem = 16 pages. 4 bytes per page.  
                            //Pages 0 to 4 are for special functions.           
  
unsigned long cardId = 0;
WiFiClient net;
PubSubClient client(net);
const char* mqtt_server = "MQTTBROKER";
const char* ssid = "MYSSID";
const char* password = "MYWIFIPASWORD";
String topicStr = "";
byte buffer2[8];

boolean Rflag=false;
int r_len;
char payload[5];
byte value[5];
void setup() {
  Serial.begin(9600);
    pinMode(buttonPin1, INPUT_PULLUP);
    pinMode(buttonPin2, INPUT_PULLUP  );

  SPI.begin();
  mfrc522.PCD_Init();
  WiFi.mode(WIFI_AP_STA);
  WiFi.begin(ssid, password);
  client.setServer(mqtt_server, 1883);
     delay(100);
    client.setCallback(callback);
      delay(100);
    client.subscribe("spotify/rfid/in/#");
}
void reconnect() {
  while (WiFi.waitForConnectResult() != WL_CONNECTED) {
  }
  while (!client.connected()) {
    String clientId = "rfid-";
    clientId += String(random(0xffff), HEX);
    if (!client.connect(clientId.c_str(), "rfidclient", "...")) {
      delay(5000);
    }
  }
  client.subscribe("spotify/rfid/in/#");
}
void callback(char* topic, byte* payload, unsigned int length) {
  Serial.print(F("Called"));
   Rflag=true; //will use in main loop
   r_len=length; //will use in main loop
   int j=0;
     for (j;j<length;j++) {
       buffer2[j]=payload[j];
       //Serial.print((char)payload[j]);
       }
if (r_len < 3) {
  Rflag=false;
  Serial.print(F("Set false"));
}
buffer2[j]='\0'; //terminate string
}

void loop() {
    if (!client.connected()) {
    reconnect();
  }

buttonState1 = digitalRead(buttonPin1);
  //Serial.print(buttonState1);
  if (buttonState1 == 0 ) {
    client.publish("spotify/rfid/but1", "0");
  }
buttonState2 = digitalRead(buttonPin2);
  //Serial.println(buttonState2);
  if (buttonState2 == 0 ) {
    client.publish("spotify/rfid/but2", "0");
  }

int reading = analogRead(0);
  //Serial.println(reading);
  if (reading > 500 ) {
    client.publish("spotify/rfid/arm", "0");
  }
  
  client.loop();
  if (!mfrc522.PICC_IsNewCardPresent()) {
    return;
  }
  if (!mfrc522.PICC_ReadCardSerial()) {
    return;
  }
if (Rflag) {
        for (int i=0; i < 4; i++) {
    //data is writen in blocks of 4 bytes (4 bytes per page)
    status = (MFRC522::StatusCode) mfrc522.MIFARE_Ultralight_Write(pageAddr+i, &buffer2[i*4], 4);
    if (status != MFRC522::STATUS_OK) {
      return;
    }
    
  }
  Rflag=false;
}

  cardId = getCardId();
  char buffer3[10];
  sprintf(buffer3, "%lu", cardId);
  client.publish("spotify/rfid/id", buffer3);

  status = (MFRC522::StatusCode) mfrc522.MIFARE_Read(pageAddr, buffer, &size);
  if (status != MFRC522::STATUS_OK) {
    Serial.println(F("MIFARE_Read() failed: (R)"));
    Serial.println(mfrc522.GetStatusCodeName(status));
    return;
  }

  Serial.println(F("Read data: "));
  for (byte i = 0; i < 5; i++) {
    Serial.write(buffer[i]);
       buffer2[i]=buffer[i];
    }
       
  client.publish("spotify/rfid/idlms", buffer,5);
  delay(1000);
  mfrc522.PICC_HaltA();
}

unsigned long getCardId() {
  byte readCard[4];
  for (int i = 0; i < 4; i++) {
    readCard[i] = mfrc522.uid.uidByte[i];
  }
  return (unsigned long)readCard[0] << 24
    | (unsigned long)readCard[1] << 16
    | (unsigned long)readCard[2] << 8
    | (unsigned long)readCard[3];
}

PCBs !

Got my new PCBs in.

My Bus Manipulator, Backplane for 6502, and C64 PLA replacement.

I’m selling the leftover PCBs if you are interested.

These are not the final versions.
They should work, but they lack holes for stand-offs or feet.

Example setups for the backplane.
Using a flatcable or direct connection to my 6502 SBC.

The backplane was designed to be chained together.
(Horizontal female – male connection)

The vertical cards I’ve planned to make are:

  • ACIA – Serial Interface
  • Sound Card (SID/AY-2-8910)
  • External Display
  • ?

68000 FC signals and Latch demo for Bus Controller

PROCESSOR FUNCTION CODES (FC0, FC1, FC2)
These function code outputs indicate the mode (user or supervisor) and the address space type currently being accessed.

The following table shows the
meaning of these three bits.
FC2 FC1 FC0 Meaning
0 0 0 Not used
0 0 1 User data
0 1 0 User program
0 1 1 Not used
1 0 0 Not used
1 0 1 Supervisor data
1 1 0 Supervisor program
1 1 1 Interrupt Acknowledge
These outputs can therefore inform external circuitry what is happening
inside the 68000. They could, for example, be used to switch in differentbanks of memory.

Using a small 8266 with a display, I wanted to see if it’s useful to monitor this information.

So using a trick with the uln2804 as level convertor (don’t connect the VCC, and the output will drop to a level that is around the 3.3v.
(I was out of bi-directional level convertors)


Latch demo

I’ve been using latches in the past, but I wanted to show how it works using a little demo setup.
Below movie is for the Bus Controller I posted recently.

68000 Testing

While busy fixing my business site, and working for a customer, I build a testing rig for the 68000.

I first made a power-on reset schematic.
The timing is different from the 6502 power-on reset, and the 68k needs HALT and RESET being pulled low.

Inverted reset signal (before the 74ls06 invertor)
Schematic with poweron reset, some leds and 8mhz crystal
Lines pulled to GND or VCC are at least needed to get a running CPU.
Data bus resistors are needed because data is r/w

All Data lines are pulled low, emulating opcode 00 00
https://68k.hax.com/ORI%20to%20CCR
This will do nothing weird, and will increment the address and try to read the next opcode.
Resulting in an endless incrementing address bus, I’ve put a Led (Red)on Address A17.

Yellow is /RESET signal and Blue /HALT

Notes for next projects I made using our short holiday in Madeira.

I think we’ve seen Maderia .. 🙂

I bought a little notebook while being there.
I wrote about 12 pages of ideas, schematics and projects to start.

  1. Rewrite Wozmon to use my composite pcb (Atmega328)
    access though via
  2. Building a 68000 pcb with a minimal machine code monitor.
    Using a atf22v10 as address decoder.
    (Same as my 6502 , I love those devices)
    Maybe I’ll add a micro sdcard reader
  3. Add a lcd matrix display to my 8088/8086
  4. Creating a PLA alternative for C64 using ath22v10 (again)
  5. Make backplanes for my 6502, so I can plug cards with different POC cards.
    Clockcard, Latched bus leds, multiple VIA’s, IRQ controller, SID + Buzzer (Maybe also AY-3-8910, see other posts), LCD, composite, serial, Matrix and serial_usb) keyboard)
  6. IRQ controller because I have some devices without opendrain, so I can’t tie all IRQ’s together
  7. Amiga Chip Mem mod for rev 5 (using a ‘new’ 8372A)
  8. 8085 Cartridge new approach
  9. C64Pico fix and add backplane + breadboard version for POCs
  10. … more
First version PLA with atf22v10
PCB mockup (two ATF22v10 on top and a wide pin setup for placement in C64
Wide PLA

8085 Cartridge revisited

Working on 8085 cartridge

Problem with cartridge: prg is 17k, exomized 10k.
So you need 2 banks of 8k.
This disables basic rom, needed for the program.
The program needs to be relocated to 0x800 anyway.
So my exomizer options will take care of that.
But the basic is not being enabled again.

exomizer sfx sys -o data.exo -Di_ram_enter=\$37 -Di_ram_during=\$34 -f'LDA #$37 STA $01' 8085.prg 
xa frame.asm -o frame.bin
x64 -cart16 frame.bin 

Result … JAM

C64Pico part 3

Today we worked on this project again. (Bigred and me)

There were some problems we needed to fix since last time:

  • It was quite hard to get the correct parts.
    Our display connector was only fitted with connection pins on the wrong side of the connector. (up/down)
    So I bought a connector with both positions populated.
    So we had to replace this hard to solder (40 pin) connector.
  • It was not clear what the orientation should be of the atmega328pb.
    We looked at the pinout, and followed the VCC/GND. But these are also available of the opposite side of the chip. (We missed that)
    Later, we saw a tiny line on the PCB, which showed the pin 1 placement.
    So we had to remove and replace the chip.
    When turning on the power, (with incorrect placement) probably fried R5 (10k resistor), on both our boards.
    Had to replace those also.
  • Programming the atmega328pb was not easy, see below fixes.
  • Compiling the pico firmware resulted in a black screen.
    Below the fixes I had to make to get the screen working.

Other things still to fix.

  • Bigreds screen.
  • atmega328p didn’t work for Bigred, so probably needs to replace with the pb version.
  • My battery controller is not charging.
    See bottom of page
  • Some of my buttons are working. The pewpew and some of the cursor keys (not as I expect, there are some up/down issues)
    And none of the other keys are working.

Some other things we noticed.

  • sdcard: remove partitions, format using mkfs.exfat
    Create a c64 directory on this filesystem where you can put the d64 files!
  • 0402 SMD is far too small for me.
    There is enough room on the board to use 0805 for example.
    Even THT is possible, there are only a few components.
  • Some components are TOO close together, removing a component resulted in other small parts disconnecting also.

My friend Bigred said: If I can see it, I can solder it.
But it is not easy. This probably keeps a lot of people from building it!

Below the diff from the source we got from:

https://github.com/silvervest/MCUME/tree/c64pico

UPDATE 20240501: We needed to clone the c64pico branch!

git clone -b c64pico https://github.com/silvervest/MCUME.git

Then it worked with the screen and keyboard!

Programming the atmega328pb using usbasp

https://www.henriaanstoot.nl/2022/06/30/morse-with-a-attiny85/
Link above shows the programmer.

To get your Arduino IDE up and running

  • Open the Arduino IDE.
  • Open the File > Preferences menu item.
  • Enter the following URL in Additional Boards Manager URLs:https://mcudude.github.io/MiniCore/package_MCUdude_MiniCore_index.json
  • Open the Tools > Board > Boards Manager… menu item.
  • Wait for the platform indexes to finish downloading.
  • Scroll down until you see the MiniCore entry and click on it.
  • Click Install.
  • After installation is complete close the Boards Manager window.

Above settings worked for me, maybe you can also try Programmer: usbasp (slow)

First install the bootloader.

When compiling the keyboard program of silvervest, you can find “Upload using programmer” in the Sketch menu!
(https://github.com/silvervest/c64pico/tree/master/keyboard)

CHARGING using BQ24230RGTT

Maybe I’ve got a problem with the ground plating of the charger.
Also very hard to solder the sides!

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.