Bought some tunebooks in Scotland

While visiting the Ardbeg dristiller on Isle of Islay, i notished a tunebook with CD in the whiskyshop. Tunes for multiple instruments and pipe settings .. interesting! Fraser Shaw, didn’t know who he was. The tunes in the book looked interesting. I bought both .. we will see.

While reading more about him, i learned he was a driving force on the islands when it comes to folk music. Sadly he died by a illness .. far to soon. While on holiday we drove by some places he was know to play.
Tunes for whistle with guitar chords and pipe settings. Some tunes are in a complex time measure. I lost the CD but it is on spotify .. favourites: £50 Cashback and Air Chall

While visiting the Kildonan Museum in South Uist, i found a tunebook which was compiled of tunes from a piper named: Calum Campbell.

This oldskool piper wrote some amazing tunes. The book was made after he, his daughter and her two children lost their lives in a heavy storm in 2005.
2005 Was a bad year .. we lost John D Burgess, Martyn Bennett and Gordon Duncan the same year.

On our way home we visited the Morpeth Chantry Bagpipe Museum.

Most of the pipes here where Northumbrian bagpipes and some borderpipes ( even a shuttlepipe )

Our Northumbrian pipes

In the touristy shop i found these books, amoung others.

Last two are Duets/Trios also for different instruments .. nice!

English humour

One of my first encounters with English Humour was when my wonderful teacher Mrs Walraven rolled in the old VCR-on-cart when i was going to technical secondary school (MTS)

She showed us Monty Python, Faulty Towers and Black Adder. THIS is the humour i like, this is for me!

So from that point on i wanted to see English Humour.

There are standup comedians i like, Billy Connolly (seen him live), Eddie Izzard (seen him live), Michael McIntyre and Jimmy Carr (tickets!!!) to name a few.
Life stories, wierd confronting idea’s and realisations of things , Real life observations and Dark humour. (in that order)

Billy Connolly 2016

But i wanted to tell about TV shows (i try to place them in order):

Monty Python
One of the first things i saw, great stuff. Liked the movies also.

Black Adder
Loved the way it was the character Rowan Atkinson played got smarter every ‘season’, and Tony Robinson (Baldrick) was getting dumber.
The last ‘season’ WWI was when all things where exactly right.
(Yearly rewatch)

Not the nine o’clock news
This one i need to review

The Young Ones
A series that broke boundaries like Monty Python.
First time i notished the perfect duo, Rik Mayall and Ade Edmonson

Fawlty Towers
To few episodes, but each a brilliant piece of work.
Superb characters! (Yearly rewatch)

Red dwarf
Great stuff, loved the characters. And the space setting

Mr Bean
Great (silent) performance of Rowan Atkinson.
Liked his One man show more i think.

Bottom
Then i learned about Bottom. It was the genius jokes and performances.
The 5 liveshows where even more amazing. (Yearly rewatch)
Also i have to mention the movie : Guest House Paradiso

So i went looking for more:

Filthy Rich & Catflap
Secret Policeman’s Ball
(not really a TV series)

Then i came across a oldie …

At last the 1948 show
A predecessor of Monty Python with Marty Feldman

Do not adjust your set
Also with guys who did Monty Python later on.

Today i was in Uist on holiday in Scotland, talking about these show.
The B&B owner said “Do you know – Ripping Yarns???”
So that’s the next to find and view!

Others i have to mention:
Alas Smith and Jones
The Bleak Old Shop of Stuff
Allo allo


The location where the bench was from the intro of Bottom the TV series. Now a plaque is there, which reads: “Rik Mayall. 1958-2014. Punched his friend in the balls on a bench near this spot.”

Photo timelapse slider fixed

I got my DIY timelapse slider out of storage, and notished it wasn’t working any more.
I’t was a quick and dirty build, using minimal components and could be build with minimal effort.
We could not take a lot of stuff with us to New Zealand.
Camera and powerbanks, those we always take with us. So i only needed:

  • Raspberry Pi
  • Steppermotor and a plastic sheet where it was mounted on (using tiewraps you can undo)
  • Timingbeld
  • Two metal feet it was mounted on

It had to be build strong enough to hold a Nikon 750, and didn’t get out of balance when moving the camera on two metal tubes i bought in NZ.

The RPI would not start anymore, just a red power smd led. SO it didn’t boot.
Taking the mini sdcard out of the raspberry trying to put it in my cardreader .. note the trying part.
The damn thing broke into two parts, never seen anything like it.
Damn, did i backup the latest version? No, i used my mobile and wifi in NZ to modify the scripts.
Well .. “We can rebuild him, we have the technology”

How does it work?

Stepper motors move my camera over two metal rods, with ball bearing wheels.
The raspberry controls my nikon using a usb cable. Mounted on the raspberry is a steppermotor hat (adafruit) which can control DC motors and stepper motors. ( In this project i used only one stepper )
The stepper motor carries the platform containing itself, a raspberry and my nikon over the “rails”
Two switches on each side sends a signal to the program to stop.
All timing are set via the Webgui.

Steps

  • At reboot, python script wil be started
  • Moving platform to the left, until switch detects the edge
  • Waiting for in structions
  • Entering for example timer 30, speed 10 and r
  • Platform wil move distance 10 to the right
  • Wait 30 seconds
  • Grab a picture
  • And loops until end of rod reached, then it wil move to left again.

Notes:

  • Gphoto works with other camera’s also
  • When placing the camera on the platform, focus once. Disable autofocus, also put your camera in manual mode, setting Apeture, ISO and shutterspeed same as your test photo. (bear in mind: when doing sundown shots maybe start with a little light over compensation)

Below old 2018 version

New Sdcard. Format, put lite on this

# install gphoto2
apt-get install photo2
# connect nikon with usb, capture test with
gphoto2 --capture-image-and-download --interval 5
# Next steppers
apt-get install python3-pip
pip3 install adafruit-circuitpython-motorkit
# enable I2C
raspi-config -> enable i2c
reboot

# Test python script
import time
import board
from adafruit_motorkit import MotorKit

kit = MotorKit(i2c=board.I2C())

for i in range(100):
    kit.stepper1.onestep()
    time.sleep(0.01)

# Create a API
apt-get install python3-flask python3-flaskext.wtf

I’m using my phone in Hotspot mode, Timelapser will connect to my phone.
Open a browser and enter : http://<ip of timelapser>:8080/form

timer in seconds to shoot pictures
speed is the movement on the rail
go = r(ight) or l(eft)
go + timer 0, move until you reach the end (switch detect)

Todo: Need to change CSS to mobile responsive gui .. like my quizzer

import time
import subprocess
from flask import Flask, jsonify
from multiprocessing import Process, Value
from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField, BooleanField, SubmitField, TextAreaField
from wtforms.validators import DataRequired
from flask import Flask, render_template, request
from flask import render_template
import board
from adafruit_motor import stepper
from adafruit_motorkit import MotorKit
import RPi.GPIO as GPIO
import os; myenv = os.environ.copy(); myenv["LANG"] = "C"


# NOTE: 
# timer = seconds between shots
# speed = distance stepper travel

# Using gpio pins to detect max left/right with switches
# BCM Numbering
GPIO.setmode(GPIO.BCM)
# pullup to 17 &amp; 18
GPIO.setup(17, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(18, GPIO.IN, pull_up_down=GPIO.PUD_UP)

# Stepper HAT is i2c
kit = MotorKit(i2c=board.I2C())

kit.stepper1.release()

global timer
global speed
timer=0
speed=0
go="nix"

app = Flask(__name__)
app.config['SECRET_KEY'] = 'you-will-never-guess'

class FormForm(FlaskForm):
    timer = StringField('timer', validators=[DataRequired()])
    speed = StringField('speed', validators=[DataRequired()])
    go = StringField('go', validators=[DataRequired()])
    submit = SubmitField('Send control')

# Make below in something like : nikon record .. slowly 10s to the right and recording stop?
# Or bounch left/right using gpio sensors
@app.route("/control/&lt;time&gt;/&lt;speed&gt;")
def action(number, message):
 
    time.sleep(1)

# Print form on: http://&lt;IP&gt;:8080/form = start page 
@app.route("/form")
def form():
    form = FormForm()
    return render_template('web.html', title='Web slide control', form=form)


# process form
@app.route('/data', methods = ['POST', 'GET'])
def data():
    if request.method == 'GET':
        return "The URL /data is accessed directly. Try going to '/form' to submit form"
    if request.method == 'POST':
         
        timer = request.form['timer']
        speed = request.form['speed']
        go = request.form['go']
        timer = int(timer)
        speed = int(speed)
        if timer == 0:
            print("Turn off")
            p = Process(target=record_loop, args=(False,speed,timer,go))
            p.start() 
            if str(go) == "l":
               while GPIO.input(17) == True:
                kit.stepper1.onestep(direction=stepper.FORWARD)
                time.sleep(0.01)
            if str(go) == "r":
               while GPIO.input(18) == True:
                kit.stepper1.onestep(direction=stepper.BACKWARD, style=stepper.DOUBLE)
                time.sleep(0.01)

        else: 
            print("Turn on")
            p = Process(target=record_loop, args=(True,speed,timer,go))
            p.start()  
# print form again
        form = FormForm()
        return render_template('web.html', title='Web slide control', form=form)


# main loop, controls stepper and camera
def record_loop(loop_on,myspeed,mytimer,mygo):
   while True:
      if loop_on == True:
# test if switch hit yet, else move
         print('timer' + str(mytimer))
         print('speed' + str(myspeed))
         time.sleep(2)
         if str(mygo) == "l":
             if GPIO.input(17):
                print("Pin 17 is HIGH")
                for i in range(myspeed):
                        kit.stepper1.onestep(direction=stepper.FORWARD, style=stepper.DOUBLE)
                        time.sleep(0.01)
                kit.stepper1.release()
             else:
                print("Pin 17 is LOW")
         if str(mygo) == "r":
             if GPIO.input(18):
                print("Pin 18 is HIGH")
                for i in range(myspeed):
                        kit.stepper1.onestep(direction=stepper.BACKWARD, style=stepper.DOUBLE)
                        time.sleep(0.01)
                kit.stepper1.release()
             else:
                print("Pin 18 is LOW")
         time.sleep(mytimer)
         subprocess.run(['/root/mycapture'])
         subprocess.Popen([
        "gphoto2",
        "--capture-image"],stdout=subprocess.PIPE)

# Main loop
if __name__ == "__main__":
   while GPIO.input(17) == True:
         kit.stepper1.onestep(direction=stepper.FORWARD, style=stepper.DOUBLE)
         time.sleep(0.01)
   kit.stepper1.release()
   p = Process(target=record_loop, args=(False,0,0,go))
   p.start()  
   app.run(host='0.0.0.0', port=8080, debug=False)
   p.join()
Other files
cat templates/web.html 
{% block content %}
    <h1>Slide control</h1>
	    <form action="/data" method = "POST">

        {{ form.hidden_tag() }}
        <p>
            {{ form.timer.label }}<br>
            {{ form.timer(size=32) }}
        </p>
        <p>
            {{ form.speed.label }}<br>
            {{ form.speed(size=32) }}
        </p>
        <p>
            {{ form.speed.go }}<br>
            {{ form.go(size=32) }}
        </p>
        <p>{{ form.submit() }}</p>
    </form>
{% endblock %}

gphoto running from cron/python is a b*tch, had to rewrite subprocess and running from screen

Start screen @reboot, just crontab -e
# crontab entry
@reboot screen -dmS slide /usr/bin/python3 /root/control.py
RPI with Stepper Hat and two Limit switches and a stepper motor
Datasheet showing me which colors are what


Photo manager addition using ML!

A few years ago i wrote a photo manager .. again .. ( see post about my first previous photo manager )
It is a web gui to find photos in my huge photo archive.
I manually added 190k tags to 120k photos in 20+ years.

I thought wouldn’t it be nice if i can generate additional metadata using Machine Learning. A few years ago i did some testing and followed a podcast and free course about machine learning.

So today i started to implement a addition to my gui. Machine recognition tags!

It already kinda works.

Things to do :

  • Make it a background job, my fileserver doesn’t run Tensorflow on a GPU, so it is slooow
  • Embed in existing GUI and stats
  • Design a editor to remove wrong tags

Below a part of ML images

Command to get a thumbnail sheet with only directory names:

montage -verbose -units PixelsPerInch -density 300 -tile 7x6 -label "%d" -font Arial -pointsize 6 -background "#FFFFFF" -fill "black" -define jpeg:size=253x154 -geometry 253x154+2+2 -auto-orient */*.JPG -title "ML Thumbs" thumbsheet.jpg

Maybe, i can use debug output like below.

['lakeside, lakeshore (score = 0.47934)', 'seashore, coast, seacoast, sea-coast (score = 0.11385)', 'sandbar, sand bar (score = 0.08822)', 'breakwater, groin, groyne, mole, bulwark, seawall, jetty (score = 0.06281)', 'valley, vale (score = 0.01790)', '']

Scraping podcast which uses a javascript to obfuscate mp3 links

wget-ting the page only gave me flat html, but no readable links.

We need the rendered version, phantomjs wil help

wget https://bitbucket.org/ariya/phantomjs/downloads/phantomjs-2.1.1-linux-x86_64.tar.bz2

printsource.js

var system = require('system');
var page   = require('webpage').create();
var url    = system.args[1];
page.open(url, function () {
  console.log(page.content);
  phantom.exit();
});

Run phantomjs

phantomjs-2.1.1-linux-x86_64/bin/phantomjs printsource.js  https://xxxxxxxx/show/xxxx > out

So now i got the rendered page, get mp3’s and titles, for this example

cat out | sed 'N;s/\n/,/' | cut -f2,7 -d\" | while read line ; do
mp3=$( echo $line | cut -f1 -d\")
title=$( echo $line | cut -f3 -d\&gt; | tr -d '/&lt;&gt;[]]\!,;' | tr -d "'" | sed s/CDATA//g | sed s#title##g | sed s/:/-/g )
echo "$mp3 $title"
wget $mp3 -O "$title.mp3"
done

bash downloadscript
done

Portable Logitech Media Server again

See post: https://www.henriaanstoot.nl/2014/04/10/portable-squeeze-server/

In the past i’ve used a home build Logitech Squeezebox server (as it was called then), Picore player and tried volumio.
Picore player has been sitting in my livingroom for ages, but was converted to a Node-Red Dashboard and recently Home Assistant Dashboard. (Has been a dasticz daskboard also)

Today i build another version, smaller and with a screen.
Why? .. because of being ‘offline’ or ‘offgrid’ on our holidays.
The car we are driving only has a Aux input.

Most of the installation is as mentioned on:
https://docs.picoreplayer.org/projects/add-a-display/

I edited  /opt/bootsync.sh
to get /dev/sda1 mounted persistent
use pcp br after editing.

Default user/pass : tc piCore

Controlling the thing is via touch or a app on my phone using wifi hotspot.

  • Audio cable 3.5mm
  • Raspberry 3
  • Large usb thumbdrive
  • 3.5inch RPi Display – 480×320 Pixel – XPT2046 Touch Controller
  • car cigarette lighter adapter for power

PiCore uses below alliases

ceChange directory to /mnt/mmcblk0p2/tce
ceoChange directory to /mnt/mmcblk0p2/tce/optional
m1Mount the boot partition /mnt/mmcblk0p1
m2Mount the second partition /mnt/mmcblk0p2
c1Change directory to /mnt/mmcblk0p1
c2Change directory to /mnt/mmcblk0p2
vicfgEdit configuration file config.txt using vi
vicmdEdit boot file cmdline.txt using vi
u1Unmount the boot partition /mnt/mmcblk0p1
u2Unmount the second partition /mnt/mmcblk0p2

Shutting down piCore is done by cutting the power, due to everything being mounted readonly. EXEPT
When you are using LMS server installation, which uses a database.
But there is a tweak for a shutdown button.

I’m using GPIO 16 because i’ve got a screen connected.
Active LOW, means you have to connect a pushbutton/switch between GND and GPIO pin. (nearest Vcc OR Gnd)

Table lamp hack

Added: ino file 20220525

Bought a cheap table lamp a few weeks ago.
Runs on batteries and when you flip it over, it turns on or off.

I thought, when i strip this thing of its internals. I can make a wifi/mqtt enabled one.


Opening it up today, i saw a minimalistic print and a battery holder. There was a tilt switch like

Which i wanted to replace by a mercury one i bought in a bunch of sensors a few years ago.

So why go though all the trouble stripping and replacing .. so i didnt

GND and 5v to the batteries, and D4 to the tilt switch. (Measure which side you have to take!) .. I used a pull down of 3k3 ohms

Esp was flashed in the past with Easy ESP .. well lets keep that one for now.

INO version

#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <Wire.h>
#include <Ethernet.h>

const char* ssid = "SSID";
const char* password = "PASSWORD";
const char* mqtt_server = "mqttserver";
const char* mqtt_username = "";
const char* mqtt_password = "";
const char* clientID = "wankel";

const int tiltPin = 4;
int tiltState = 0;    
int previousState = 0;    
WiFiClient espClient;

PubSubClient client(espClient);

void reconnect() {
  while (!client.connected()) {
    if (client.connect(clientID, mqtt_username, mqtt_password)) {
    } else {
      delay(2000);
    }
  }
}

void setup()
{
  {
    client.setServer(mqtt_server, 1883);
    pinMode(tiltPin, INPUT);
  }
}
void loop() {
  tiltState = digitalRead(tiltPin);
  if (tiltState != previousState) {
    if (tiltState == HIGH) {
      client.publish("onoff-wankel/wankel/State", "0"); //
    } else {
      client.publish("onoff-wankel/wankel/State", "1"); //
    }
    delay(100);
  }
  previousState = tiltState;

  {
    if (!client.connected()) {
      reconnect();
    }
    client.loop();
  }
}
Node red + led server

Example is using my ledserver, see other post, but i intent to made a easy to configure node red panel where the to be controlled devices are preconfigured.

[
    {
        "id": "9ec21acaec91aecc",
        "type": "mqtt in",
        "z": "54f3b5b461471f2c",
        "name": "",
        "topic": "onoff-wankel/wankel/State",
        "qos": "2",
        "datatype": "auto",
        "broker": "8c74c5f6.9a7a48",
        "nl": false,
        "rap": true,
        "rh": 0,
        "inputs": 0,
        "x": 400,
        "y": 260,
        "wires": [
            [
                "0fe77b535517f818"
            ]
        ]
    },
    {
        "id": "159f65f444a0d7c2",
        "type": "http request",
        "z": "54f3b5b461471f2c",
        "name": "1 - 30 red",
        "method": "GET",
        "ret": "txt",
        "paytoqs": "ignore",
        "url": "http://ledserver:8080/range/01/30/ff0000",
        "tls": "",
        "persist": false,
        "proxy": "",
        "authType": "",
        "senderr": false,
        "credentials": {},
        "x": 900,
        "y": 280,
        "wires": [
            []
        ]
    },
    {
        "id": "5806fbfd0e99daab",
        "type": "http request",
        "z": "54f3b5b461471f2c",
        "name": "1 - 30 black",
        "method": "GET",
        "ret": "txt",
        "paytoqs": "ignore",
        "url": "http://ledserver:8080/range/01/30/000000",
        "tls": "",
        "persist": false,
        "proxy": "",
        "authType": "",
        "senderr": false,
        "credentials": {
            "user": "",
            "password": ""
        },
        "x": 910,
        "y": 220,
        "wires": [
            []
        ]
    },
    {
        "id": "0fe77b535517f818",
        "type": "switch",
        "z": "54f3b5b461471f2c",
        "name": "",
        "property": "payload",
        "propertyType": "msg",
        "rules": [
            {
                "t": "eq",
                "v": "0",
                "vt": "str"
            },
            {
                "t": "eq",
                "v": "1",
                "vt": "str"
            }
        ],
        "checkall": "true",
        "repair": false,
        "outputs": 2,
        "x": 660,
        "y": 260,
        "wires": [
            [
                "5806fbfd0e99daab"
            ],
            [
                "159f65f444a0d7c2"
            ]
        ]
    },
    {
        "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": ""
    }
]

Cheezy Hamburger

In the past i came up with a hamburger that most liked.
(The computer party burger)

This one is quite cheezy, and heavy cheese, so not to everyones liking.
But we loved this “experiment”!

And indeed an experiment, i’m not a cook. I only know how to smoke meat, slowcook and so on.
The only other thing i can make which gets compliments, is a real Pasta Carbonara

  • Viking blue cheese
  • Camembert cheese
    • Red onion (outer rings only)
  • Brown sugar
  • Rucola lettuce
  • Hamburger made from deer. ( Gamey taste )
    https://www.grutto.com/nl/wild/hert-pakket-groot
  • Chestnut mushrooms
  • Shitake olive oil
  • Balsamic vinegar
  • Teardrop tony roasted onion bbq sauce

Mix a lot of the cheeses and melt in the preheated oven.
Glaze the onion in olive oil and brown sugar.
Fry the mushrooms in shitake olive oil and add some balsamic vinegar.
Prepare the burgers on your BBQ, use some smoke.
(I like to put the cheese on top of the burgers the last 2 minutes or so, it will melt over the burgers and get some smoke)
Slice the burger buns in two, and put in the oven. (Sliced part down)
(until a little brown/crispy)

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