Ultrasonic Sensor HC-SR04 + RP2040 (waveshare) Auto screen lock

Point the sensor at yourself when behind your computer.
When you leave your computer for some seconds, it wil automatically lock your screen. (Windows-L keypress)
The RP2040 is configured as HID so it emulates a keyboard.
Just connect via an usb-cable to your machine

Arduino Code

File > Preferences > Additional Board URLS
https://github.com/earlephilhower/arduino-pico/releases/download/global/package_rp2040_index.json

Change USB Stack!

Download and install Adafruit_TinyUSB.zip

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
#include "Adafruit_TinyUSB.h"
// defines pins numbers
const int trigPin = D4;
const int echoPin = D5;
// defines variables
long duration;
int distance;
int maxcounter;
uint8_t const desc_hid_report[] =
{
TUD_HID_REPORT_DESC_KEYBOARD()
};
// D0-D3 NOT USED AT THE MOMENT, I'VE GOT IDEAS FOR EXTRA FUNCTIONALLITY!
// USB HID object. For ESP32 these values cannot be changed after this declaration
// desc report, desc len, protocol, interval, use out endpoint
Adafruit_USBD_HID usb_hid(desc_hid_report, sizeof(desc_hid_report), HID_ITF_PROTOCOL_KEYBOARD, 2, false);
//------------- Input Pins -------------//
// Array of pins and its keycode.
uint8_t pins[] = { D0, D1, D2, D3 };
// number of pins
uint8_t pincount = sizeof(pins)/sizeof(pins[0]);
// For keycode definition check out https://github.com/hathach/tinyusb/blob/master/src/class/hid/hid.h
uint8_t hidcode[] = { HID_KEY_0, HID_KEY_1, HID_KEY_2, HID_KEY_3 , HID_KEY_4, HID_KEY_5 };
#if defined(ARDUINO_SAMD_CIRCUITPLAYGROUND_EXPRESS) || defined(ARDUINO_NRF52840_CIRCUITPLAY) || defined(ARDUINO_FUNHOUSE_ESP32S2)
bool activeState = true;
#else
bool activeState = false;
#endif
void setup()
{
// Setting pins for Ultrasonic Sensor HC-SR04
pinMode(trigPin, OUTPUT); // Sets the trigPin as an Output
pinMode(echoPin, INPUT); // Sets the echoPin as an Input
#if defined(ARDUINO_ARCH_MBED) && defined(ARDUINO_ARCH_RP2040)
// Manual begin() is required on core without built-in support for TinyUSB such as mbed rp2040
TinyUSB_Device_Init(0);
#endif
// Set up output report (on control endpoint) for Capslock indicator
// Not used .. yet
usb_hid.setReportCallback(NULL, hid_report_callback);
usb_hid.begin();
// overwrite input pin with PIN_BUTTONx
// NOT USED
#ifdef PIN_BUTTON1
pins[0] = PIN_BUTTON1;
#endif
#ifdef PIN_BUTTON2
pins[1] = PIN_BUTTON2;
#endif
#ifdef PIN_BUTTON3
pins[2] = PIN_BUTTON3;
#endif
#ifdef PIN_BUTTON4
pins[3] = PIN_BUTTON4;
#endif
// Set up pin as input
for (uint8_t i=0; i<pincount; i++)
{
pinMode(pins[i], activeState ? INPUT_PULLDOWN : INPUT_PULLUP);
}
// wait until device mounted
while( !TinyUSBDevice.mounted() ) delay(1);
maxcounter =0;
}
void loop()
{
// Clears the trigPin
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
// Sets the trigPin on HIGH state for 10 micro seconds
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
// Reads the echoPin, returns the sound wave travel time in microseconds
duration = pulseIn(echoPin, HIGH);
// Calculating the distance
distance = duration * 0.034 / 2;
// Prints the distance on the Serial Monitor - DEBUG
//Serial.print("Distance: ");
//Serial.println(distance);
// Below will wait for more than 100 measurements with a distance of 100
// Then it will send a WINDOWS-L (lock) keyboard combination
if (distance > 100)
{
maxcounter +=1;
}
else
{
maxcounter = 0;
}
if (maxcounter > 100 && maxcounter < 150)
{
maxcounter = 200;
// Send report if there is key pressed
uint8_t const report_id = 0;
uint8_t modifier = KEYBOARD_MODIFIER_LEFTGUI;
uint8_t keycode[6] = { 0 };
keycode[0] = HID_KEY_L;
usb_hid.keyboardReport(report_id, modifier, keycode);
delay(10);
// Un-press keys :)
usb_hid.keyboardRelease(0);
}
// poll gpio once each 2 ms
delay(20);
// used to avoid send multiple consecutive zero report for keyboard
static bool keyPressedPreviously = false;
uint8_t count=0;
uint8_t keycode[6] = { 0 };
// scan normal key and send report
for(uint8_t i=0; i < pincount; i++)
{
if ( activeState == digitalRead(pins[i]) )
{
// if pin is active (low), add its hid code to key report
keycode[count++] = hidcode[i];
// 6 is max keycode per report
if (count == 6) break;
}
}
if ( TinyUSBDevice.suspended() && count )
{
// Wake up host if we are in suspend mode
// and REMOTE_WAKEUP feature is enabled by host
TinyUSBDevice.remoteWakeup();
}
// skip if hid is not ready e.g still transferring previous report
if ( !usb_hid.ready() ) return;
if ( count )
{
// Send report if there is key pressed
uint8_t const report_id = 0;
uint8_t const modifier = 0;
keyPressedPreviously = true;
usb_hid.keyboardReport(report_id, modifier, keycode);
}else
{
// Send All-zero report to indicate there is no keys pressed
// Most of the time, it is, though we don't need to send zero report
// every loop(), only a key is pressed in previous loop()
if ( keyPressedPreviously )
{
keyPressedPreviously = false;
usb_hid.keyboardRelease(0);
}
}
}
// Output report callback for LED indicator such as Caplocks
void hid_report_callback(uint8_t report_id, hid_report_type_t report_type, uint8_t const* buffer, uint16_t bufsize)
{
(void) report_id;
(void) bufsize;
}
#include "Adafruit_TinyUSB.h" // defines pins numbers const int trigPin = D4; const int echoPin = D5; // defines variables long duration; int distance; int maxcounter; uint8_t const desc_hid_report[] = { TUD_HID_REPORT_DESC_KEYBOARD() }; // D0-D3 NOT USED AT THE MOMENT, I'VE GOT IDEAS FOR EXTRA FUNCTIONALLITY! // USB HID object. For ESP32 these values cannot be changed after this declaration // desc report, desc len, protocol, interval, use out endpoint Adafruit_USBD_HID usb_hid(desc_hid_report, sizeof(desc_hid_report), HID_ITF_PROTOCOL_KEYBOARD, 2, false); //------------- Input Pins -------------// // Array of pins and its keycode. uint8_t pins[] = { D0, D1, D2, D3 }; // number of pins uint8_t pincount = sizeof(pins)/sizeof(pins[0]); // For keycode definition check out https://github.com/hathach/tinyusb/blob/master/src/class/hid/hid.h uint8_t hidcode[] = { HID_KEY_0, HID_KEY_1, HID_KEY_2, HID_KEY_3 , HID_KEY_4, HID_KEY_5 }; #if defined(ARDUINO_SAMD_CIRCUITPLAYGROUND_EXPRESS) || defined(ARDUINO_NRF52840_CIRCUITPLAY) || defined(ARDUINO_FUNHOUSE_ESP32S2) bool activeState = true; #else bool activeState = false; #endif void setup() { // Setting pins for Ultrasonic Sensor HC-SR04 pinMode(trigPin, OUTPUT); // Sets the trigPin as an Output pinMode(echoPin, INPUT); // Sets the echoPin as an Input #if defined(ARDUINO_ARCH_MBED) && defined(ARDUINO_ARCH_RP2040) // Manual begin() is required on core without built-in support for TinyUSB such as mbed rp2040 TinyUSB_Device_Init(0); #endif // Set up output report (on control endpoint) for Capslock indicator // Not used .. yet usb_hid.setReportCallback(NULL, hid_report_callback); usb_hid.begin(); // overwrite input pin with PIN_BUTTONx // NOT USED #ifdef PIN_BUTTON1 pins[0] = PIN_BUTTON1; #endif #ifdef PIN_BUTTON2 pins[1] = PIN_BUTTON2; #endif #ifdef PIN_BUTTON3 pins[2] = PIN_BUTTON3; #endif #ifdef PIN_BUTTON4 pins[3] = PIN_BUTTON4; #endif // Set up pin as input for (uint8_t i=0; i<pincount; i++) { pinMode(pins[i], activeState ? INPUT_PULLDOWN : INPUT_PULLUP); } // wait until device mounted while( !TinyUSBDevice.mounted() ) delay(1); maxcounter =0; } void loop() { // Clears the trigPin digitalWrite(trigPin, LOW); delayMicroseconds(2); // Sets the trigPin on HIGH state for 10 micro seconds digitalWrite(trigPin, HIGH); delayMicroseconds(10); digitalWrite(trigPin, LOW); // Reads the echoPin, returns the sound wave travel time in microseconds duration = pulseIn(echoPin, HIGH); // Calculating the distance distance = duration * 0.034 / 2; // Prints the distance on the Serial Monitor - DEBUG //Serial.print("Distance: "); //Serial.println(distance); // Below will wait for more than 100 measurements with a distance of 100 // Then it will send a WINDOWS-L (lock) keyboard combination if (distance > 100) { maxcounter +=1; } else { maxcounter = 0; } if (maxcounter > 100 && maxcounter < 150) { maxcounter = 200; // Send report if there is key pressed uint8_t const report_id = 0; uint8_t modifier = KEYBOARD_MODIFIER_LEFTGUI; uint8_t keycode[6] = { 0 }; keycode[0] = HID_KEY_L; usb_hid.keyboardReport(report_id, modifier, keycode); delay(10); // Un-press keys :) usb_hid.keyboardRelease(0); } // poll gpio once each 2 ms delay(20); // used to avoid send multiple consecutive zero report for keyboard static bool keyPressedPreviously = false; uint8_t count=0; uint8_t keycode[6] = { 0 }; // scan normal key and send report for(uint8_t i=0; i < pincount; i++) { if ( activeState == digitalRead(pins[i]) ) { // if pin is active (low), add its hid code to key report keycode[count++] = hidcode[i]; // 6 is max keycode per report if (count == 6) break; } } if ( TinyUSBDevice.suspended() && count ) { // Wake up host if we are in suspend mode // and REMOTE_WAKEUP feature is enabled by host TinyUSBDevice.remoteWakeup(); } // skip if hid is not ready e.g still transferring previous report if ( !usb_hid.ready() ) return; if ( count ) { // Send report if there is key pressed uint8_t const report_id = 0; uint8_t const modifier = 0; keyPressedPreviously = true; usb_hid.keyboardReport(report_id, modifier, keycode); }else { // Send All-zero report to indicate there is no keys pressed // Most of the time, it is, though we don't need to send zero report // every loop(), only a key is pressed in previous loop() if ( keyPressedPreviously ) { keyPressedPreviously = false; usb_hid.keyboardRelease(0); } } } // Output report callback for LED indicator such as Caplocks void hid_report_callback(uint8_t report_id, hid_report_type_t report_type, uint8_t const* buffer, uint16_t bufsize) { (void) report_id; (void) bufsize; }
#include "Adafruit_TinyUSB.h"
// defines pins numbers
const int trigPin = D4;
const int echoPin = D5;
// defines variables
long duration;
int distance;
int maxcounter;
uint8_t const desc_hid_report[] =
{
  TUD_HID_REPORT_DESC_KEYBOARD()
};

// D0-D3 NOT USED AT THE MOMENT, I'VE GOT IDEAS FOR EXTRA FUNCTIONALLITY!

// USB HID object. For ESP32 these values cannot be changed after this declaration
// desc report, desc len, protocol, interval, use out endpoint
Adafruit_USBD_HID usb_hid(desc_hid_report, sizeof(desc_hid_report), HID_ITF_PROTOCOL_KEYBOARD, 2, false);

//------------- Input Pins -------------//
// Array of pins and its keycode.
  uint8_t pins[] = { D0, D1, D2, D3 };


// number of pins
uint8_t pincount = sizeof(pins)/sizeof(pins[0]);

// For keycode definition check out https://github.com/hathach/tinyusb/blob/master/src/class/hid/hid.h
uint8_t hidcode[] = { HID_KEY_0, HID_KEY_1, HID_KEY_2, HID_KEY_3 , HID_KEY_4, HID_KEY_5 };

#if defined(ARDUINO_SAMD_CIRCUITPLAYGROUND_EXPRESS) || defined(ARDUINO_NRF52840_CIRCUITPLAY) || defined(ARDUINO_FUNHOUSE_ESP32S2)
  bool activeState = true;
#else
  bool activeState = false;
#endif

void setup()
{
  // Setting pins for Ultrasonic Sensor HC-SR04
  pinMode(trigPin, OUTPUT); // Sets the trigPin as an Output
  pinMode(echoPin, INPUT); // Sets the echoPin as an Input
  
#if defined(ARDUINO_ARCH_MBED) && defined(ARDUINO_ARCH_RP2040)
  // Manual begin() is required on core without built-in support for TinyUSB such as mbed rp2040
  TinyUSB_Device_Init(0);
#endif

  // Set up output report (on control endpoint) for Capslock indicator
  // Not used .. yet
  usb_hid.setReportCallback(NULL, hid_report_callback);

  usb_hid.begin();

  // overwrite input pin with PIN_BUTTONx
  // NOT USED 
#ifdef PIN_BUTTON1
  pins[0] = PIN_BUTTON1;
#endif

#ifdef PIN_BUTTON2
  pins[1] = PIN_BUTTON2;
#endif

#ifdef PIN_BUTTON3
  pins[2] = PIN_BUTTON3;
#endif

#ifdef PIN_BUTTON4
  pins[3] = PIN_BUTTON4;
#endif

  // Set up pin as input
  for (uint8_t i=0; i<pincount; i++)
  {
    pinMode(pins[i], activeState ? INPUT_PULLDOWN : INPUT_PULLUP);
  }

  // wait until device mounted
  while( !TinyUSBDevice.mounted() ) delay(1);

maxcounter =0;
}

void loop()
{
  
  // Clears the trigPin
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  // Sets the trigPin on HIGH state for 10 micro seconds
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);
  // Reads the echoPin, returns the sound wave travel time in microseconds
  duration = pulseIn(echoPin, HIGH);
  // Calculating the distance
  distance = duration * 0.034 / 2;
  // Prints the distance on the Serial Monitor - DEBUG
  //Serial.print("Distance: ");
  //Serial.println(distance);

  // Below will wait for more than 100 measurements with a distance of 100
  // Then it will send a WINDOWS-L (lock) keyboard combination 
  if (distance > 100)
  {
    maxcounter +=1; 
  }
  else
  {
    maxcounter = 0;
  }
  if (maxcounter > 100 && maxcounter < 150)
  {
    maxcounter = 200;
       // Send report if there is key pressed
    uint8_t const report_id = 0;


    uint8_t  modifier = KEYBOARD_MODIFIER_LEFTGUI;
          uint8_t keycode[6] = { 0 };
      keycode[0] = HID_KEY_L;


    usb_hid.keyboardReport(report_id, modifier, keycode);
    delay(10);
    // Un-press keys :)
    usb_hid.keyboardRelease(0);
    
  }

  
  // poll gpio once each 2 ms
  delay(20);

  // used to avoid send multiple consecutive zero report for keyboard
  static bool keyPressedPreviously = false;

  uint8_t count=0;
  uint8_t keycode[6] = { 0 };

  // scan normal key and send report
  for(uint8_t i=0; i < pincount; i++)
  {
    if ( activeState == digitalRead(pins[i]) )
    {
      // if pin is active (low), add its hid code to key report
      keycode[count++] = hidcode[i];

      // 6 is max keycode per report
      if (count == 6) break;
    }
  }

  if ( TinyUSBDevice.suspended() && count )
  {
    // Wake up host if we are in suspend mode
    // and REMOTE_WAKEUP feature is enabled by host
    TinyUSBDevice.remoteWakeup();
  }

  // skip if hid is not ready e.g still transferring previous report
  if ( !usb_hid.ready() ) return;

  if ( count )
  {
    // Send report if there is key pressed
    uint8_t const report_id = 0;
    uint8_t const modifier = 0;

    keyPressedPreviously = true;
    usb_hid.keyboardReport(report_id, modifier, keycode);
  }else
  {
    // Send All-zero report to indicate there is no keys pressed
    // Most of the time, it is, though we don't need to send zero report
    // every loop(), only a key is pressed in previous loop()
    if ( keyPressedPreviously )
    {
      keyPressedPreviously = false;
      usb_hid.keyboardRelease(0);
    }
  }
}

// Output report callback for LED indicator such as Caplocks
void hid_report_callback(uint8_t report_id, hid_report_type_t report_type, uint8_t const* buffer, uint16_t bufsize)
{
  (void) report_id;
  (void) bufsize;

}

Arduino with Huskylens detecting learned face

Arduino Uno with Husky Lens using I2C

The HuskyLens is an easy-to-use AI machine vision sensor. It is equipped with multiple functions such as:

  • Face recognition
  • Object tracking
  • Object recognition
  • Line trace
  • Color recognition
  • Tag recognition (QR code).

Via the UART / I2C port you can among others: boards connect:

  • Arduino
  • micro:bit
  • Raspberry Pi

Steps to take: Press Face detection, when a cross in a square is displayed, press the button on your HuskyLens

Set your husky protocol to I2C in the settings.

Minimal Code needed

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
/***************************************************
HUSKYLENS An Easy-to-use AI Machine Vision Sensor
<https://www.dfrobot.com/product-1922.html>
****************************************************/
#include "HUSKYLENS.h"
HUSKYLENS huskylens;
//HUSKYLENS green line >> SDA; blue line >> SCL
int ID0 = 0; //not learned results. Grey result on HUSKYLENS screen
int ID1 = 1; //first learned results. colored result on HUSKYLENS screen
int ID2 = 2; //second learned results. colored result on HUSKYLENS screen
// and so on.....
int arjprevious = 0;
void printResult(HUSKYLENSResult result);
void setup() {
Serial.begin(115200);
Wire.begin();
while (!huskylens.begin(Wire))
{
Serial.println(F("Begin failed!"));
Serial.println(F("1.Please recheck the \"Protocol Type\" in HUSKYLENS (General Settings>>Protocol Type>>I2C)"));
Serial.println(F("2.Please recheck the connection."));
delay(100);
}
huskylens.writeAlgorithm(ALGORITHM_FACE_RECOGNITION);
}
void loop() {
if (huskylens.requestLearned()) //request blocks and arrows tangged ID != 0 from HUSKYLENS
if (huskylens.requestBlocksLearned()) //request blocks tangged ID != ID0 from HUSKYLENS
{
for (int i = 0; i < huskylens.countArrows(ID0); i++)
{
HUSKYLENSResult result = huskylens.getArrow(ID0, i);
}
int arj = huskylens.count(ID1);
if ( arj != arjprevious )
{
if ( arj == 1 )
{
Serial.println("Learned face detected");
}
else
{
Serial.println("Learned face not detected");
}
arjprevious = arj;
}
}
else
{
Serial.println("Fail to request objects from Huskylens!");
}
}
/*************************************************** HUSKYLENS An Easy-to-use AI Machine Vision Sensor <https://www.dfrobot.com/product-1922.html> ****************************************************/ #include "HUSKYLENS.h" HUSKYLENS huskylens; //HUSKYLENS green line >> SDA; blue line >> SCL int ID0 = 0; //not learned results. Grey result on HUSKYLENS screen int ID1 = 1; //first learned results. colored result on HUSKYLENS screen int ID2 = 2; //second learned results. colored result on HUSKYLENS screen // and so on..... int arjprevious = 0; void printResult(HUSKYLENSResult result); void setup() { Serial.begin(115200); Wire.begin(); while (!huskylens.begin(Wire)) { Serial.println(F("Begin failed!")); Serial.println(F("1.Please recheck the \"Protocol Type\" in HUSKYLENS (General Settings>>Protocol Type>>I2C)")); Serial.println(F("2.Please recheck the connection.")); delay(100); } huskylens.writeAlgorithm(ALGORITHM_FACE_RECOGNITION); } void loop() { if (huskylens.requestLearned()) //request blocks and arrows tangged ID != 0 from HUSKYLENS if (huskylens.requestBlocksLearned()) //request blocks tangged ID != ID0 from HUSKYLENS { for (int i = 0; i < huskylens.countArrows(ID0); i++) { HUSKYLENSResult result = huskylens.getArrow(ID0, i); } int arj = huskylens.count(ID1); if ( arj != arjprevious ) { if ( arj == 1 ) { Serial.println("Learned face detected"); } else { Serial.println("Learned face not detected"); } arjprevious = arj; } } else { Serial.println("Fail to request objects from Huskylens!"); } }
/***************************************************
 HUSKYLENS An Easy-to-use AI Machine Vision Sensor
 <https://www.dfrobot.com/product-1922.html> 
****************************************************/

#include "HUSKYLENS.h"

HUSKYLENS huskylens;
//HUSKYLENS green line >> SDA; blue line >> SCL
int ID0 = 0; //not learned results. Grey result on HUSKYLENS screen
int ID1 = 1; //first learned results. colored result on HUSKYLENS screen
int ID2 = 2; //second learned results. colored result on HUSKYLENS screen
// and so on.....

int arjprevious = 0;
void printResult(HUSKYLENSResult result);
void setup() {
    Serial.begin(115200);
    Wire.begin();
    while (!huskylens.begin(Wire))
    {
        Serial.println(F("Begin failed!"));
        Serial.println(F("1.Please recheck the \"Protocol Type\" in HUSKYLENS (General Settings>>Protocol Type>>I2C)"));
        Serial.println(F("2.Please recheck the connection."));
        delay(100);
    }
    
     huskylens.writeAlgorithm(ALGORITHM_FACE_RECOGNITION);
}

void loop() {
   if (huskylens.requestLearned())          //request blocks and arrows tangged ID != 0 from HUSKYLENS
   if (huskylens.requestBlocksLearned())    //request blocks tangged ID != ID0 from HUSKYLENS

    {
        for (int i = 0; i < huskylens.countArrows(ID0); i++)
        {
            HUSKYLENSResult result = huskylens.getArrow(ID0, i);  
        }
        int arj = huskylens.count(ID1);
        if ( arj != arjprevious )
        {
        if ( arj == 1 )
            {
            Serial.println("Learned face detected");
            }
            else
            {
            Serial.println("Learned face not detected");
            }
            arjprevious = arj;
        }
    }
    else
    {
        Serial.println("Fail to request objects from Huskylens!");
    }
}
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
Learned face detected ID1
Learned face not detected
Learned face detected ID1
Learned face not detected
Learned face detected ID1
Learned face not detected
Learned face detected ID1 Learned face not detected Learned face detected ID1 Learned face not detected Learned face detected ID1 Learned face not detected
Learned face detected ID1
Learned face not detected
Learned face detected ID1
Learned face not detected
Learned face detected ID1
Learned face not detected

Tiny animator for stop-motion

I was working on a RP2040 HID project, but I needed some components I didn’t have … right now .. again ..

So I made something else ..

A tiny animator for stop motion animations using my webcam, python and OpenCV.

For claymotion or lego or whatever.

The program displays your webcam with the previous snapshot overlayed, so you can position everything relative to your previous snapshot.

Difference between two shots.

Press B to take a frame.

Just a proof of concept using a (BAD) webcam. (Don’t look at my hand )

CODE (short but you need OpenCV)

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
import cv2
from datetime import datetime
# black is just a start empty image ..
img=cv2.imread("black.png");
cap = cv2.VideoCapture(0)
while True:
ret,vid=cap.read()
dim = (800,600)
img1 = cv2.resize(img, dim, interpolation = cv2.INTER_AREA)
vid1 = cv2.resize(vid, dim, interpolation = cv2.INTER_AREA)
result=cv2.addWeighted(img1,0.5,vid1,0.5,0)
cv2.imshow('overlay', result)
if(cv2.waitKey(10) & 0xFF == ord('b')):
now = datetime.now()
current_time = now.strftime("%d_%m_%Y_%H_%M_%S")
filename = '%s.png' % current_time
if not cv2.imwrite(filename, vid1):
raise Exception("Could not write image")
img=cv2.imread(filename);
import cv2 from datetime import datetime # black is just a start empty image .. img=cv2.imread("black.png"); cap = cv2.VideoCapture(0) while True: ret,vid=cap.read() dim = (800,600) img1 = cv2.resize(img, dim, interpolation = cv2.INTER_AREA) vid1 = cv2.resize(vid, dim, interpolation = cv2.INTER_AREA) result=cv2.addWeighted(img1,0.5,vid1,0.5,0) cv2.imshow('overlay', result) if(cv2.waitKey(10) & 0xFF == ord('b')): now = datetime.now() current_time = now.strftime("%d_%m_%Y_%H_%M_%S") filename = '%s.png' % current_time if not cv2.imwrite(filename, vid1): raise Exception("Could not write image") img=cv2.imread(filename);
import  cv2
from datetime import datetime
# black is just a start empty image .. 
img=cv2.imread("black.png");
cap = cv2.VideoCapture(0)

while True: 

    ret,vid=cap.read()
    dim = (800,600)
    img1 = cv2.resize(img, dim, interpolation = cv2.INTER_AREA)
    vid1 = cv2.resize(vid, dim, interpolation = cv2.INTER_AREA)

    result=cv2.addWeighted(img1,0.5,vid1,0.5,0)
    cv2.imshow('overlay', result)
    if(cv2.waitKey(10) & 0xFF == ord('b')):
            now = datetime.now()
            current_time = now.strftime("%d_%m_%Y_%H_%M_%S")
            filename = '%s.png' % current_time
            if not cv2.imwrite(filename, vid1):
                raise Exception("Could not write image")
            img=cv2.imread(filename);

Pressing B fills your directory with PNG’s
like 24_10_2023_00_01_01.png (date formatted)

convert to GIF

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
convert -delay 10 -loop 0 24*.png animation.gif
convert -delay 10 -loop 0 24*.png animation.gif
convert -delay 10 -loop 0 24*.png animation.gif

Thunderbird mail notification flag via USB

In 2021 I made a MQTT notification Flag using a Servo and python code and webhooks to get notifications.
Webhook was used for Mattermost.

Now i’ve changed the notification flag for Email using Thunderbird.
Just connect the wemos to a USB on your computer, no mqtt/wifi needed. (On the road solution)

Steps:

Install FiltaQuilla Add-on in thunderbird
select run program in config.

Next create a filter

Create two bash files (i’ve got mine in ~/bin/ )
Change ttyUSB0 if needed

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
::::::::::::::
flagoff.sh
::::::::::::::
#!/bin/bash
stty -F /dev/ttyUSB0 ispeed 9600 ospeed 9600 -ignpar cs8 -cstopb -echo
echo 0 > /dev/ttyUSB0
::::::::::::::
flagon.sh
::::::::::::::
#!/bin/bash
stty -F /dev/ttyUSB0 ispeed 9600 ospeed 9600 -ignpar cs8 -cstopb -echo
echo 1 > /dev/ttyUSB0
:::::::::::::: flagoff.sh :::::::::::::: #!/bin/bash stty -F /dev/ttyUSB0 ispeed 9600 ospeed 9600 -ignpar cs8 -cstopb -echo echo 0 > /dev/ttyUSB0 :::::::::::::: flagon.sh :::::::::::::: #!/bin/bash stty -F /dev/ttyUSB0 ispeed 9600 ospeed 9600 -ignpar cs8 -cstopb -echo echo 1 > /dev/ttyUSB0
::::::::::::::
flagoff.sh
::::::::::::::
#!/bin/bash
stty -F /dev/ttyUSB0 ispeed 9600 ospeed 9600 -ignpar cs8 -cstopb -echo
echo 0 > /dev/ttyUSB0

::::::::::::::
flagon.sh
::::::::::::::
#!/bin/bash
stty -F /dev/ttyUSB0 ispeed 9600 ospeed 9600 -ignpar cs8 -cstopb -echo
echo 1 > /dev/ttyUSB0

Install YAD and a autostart icon to make the systemtray to pull the flag down.

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
henri@zspot:~$ cat .config/autostart/servoflag.desktop
[Desktop Entry]
Type=Application
Version=1.0.0
Name=flag-off
Comment=
Icon=
Exec=yad --notification --image="gtk-execute" --command="bash /home/henri/bin/flagoff.sh" --image="mail-app"
Terminal=false
henri@zspot:~$ cat .config/autostart/servoflag.desktop [Desktop Entry] Type=Application Version=1.0.0 Name=flag-off Comment= Icon= Exec=yad --notification --image="gtk-execute" --command="bash /home/henri/bin/flagoff.sh" --image="mail-app" Terminal=false
henri@zspot:~$ cat .config/autostart/servoflag.desktop 
[Desktop Entry]
Type=Application
Version=1.0.0
Name=flag-off
Comment=
Icon=
Exec=yad --notification --image="gtk-execute" --command="bash /home/henri/bin/flagoff.sh" --image="mail-app"
Terminal=false

Arduino Code

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
#include <Servo.h>
Servo flag;
char val;
void setup() {
Serial.begin(9600);
flag.attach(D5);
}
void loop () {
val = Serial.read();
if (val == '0') {
flag.write(180);
}
if (val == '1') {
flag.write(0);
}
}
#include <Servo.h> Servo flag; char val; void setup() { Serial.begin(9600); flag.attach(D5); } void loop () { val = Serial.read(); if (val == '0') { flag.write(180); } if (val == '1') { flag.write(0); } }
#include <Servo.h> 

Servo flag; 
char val;
 
void setup() {
  Serial.begin(9600);
  flag.attach(D5);
  }

void loop () {
  val = Serial.read(); 
  if (val == '0') {
     flag.write(180); 
  } 
  if (val == '1') {
     flag.write(0); 
  }
}

Webos Developer Mode and Homebrew

Besides sending notifications and controlling my tv using bash, Nodered and HomeAssistant, i wanted to look at developing and homebrew for WebOS.

Goto the WebOS Dev website and register.

Install Developer App on your TV.

Login and write down your access information.

Remain session can be extended using the button, or using a script.

Below how to access you tv using ssh

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
wget http://IP_FROM_YOUR_TV:9991/webos_rsa
mv webos_rsa .ssh/
chmod 600 .ssh/webos_rsa
ssh -i .ssh/webos_rsa prisoner@10.1.0.14 -p9922 -T
Enter passphrase for key '.ssh/webos_rsa':
Enter the key mentioned on the Developer App Screen on your TV
Note the -T .. this disables pseudo terminals,
You won't see a prompt, but commands work
You can remove passphrases on ssh keys using below
ssh-keygen -p -f .ssh/webos_rsa
Enter old passphrase:
Enter new passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved with the new passphrase.
wget http://IP_FROM_YOUR_TV:9991/webos_rsa mv webos_rsa .ssh/ chmod 600 .ssh/webos_rsa ssh -i .ssh/webos_rsa prisoner@10.1.0.14 -p9922 -T Enter passphrase for key '.ssh/webos_rsa': Enter the key mentioned on the Developer App Screen on your TV Note the -T .. this disables pseudo terminals, You won't see a prompt, but commands work You can remove passphrases on ssh keys using below ssh-keygen -p -f .ssh/webos_rsa Enter old passphrase: Enter new passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved with the new passphrase.
wget http://IP_FROM_YOUR_TV:9991/webos_rsa
mv webos_rsa .ssh/
chmod 600 .ssh/webos_rsa
ssh -i .ssh/webos_rsa prisoner@10.1.0.14 -p9922 -T
       Enter passphrase for key '.ssh/webos_rsa':
Enter the key mentioned on the Developer App Screen on your TV

Note the -T .. this disables pseudo terminals,
You won't see a prompt, but commands work

You can remove passphrases on ssh keys using below
ssh-keygen -p -f .ssh/webos_rsa
Enter old passphrase:
Enter new passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved with the new passphrase.


Download WebOS manager from here:

https://github.com/webosbrew/dev-manager-desktop/releases/tag/v1.11.18

Install and use same ip/access key info to install homebrew

After that you can install homebrew apps using the App on your TV or via above dev-manager.
Also nice .. A ad-free version of Youtube!

By the way, I tried rootmy.tv .. but that didn’t work for me.
My TV was already patched for that exploit

Raspberry PI and Arduino black hole

This is NOT a post about the pi-hole project. Of which I apparantly never posted my setup.

I needed an extra PI for a project, and I always try to keep one spare.
But they are always gone, in use, missing .. whatever.

So I can´t work on this project right now, so lets rant about disappearing stuff

Like they are being sucked up in another dimension .. gone. WHERE ARE THEY?!?

How to keep track of them?

Any suggestions?


I used to have a sheet, but I often forget to keep track.
Do I use a MAC address scan on my switches?
First 3 parts of the Mac address are vendor specific.

So far i’ve found : Octopi, Beerbrew computer, Retro Arcade, Picore, Nodered, Domoticz 433toMqtt, Ledserver, Lasercutter-etch-a-sketch, mobile LMS music server, Pressure Lab AP, Escape Game AP (3 of them), one unused Raspberry zero (without Wifi), One at my old work, one broke, Kodi+Netflix,Ansible project, found another one .. Jumanji/Dashticz/NoderedDashboard demo (with screen)
WHERE THE F are the rest of them?
(Sdcards with temporary projects on them 29, I need to combine project on those cards. I’ve got a 64Gb card holding a Rpi OS and only a 1K python script!)

And Arduino’s are even worse … they are all over the place.
Those are probably 100+
(ESP32, 8266, Nano’s, Mega, M5Stack and alikes)

I know i have many temporary projects, but I keep most things organized in my projects containers.

One of the rows with Ikea containers, a few for bigger projects and now i’m using the plastic boxes you get when you order chinese or thai.

Obfuscating color logo in bash

Something from my old archive.

Colleage’s used to like the method.

source with color escape code applied
32=green 31=red and 97=white

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
echo -e "\e[0;32m '.::///+:/-. --///+//-:'' "
echo -e "\e[0;32m '+oooooooooooo: '+oooooooooooo: "
echo -e "\e[0;32m /oooo++//ooooo: ooooo+//+ooooo. "
echo -e "\e[0;32m '+ooooooo:-:oo- +o+::/ooooooo: "
echo -e "\e[0;32m ':oooooooo+'' '.oooooooo+- "
echo -e "\e[0;32m ':++ooo/. :+ooo+/.' "
echo -e "\e[0;31m ...' '.----.' ''.. "
echo -e "\e[0;31m .::::-'':::::::::.'-:::-' \e[0;97m www.henriaanstoot.nl"
echo -e "\e[0;31m -:::-' .:::::::-' '-:::- \e[0;97m Test logo"
echo -e "\e[0;31m '::. '.--.' '' '.---.''.::' "
echo -e "\e[0;31m .::::::::' -::::::::' ' "
echo -e "\e[0;31m .::' .:::::::::- '::::::::::''::. "
echo -e "\e[0;31m -:::' ::::::::::. ::::::::::.':::- "
echo -e "\e[0;31m :::: -::::::::. '-:::::::: :::: "
echo -e "\e[0;31m -::- .-:::-.''....''.-::-. -::- "
echo -e "\e[0;31m .. '' .::::::::. '..'.. "
echo -e "\e[0;31m -:::-' -::::::::::' .:::::' "
echo -e "\e[0;31m :::::::' -::::::::::' :::::::. "
echo -e "\e[0;31m .::::::: -::::::::. :::::::: "
echo -e "\e[0;31m '-:::::' ..--.' ::::::. "
echo -e "\e[0;31m '...' '...--..' '...' "
echo -e "\e[0;31m .:::::::::: "
echo -e "\e[0;31m '.-::::-' "
echo -e "\e[0;32m '.::///+:/-. --///+//-:'' " echo -e "\e[0;32m '+oooooooooooo: '+oooooooooooo: " echo -e "\e[0;32m /oooo++//ooooo: ooooo+//+ooooo. " echo -e "\e[0;32m '+ooooooo:-:oo- +o+::/ooooooo: " echo -e "\e[0;32m ':oooooooo+'' '.oooooooo+- " echo -e "\e[0;32m ':++ooo/. :+ooo+/.' " echo -e "\e[0;31m ...' '.----.' ''.. " echo -e "\e[0;31m .::::-'':::::::::.'-:::-' \e[0;97m www.henriaanstoot.nl" echo -e "\e[0;31m -:::-' .:::::::-' '-:::- \e[0;97m Test logo" echo -e "\e[0;31m '::. '.--.' '' '.---.''.::' " echo -e "\e[0;31m .::::::::' -::::::::' ' " echo -e "\e[0;31m .::' .:::::::::- '::::::::::''::. " echo -e "\e[0;31m -:::' ::::::::::. ::::::::::.':::- " echo -e "\e[0;31m :::: -::::::::. '-:::::::: :::: " echo -e "\e[0;31m -::- .-:::-.''....''.-::-. -::- " echo -e "\e[0;31m .. '' .::::::::. '..'.. " echo -e "\e[0;31m -:::-' -::::::::::' .:::::' " echo -e "\e[0;31m :::::::' -::::::::::' :::::::. " echo -e "\e[0;31m .::::::: -::::::::. :::::::: " echo -e "\e[0;31m '-:::::' ..--.' ::::::. " echo -e "\e[0;31m '...' '...--..' '...' " echo -e "\e[0;31m .:::::::::: " echo -e "\e[0;31m '.-::::-' "
echo  -e "\e[0;32m '.::///+:/-.        --///+//-:'' " 
echo  -e "\e[0;32m  '+oooooooooooo:   '+oooooooooooo: " 
echo  -e "\e[0;32m   /oooo++//ooooo:  ooooo+//+ooooo. " 
echo  -e "\e[0;32m   '+ooooooo:-:oo-  +o+::/ooooooo: " 
echo  -e "\e[0;32m    ':oooooooo+''    '.oooooooo+- " 
echo  -e "\e[0;32m      ':++ooo/.        :+ooo+/.' " 
echo  -e "\e[0;31m        ...'  '.----.' ''.. " 
echo  -e "\e[0;31m      .::::-'':::::::::.'-:::-'            \e[0;97m    www.henriaanstoot.nl" 
echo  -e "\e[0;31m     -:::-'   .:::::::-'  '-:::-           \e[0;97m    Test logo"
echo  -e "\e[0;31m    '::.  '.--.'  '' '.---.''.::' " 
echo  -e "\e[0;31m        .::::::::'  -::::::::' ' " 
echo  -e "\e[0;31m  .::' .:::::::::- '::::::::::''::. " 
echo  -e "\e[0;31m -:::' ::::::::::.  ::::::::::.':::- " 
echo  -e "\e[0;31m ::::  -::::::::.   '-::::::::  :::: " 
echo  -e "\e[0;31m -::-   .-:::-.''....''.-::-.   -::- " 
echo  -e "\e[0;31m  .. ''       .::::::::.     '..'.. " 
echo  -e "\e[0;31m    -:::-'   -::::::::::'  .:::::' " 
echo  -e "\e[0;31m    :::::::' -::::::::::' :::::::. " 
echo  -e "\e[0;31m    .:::::::  -::::::::. :::::::: " 
echo  -e "\e[0;31m     '-:::::'   ..--.'   ::::::. " 
echo  -e "\e[0;31m       '...'  '...--..'  '...' " 
echo  -e "\e[0;31m             .:::::::::: " 
echo  -e "\e[0;31m              '.-::::-'  " 

Obfuscate the logo to a file (1 time only)

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
cat source | base64 - -w0 1> ~/bin/logo.ob
Writes file (safe to copy paste/transfer) with:
ZWNobyAgLWUgIlxlWzA7MzJtICcuOjovLy8rOi8tLiAgICAgICAgLS0vLy8rLy8tOicnICIgCmVjaG8gIC1lICJcZVswOzMybSAgJytvb29vb29vb29vb286ICAgJytvb29vb29vb29vb286ICIgCmVjaG8gIC1lICJcZVswOzMybSAgIC9vb29vKysvL29vb29vOiAgb29vb28rLy8rb29vb28uICIgCmVjaG8gIC1lICJcZVswOzMybSAgICcrb29vb29vbzotOm9vLSAgK28rOjovb29vb29vbzogIiAKZWNobyAgLWUgIlxlWzA7MzJtICAgICc6b29vb29vb28rJycgICAgJy5vb29vb29vbystICIgCmVjaG8gIC1lICJcZVswOzMybSAgICAgICc6Kytvb28vLiAgICAgICAgOitvb28rLy4nICIgCmVjaG8gIC1lICJcZVswOzMxbSAgICAgICAgLi4uJyAgJy4tLS0tLicgJycuLiAiIAplY2hvICAtZSAiXGVbMDszMW0gICAgICAuOjo6Oi0nJzo6Ojo6Ojo6Oi4nLTo6Oi0nICAgICAgICAgICAgXGVbMDs5N20gICAgd3d3LmhlbnJpYWFuc3Rvb3QubmwiIAplY2hvICAtZSAiXGVbMDszMW0gICAgIC06OjotJyAgIC46Ojo6Ojo6LScgICctOjo6LSAgICAgICAgICAgXGVbMDs5N20gICAgVGVzdCBsb2dvIgplY2hvICAtZSAiXGVbMDszMW0gICAgJzo6LiAgJy4tLS4nICAnJyAnLi0tLS4nJy46OicgIiAKZWNobyAgLWUgIlxlWzA7MzFtICAgICAgICAuOjo6Ojo6OjonICAtOjo6Ojo6OjonICcgIiAKZWNobyAgLWUgIlxlWzA7MzFtICAuOjonIC46Ojo6Ojo6OjotICc6Ojo6Ojo6Ojo6Jyc6Oi4gIiAKZWNobyAgLWUgIlxlWzA7MzFtIC06OjonIDo6Ojo6Ojo6OjouICA6Ojo6Ojo6Ojo6Lic6OjotICIgCmVjaG8gIC1lICJcZVswOzMxbSA6Ojo6ICAtOjo6Ojo6OjouICAgJy06Ojo6Ojo6OiAgOjo6OiAiIAplY2hvICAtZSAiXGVbMDszMW0gLTo6LSAgIC4tOjo6LS4nJy4uLi4nJy4tOjotLiAgIC06Oi0gIiAKZWNobyAgLWUgIlxlWzA7MzFtICAuLiAnJyAgICAgICAuOjo6Ojo6OjouICAgICAnLi4nLi4gIiAKZWNobyAgLWUgIlxlWzA7MzFtICAgIC06OjotJyAgIC06Ojo6Ojo6Ojo6JyAgLjo6Ojo6JyAiIAplY2hvICAtZSAiXGVbMDszMW0gICAgOjo6Ojo6OicgLTo6Ojo6Ojo6OjonIDo6Ojo6OjouICIgCmVjaG8gIC1lICJcZVswOzMxbSAgICAuOjo6Ojo6OiAgLTo6Ojo6Ojo6LiA6Ojo6Ojo6OiAiIAplY2hvICAtZSAiXGVbMDszMW0gICAgICctOjo6OjonICAgLi4tLS4nICAgOjo6Ojo6LiAiIAplY2hvICAtZSAiXGVbMDszMW0gICAgICAgJy4uLicgICcuLi4tLS4uJyAgJy4uLicgIiAKZWNobyAgLWUgIlxlWzA7MzFtICAgICAgICAgICAgIC46Ojo6Ojo6Ojo6ICIgCmVjaG8gIC1lICJcZVswOzMxbSAgICAgICAgICAgICAgJy4tOjo6Oi0nICAiIAo=
cat source | base64 - -w0 1> ~/bin/logo.ob Writes file (safe to copy paste/transfer) with: ZWNobyAgLWUgIlxlWzA7MzJtICcuOjovLy8rOi8tLiAgICAgICAgLS0vLy8rLy8tOicnICIgCmVjaG8gIC1lICJcZVswOzMybSAgJytvb29vb29vb29vb286ICAgJytvb29vb29vb29vb286ICIgCmVjaG8gIC1lICJcZVswOzMybSAgIC9vb29vKysvL29vb29vOiAgb29vb28rLy8rb29vb28uICIgCmVjaG8gIC1lICJcZVswOzMybSAgICcrb29vb29vbzotOm9vLSAgK28rOjovb29vb29vbzogIiAKZWNobyAgLWUgIlxlWzA7MzJtICAgICc6b29vb29vb28rJycgICAgJy5vb29vb29vbystICIgCmVjaG8gIC1lICJcZVswOzMybSAgICAgICc6Kytvb28vLiAgICAgICAgOitvb28rLy4nICIgCmVjaG8gIC1lICJcZVswOzMxbSAgICAgICAgLi4uJyAgJy4tLS0tLicgJycuLiAiIAplY2hvICAtZSAiXGVbMDszMW0gICAgICAuOjo6Oi0nJzo6Ojo6Ojo6Oi4nLTo6Oi0nICAgICAgICAgICAgXGVbMDs5N20gICAgd3d3LmhlbnJpYWFuc3Rvb3QubmwiIAplY2hvICAtZSAiXGVbMDszMW0gICAgIC06OjotJyAgIC46Ojo6Ojo6LScgICctOjo6LSAgICAgICAgICAgXGVbMDs5N20gICAgVGVzdCBsb2dvIgplY2hvICAtZSAiXGVbMDszMW0gICAgJzo6LiAgJy4tLS4nICAnJyAnLi0tLS4nJy46OicgIiAKZWNobyAgLWUgIlxlWzA7MzFtICAgICAgICAuOjo6Ojo6OjonICAtOjo6Ojo6OjonICcgIiAKZWNobyAgLWUgIlxlWzA7MzFtICAuOjonIC46Ojo6Ojo6OjotICc6Ojo6Ojo6Ojo6Jyc6Oi4gIiAKZWNobyAgLWUgIlxlWzA7MzFtIC06OjonIDo6Ojo6Ojo6OjouICA6Ojo6Ojo6Ojo6Lic6OjotICIgCmVjaG8gIC1lICJcZVswOzMxbSA6Ojo6ICAtOjo6Ojo6OjouICAgJy06Ojo6Ojo6OiAgOjo6OiAiIAplY2hvICAtZSAiXGVbMDszMW0gLTo6LSAgIC4tOjo6LS4nJy4uLi4nJy4tOjotLiAgIC06Oi0gIiAKZWNobyAgLWUgIlxlWzA7MzFtICAuLiAnJyAgICAgICAuOjo6Ojo6OjouICAgICAnLi4nLi4gIiAKZWNobyAgLWUgIlxlWzA7MzFtICAgIC06OjotJyAgIC06Ojo6Ojo6Ojo6JyAgLjo6Ojo6JyAiIAplY2hvICAtZSAiXGVbMDszMW0gICAgOjo6Ojo6OicgLTo6Ojo6Ojo6OjonIDo6Ojo6OjouICIgCmVjaG8gIC1lICJcZVswOzMxbSAgICAuOjo6Ojo6OiAgLTo6Ojo6Ojo6LiA6Ojo6Ojo6OiAiIAplY2hvICAtZSAiXGVbMDszMW0gICAgICctOjo6OjonICAgLi4tLS4nICAgOjo6Ojo6LiAiIAplY2hvICAtZSAiXGVbMDszMW0gICAgICAgJy4uLicgICcuLi4tLS4uJyAgJy4uLicgIiAKZWNobyAgLWUgIlxlWzA7MzFtICAgICAgICAgICAgIC46Ojo6Ojo6Ojo6ICIgCmVjaG8gIC1lICJcZVswOzMxbSAgICAgICAgICAgICAgJy4tOjo6Oi0nICAiIAo=
cat source | base64 - -w0 1> ~/bin/logo.ob

Writes file (safe to copy paste/transfer) with:
ZWNobyAgLWUgIlxlWzA7MzJtICcuOjovLy8rOi8tLiAgICAgICAgLS0vLy8rLy8tOicnICIgCmVjaG8gIC1lICJcZVswOzMybSAgJytvb29vb29vb29vb286ICAgJytvb29vb29vb29vb286ICIgCmVjaG8gIC1lICJcZVswOzMybSAgIC9vb29vKysvL29vb29vOiAgb29vb28rLy8rb29vb28uICIgCmVjaG8gIC1lICJcZVswOzMybSAgICcrb29vb29vbzotOm9vLSAgK28rOjovb29vb29vbzogIiAKZWNobyAgLWUgIlxlWzA7MzJtICAgICc6b29vb29vb28rJycgICAgJy5vb29vb29vbystICIgCmVjaG8gIC1lICJcZVswOzMybSAgICAgICc6Kytvb28vLiAgICAgICAgOitvb28rLy4nICIgCmVjaG8gIC1lICJcZVswOzMxbSAgICAgICAgLi4uJyAgJy4tLS0tLicgJycuLiAiIAplY2hvICAtZSAiXGVbMDszMW0gICAgICAuOjo6Oi0nJzo6Ojo6Ojo6Oi4nLTo6Oi0nICAgICAgICAgICAgXGVbMDs5N20gICAgd3d3LmhlbnJpYWFuc3Rvb3QubmwiIAplY2hvICAtZSAiXGVbMDszMW0gICAgIC06OjotJyAgIC46Ojo6Ojo6LScgICctOjo6LSAgICAgICAgICAgXGVbMDs5N20gICAgVGVzdCBsb2dvIgplY2hvICAtZSAiXGVbMDszMW0gICAgJzo6LiAgJy4tLS4nICAnJyAnLi0tLS4nJy46OicgIiAKZWNobyAgLWUgIlxlWzA7MzFtICAgICAgICAuOjo6Ojo6OjonICAtOjo6Ojo6OjonICcgIiAKZWNobyAgLWUgIlxlWzA7MzFtICAuOjonIC46Ojo6Ojo6OjotICc6Ojo6Ojo6Ojo6Jyc6Oi4gIiAKZWNobyAgLWUgIlxlWzA7MzFtIC06OjonIDo6Ojo6Ojo6OjouICA6Ojo6Ojo6Ojo6Lic6OjotICIgCmVjaG8gIC1lICJcZVswOzMxbSA6Ojo6ICAtOjo6Ojo6OjouICAgJy06Ojo6Ojo6OiAgOjo6OiAiIAplY2hvICAtZSAiXGVbMDszMW0gLTo6LSAgIC4tOjo6LS4nJy4uLi4nJy4tOjotLiAgIC06Oi0gIiAKZWNobyAgLWUgIlxlWzA7MzFtICAuLiAnJyAgICAgICAuOjo6Ojo6OjouICAgICAnLi4nLi4gIiAKZWNobyAgLWUgIlxlWzA7MzFtICAgIC06OjotJyAgIC06Ojo6Ojo6Ojo6JyAgLjo6Ojo6JyAiIAplY2hvICAtZSAiXGVbMDszMW0gICAgOjo6Ojo6OicgLTo6Ojo6Ojo6OjonIDo6Ojo6OjouICIgCmVjaG8gIC1lICJcZVswOzMxbSAgICAuOjo6Ojo6OiAgLTo6Ojo6Ojo6LiA6Ojo6Ojo6OiAiIAplY2hvICAtZSAiXGVbMDszMW0gICAgICctOjo6OjonICAgLi4tLS4nICAgOjo6Ojo6LiAiIAplY2hvICAtZSAiXGVbMDszMW0gICAgICAgJy4uLicgICcuLi4tLS4uJyAgJy4uLicgIiAKZWNobyAgLWUgIlxlWzA7MzFtICAgICAgICAgICAgIC46Ojo6Ojo6Ojo6ICIgCmVjaG8gIC1lICJcZVswOzMxbSAgICAgICAgICAgICAgJy4tOjo6Oi0nICAiIAo=

Create an alias with the logo

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
alias logo=$(cat ~/bin/logo.ob | base64 -d )
alias logo=$(cat ~/bin/logo.ob | base64 -d )
alias logo=$(cat ~/bin/logo.ob | base64 -d )

executing logo will produce the logo

Bookstack – A new (for me) way do document stuff.

I’m always looking for new better ways to document stuff.

I’ve tested a lot, some things i’ve used personally for years.
Same or other tools I implemented also at Customers.

Everybody starts off with text files.
Then I used Hyper when I was using MS-Dos.

Many wiki’s came, and went.

  • Twiki – Work
  • Foswiki – Work, Highland Valley Pipeband, personal
  • Docuwiki
  • MediaWiki (pipetunesearch) and more

I tried to document in wordpress, but that’s not suitable.

I still got stuff in Nextcloud, Google Drive and Joplin. These are only for fast access to unstructured information.

I don’t like Wysiwig that much, also I like to use OpenSource and Open standards.

So discovering a knowledge base engine like Bookstack is always nice.

I installed a docker version in my Lab to experiment with.

So far so good.
Markup Language, and export to PDF, Markup, Html and Contained webfile.

I’ve changed the docker-compose.yml because I’ve got my dedicated Database server for that:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
---
version: "2"
services:
bookstack:
image: lscr.io/linuxserver/bookstack
container_name: bookstack
environment:
- PUID=1000
- PGID=1000
- APP_URL=http://bookstack.henriaanstoot.nl:6875/
- DB_HOST=IPDATABASESERVER
- DB_PORT=3306
- DB_USER=bookstackuser
- DB_PASS=bookstackpassword
- DB_DATABASE=bookstackapp
volumes:
- ./bookstack_app_data:/config
ports:
- 6875:80
restart: unless-stopped
volumes:
- ./bookstack_db_data:/config
restart: unless-stopped
--- version: "2" services: bookstack: image: lscr.io/linuxserver/bookstack container_name: bookstack environment: - PUID=1000 - PGID=1000 - APP_URL=http://bookstack.henriaanstoot.nl:6875/ - DB_HOST=IPDATABASESERVER - DB_PORT=3306 - DB_USER=bookstackuser - DB_PASS=bookstackpassword - DB_DATABASE=bookstackapp volumes: - ./bookstack_app_data:/config ports: - 6875:80 restart: unless-stopped volumes: - ./bookstack_db_data:/config restart: unless-stopped
---
version: "2"
services:
  bookstack:
    image: lscr.io/linuxserver/bookstack
    container_name: bookstack
    environment:
      - PUID=1000
      - PGID=1000
      - APP_URL=http://bookstack.henriaanstoot.nl:6875/
      - DB_HOST=IPDATABASESERVER
      - DB_PORT=3306
      - DB_USER=bookstackuser
      - DB_PASS=bookstackpassword
      - DB_DATABASE=bookstackapp
    volumes:
      - ./bookstack_app_data:/config
    ports:
      - 6875:80
    restart: unless-stopped
    volumes:
      - ./bookstack_db_data:/config
    restart: unless-stopped

While playing with this I forgot my credentials .. duh

Using portainer terminal access to the docker to add a new admin user

OpenPLC editor with Raspberry and Arduino

Here I’m going to post my tests with OpenPLC.

UPDATE 20231012 202301015

It’s a long time i’ve made a PLC ladder, but lets see how and what this integration brings me.

OpenPLC interface on a Raspberry, I could not start a program on RPI 5!
But it compiled correctly. See below rpi3
Schematic with a led and two buttons (and one floating in the middel, which i forgot to remove)
Working example ( wemos and display are from another project those are not connected )

UPDATE 20231015 – Raspberry 3 with OpenPLC

GND to leds and buttons
GPIO2 (pin 3) to a button
GPIO3 (pin 5) to another button
GPIO14 (pin 8) to the led

Now OpenPLC works correct (RPI3)

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
https://github.com/thiagoralves/OpenPLC_v3.git
cd OpenPLC_v3
./install.sh rpi
## Warning .. takes a really long time
Wiringpi is deprecated
But can be installed using the last git repo
git clone https://github.com/WiringPi/WiringPi.git
cd WiringPi
./build
https://github.com/thiagoralves/OpenPLC_v3.git cd OpenPLC_v3 ./install.sh rpi ## Warning .. takes a really long time Wiringpi is deprecated But can be installed using the last git repo git clone https://github.com/WiringPi/WiringPi.git cd WiringPi ./build
https://github.com/thiagoralves/OpenPLC_v3.git
cd OpenPLC_v3
./install.sh rpi 

## Warning .. takes a really long time

Wiringpi is deprecated
But can be installed using the last git repo

git clone https://github.com/WiringPi/WiringPi.git
cd WiringPi
./build

I’ve got a Raspberry 5, lets start experimenting

So many things to try .. and probably buy.
I’m lucky to have this already, official it’s not even out yet.

Specification

  • Processor : Broadcom BCM2712 2.4GHz quad-core 64-bit Arm Cortex-A76 CPU, B with cryptography extensions, 512KB per-core L2 caches, and a 2MB shared L3 cache

Features:

  • VideoCore VII GPU, supporting OpenGL ES 3.1, Vulkan 1.2
  • Dual 4Kp60 HDMI® display output with HDR support
  • 4Kp60 HEVC decoder
  • LPDDR4X-4267 SDRAM
    (4GB and 8GB SKUs available at launch)
  • Dual-band 802.11ac Wi-Fi
  • Bluetooth 5.0 / Bluetooth Low Energy (BLE)
  • microSD card slot, with support for high-speed SDR104 mode
  • 2 × USB 3.0 ports, supporting simultaneous 5Gbps operation
  • 2 × USB 2.0 ports
  • Gigabit Ethernet, with PoE+ support
    (requires separate PoE+ HAT)
  • 2 × 4-lane MIPI camera/display transceivers
  • PCIe 2.0 x1 interface for fast peripherals
    (requires separate M.2 HAT or other adapter)
  • 5V/5A DC power via USB-C, with Power Delivery support
  • Raspberry Pi standard 40-pin header
  • Real-time clock (RTC), powered from external battery
  • Power button

Some things come to mind to test:

  • Kubernetes
  • Dual Camera OpenCV – depthmap and more

You really want to use a case with an active blower to cool the rpi.

Measurements without cooling:

  • Power off – part most hot 28 degrees
  • Power on – Idle, around 40 degrees
  • Power on – Playing 4k for 5 minutes – 60+ degrees

Flir info https://www.henriaanstoot.nl/2023/06/05/checking-faulty-chips-hardware/

I didn’t have a image for Raspberry OS 5 at first, so I took a rpi 4 version and first replaced files in /boot
(Device Tree blob files)

Now at least i could boot into an OS.

Later I got a link to the Alpha boot images, this greatly improved usability and speed 🙂

Youtube 4k movie on a 2560×1080 monitor

Made a little overview website:

https://media.henriaanstoot.nl/websites/rpi5/index.html

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