Ben's Blog

miscellaneous ben July 06, 2020

Giant Paper Airplane

nature encounters ben June 26, 2020

Rabbit

self sustainability, water ben June 21, 2020

The Great Plentiful Douche of 2020

We updated our outside shower to something honestly quite amazing. It’s missing finishing touches but we have most likely found the final location and configuration.

Quaint! And private, I don’t care if a coyote sees me bare assed.

Now before I get into the details, the one big gain here for us is infinite hot water, at will. I know it doesn’t sound like much but believe me, to us it’s the most amazing thing in the world.

First of all, this is water we do not move by hand, which is a first in 5 years. How does it works in the middle of the woods? Well we improved an abandoned beaver dam to buffer some water in the stream. Stream water can be murky so we made a siphon between the beaver buffer upstream and a giant tub downstream. The tub is one more opportunity for sediment to settle. I tried to make the water run down a long hollowed out pine tree but we couldn’t get the level quite high enough. Turns out a siphon is a thousand times better anyway.

From the giant tub, a simple 12V pump pumps the water into a tankless heater.

The water pump, some things still need proper places.

I had enough spare parts for a whole other solar setup. 1 charge controllers, 3 super dead lead acid batteries I revived with the water trick, and finally 1 charge controller. It’s not much of a solar setup, it’s what we started with years ago, but it’s perfect for 1 water pump in the woods.

It remains to be determined if we’ll consume more electricity than we’ll produce with this 1 panel in this 1 spot. We used to have a second extra panel but I tractored it by accident :\.

This pump is setup to stop when a certain pressure is reached. So it keeps the line to the tankless heater pressurized and then stops drawing power. When you call for water, the pressure drops and it starts up automatically. The tankless heater lights up and you get hot water.

The really incredible device tying all together: an outside tankless heater.

There is literally no work to the whole operation, no moving water nor applying heat with a fire like we did before when we wanted hot water.

The whole setup

Now the one imperfection of this system is that heating is done with propane: a fossil fuel not from our land. I’m sure no one in the family will dare disparage the approach given how much time we all spent taking hot showers. The kids especially spend extra long in a small tub, toys have been replaced with various forest things we find and throw in the water (ferns, sticks).

It’s worth mentioning that hot water is a mixed blessing. On the warm days, there is nothing better than being forced to take a uncomfortably cold shower. It really cools you down for several hours. With this luxurious shower it’s impossible to resist the temptation of comfortable warm water, this does nothing to help you bear the oppressive heat of a Summer day. I’m sure there’s a moral in there about easy choices not necessarily being the best ones. I choose to ignore it from the depths of my steaming hot water.

Funny language anecdote: shower is quite funnily “douche” in French, and so when we used solar heated camping water bags years ago, we inevitably called them douche-bags. This new one’s been dubbed mega-douche.

nature encounters ben May 26, 2020

Porquepic

We found this guy deep in the woods on a new trail we’re making. Good climber!

self sustainability ben May 14, 2020

Made it to the Other Side

It doesn’t look like much, but it took a lot of moving big rocks and big trees to get to this little bridge:

Ever since we moved to the land, we’ve tried to get access to beyond the stream with the ATV, and later the tractor. A good 70% of the land is beyond the stream and it’s the 70% with the most trees. Being able to get there with the ATV means a lot of easy pickings for firewood. We also would like to build a little retreat of a cabin up there, far from everything.

This little bridge allows for glorious moments of trail blazing such at this:

We are actually very close to being able to close a nice loop of trails around the land. We’ll try to make a push for it this year but they will take several more to be nice trails, most are currently pretty rough.

miscellaneous ben May 13, 2020

Umbrella Flight Trials

miscellaneous ben May 13, 2020

Vermonting Toddler

 

agriculture, self sustainability ben April 26, 2020

107

Adding a few every year, I didn’t see it coming. But it turns out we planted our 100th blueberry plant this year for a grand total of 107. They’re all still fairly small but they’re growing exponentially and it’s clear that we’ll have an overabundance in a year or 2.

agriculture, self sustainability ben April 21, 2020

Feeling Wealthy in Uncertain Times

We just received a massive pile of compost, behind this is a massive pile of wood chips. Both of which are gold for growers, and so we get to be generous with our plants.

We ordered 18 yards of compost, I learned another completely insane measure: the yard. The amount of hand waving I see when talking about yards is peculiar. Trying to make sense of it online yields the same written hand waving. A cubic yard is a cubic yard, let’s consider ourselves lucky it’s cubic and not using the 11th dimension.

Here’s one thing I love about the U.S. system of measures, it encourages generosity. Because no one has but a vague idea what a cord, a bushel, or a yard is, we over-give to make sure we gave enough.

 

We received the plants we ordered this year. As always we’ll grow our operation a little. They’ll go in the ground as soon as tomorrow. 7 more fruit trees and a bunch more berries.

 

I built more proper shelves in the green house, Nicole is growing the garden significantly. Everything is about to explode in growth.

building, self sustainability ben April 14, 2020

Trenching for Fiber

In preparation for a fiber drop, I buried conduit from the pole to the solar shed. I had never done anything like this before, adding to the long list of skills I’m happy to have.

 

The part in the woods was super hard, I tried to do it by hand but there was no going through the roots. I ended up chainsawing a path for the tractor. With this and some crazy maneuvering, the trench was dug.

The tractor was invaluable to the operation. It always blows my mind how hard it is to move dirt by hand.

Lego / Duplo ben April 11, 2020

Cool Duplo Project #50 – Confinement Focus Measures

maple syrup, self sustainability ben April 02, 2020

Protected: Maple Juice 2020 wrapping up

This content is password-protected. To view it, please enter the password below.

I.T. ben April 02, 2020

PHP Zoom API JWT Bit Banging

It’s always hard to nail the exact sequence when authorizing through a new API. Here’s what I came up with for PHP authorization with Zoom’s JWTs. This is essentially a quick start which gets you enough functions to do a first API call: to list zoom users. Line 40->68 is where the JWt meat happens.

[php]
<?php

// config parameters you need to define
define( ‘ZOOM_TOKEN_FILE’, "/var/.zoom_token" ) ; // some location on the filesystem used to cache your token while it’s current (make sure permissions are restrictive)
define( ‘ZOOM_API_KEY’, "" ) ;
define( ‘ZOOM_API_SECRET’, "" ) ;

// main
print_r( zoom_list_users() ) ;
exit( 0 ) ;

// functions
function zoom_list_users() {
$users = array() ;

$page_number = 1 ;
$keep_going = true ;
while( $keep_going && $page_number<10000 ) {
$result = zoom_make_api_call( "GET", "https://api.zoom.us/v2/users", array(‘page_size’=>300, ‘page_number’=>$page_number, ‘status’=>"active") ) ;
$result = json_decode( $result, true ) ;
if( array_key_exists(‘users’, $result) &&
count($result[‘users’])>0 ) {
foreach( $result[‘users’] as $user ) {
$users[] = $user ;
}
$page_number++ ;
if( $page_number>$result[‘page_count’] ) {
$keep_going = false ;
}
} else {
$keep_going = false ;
}
}

return $users ;
}

// PHP’s default base64 encode isn’t URL safe which messes up the JWT, we need these functions instead
function base64_url_encode( $data ) {
return rtrim( strtr(base64_encode($data), ‘+/’, ‘-_’), ‘=’ ) ;
}
function base64_url_decode( $data ) {
return base64_decode( str_pad(strtr($data, ‘-_’, ‘+/’), strlen($data) % 4, ‘=’, STR_PAD_RIGHT) ) ;
}

function get_token( $refresh=false ) {
if( $refresh===false &&
file_exists(ZOOM_TOKEN_FILE) ) {
return file_get_contents( ZOOM_TOKEN_FILE ) ;
}

$jwt_request_date = @date( "U" ) ; // no warning, proper system timezone assumed
$jwt_expiration_date = $jwt_request_date + 60*60 ; # +1 hour
$jwt_header = ‘{"alg":"HS256","typ":"JWT"}’ ;
$jwt_claim_set = ‘{"iss":"’ . ZOOM_API_KEY . ‘","exp":’ . $jwt_expiration_date . ‘}’ ;
$jwt_signature = sign_data( base64_url_encode($jwt_header) . ‘.’ . base64_url_encode($jwt_claim_set), ZOOM_API_SECRET ) ;
$jwt = base64_url_encode( $jwt_header ) . "." . base64_url_encode( $jwt_claim_set ) . "." . base64_url_encode( $jwt_signature ) ;

file_put_contents( ZOOM_TOKEN_FILE, $jwt ) ;
return $jwt ;
}

function sign_data( $data, $key ) {
return hash_hmac( "SHA256" , $data, $key, true) ;
}

function zoom_make_api_call( $request, $url, $get_variables=null, $post_variables=null, $force_refresh_token=false ) {
$ch = curl_init() ;
$token = get_token( $force_refresh_token ) ;

$getfields = "" ;
if( $get_variables!==null && is_array($get_variables) ) {
foreach( $get_variables as $get_variable_key=>$get_variable_value ) {
$getfields .= "&" . urlencode( $get_variable_key ) . "=" . urlencode( $get_variable_value ) ;
}
if( strlen($getfields)>0 ) {
$getfields = "?" . substr( $getfields, 1 ) ;
}
}

curl_setopt( $ch, CURLOPT_URL, "{$url}{$getfields}" ) ;
curl_setopt( $ch, CURLOPT_PORT , 443 ) ;
curl_setopt( $ch, CURLOPT_CUSTOMREQUEST, $request ) ;
curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, false ) ;
if( $post_variables!==null && is_array($post_variables) ) {
$postfields = "" ;
foreach( $post_variables as $post_variable_key=>$post_variable_value ) {
$postfields .= "&" . urlencode( $post_variable_key ) . "=" . urlencode( $post_variable_value ) ;
}
$postfields = substr( $postfields, 1 ) ;
curl_setopt( $ch, CURLOPT_POSTFIELDS, $postfields ) ;
} else if( $post_variables!==null && is_string($post_variables) ) {
curl_setopt( $ch, CURLOPT_POSTFIELDS, $post_variables ) ;
}
curl_setopt( $ch, CURLOPT_HTTPHEADER, array( "authorization: Bearer {$token}",
"content-type: application/json") ) ;

curl_setopt( $ch, CURLOPT_RETURNTRANSFER, 1 ) ;
curl_setopt( $ch, CURLOPT_HEADER, true ) ;

$response = curl_exec( $ch ) ;
curl_close( $ch ) ;

$response = parse_http_response( $response ) ;

if( $response[‘code’]=="200" ||
$response[‘code’]=="204" ||
$response[‘code’]=="404" ) {
return $response[‘body’] ;
} else if( $response[‘code’]=="401" ) { // expired token
if( $force_refresh_token===false ) {
// safe to recurse
return zoom_make_api_call( $request, $url, $get_variables, $post_variables, true ) ;
} else {
echo "ERROR: had an expired token and I tried to refresh it, yet somehow it’s still expired\n" ;
print_r( $response ) ;
exit( 1 ) ;
}
} else {
echo "ERROR: I have no idea what to do with this response from Zoom\n" ;
print_r( $response ) ;
exit( 1 ) ;
}
}

function parse_http_response( $raw_data ) {
$parsed_response = array( ‘code’=>-1, ‘headers’=>array(), ‘body’=>"" ) ;

$raw_data = explode( "\r\n", $raw_data ) ;

$parsed_response[‘code’] = explode( " ", $raw_data[0] ) ;
$parsed_response[‘code’] = $parsed_response[‘code’][1] ;
$i = 1 ;
if( $parsed_response[‘code’]=="100" ) {
$parsed_response[‘code’] = explode( " ", $raw_data[2] ) ;
$parsed_response[‘code’] = $parsed_response[‘code’][1] ;
$i = 3 ;
}

for( ; $i<count($raw_data) ; $i++ ) {
$raw_datum = $raw_data[$i] ;

$raw_datum = trim( $raw_datum ) ;
if( $raw_datum!="" ) {
if( substr_count($raw_datum, ‘:’)>=1 ) {
$raw_datum = explode( ‘:’, $raw_datum, 2 ) ;
$parsed_response[‘headers’][strtolower($raw_datum[0])] = trim( $raw_datum[1] ) ;
} else {
echo "ERROR: we’re in the headers section of parsing an HTTP section and no colon was found for line: {$raw_datum}\n" ;
exit( 1 ) ;
}
} else {
// we’ve moved to the body section
if( ($i+1)<count($raw_data) ) {
for( $j=($i+1) ; $j<count($raw_data) ; $j++ ) {
$parsed_response[‘body’] .= $raw_data[$j] . "\n" ;
}
}

// we don’t need to continue the $i loop
break ;
}
}

return $parsed_response ;
}

?>
[/php]

maple syrup, self sustainability ben March 09, 2020

Protected: Grand Opening

This content is password-protected. To view it, please enter the password below.

nature encounters ben February 19, 2020

Little by little

he ventures out in the woods by himself a bit further every day

self sustainability, wood ben February 16, 2020

The family is growing

We just acquired another cookstove. It is in excellent shape for a stove built in 1905, so much so that we couldn’t let it pass. Like we did with our Sweetheart, it’ll sit unused for a couple of years, and we’ll use that time to give it the bit of TLC it needs.

It’s quite beautiful and has many bells and whistles.

apple, self sustainability ben February 16, 2020

Cider in a Bottle

Our 2nd year making hard cider, we skipped one last year when the apple trees didn’t produce anything. Such are the whims of mother nature.

We did this one a little more “right” by transferring to a 2nd fermenter after a couple of months and by letting it age for 5 months total. It definitely helped refine the flavor and remove some of the less desirable tones.

As before we used our maple syrup to fuel the fermentation. It’s kind of a shame because the taste of maple syrup is completely lost in the process, I would love to have something mapley left. At the same time, it’s completely awesome that we are able to make hard cider with 100% local ingredients. And by local I mean right from our backyard. It may seem completely absurd to use maple syrup like this, we could sell it and buy many times its weight in refined cane sugar with the money. This isn’t what we’re after though, closing cycles as locally as possible is the end game, not making money. And so using maple syrup is the most sensical and harmonious thing we can do.

I commissioned labels from Robin, I would like to build up a portfolio of labels made from people I love to satisfy any future circumstances. This year we had deer go through apple trees during a ghost moon, and we had a press day heavy on yellow jackets.

Overall it’s really super nice that all these projects are well established these days. We are so much more relaxed going through the motions with experience under our belt. It’s still a lot of work, but at least we’re no longer worried we’re going to majorly fuck something up and ruin everything.

We’ll be sugaring soon, and we’ll have cider to drink while we boil the maple syrup we’ll use the make the cider. It’s the circle of life or something.

homestead automation, I.T. ben January 12, 2020

GPIO 2 Inverter

I figured out a way to turn our inverter on and off with a Pi so I can leave it off when Winter forces us to be frugal. It takes a little more than an amp hour just sitting there doing nothing, so I do like to turn it off. This capability will serve to automate the fridge in the future, before I do that though, I need to figure out a way to bring cold air from the outside into it. The idea is to have a logic which looks at outside temperature, solar status, and fridge temperature to decide if we just turn it on or if we can simply (and for less electricity) fan in cold air from the outside.

Running a fridge on the coldest months, when solar power is scarce, is doubly absurd.

building, self sustainability ben January 12, 2020

Protected: SugarHouse

This content is password-protected. To view it, please enter the password below.

miscellaneous ben January 12, 2020

Never seen a kid

go from bed to snow as fast as he does. Not 30 seconds pass from the warmth of his sheets to the blistery morning cold.

His new morning routine

aesthetics, I.T., plotters ben January 12, 2020

Plotter Trials

I’m getting closer to a very usable plotter, for now the prototype is serving all my plotting needs. Another prototype is in the works, this way I’ll be able to work on a plotter and keep another one for drawing. I keep finding ideas for really cool videos which I’m certain will make splashes online. I want to have my next steps figured out before I try to do just that. I know that at least the plotter build will be documented as a DYI project.

I found my birthday presents for the next 10 years

First trial with paint, I coded for “ink refill” capabilities for all instruments which require it. Obviously I’ve learned a few lessons here 🙂

I.T., plotters ben January 01, 2020

Protected: Learning about Cartesian coordinate systems to control the plotter

This content is password-protected. To view it, please enter the password below.

electronics, I.T. ben December 14, 2019

Raspberry Pi Servo Jitter

Here’s the final solution I came up with to finally get a servo motor to behave on a Pi. It may not seem like much but it took a lot of doing to gather all the right bits. This was tested with an SG90, SG92R, and an MG90S on a Pi Zero.

Scroll straight to the end for the solution.

The most common way for controlling a servo motor on a Pi with is through RPi.GPIO as such:

#!/usr/bin/python3
import RPi.GPIO as GPIO
import time

servo = 23

GPIO.setmode( GPIO.BCM )
GPIO.setup( servo, GPIO.OUT )

# info on frequency and PWM formula at https://rpi.science.uoit.ca/lab/servo/
pwm = GPIO.PWM( servo, 50 )
pwm.start( 2.5 )

print( "0 deg" )
pwm.ChangeDutyCycle( 2.5 )  # turn towards 0 degree
time.sleep( 3 )

print( "90 deg" )
pwm.ChangeDutyCycle( 7.5 )  # turn towards 90 degree
time.sleep( 3 )

print( "180 deg" )
pwm.ChangeDutyCycle( 12.5 ) # turn towards 180 degree
time.sleep( 3 )

pwm.stop()
GPIO.cleanup()

Stuff you might need for this to run:

sudo apt-get update && sudo apt-get install python3-rpi.gpio

It results in super jitter which is unacceptable for the holy mission of pen plotting.

As far as I understand, the jitter comes from the wave form RPi.GPIO produces for Pulse Width Modulation, which is made in software and so it’s not super stable (no dedicated resources to build it). From what I gather, pigpio is programmed to tap into the one hardware PWM that Pis have.

The solution thus is as such:

#!/usr/bin/python3
import RPi.GPIO as GPIO
import pigpio
import time

servo = 23

# more info at http://abyz.me.uk/rpi/pigpio/python.html#set_servo_pulsewidth

pwm = pigpio.pi()
pwm.set_mode(servo, pigpio.OUTPUT)

pwm.set_PWM_frequency( servo, 50 )

print( "0 deg" )
pwm.set_servo_pulsewidth( servo, 500 ) ;
time.sleep( 3 )

print( "90 deg" )
pwm.set_servo_pulsewidth( servo, 1500 ) ;
time.sleep( 3 )

print( "180 deg" )
pwm.set_servo_pulsewidth( servo, 2500 ) ;
time.sleep( 3 )

# turning off servo
pwm.set_PWM_dutycycle( servo, 0 )
pwm.set_PWM_frequency( servo, 0 )

Stuff you might need for this to run:

sudo apt-get update && sudo apt-get install python3-pigpio
sudo pigpiod

And the resulting super smooth motion and holds:

Posts pagination

← Previous 1 … 20 21 22 … 53 Next →

This blog is solar powered

Interactive

Handwriting Capture
Mandalagaba
IPv6 link-local to MAC converter
IPv6 MAC to link-local converter
Markov Text Generation
Markov Word Generation
Markov Music Generation
Duplogrifier
Flood Fill Algorithms
Homestead Metrics
RGB Playground
Web Games

Categories

  • aesthetics112
    • plots54
    • specular holography6
  • Books4
  • I.T.207
    • 3D modeling / printing21
    • AI7
    • all out geekery38
    • electronics29
    • homestead automation7
    • maniacal paranoia27
    • plotters49
    • unix / linux29
    • video games4
    • web development30
    • web games3
  • Lego / Duplo67
  • life in the U.S.42
  • miscellaneous204
  • nature encounters116
  • old vinyls3
  • organs2
  • self sustainability565
    • agriculture109
    • apiculture38
    • apple20
    • building132
    • canning3
    • crochet6
    • foraging6
    • hunting10
    • maple syrup47
    • poultry39
    • preserving3
    • solar power28
    • water23
    • wood85
  • trip to a new life6
Theme by Bloompixel. Proudly Powered by WordPress