Ben's Blog

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:

aesthetics, I.T., web development ben December 08, 2019

Fibonacci Assist

It’s been a while since I pushed a feature to Mandalagaba worthy of a post.

I just pushed a tool I call “Fibonacci Assist”. It’s meant to help you draw Fibonacci spirals by overlaying the proper framing based on the beginning of your penstroke.

I was reminded of the existence of this sequence and its ties to nature reading the most excellent children book: Swirl by Swirl. The book is simply magnificent and so I thought I’d do my part to help bring into the world more Fibonacci spirals.

I have yet to play with it using a stylus.

aesthetics, all out geekery, I.T. ben December 07, 2019

Fluid Dynamics Simulation

all out geekery, I.T. ben December 07, 2019

Nosy Monster Nosying & Monstering around

Still going strong

3D modeling / printing, aesthetics, I.T., plotters ben December 02, 2019

Plotting Plotters

Well so, I fell into a very deep rabbit hole. The world of pen plotters… A year in, I finally have some good results. After several prototypes of Gondola plotters (V-plotters) and regular tabletop plotters. I’ve homed in on a set of designs, hardware, electronics, and algorithms to think I can make a small difference in that world. I still need to iterate a little but I’m hoping to release each plotter as a DYI projects in 2020. Maybe I’ll even sell my making them for others. Of course there will be integrations with Mandalagaba because that just makes sense.

Now there are several such plotters one can buy or build for a wide range of prices. And they all have a very shitty software stack. This is where I believe I can make the biggest difference.

As with building houses, it’s enormously relieving to finally see into the real world a model you’ve been immersed in, CADing it for a year.

I’ll skip talking about the long series of challenges I ran into building this. It’s really, really nice to see a long plot finished to perfection knowing that finally, nothing is wrong. I’ve learned a lot along the way.

There’s a bazillion pen plotters on Thingiverse, I’ve used some of them as stepping stones until I was ready to finally make my own top to bottom. As I said, software is where I think I can make the biggest difference. I’m a Raspberry Pi aficionado, and this opens the door to a sophisticated software stack (web servers, HTML canvasses, format conversion, penstroke optimization, live link with Mandalagaba). I found not a single plotter using a Pi, in fact I found very few projects of anything using stepper motors with a Pi. I had to do some serious trail blazing to step a motor reliably.

Here is for example a pen stroke optimization algorithm I developed to speed up plotting.

 

The base, drawing penstrokes as they come. “Empty” travel going from one penstroke to the next without the pen drawing: ~36437 (relative pixels).

The next penstrokes is the closest. Empty travel ~15820, 0.43 compression ratio.

The next penstrokes is the closest, but consider its beginning as well as its end, draw the penstroke reversed if it was the end which was closest. Empty travel ~12467, 0.34 compression ratio.

 

Now for the eye candy 🙂

I could watch this for hours, and I did.

Of course the efficacy of this algorithm depends heavily on the model to be drawn. I found that anything coming from Mandalagaba tends to benefit enormously, especially tessellations. And it makes sense, for every penstroke drawn, the repetitions occur throughout the canvas and they show up in that order even if you drew in a very localized area. The example above comes from the most excellent turtletoy.net.

More to come very soon on the great world of plotters…

self sustainability, wood ben December 02, 2019

Wooden Snake

This is unfortunately not an improvement from my last attempt. The design is barely visible due to my poor choice of facing bark. Still, I’m trying to get better at this every year.

miscellaneous, trip to a new life ben November 18, 2019

Protected: One day we’ll build a house up there

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

Posts pagination

← Previous 1 … 20 21 22 … 52 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

  • aesthetics111
    • plots54
    • specular holography6
  • Books4
  • I.T.204
    • 3D modeling / printing21
    • AI7
    • all out geekery37
    • electronics28
    • homestead automation7
    • maniacal paranoia27
    • plotters49
    • unix / linux29
    • video games4
    • web development30
    • web games3
  • Lego / Duplo67
  • life in the U.S.42
  • miscellaneous204
  • nature encounters115
  • old vinyls3
  • organs2
  • self sustainability563
    • agriculture107
    • apiculture38
    • apple20
    • building132
    • canning3
    • crochet6
    • foraging6
    • hunting10
    • maple syrup47
    • poultry39
    • preserving2
    • solar power28
    • water23
    • wood84
  • trip to a new life6
Theme by Bloompixel. Proudly Powered by WordPress