diff --git a/content/blog/raspberry-pi-temperature-monitoring.md b/content/blog/raspberry-pi-temperature-monitoring.md
index 6f2a1a0..1f8f7cf 100644
--- a/content/blog/raspberry-pi-temperature-monitoring.md
+++ b/content/blog/raspberry-pi-temperature-monitoring.md
@@ -1,7 +1,7 @@
+++
title = "Raspberry Pi 0 W + sensors + OLED display = temperature monitoring and calendar"
date = 2022-10-05
-updated = 2023-10-02
+updated = 2023-11-11
+++
@@ -22,10 +22,10 @@ When activating another display mode (not active in the picture), this area of t
yellow push switch: TRU Components PBS-18B 701912
-The components are connected to the Pi as indicated in the wiring diagram below.
+The components are connected to the Pi as indicated in the wiring diagram below (made using [Circuit Diagram](https://www.circuit-diagram.org/)).
@@ -50,7 +50,7 @@ Wiring of the AM2302 to the RPi:
Wiring of the push switch to the Pi: one pin to GPIO 19, the other to 3.3V.
-Software
+### Software
The Raspberry Pi 0 W is running Raspberry Pi OS 11 (bullseye).
@@ -74,7 +74,7 @@ It is run by another Python script (
+
+To make the whole setup look a bit nicer, I designed a casing using [OpenSCAD](https://openscad.org/).
+The image on the right shows the final result as rendered by OpenSCAD ([.scad](/assets/RPi-Zero.scad)).
+
+[Raspberry Pi 0 W - Slim Case](https://www.thingiverse.com/thing:4199739) (by OhSnap) proved to be a great base to build on.
+I added some supports around it to ensure it won't topple over as easily.
+Since I was too lazy to measure the dimensions of my OLED display, I extracted the relevant part of [Zoid, the Trapezoidal Under Cabinet 1.5" OLED Display](https://www.thingiverse.com/thing:3397089) (by rhattie).
+Feeling a little bit fancy, I decided to add some inset icons underneath.
+The pin holes will be useful to add some status LEDs later.
+Because one button will soon not be enough control, I added three button holders on the top.
+A library near me offers a 3D printing service so it was easy to get the case printed.
+
+The new buttons and LEDs will need to be wired up to some unused GPIO pins.
+All LEDs are connected using a single resistor since these will only turn on rarely and even more rarely at the same time.
+
+
+
+To make full use of the three buttons, I came up with a simple one/two-step selection menu to get to the most important functionality.
+
+1. Show time table and large clock
+ 1. (unused)
+ 2. Show temperature chart
+ 3. Show upcoming events
+2. Dismiss active action
+3. Show TOTP codes
+ 1. Next page
+ 2. (unused)
+ 3. Show RPi screensaver
+
+This post will be updated soon™ to show to the final 3D print (which required some adjustments not yet mentioned).
\ No newline at end of file
diff --git a/static/assets/RPi-Zero.scad b/static/assets/RPi-Zero.scad
new file mode 100644
index 0000000..8ea8882
--- /dev/null
+++ b/static/assets/RPi-Zero.scad
@@ -0,0 +1,227 @@
+final = !$preview;
+module pizero() {
+difference() {
+color("green") import("pizero-scase_new.stl");
+if (final) {
+ translate([34.4, -25, 1.05]) cube([1,50,.5]);
+ translate([34.5, -25, 1.15]) cube([1,50,.5]);
+ translate([34.6, -25, 1.25]) cube([1,50,.5]);
+ translate([34.7, -25, 1.35]) cube([1,50,.5]);
+ translate([34.8, -25, 1.45]) cube([1,50,.5]);
+ // keep 4.75 - 5.45 = 0.7
+ h = 10.5;
+ translate([34.8, -25, 5.45]) cube([1,50,h]);
+ translate([34.7, -25, 5.55]) cube([1,50,h]);
+ translate([34.6, -25, 5.65]) cube([1,50,h]);
+ translate([34.5, -25, 5.75]) cube([1,50,h]);
+ translate([34.4, -25, 5.85]) cube([1,50,h]);
+}
+}
+}
+module oled_hole() {
+intersection () {
+ translate([0,0,0]) import("OLED_Under_Cabinet.stl");
+ cube([48, 10, 40], center=true);
+}
+}
+module led_hole() {
+ translate([-1.25, 19, 30]) {
+ rotate([90, 0, 0]) cylinder(10, .5, .5, center = true, $fn=32);
+ }
+ translate([1.25, 19, 30]) {
+ rotate([90, 0, 0]) cylinder(10, .5, .5, center = true, $fn=32);
+ }
+}
+module extender() {
+ difference() {
+ s = 90 - 8.5;
+ //s = 12.5;
+ h = s;
+ union() {
+ /*
+ translate([0, 19, 60]) {
+ color("red") rotate([90, 0, 0]) cylinder(10, 1, center = true);
+ }
+ */
+ translate([0,0,8.5 + s/2]) linear_extrude(s, center=true) projection(cut = true) translate([0,0,-8]) pizero();
+ translate([33, -15, 8.5]) cube([1,30,s]);
+ for ( i = [ 1 : 6 ] ) {
+ w = 19.95;
+ color("red")
+ translate([33 + i/10, -w/2 + 0.65, 8.5 - i/10]) cube([0.7 - i/10,w,s]);
+ }
+ difference() {
+ union() {
+ translate([0,0,8]) cube([34*2,33,2], center=true);
+ translate([0,0,9]) cube([34*2,33,1], center=true);
+ }
+ union () {
+ scale([0.99, 0.99, 1]) pizero();
+ translate([-33,17.5,8.5]) cube([3.4,3.4,10], center=true);
+ translate([-34.9,16,8.5]) cube([3.4,3.4,10], center=true);
+ translate([33,17.5,8.5]) cube([3.4,3.4,10], center=true);
+ translate([34.9,16,8.5]) cube([3.4,3.4,10], center=true);
+ mirror([0,1,0]) {
+ translate([-33,17.5,8.5]) cube([3.4,3.4,10], center=true);
+ translate([-34.9,16,8.5]) cube([3.4,3.4,10], center=true);
+ translate([33,17.5,8.5]) cube([3.4,3.4,10], center=true);
+ translate([34.9,16,8.5]) cube([3.4,3.4,10], center=true);
+
+ }
+ translate([0,0,8.5]) cube([32*2,14.5*2,10],center=true);
+ translate([34,0,8.5]) cube([5,14.5*2,10],center=true);
+ }
+ }
+ }
+ translate([34.4, -25, 8.5]) cube([1,50,h]);
+ translate([0, 19, 60]) difference() {
+ cube([48,10,40], center=true);
+ oled_hole();
+ }
+ led_hole();
+ translate([-10,0,0]) {
+ led_hole();
+ }
+ translate([-20,0,0]) {
+ led_hole();
+ }
+ translate([10,0,0]) {
+ led_hole();
+ }
+ translate([20,0,0]) {
+ led_hole();
+ }
+ // cable hole
+ translate([35,0,70]) {
+ minkowski()
+{
+ color("red") cube([5,5,2], center=true);
+ rotate([0,90,0]) cylinder(r1=2,r2=2,h=1, center=true, $fn=32);
+}
+ }
+ // icons
+ translate([0, 17.9 - .5, 41]) {
+ scale = 0.19;
+ translate([-14, 0, 0]) scale([scale, 1, scale]) rotate([90,0,0]) linear_extrude(1) import("./rpi_logo.svg", center=true);
+ translate([-5, 0, 0]) scale([scale, 1, scale]) rotate([90,0,0]) linear_extrude(1) import("./Calendar_font_awesome.svg", center=true);
+ translate([5, 0, 0]) scale([scale, 1, scale]) rotate([90,0,0]) linear_extrude(1) import("./to cry.svg", center=true);
+ translate([14, 0, 0]) scale([scale, 1, scale]) mirror([1,0,0]) rotate([90,0,0]) linear_extrude(1) import("./temp.svg", center=true);
+ }
+}
+}
+module button_hole() {
+ difference() {
+ cube([12.4 + 0.05, 12.4 + 0.05,5], center=true);
+ translate([6.05 + 0.05 / 2, -3.81, 0]) cube([0.3,2.6,5], center=true);
+ translate([6.05 + 0.05 / 2, 3.81, 0]) cube([0.3,2.6,5], center=true);
+ translate([-6.05 - 0.05 / 2, -3.81, 0]) cube([0.3,2.6,5], center=true);
+ translate([-6.05 - 0.05 / 2, 3.81, 0]) cube([0.3,2.6,5], center=true);
+ }
+}
+module hat() {
+ difference() {
+ translate([0,0,98.5]) mirror([0,0,1]) difference() {
+ union() {
+ pizero();
+ color("red") translate([33, -13.5, 2.65]) cube([1.4,27,5.85]);
+ color("red") translate([-33-1.4, -13.5, 2.65]) cube([1.4,27,5.85]);
+ color("red") translate([-30, -18.3+1.4, 2.4]) cube([60,1.4,5.85]);
+ translate([-30, -15, 0]) cube([60,30,1.4]);
+ translate([0,0,8.5]) difference() {
+ cube([66,32,4],center=true);
+ cube([63,28,4],center=true);
+ }
+ }
+ translate([34.4, -25, 1.05]) cube([1,50,5]);
+ translate([0, 0, 0]) button_hole();
+ translate([-20, 0, 0]) button_hole();
+ translate([20, 0, 0]) button_hole();
+ }
+ scale([0.99, 0.99, 1]) extender();
+}
+}
+module sticks1(s=1) {
+ for ( i = [0 : 8] ){
+ if (i != 6) {
+ translate([33.7,0,20+i*8]) cube([s*.75,8,s*.75], center=true);
+ }
+ translate([-33.7,0,20+i*8]) cube([s*.75,8,s*.75], center=true);
+ }
+ }
+ module sticks2(s=1) {
+ translate([0,0,4]) sticks1(s);
+ }
+module print1() {
+ difference() {
+ intersection() {
+ extender();
+ translate([0,50,0]) cube([1000,100,1000], center=true);
+ }
+ sticks2(1.05);
+}
+ sticks1();
+}
+module print2() {
+ difference() {
+ intersection() {
+ extender();
+ mirror([0,1,0]) translate([0,50,0]) cube([1000,100,1000], center=true);
+ }
+ sticks1(1.05);
+}
+ sticks2();
+}
+module print3() {
+ hat();
+}
+module pyramid() {
+difference() {
+union() {
+ for ( i = [0 : 8]) {
+ s = (8 - i) / 2;
+ translate([- s, - s, i * 0.5])
+ cube([4+s,4+s,.5]);
+ x = 2.5;
+ }
+ }
+ x = 2.6;
+ translate([4-x,4-x,1])
+ cube([x,x,4]);
+ }
+}
+module fixer() {
+translate([0, 30, 1]) linear_extrude(2, center=true) circle(5, $fn=32);
+ translate([-15, 25, 1]) rotate([0,0,20])scale([1,0.1,1]) linear_extrude(2, center=true) circle(20, $fn=32);
+ mirror([1,0,0]) translate([-15, 25, 1]) rotate([0,0,20])scale([1,0.1,1]) linear_extrude(2, center=true) circle(20, $fn=32);
+
+ translate([0, 50, 1]) linear_extrude(2, center=true) circle(5, $fn=32);
+ translate([0, 40, 1]) rotate([0,0,90])scale([.7,0.1,1]) linear_extrude(2, center=true) circle(20, $fn=32);
+ }
+module print4() {
+difference() {
+union() {
+ pizero();
+ translate([-34.4 , -16.9, 0]) pyramid();
+ translate([-34.4 , 16.9, 0]) rotate([0, 0, 270]) pyramid();
+ translate([34.4 , -16.9, 0]) rotate([0,0,90]) pyramid();
+ translate([34.4 , 16.9, 0]) rotate([0, 0, 180]) pyramid();
+ fixer();
+ mirror([0, 1, 0]) {
+ fixer();
+ }
+ }
+ translate([21.5, -17, 4.5]) cube([14, 4, 9], center=true);
+ translate([21.5, -25, 4.5]) cube([14,20, 7], center=true);
+ }
+}
+//rotate([-90,0,0]) print1();
+//rotate([90,0,0]) print2();
+//mirror([0,0,1]) print3();
+//print4();
+module all() {
+ print1();
+ print2();
+ print3();
+ print4();
+}
+all();
\ No newline at end of file
diff --git a/static/assets/circuit_new.svg b/static/assets/circuit_new.svg
new file mode 100644
index 0000000..66d1558
--- /dev/null
+++ b/static/assets/circuit_new.svg
@@ -0,0 +1,247 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 200 Ω
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 3.3V
+ 5V
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ AM2302 sensor
+ SSD1351 OLED
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ VCC
+ DATA
+
+
+
+
+
+
+
+ GND
+
+
+
+
+
+
+
+ VCC
+ GND
+
+
+
+ DIN
+
+
+
+ CLK
+
+
+
+ CS
+
+
+
+ DC
+
+
+
+ RST
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 3V3
+ GPIO2
+ GPIO3
+ GPIO4
+ GND
+ GPIO17
+ GPIO27
+ GPIO22
+ 3V3
+ GPIO10
+ GPIO9
+ GPIO11
+ GND
+ ID_SD
+ GPIO5
+ GPIO6
+ GPIO13
+ GPIO19
+ GPIO26
+ GND
+ 5V0
+ 5V0
+ GND
+ GPIO14
+ GPIO15
+ GPIO18
+ GND
+ GPIO23
+ GPIO24
+ GND
+ GPIO25
+ GPIO8
+ GPIO7
+ ID_SC
+ GND
+ GPIO12
+ GND
+ GPIO16
+ GPIO20
+ GPIO21
+
+
+
+
+
+
+
+
\ No newline at end of file