After fooling around on my trusty Weber, i bought myself a offset smoker.
My good friend Vincent, talked me into buying a big metal beast, and i never had any regrets.
After fooling around on my trusty Weber, i bought myself a offset smoker.
My good friend Vincent, talked me into buying a big metal beast, and i never had any regrets.
A box with macro buttons for your PC using Arduino Leonardo
#include <Keypad.h> // matrix read #include <Keyboard.h> // keyboard out #define ENABLE_PULLUPS // fuck the resistors #define NUMBUTTONS 25 // matrix #define NUMROWS 5 // matrix rows #define NUMCOLS 5 // matrix cols int analog1 = A3; int analog2 = A7; int inPinctrl = 3; // function ctrl, pull to vcc int inPinalt = 4; // function alt, pull to vcc int valctrl = 0; // variable to store shifter int valalt = 0; // variable to store shifter int joyx = 0; int joyy = 0; //define the symbols per key char buttons[NUMROWS][NUMCOLS] = { {'q','w','e','r','t'}, {'y','u','i','o','p'}, {'a','s','d','f','g'}, {'h','j','k','l','z'}, {'x','c','v','b','n'}, }; // q-1 (star) e-zoomin r-prev t-up // y-2 u-clearstar o-open p-down // a-3 (rate) d-zoomreset f-full g-left // h-4 j-clearrate l-esc z-right // x-5 c-slideshow v=zoomout b-next // 14 16 10 9 8 // 21 q y a h x // 20 w u s j c // 19 e i d k v // 18 t p g z n // 15 r o f l b byte rowPins[NUMROWS] = {16,20,19,18,15}; //connect to the row pinouts of the keypad byte colPins[NUMCOLS] = {14,7,10,9,8}; //connect to the column pinouts of the keypad //initialize an instance of class NewKeypad Keypad buttbx = Keypad( makeKeymap(buttons), rowPins, colPins, NUMROWS, NUMCOLS); void setup() { Serial.begin(115200); // debug out baud pinMode(inPinctrl, INPUT); // sets the digital pin 3 as input pinMode(inPinalt, INPUT); // sets the digital pin 4 as input digitalWrite(inPinctrl, HIGH); // turn on pullup resistors digitalWrite(inPinalt, HIGH); // turn on pullup resistors Keyboard.begin(); // keyb starter } void loop() { // loop the program CheckAllButtons(); // check tha buttons } void CheckAllButtons(void) { joyx = analogRead(analog1); joyy = analogRead(analog2); Serial.println(joyx); Serial.println(joyy); if (joyx > 900) { Keyboard.press(KEY_UP_ARROW); delay(150); Keyboard.releaseAll(); } if (joyx < 200) { Keyboard.press(KEY_DOWN_ARROW); delay(150); Keyboard.releaseAll(); } if (joyy > 900) { Keyboard.press(KEY_LEFT_ARROW); delay(150); Keyboard.releaseAll(); } if (joyy < 200) { Keyboard.press(KEY_RIGHT_ARROW); delay(150); Keyboard.releaseAll(); } char key = buttbx.getKey(); if (key != NO_KEY) { valctrl = digitalRead(inPinctrl); // read the function pin valalt = digitalRead(inPinalt); // read the function pin Serial.write(valctrl); // debug Serial.println(); // enter Serial.write(valalt); // debug Serial.println(); // enter Serial.write(key); // debug Serial.println(); // enter // button 1 if (key == 'q') { if (valctrl == 0) { // function shifter active? Keyboard.press(KEY_LEFT_CTRL); } if (valalt == 0) { // function shifter active? Keyboard.press(KEY_LEFT_ALT); } Keyboard.press('1'); delay(150); Keyboard.releaseAll(); } // button 2 if (key == 'y') { if (valctrl == 0) { // function shifter active? Keyboard.press(KEY_LEFT_CTRL); } if (valalt == 0) { // function shifter active? Keyboard.press(KEY_LEFT_ALT); } Keyboard.press('2'); delay(150); Keyboard.releaseAll(); } // button 3 if (key == 'a') { if (valctrl == 0) { // function shifter active? Keyboard.press(KEY_LEFT_CTRL); } if (valalt == 0) { // function shifter active? Keyboard.press(KEY_LEFT_ALT); } Keyboard.press('3'); delay(150); Keyboard.releaseAll(); } // button 4 if (key == 'h') { if (valctrl == 0) { // function shifter active? Keyboard.press(KEY_LEFT_CTRL); } if (valalt == 0) { // function shifter active? Keyboard.press(KEY_LEFT_ALT); } Keyboard.press('4'); delay(150); Keyboard.releaseAll(); } // button 5 if (key == 'x') { if (valctrl == 0) { // function shifter active? Keyboard.press(KEY_LEFT_CTRL); } if (valalt == 0) { // function shifter active? Keyboard.press(KEY_LEFT_ALT); } Keyboard.press('5'); delay(150); Keyboard.releaseAll(); } // button i - clear rate if (key == 'i') { Keyboard.press(KEY_LEFT_CTRL); Keyboard.press('0'); delay(150); Keyboard.releaseAll(); } // button k - clear label if (key == 'k') { Keyboard.press(KEY_LEFT_ALT); Keyboard.press('0'); delay(150); Keyboard.releaseAll(); } // button v - slideshow if (key == 'v') { Keyboard.press(KEY_ESC); Keyboard.press(KEY_LEFT_CTRL); Keyboard.press('s'); delay(150); Keyboard.releaseAll(); } // button t - zoomin if (key == 't') { Keyboard.press('+'); delay(150); Keyboard.releaseAll(); } // button g - zoomreset if (key == 'g') { Keyboard.press('*'); delay(150); Keyboard.releaseAll(); } // button n - zoomout if (key == 'n') { Keyboard.press('-'); delay(150); Keyboard.releaseAll(); } //r o f l b // button r - prev if (key == 'r') { Keyboard.press(KEY_LEFT_CTRL); Keyboard.press(KEY_LEFT_ARROW); delay(150); Keyboard.releaseAll(); } // button o - open if (key == 'o') { Keyboard.press(KEY_RETURN); delay(150); Keyboard.releaseAll(); } // button f - full if (key == 'f') { Keyboard.press('f'); delay(150); Keyboard.releaseAll(); } // button l - esc if (key == 'l') { Keyboard.press(KEY_ESC); delay(150); Keyboard.releaseAll(); } // button b - next if (key == 'b') { Keyboard.press(KEY_LEFT_CTRL); Keyboard.press(KEY_RIGHT_ARROW); delay(150); Keyboard.releaseAll(); } } }
Why? Because i can
While on holiday in New Zealand i made photos of a rock i found on the campsite we where. Nothing special about the rock, but it was a nice subject to try to replicate.
So i took many many pictures of the stone from all sides.
Imported those images in meshroom and convered it to a 3D stl object.
Printing and airbrushing
Added some grass from our clock project
For measuring pressure in fermentation containers, I designed a pressure sensor which could be wireless connected to a fermentation container.
The sensor would transmit the values to a Raspberry which was configured as a Access Point and would store the measurements and generated graphs using Grafana.
Nodes config:
Esp configuration, connect with micro-usb
Flashing with linux
esptool.py -p /dev/ttyUSB0 write_flash 0x00000 ESP_Easy_mega-20190311_normal_ESP8266_4M.bin
Make a connection with the ESP Access point
Connect esp with a power source.
Look for a AP with ESP_Easy_0
Use password “configesp” to connect
Start you browser and enter http://192.168.4.1
In wifi wizard setup select “pressurespot”
Enter password “pressurespot”
Press connect
Wait 20s and look in the raspberry logs which IP the ESP got.
Connect laptop/mobile to wifi “pressurespot”and connect
Enter found IP from ESP in your browser.
Proceed to main config
Main setting table, set the following
Press controller tab
Press first edit button and set following
– Protocol: domoticz http
Next set
– Controller IP : 10.42.0.1
– Toggle enabled and press submit
Resulting in:
Next we got to Hardware
I2C interface switch GPIO-4 and GPIO-5
Devices TAB
Press edit, and select device “Environment – BMx280” from the pulldown menu.
Next, set the following
In the Devices tab, you should be able to see the sensor with the values (Temperature and pressure)
No values? Do a i2c scan and/or reboot ESP ( You can find these in the tools tab)
Tools TAB
Press I2C scan, when seeing a address like 0x76 or 0x77 use this in previous tabs.
Still nothing, even after reboot? Maybe faulty hardware?
Everything okay? Back to the config tab
We are going to set the sleep mode.
Warning ! .. when setting this it is hard to get into the config pages again.
ESP will startup, connect to wifi, send values and goes to sleep again.
At the bottom set: Sleep awake time 1 sec
Buttons on the raspberry / pressurespot
Red button :
Led lights on the sensors
Add shutdown script to /etc/rc.local
python /usr/local/bin/power-switch.py &
/usr/local/bin/power-switch.py
#!/usr/bin/python import threading, subprocess import RPi.GPIO as GPIO def shutdown(): subprocess.call('sudo shutdown -h now', shell=True) def edge_detected(pin): if GPIO.input(pin): t.cancel() subprocess.call('sudo reboot', shell=True) else: t.start() if __name__ == '__main__': try: GPIO.setmode(GPIO.BOARD) GPIO.setup(5, GPIO.IN) GPIO.add_event_detect(5, GPIO.BOTH, callback=edge_detected, bouncetime=10) t = threading.Timer(3.0, shutdown) while True: pass finally: GPIO.cleanup()
/usr/local/bin/ledoff.py
#!/usr/bin/python import RPi.GPIO as GPIO import time GPIO.setmode(GPIO.BCM) GPIO.setwarnings(False) GPIO.setup(18,GPIO.OUT) GPIO.output(18,GPIO.LOW)
/usr/local/bin/ledon.py
#!/usr/bin/python import RPi.GPIO as GPIO import time GPIO.setmode(GPIO.BCM) GPIO.setwarnings(False) GPIO.setup(18,GPIO.OUT) GPIO.output(18,GPIO.HIGH)
nmcli device wifi hotspot ssid pressurespot password pressurespot
/etc/NetworkManager/system-connections/Hotspot-1
[connection]
id=Hotspot-1
uuid=c2c05528-63f9-44c7-93ce-264187a45086
type=wifi
permissions=
timestamp=1553708934
[wifi]
hidden=true
mac-address=B8:27:EB:7F:D5:E7
mac-address-blacklist=
mode=ap
seen-bssids=B8:27:EB:7F:D5:E7;
ssid=pressurespot
[wifi-security]
group=ccmp;
key-mgmt=wpa-psk
pairwise=ccmp;
proto=rsn;
psk=pressurespot
[ipv4]
dns-search=
method=shared
[ipv6]
addr-gen-mode=stable-privacy
dns-search=
method=ignore
/usr/bin/servicecheck.sh (in rc.local and crontab root user – every minute
#!/bin/bash nmcli connection show | grep "Hotspot-1 c2c05528-63f9-44c7-93ce-264187a45086 802-11-wireless wlan0" >/dev/null && touch /tmp/wlan || rm -f /tmp/wlan for f in influx domoticz telegraf grafana mosquitto ; do pgrep $f >/dev/null && touch /tmp/$f || rm -f /tmp/$f done count=$(ls /tmp/influx /tmp/domoticz /tmp/telegraf /tmp/grafana /tmp/mosquitto /tmp/wlan | wc -l) if [ $count -eq 6 ] ; then /usr/local/bin/ledon.py exit 0 fi for timer in {1..10} ; do /usr/local/bin/ledon.py sleep 1 /usr/local/bin/ledoff.py sleep 1 done
Rest services to be installed on Raspberry
At the moment the raspberry uses domoticz between the Mqtt broker (Mosquitto) and the database (Influx)
Data wil be displayed using grafana.
tail -f /var/log/syslog shows which ip to which ESP
DHCPACK(wlan0) 10.42.0.104 cc:50:e3:c4:96:61 lab-
DHCPACK(wlan0) 10.42.0.181 cc:50:e3:c4:8d:73 lab-4
DHCPACK(wlan0) 10.42.0.186 cc:50:e3:c4:9b:ef lab-1
Configuring the raspberry
Install influx and grafana
First we add Influx repositories to apt:
wget -qO- https://repos.influxdata.com/influxdb.key | sudo apt-key add - source /etc/os-release echo "deb https://repos.influxdata.com/debian $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/influxdb.list
Update apt with the new repo & install.
sudo apt update && sudo apt install -y influxdb
Then start the influxdb
service and set it to run at boot:
sudo systemctl enable influxdb --now
Again we need to add the Grafana packages to apt:
wget -q -O - https://packages.grafana.com/gpg.key | sudo apt-key add - echo "deb https://packages.grafana.com/oss/deb stable main" | sudo tee /etc/apt/sources.list.d/grafana.list
We can now update and install the binaries:
sudo apt update && sudo apt install -y grafana
Then simply enable the service and set to run at boot:
sudo systemctl enable grafana-server.service --now
Now we can check that grafana is up by loading it in a browser: http://10.42.0.1:3000
. If so, you can log in with the username and password = admin
and set a new admin password.
Install mosquitto
sudo apt install mosquitto mosquitto-clients
Install domoticz using below command
<code><strong>curl -sSL install.domoticz.com | sudo bash</strong></code>
Under hardware add MQTT server adress 127.0.0.1
Add virtual sensors to domoticz.
Click hardware and create virtual sensor, lab with sensornumber. Sensor type is Temp+Baro.
When looking at devices you will see the virtual devices.
Pushing the data into Influxdb:
Goto settings > more options > data push > influxdb
Add temperature
Add barometer
Configure Grafana
Go with your browser to http://10.42.0.1 when connected to the rpi access point
Goto settings and data sources, add influxdb with source http://localhost:8086
Goto dashboard and create a new one.
TODO
Telegraf/mosquito
Services in domoticz
Rpi status display
Sensor test / monitor
Today i did a workshop ‘making your own sausage’ with Monique.
After the workshop i bought my own meat grinder.
see : https://www.henriaanstoot.nl/2019/07/14/slavink-en-hamburgers/
Some books about the subject we own
When using Spice and VNC to virtual machine consoles, and remote consoles like idrac and ilo, it is not alway possible to copy-paste.
When doing maintenance it is a annoyance to type a super strong and long password by hand, Prone to typing errors, timeouts. And following lockouts.
So i wanted to auto type the password.
First solution was to bind a little bash script to a key combination.
#!/bin/bash # Usage: make a keypress shortcut to this script # activate shortcut, and the script wil give you 10 seconds to click and focus remote console window. # It pastes the password, and you can press enter to login # ( you can use xdotool also to press enter for you ) sleep 10 xdotool type "SUP3Rl00000ngandcompl3xpasswo0d@#@#@#%$%$%%$-you-cant-type-me-without-erors"
I’ve bound this to a key combination on my workstation.
gsettings set org.gnome.settings-daemon.plugins.media-keys custom-keybindings "['/org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom0/']" gsettings set org.gnome.settings-daemon.plugins.media-keys.custom-keybinding:/org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom0/ name 'passpaste' gsettings set org.gnome.settings-daemon.plugins.media-keys.custom-keybinding:/org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom0/ command '~/bin/passpaste.sh' gsettings set org.gnome.settings-daemon.plugins.media-keys.custom-keybinding:/org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom0/ binding '<Super>p'
This works, but only where this script is installed.
So not on colleagues machines, workstations with windows, and the super secret admin/root account sits in a file.
So i made a password key, which count be behind lock and key.
Using a digistump, a push-button and a resistor, the passpaster was born.
Program to flash on the digistump
#include "DigiKeyboard.h" void setup() { DigiKeyboard.sendKeyStroke(0); DigiKeyboard.delay(1000); } void loop() { if (digitalRead(0) == HIGH) WorkPass(); if (digitalRead(1) == HIGH) LtPass(); } void WorkPass() { DigiKeyboard.print("SUP3Rl00000ngandcompl3xpasswo0d@#@#@#%$%$%%$-you-cant-type-me-without-erors"); DigiKeyboard.println(); DigiKeyboard.delay(50); setup(); } void LtPass() { DigiKeyboard.print("secondlongpasswordifyouareusingtwobuttons"); DigiKeyboard.println(); DigiKeyboard.delay(50); setup(); }
Plug the Digispark into you machine, it wil emulate a HID device (Keyboard).
Get your remote console into focus, press button .. presto!
TODO:
It would be nice to have something like:
Rotary encoder 1 – selects which password to paste
Rotary encoder 2 – (1-255) does a encryption method on the password
Display shows : Password #32 – Crypt # 88
So you can have for example 255 passwords with 255 encryptions .. which to use when? Only you know.
Above can’t be done with a Digispark, so i’ll have to use a Arduino Pro Mini or a equivalent
Made a design for my Laptop, using a Wordcloud which i’m going to print using a transparent sticker.
While traveling New Zealand we went to see Mt Taranaki
Mount Taranaki (Māori: Taranaki Maunga), also known as Mount Egmont, is a dormant stratovolcano in the Taranaki region on the west coast of New Zealand’s North Island. It is the second highest point in the North Island, after Mount Ruapehu.
I made this timelapse using a Nikon D750.
Convert a series of jpgs into a mp4
ffmpeg -f image2 -r 24 -start_number 8296 -i "750_%04d.JPG" -vcodec libx264 -profile:v high444 -refs 16 -crf 0 -preset ultrafast -vf scale=1920:1080 output.mp4
I’ve got a backup disk for my photos.
You can connect it via USB and has a SDCard slot for your camera SDCards.
You can also connect to is using it as a Wifi Access Point.
(You can even install twonky!)
The cardreader should automatically copy a inserted card to its internal harddrive.
I’ve tested this at home, but here in New Zealand it woudn’t work.
So i started investigating.
(I was in the middle of nowhere, so I could not search for answers.)
I’ve got the juice ssh client on my phone.
Connecting to the AP will give you a IP, but whats the IP from de WD?
Just use JuiceSSH to make a local connection (to your android) first.
And type: ip neigh
This will give you the ip from neighbouring devices, thats only one .. the WD.
Connect to the WD with ssh using root@IPNUMMER (password should be same as you configured the device with)
Looking at the logs gave me some idea where the problem was.
It would not mount the sdcard! Why, that one is working.
(In de Nikon Camera and using a cardreader with OTG on my android)
I first wrote my own mounter and copy program. That worked, so i could at least backup my photos.
Now I could search for the problem.
mkdir /tmp/fash ; mount /dev/mmcblk0p1 /tmp/fash mounts okay!
The sdmount.sh has a problem, it uses the timezone in its script.
This will work when in GMT+12 -> GMT-12.
But we are in NZ .. thats GMT+13
Removing some checks in above script (sdmount.sh)
(Adding timeoffset_min=8)
Made the script work for me again.
When I got home from our trip, I flashed a new firmware version on the device, which corrected the problem.