Just a quick note to self on how to use Tcl’s regsub
command:
% regsub -all {pattern} "input string containing pattern" "replacement" target 1 % puts $target input string containing replacement
Some kind of mélange of computing hardware, software, music and sound recording.
Just a quick note to self on how to use Tcl’s regsub
command:
% regsub -all {pattern} "input string containing pattern" "replacement" target 1 % puts $target input string containing replacement
/dev
directory)Inspired by reading an old thread on my local Linux user group mailing list:
$ history | awk '{a[$2]++ } END{for(i in a){print a[i] " " i}}' | sort -rn | head 94 povray 58 source 55 ./wacdump 32 l 31 cd 25 dcraw 22 cp 21 gimp 20 less 19 gvim
:)
I should run that more often. Maybe feed to Twitter. Or not.
Here’s a little Expect script for getting a control stream into Pure Data, in my case from a butchered Genius serial mouse that I wrote an interrupt-driven Arduino driver for. The driver sends a “+
” or “-
” down the serial line each time the optical rotary encoder in the mouse guts moves a click. This assumes the Arduino is connected on /dev/ttyUSB0
(e.g. on Linux). Use a [netreceive 3000]
(or whatever port you like) in Pure Data to receive.
Note: this only uses one mouse axis, requiring two interrupts. Apparntley the Arduino Mega has six interrupt lines externally available, so I'll be adding another axis of control soon.
#!/usr/bin/expect # Take Arduino mouse '+'/'-' stream and convert into Pure Data FUDI format, without buffering. # To run: # expect mouse-pd.expect | pdsend 3000 # TODO: this should probably use Expect's stty command to set the serial port up to match the Arduino program. eval spawn -noecho cat /dev/ttyUSB0 log_user 0 while (true) { expect { + {send_user "1;\n"} -- {-} {send_user -- "-1;\n"} } }
Here’s the Arduino code:
// Simple interrupt-driven driver for quadrature encoder input (e.g. from a disassembled photoelectric ball mouse). // Many Arduino boards provide only two interrupts, I believe: INT0 (on pin 2) and INT1 (on pin 3): const int intA = 0, intAPin = 2; const int intB = 1, intBPin = 3; volatile int A = 0, B = 0; // For storing the pin states for future reference to determine rotation direction int A_Prev = 0, B_Prev = 0; // Should these be volatile, too? void setup() { // Configure digital input pins for interrupt-driven timing: pinMode(intAPin, INPUT); digitalWrite(intAPin, LOW); pinMode(intBPin, INPUT); digitalWrite(intBPin, LOW); Serial.begin(115200); // Read initial state of the pins: A_Prev = digitalRead(intAPin); B_Prev = digitalRead(intBPin); A = digitalRead(intAPin); B = digitalRead(intBPin); attachInterrupt(intA, changeA, CHANGE); attachInterrupt(intB, changeB, CHANGE); } void changeA() { A = !A; output(); A_Prev = A; } void changeB() { B = !B; output(); B_Prev = B; } void output() { if (A == B_Prev) Serial.print("+"); else if (B == A_Prev) Serial.print("-"); else Serial.print('?'); } void loop() {}
Microcontroller programming is fun, BTW! I’d never written a driver or an interrupt handler until two days ago.