Author: root42
Soldering a DSO138 Oscilloscope – Part 3
Soldering a DSO138 Oscilloscope – Part 2
Soldering a DSO138 Oscilloscope – Part 1
RGB LED Matrix with the Raspberry Pi
Here I show how to attach a WS2812 based LED strip or matrix to the Raspberry Pi.
Short introduction on how to actually install the rpi_ws218x library on the Pi:
-
- Install build essentials:
sudo apt-get update && sudo apt-get install build-essential python-dev git scons swig
- Clone the repository and build the library:
git clone https://github.com/jgarff/rpi_ws281x.git cd rpi_ws281x scons
- Compile and install the Python library:
cd python sudo python setup.py install
- Install build essentials:
Also, I have written this small example program, large parts were taken from the supplied example programs in the repository:
#!/usr/bin/env python import time import math import colorsys from neopixel import * # LED strip configuration: LED_COUNT = 64 # Number of LED pixels. LED_PIN = 18 # GPIO pin connected to the pixels (must support PWM!). LED_FREQ_HZ = 800000 # LED signal frequency in hertz (usually 800khz) LED_DMA = 10 # DMA channel to use for generating signal (try 10) LED_BRIGHTNESS = 255 # Set to 0 for darkest and 255 for brightest # True to invert the signal (when using NPN transistor level shift) LED_INVERT = False def plasma (w, h, t): out = [ Color( 0, 0, 0 ) for x in range( w * h ) ] for x in range( w ): for y in range( h ): hue = 4.0 + math.sin( t + x ) + math.sin( t + y / 4.5 ) \ + math.sin( x + y + t ) + math.sin( math.sqrt( ( x + t ) ** 2.0 + ( y + 1.5 * t ) ** 2.0 ) / 4.0 ) hsv = colorsys.hsv_to_rgb( hue / 8.0, 1, 1 ) out[ x + y * w ] = Color( *[ int( round( c * 10.0 ) ) for c in hsv ] ) return out # Main program logic follows: if __name__ == '__main__': # Create NeoPixel object with appropriate configuration. strip = Adafruit_NeoPixel( LED_COUNT, LED_PIN, LED_FREQ_HZ, LED_DMA, LED_INVERT, LED_BRIGHTNESS ) # Intialize the library (must be called once before other functions). strip.begin() t = 0.0 # time dt = 0.1 # speed of time for i in range( 0, strip.numPixels(), 1): # iterate over all LEDs strip.setPixelColor( i, Color( 0, 0, 0 ) ) # set LED to black (off) while True: t = t + dt # increment time pic = plasma( 8, 8, t ) # render plasma of size 8x8 at time t for i in range( 0, strip.numPixels(), 1 ): # iterate over all LEDs strip.setPixelColor( # set pixel to color in picture i, pic[ i ] ) strip.show() # update LEDs time.sleep(0.001) # white a short while before loop
Assembling a DIY solder blinking LED circuit
Parsing compiler or grep output for emacsclient
This short bash snippet allows you to copy and paste any grep or compiler output of the form some/file.java:12:34
to emacsclient
to jump to the specified file, line and column in Emacs:
function emacsClient() { local IFS=":" set $1 if [ $# -eq 3 ] then emacsclient -n +"$2:$3" "$1" elif [ $# -eq 2 ] then emacsclient -n +"$2:1" "$1" else emacsclient -n "$1" fi } alias ec=emacsClient
Example call:
$ grep -nH custom init.el init.el:93: (setq custom-file (expand-file-name "custom.el" (or (file-name-directory user-init-file) default-directory))) init.el:94: (load custom-file) init.el:95: (global-set-key (kbd "") '(lambda () (interactive) (load custom-file))) $ ec init.el:95: $
Update: I forgot to make the IFS variable local to the function. This would break things like git-bash-prompt, if the IFS is suddenly set to something else.
Simple rsync backup of your remote server w/ crontab
If you have a remote server, e.g. for you website, small business or whatever, it is a good idea to replicate it regularly onto local storage. You at least want /etc, /home, /var/www, /usr/local to be in the backup. Maybe more stuff, depending on what you are doing.
For now I assume you are running the backup on OS X’s user with admin/sudo rights, or some Linux user with sudo rights.
The reason why we want to do this with sudo and root on the remote system is to have a simple way to backup the whole system with all files, users and permissions. If you only want to backup a remote user, you don’t need the whole sudo and root part, but can use the remote user login instead.
First, you need the backup script:
#!/bin/bash if [ "${UID}" != 0 ] then echo "Must be run as root." exit 1 fi shopt -s nocasematch pushd `dirname $0` > /dev/null SCRIPTPATH=`pwd` popd > /dev/null if [[ "${PWD}" != "${SCRIPTPATH}" ]] then echo "Wrong path: ${PWD}" exit 2 fi RSYNC_RSH="ssh -C -o IdentitiesOnly=yes -i /Path/to/key/without/password" RSYNC_CMD='rsync -aP --delete --delete-after' RSYNC_HOSTNAME='your.server.name' ($RSYNC_CMD -e "${RSYNC_RSH}" root@${RSYNC_HOSTNAME}:/etc :/home :/root :/usr/local :/var/www . > /tmp/rsync.log 2>&1 ) || \ (>&2 echo "An error occured while doing the backup: " ; cat /tmp/rsync.log ) exit $?
Adjust your hostname accordingly and also the directories to be backed up. Use the :/dir notation to reuse the SSH connection. Also make sure to use SSH key authentication, so no password is needed, since this backup is supposed to run via crontab. SSH access as root must only be allowed via key exchange! Make sure to disable password access, or else you are running a security risk! Also, keep the SSH key secret — it is the door to your server!
There are probably more secure ways, but they are more complicated than this.
Next up, put you script somewhere your sudo user can run it, and edit the crontab via “crontab -e”:
MAILTO=user@domain # or simply your local user, to put it into the local mbox 0 * * * * cd /Users/youruser/Documents/Backup && sudo /Users/youruser/Documents/Backup/backup.sh
You can make the script runnable with sudo without password by adding the following line to your /etc/sudoers file:
# allow passwordless access to the backup script youruser ALL = (ALL) NOPASSWD: /Users/youruser/Documents/Backup/backup.sh
The script will only generate output on an error, hence cron will only send an email if there is an error.
If you are now also running TimeMachine, your server will have a nice, hourly history of backups.
Indexed Java 8 enums with gaps
This is an example enum for Java 8 that supports gaps in its indices is relatively fast for enums with a large amount of values:
import java.util.Arrays; import java.util.Map; import java.util.stream.Collectors; public enum TestEnum { VALUE1( 0 ), VALUE2( 2 ), VALUE3( 50 ); private final Integer id_; private static Map< Integer, TestEnum > values_ = Arrays.stream( TestEnum.values() ).collect( Collectors.toMap(e -> e.id_, e -> e) );; private TestEnum( int i ) { id_ = i; } public static TestEnum fromInteger( int i ) { return values_.get( i ); } }
How to concatenate strings efficiently in bash
The naive implementation for concatenating strings in bash goes something like this:
#!/bin/bash statement="1234567890" result="" for i in $(seq 1 100000) do result=${result}${statement} done wc <<< ${result}
This takes around two minutes on a modern machine. This is slow. Very, very slow.
Instead you can build an intermediate array and use the star operator to expand it into a string. Make sure to change the input field seperator to empty, so that you don’t get spaces in between the individual entries:
#!/bin/bash statement="1234567890" for i in $(seq 1 100000) do statements[${#statements[@]}]=${statement} done IFS= eval 'result="${statements[*]}"' wc <<< ${result}
This will run in a few hundred milliseconds. You get roughly three orders of magnitude speedup.