While attending Bornhack 2024 in Danmark, I came up with the below fun ideas.
Using Python and OpenCV, I made some funny webcam hacks.
Note: My laptop webcam is very bad, a better webcam should give you a more stable result.
First, a virtual workspace flipper. Just using my head movement to flip through my virtual desktops. (Turning left and right)
Next, an image viewer. Using your head movement up, down, left and right to control the image. Note : this is not the same movement as above. This won’t use rotation of your head!
Although there are bad hackers (black hat), the term hacker is being used to describe people who are using technology alternative or even hack food and drinks. Create something new or improve. Mostly using computers, but think of it in a broad way. Programming, 3D designing or printing. Learning new things.
We (me and my girlfriend) went with Bigred (and his girlfriend) and Tyrone. Both good old friends.
With Bigred I made a mini C64 Badge in the last few months. With Tyrone I started coding 6502 Machine Language again. (Planning to release a demo at X2025)
Old badges I boughtExplaining my compile pipeline to TyroneSoldering bus manipulatorCampsite
Stuff I did there:
Programming demo parts (Sprite multiplexing, Music Sync)
Made some demo graphics
Programmed some shaders
Circuit Python hacking on the Badges, no new one this year 🙁
Soldering my Bus Manipulator
Python to generate SIN tables (acme output) !byte $CA,$FE,$BA,$BE
Coding 101 with Tyrone (Acme pipeline, Git and MircoPython on his MCH badge)
Drank too much
Slept too short
Removing gallons of rain water from Tyrone’s tent.
Mini shader in GLSL language
After a week of hacking, we went for a short holiday in Denmark.
Visiting Viking Museums, Old cosy towns, WWII bunkers, the Beach and more. Driving back to the Netherlands, we visited the only surviving VII-C U-boat in the world. (Same as I 3D printed for the Uboot game)
The lone surviving example, U-995, is on display at the Laboe Naval Memorial located in Laboe, Schleswig-Holstein, Germany
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];
}
I’ve connected the rotary encoder directly to the zero. Although many websites state that you need pull-up resistors, there is no need. Just use the internal pull-up resistors in the Pi.
Example code
GPIO.setmode(GPIO.BCM) # Use BCM mode
GPIO.setup(self.24, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(self.25, GPIO.IN, pull_up_down=GPIO.PUD_UP)
NOTE: Between 24 and 25 is a GND connection
Besides USB HID below XT, C64 and Amiga connectors will be emulated
C64XTAmigaC64
"If something is worth doing, it's worth overdoing."