Tumgik
pi-pixel · 13 years
Text
Nubstep: Overview and Part I - knob.io
Nubstep: Overview and Part I - knob.io
Nubstep is the project @pedrogte, @telmofcosta and me presented at Codebits 2011.
It is a sound synthethizer that collects inputs from an arduino, and generates sound through Core Audio. It also includes a web console for looking at readings (not shown at the competition presentation due to presenter lameness). All the data flowing from the arduino to the synthetizer is channeled through hook.io.
Overview:
Tumblr media
Arduino: Collect data from analog inputs (Detailed in this post)
knob.io: Get readings from arduino and send them to hook.io (Also detailed in this post)
knob-view.io: Show arduino readings on a browser
nubstep: Synthetize sound waves and feed them to roar
roar: Node library to output sound through Core Audio
Arduino Sketch
Reading the analog inputs on the arduino and sending them through the serial port is fairly easy. Here's the arduino sketch:
(If you're an arduino newbie, you can read "Serial port" as "USB")
void setup() { Serial.begin(9600); } void loop() { int analogValues[6]; int i; for(i=0; i<6; i++) analogValues[i] = analogRead(i); for(i=0; i<6; i++) Serial.println(analogValues[i]); Serial.println(); delay(100); }
This code may seem familiar, and it is, because it's basically this arduino example adapted to read all the 6 analog inputs.
Here's the fritzing sketch for our box:
Tumblr media
And the actual box:
Tumblr media
knob.io
Reading the serial port on node.js requires the node-serialport module. Currently this module is stable enough, so, the hard work consists on interpreting the arduino output correctly.
Here's code for reading the serial port and sending it to hook.io:
(See below for more details)
#!/usr/bin/env node var util = require("util"); var serialport = require("serialport"); var Hook = require('hook.io').Hook; var SerialPort = serialport.SerialPort; var SerialHook = exports.SerialHook = function (options) { var self = this; Hook.call(this, options); this.on('hook::ready', function () { var sp = new SerialPort("/dev/tty.usbserial-A7006xos", { parser: serialport.parsers.readline("\r\n\r\n") }); var first_time = true; var values = [-1, -1, -1, -1, -1, -1]; sp.on("data", function (data) { // always ignore the first sample // data may be incomplete -> no way to know if(first_time) { first_time = false; return; } var knobs = data.split("\r\n").map(function(k) { return parseInt(k,10); }); if(knobs.length !== 6) { return; } var changes = 0; knobs = knobs.reduce(function(map, k, i) { if(k !== values[i]) { map[i] = values[i] = k; changes++; } return map; }, {}); if(changes !== 0) { self.emit('knobs', knobs); console.log('Emitting: ' + util.inspect(knobs)); } }); }); }; util.inherits(SerialHook, Hook); var serialhook = new SerialHook({ name: 'serial', 'hook-host' : '0.0.0.0' }); serialhook.start();
Reading the first valid sample
The data stream sent by the arduino has the following structure:
... <analog input 0>(end of line -> \r\n) <analog input 1>(end of line) <analog input 2>(end of line) <analog input 3>(end of line) <analog input 4>(end of line) <analog input 5>(end of line) (empty line, which means just an end of line) <analog input 0>(end of line) <analog input 1>(end of line) <analog input 2>(end of line) <analog input 3>(end of line) <analog input 4>(end of line) <analog input 5>(end of line) ...
Actual data looks like:
... 511 255 767 1023 0 511 511 239 767 1023 0 511 ...
To read input from the arduino, node-serialport is initialized with:
var sp = new SerialPort("/dev/tty.usbserial-A7006xos", { parser: serialport.parsers.readline("\r\n\r\n") });
The parser option is a recent feature of node-serialport and used like this allows us to split readings from the arduino easily. In this case, note that the empty line between readings results in two consequent end-of-lines on the data stream (one from the last input being read and the other from the empty line).
Using the parser option simplifies parsing a lot, so, getting each reading becomes just wait for data with an event listener:
sp.on("data", function (data) { //... }
There is no flow control nor any field delimiters (apart from the line endings). This means that the application reading the arduino feed may start reading it on the middle of something, so, the first input reaching the app (for the data given above) could be:
23 0 511 511 239 767 1023 0 511 ...
The the first number is a truncated 1023. This is why the code always ignores the first set of readings, even if it contains the expected 6 readings.
Reading 6 and only 6 inputs
The data transmission protocol presented here is too simple, not only there are no field definitions, packet delimiters, etc, but there are also no checksums. This results in the following stream being received from time to time:
... 511 255 767 1023 0 511 // Note no empty line between these values. 511 // 239 767 1023 0 511 ...
This kind of error results in a stream of 12 values being read instead of 2 sets of 6 values. Due to the nature of this application, ignoring this values is safe, so off they go.
Caveat emptor: If you're running this code, check for the device used to initialize SerialPort - it may be different according to the arduino version that you're using, so make it the same as the one that's configured on the arduino IDE.
Sending data to hook.io
To define a hook in hook.io you start by extending the Hook class:
var SerialHook = exports.SerialHook = function (options) { //... }; util.inherits(SerialHook, Hook);
To boot hook.io, instantiate the hook and start it:
var serialhook = new SerialHook({ name: 'serial', 'hook-host' : '0.0.0.0' }); serialhook.start();
The actual hook code relies on calling the super constructor and waiting for a hook::ready event:
// ... Hook.call(this, options); this.on('hook::ready', function () { // ...
For our data protocol we chose to only send value variations, so the following snippet deals with detecting those changes and sending them encoded as maps to hook.io:
var changes = 0; knobs = knobs.reduce(function(map, k, i) { if(k !== values[i]) { map[i] = values[i] = k; changes++; } return map; }, {}); if(changes !== 0) { self.emit('knobs', knobs); }
74 notes · View notes
pi-pixel · 13 years
Text
Bundler 1.0rc5 keeps appearing on my rvm installs...
Each time I upgrade a rvm managed ruby a fresh install of bundler 1.0.0.rc5 pops up. I still don't know what causes this, but here are some instructions to deal with it.
The symptoms are:
As soon as you install a fresh version of a ruby (let's say 1.9.2-p290)...
$ rvm install 1.9.2-p290 (...) $ rvm use 1.9.2-p290 Using (...)/.rvm/gems/ruby-1.9.2-p290 $ gem list *** LOCAL GEMS *** bundler (1.0.0.rc.5) rake (0.9.2) rdoc (3.8)
So the dreaded old version of bundler is already installed.
Let's try to uninstall it:
$ gem uninstall bundler ERROR: While executing gem ... (Gem::InstallError) cannot uninstall, check `gem list -d bundler`
Maybe rvm didn't understand bundler's version... (/sarcasm)
$ gem uninstall bundler -v 1.0.0.rc.5 ERROR: While executing gem ... (Gem::InstallError) cannot uninstall, check `gem list -d bundler`
Well lets do what rvm uninstall suggests:
$ gem list -d bundler *** LOCAL GEMS *** bundler (1.0.0.rc.5) Authors: Carl Lerche, Yehuda Katz, André Arko Rubyforge: http://rubyforge.org/projects/bundler Homepage: http://gembundler.com Installed at: /Users/lmfr/.rvm/gems/ruby-1.9.2-p290@global The best way to manage your application's dependencies
Funny... nothing helpful here... After googling for a while (and, no, google, I don't mean "+rvm +install bundler 1.0.0.rc.5"), some solutions appear:
$ rvm gemset use global $ gem uninstall bundler -v 1.0.0.rc.5 Remove executables: bundle in addition to the gem? [Yn] y Removing bundle Successfully uninstalled bundler-1.0.0.rc.5
Just to verify it:
$ gem list *** LOCAL GEMS *** rake (0.9.2) rdoc (3.8)
Bonus points for style: If you are asking other other rubies suffer from the same problem in your install just run on your home directory:
$ find .rvm -name 'bundler-1.0.0.rc.5' .rvm/gems/rbx-head@global/doc/bundler-1.0.0.rc.5 .rvm/gems/rbx-head@global/gems/bundler-1.0.0.rc.5
Proceed as described above for each bundler you find.
References:
http://answerpot.com/showthread.php?1520789-Desinstalando+bundler+pre http://lists.simplelogica.net/pipermail/ror-es/2010-October/024332.html
13 notes · View notes
pi-pixel · 14 years
Text
How to compile VirtualBox on Snow Leopard with macports
This instructions allow you to do a full build of VirtualBox OSE (the one with the GPL license) on Snow Leopard using macports.
Here are some reasons to roll your own VirtualBox OSE build:
To use VirtualBox without encumbrance by license issues on commercial projects. All current VirtualBox 4.x official binaries are OSE (GPL).
To try an SVN version of VirtualBox.
My drivers to use VirtualBox were:
To try out Vagrant and Chef.
To try out Hudson/Jenkins integration with VirtualBox. Hudson/Jenkins currently interacts with VirtualBox through soap/webservices, this is why there's all the trouble to enable gsoap (see below).
Note: This tutorial has an high dosage of YMMV, some parts more than others.
It assumes that all build work will be performed on a $HOME/work/virtualbox directory.
Prepare the sandbox:
mkdir -p ~/work/virtualbox cd ~/work/virtualbox
Prepare macports:
Ensure macports has everything needed installed as universal:
sudo port install libidl +universal sudo port upgrade --enforce-variants curl +universal
Remove old/conflicting macports packages:
sudo port uninstall gsoap
Ensure the installed libpng is 1.2.x (1.4.x DOES NOT WORK)
Macports r. 71090 is the last version containing the portfile for libpng 1.2.44
sudo port uninstall -f libpng cd ~/work/virtualbox svn co -r 71090 http://svn.macports.org/repository/macports/trunk/dports/graphics/libpng cd libpng sudo port install -v +universal
Install the Official Qt (from Nokia)
Do not install Qt from macports because:
The virtualbox build doesn't recognize it.
It takes ages to build/install. After that the VirtualBox build doesn't recognize it.
Every time Qt has an update on macports your update will take ages to complete.
Fetch Qt from the official Nokia Qt site and install it using the regular mac way.
Install gsoap from source
If gsoap isn't tackled properly VirtualBox will just disable it at configuration/compile time and build everything else without problems.
The default virtual box configuration files won't find gsoap without some help. On top of that, without further patching of VirtualBox/gsoap, the build will fail compiling the soap stubs.
The build problem is related to the syntax of how gsoap allocates memory on generated stubs. Due to dependencies on the implementation of this kind of stubs, the problem isn't easily fixable on VirtualBox. From gsoap's version 2.7.16 on the problem is fixed, but, I don't really know the reason why, the fix either doesn't work or isn't properly used on a mac.
The patch consists on telling gsoap that the new c++ operator can't be used with parenthesis on mac. The 5664 version is the highest available from all apple supplied gcc compilers on Snow Leopard at this time. This includes gcc 4.0.1, gcc 4.2.1 and llvm-gcc 4.2.1. Macports gcc 4.4 was also tried, but, even after forcing VirtualBox build to use it (not easy), the build fails (with a gcc related problem, not a gsoap one).
Also, to gain freedom for architechture choice later on, gsoap is being built as an universal binary (intel 32 and 64 bit)
So, off with the talk and on with the walk:
cd ~/work/virtualbox curl -L -o gsoap_2.8.1.zip http://sourceforge.net/projects/gsoap2/files/gSOAP/gsoap_2.8.1.zip/download unzip gsoap_2.8.1.zip cd gsoap-2.8 cp gsoap/stdsoap2.h gsoap/stdsoap2.h.orig sed -e 's/!defined(__BORLANDC__)/& || defined(__APPLE_CC__) \&\& (__APPLE_CC__ <= 5664)/' < gsoap/stdsoap2.h.orig > gsoap/stdsoap2.h CC="gcc -arch i386 -arch x86_64" CXX="g++ -arch i386 -arch x86_64" CPP="cpp -arch i386 -arch x86_64" ./configure --prefix=$HOME/work/virtualbox/gsoap-2.8.1-install make all install cd $HOME/work/virtualbox/gsoap-2.8.1-install ln -s include/stdsoap2.h .
Patch (and build) VirtualBox OSE
Fetch and untar VirtualBox:
cd ~/work/virtualbox curl -o http://download.virtualbox.org/virtualbox/4.0.2/VirtualBox-4.0.2.tar.bz2 tar jxf VirtualBox-4.0.2.tar.bz2 cd VirtualBox-4.0.2_OSE
Create a VirtualBox LocalConfig.kmk file as described in the official instructions:
mv LocalConfig.kmk LocalConfig.kmk.backup echo "VBOX_DEF_MACOSX_VERSION_MIN = 10.6" >> LocalConfig.kmk echo "VBOX_DARWIN_NO_COMPACT_LINKEDIT =" >> LocalConfig.kmk echo "VBOX_MACOS_10_5_WORKAROUND =" >> LocalConfig.kmk
Patch Config.kmk to recognize macports library and include directories. Open Config.kmk and replace:
(Note: For VirtualBox 4.0.2 this block starts at line 1710. Also note that the variables have no embedded OS version numbers)
VBOX_DARWIN_DEF_SDK_CFLAGS := -mmacosx-version-min=$(VBOX_DEF_MACOSX_VERSION_MIN) -isysroot $(VBOX_PATH_MACOSX_SDK) VBOX_DARWIN_DEF_SDK_CXXFLAGS := -mmacosx-version-min=$(VBOX_DEF_MACOSX_VERSION_MIN) -isysroot $(VBOX_PATH_MACOSX_SDK) VBOX_DARWIN_DEF_SDK_OBJCFLAGS := -mmacosx-version-min=$(VBOX_DEF_MACOSX_VERSION_MIN) -isysroot $(VBOX_PATH_MACOSX_SDK) VBOX_DARWIN_DEF_SDK_OBJCXXFLAGS := -mmacosx-version-min=$(VBOX_DEF_MACOSX_VERSION_MIN) -isysroot $(VBOX_PATH_MACOSX_SDK) VBOX_DARWIN_DEF_SDK_LDFLAGS = -mmacosx-version-min=$(VBOX_DEF_MACOSX_VERSION_MIN) -Wl,-syslibroot,$(VBOX_PATH_MACOSX_SDK) \ -Wl,-headerpad_max_install_names $(VBOX_DARWIN_CLASSIC_LINKER) $(VBOX_DARWIN_NO_COMPACT_LINKEDIT)
By:
VBOX_DARWIN_DEF_SDK_CFLAGS := -mmacosx-version-min=$(VBOX_DEF_MACOSX_VERSION_MIN) -isysroot $(VBOX_PATH_MACOSX_SDK) -I/opt/local/include VBOX_DARWIN_DEF_SDK_CXXFLAGS := -mmacosx-version-min=$(VBOX_DEF_MACOSX_VERSION_MIN) -isysroot $(VBOX_PATH_MACOSX_SDK) -I/opt/local/include VBOX_DARWIN_DEF_SDK_OBJCFLAGS := -mmacosx-version-min=$(VBOX_DEF_MACOSX_VERSION_MIN) -isysroot $(VBOX_PATH_MACOSX_SDK) -I/opt/local/include VBOX_DARWIN_DEF_SDK_OBJCXXFLAGS := -mmacosx-version-min=$(VBOX_DEF_MACOSX_VERSION_MIN) -isysroot $(VBOX_PATH_MACOSX_SDK) -I/opt/local/include VBOX_DARWIN_DEF_SDK_LDFLAGS = -mmacosx-version-min=$(VBOX_DEF_MACOSX_VERSION_MIN) -Wl,-syslibroot,$(VBOX_PATH_MACOSX_SDK) \ -Wl,-headerpad_max_install_names $(VBOX_DARWIN_CLASSIC_LINKER) $(VBOX_DARWIN_NO_COMPACT_LINKEDIT) -L/opt/local/lib -L$HOME/work/virtualbox/gsoap-2.8.1-install/lib
Build VirtualBox
Configuration for a 32bit build:
You will need this build if you are running a 32bit kernel like in most desktop/laptop machines.
./configure --disable-hardening\ --with-openssl-dir=/opt/local\ --with-gsoap-dir=$HOME/work/virtualbox/gsoap-2.8.1-install\ --with-gsoap-import=$HOME/work/virtualbox/gsoap-2.8.1-install/share/gsoap/import\ --enable-webservice
Configuration for a 64bit build:
You will need this build if you are running a 64bit kernel like in some more recent servers.
./configure --disable-hardening\ --with-openssl-dir=/opt/local\ --with-gsoap-dir=$HOME/work/virtualbox/gsoap-2.8.1-install\ --with-gsoap-import=$HOME/work/virtualbox/gsoap-2.8.1-install/share/gsoap/import\ --target-arch=amd64\ --enable-webservice
Note: Regardless of the GCC version stated, the build will use the system's 4.2 gcc. It is possible to force usage of another compiler, but, I haven't been successful with that.
The actual build:
Note: I like to launch a subshell here so that if anything goes wrong, I can just exit it to get back to a clean environment.
bash # or other shell source ./env.sh kmk 2>1 | tee ../build.`date +"%Y-%m-%d_%H%M"`.log
Note: The build command is a little bit more complex than usual, but it saves a log so that errors may be checked easily later on.
Wait for the build and follow the instructions at the VirtualBox official build instructions to run VirtualBox
That's It!
You can do both builds on the same machine. You'll have two separate distributions ready for 32 and 64 bit usage.
My ideal scenario for building all of this stuff would be to compile just the kernel modules as universal and everything else as 64bit (all current machines are 64bit). I don't know how to do that (yet?).
Useful links for troubleshooting:
iconv/libiconv related problems:
http://permalink.gmane.org/gmane.comp.emulators.virtualbox.devel/2862
gsoap related problems:
http://forums.freebsd.org/showthread.php?t=12987
http://www.mail-archive.com/[email protected]/msg01420.html
macports / libpng related problems:
https://trac.macports.org/wiki/howto/InstallingOlderPort
running on 32 vs 64 bit systems:
http://forums.virtualbox.org/viewtopic.php?f=10&t=28561&hilit=snow+leopard+build
Common problems:
Error:
Undefined symbols: "_png_set_longjmp_fn", referenced from: DisplayMakePNG(unsigned char*, unsigned int, unsigned int, unsigned char**, unsigned int*, unsigned int*, unsigned int*, unsigned char)in DisplayPNGUtil.o
Cause:
You are using libpng v. 1.4
Solution:
Remove the latest libpng install from macports and manualy install version 1.2.44 as described above
Error:
Checking for ssl: found version OpenSSL 0.9.7l 28 Sep 2006, expected version 0.9.8 or higher
Cause:
You are using the system's OpenSSL implementation.
Solution:
Install OpenSSL in macports (this should be a dependency of curl) and specify it on the configure script with --with-openssl-dir as stated above.
Error:
Config.kmk:2018: /Users/.../work/VirtualBox-4.0.2_OSE/out/darwin.amd64/release/GCCConfig.kmk: No such file or directory Config.kmk:4649: /Users/.../work/VirtualBox-4.0.2_OSE/out/darwin.amd64/release/revision.kmk: No such file or directory /Users/.../work/VirtualBox-4.0.2_OSE/kBuild/footer.kmk:1991: *** Using 10.5 SDK. Stop.
Cause:
There's no LocalConfig.kmk or Config.kmk wasn't patched
Solution:
See instructions above for creating and patching those files.
Error:
kmk: *** No rule to make target `/QtGui.framework/Versions/4/Resources/qt_menu.nib/classes.nib', needed by `/Users/.../work/VirtualBox-4.0.2_OSE/out/darwin.x86/release/dist/VirtualBox.app/Contents/Frameworks/QtGui.framework/Versions/4/Resources/qt_menu.nib/classes.nib'. Stop.
Cause:
Either: the official Qt isn't installed or you are using --build-headless option
Solution:
Install Qt from the link above or remove the --build-headless option. Macports's Qt doesn't work and --build-headless also causes this error.
Error:
kBuild: Compiling VBoxXPCOM - /Users/.../work/VirtualBox-4.0.2_OSE/src/libs/xpcom18a4/xpcom/build/nsXPComInit.cpp Undefined symbols: "_fopen$UNIX2003", referenced from: _BIO_new_file in libcrypto.a(bss_file.o) _file_ctrl in libcrypto.a(bss_file.o) _open_console in libcrypto.a(ui_openssl.o) _open_console in libcrypto.a(ui_openssl.o) ld: symbol(s) not found collect2: ld returned 1 exit status
Cause:
OpenSSL isn't installed properly
Solution:
Install OpenSSL as an universal build.
sudo port upgrade --enforce-variants openssl +universal
Error:
In file included from /Users/.../work/virtualbox/vbox/out/darwin.amd64/release/obj/webservice/soapH.h:10, from /Users/.../work/virtualbox/vbox/src/VBox/Main/webservice/vboxweb.cpp:56: /Users/.../work/virtualbox/vbox/out/darwin.amd64/release/obj/webservice/soapStub.h:11:22: error: stdsoap2.h: No such file or directory In file included from /Users/.../work/virtualbox/vbox/out/darwin.amd64/release/obj/webservice/soapH.h:10, from /Users/.../work/virtualbox/vbox/out/darwin.amd64/release/obj/webservice/methodmaps.cpp:25: /Users/.../work/virtualbox/vbox/out/darwin.amd64/release/obj/webservice/soapStub.h:11:22: error: stdsoap2.h: No such file or directory In file included from /Users/.../work/virtualbox/vbox/out/darwin.amd64/release/obj/webservice/soapH.h:10, from /Users/.../work/virtualbox/vbox/src/VBox/Main/webservice/vboxweb.cpp:56: /Users/.../work/virtualbox/vbox/out/darwin.amd64/release/obj/webservice/soapStub.h:391: error: function definition does not declare parameters
Cause:
The VirtualBox build expects a directory layout different from the generated by default by gsoap's install make target.
Solution:
Execute the ln command as described in the gsoap build instructions above.
Error:
/Users/.../work/virtualbox/vbox/out/darwin.amd64/release/obj/webservice/soapC-4.cpp: In function '_vbox__IGuestMonitorChangedEvent_USCOREgetHeightResponse* soap_instantiate__vbox__IGuestMonitorChangedEvent_USCOREgetHeightResponse(soap*, int, const char*, const char*, size_t*)': /Users/.../work/virtualbox/vbox/out/darwin.amd64/release/obj/webservice/soapC-4.cpp:17: error: ISO C++ forbids variable-size array /Users/.../work/virtualbox/vbox/out/darwin.amd64/release/obj/webservice/soapC-4.cpp: In function '_vbox__IGuestMonitorChangedEvent_USCOREgetHeight* soap_instantiate__vbox__IGuestMonitorChangedEvent_USCOREgetHeight(soap*, int, const char*, const char*, size_t*)': /Users/.../work/virtualbox/vbox/out/darwin.amd64/release/obj/webservice/soapC-4.cpp:153: error: ISO C++ forbids variable-size array
Cause:
You are using macports or other machine install of gsoap.
Solution:
Build gsoap with the patch described above. Ensure that there is no gsoap installed by macports or it will take precedence over the custom built.
18 notes · View notes
pi-pixel · 14 years
Link
0 notes
pi-pixel · 14 years
Photo
Tumblr media
Beacon board on top of 1st gen arduino ethernet shield and an arduino 10k.
0 notes
pi-pixel · 14 years
Photo
Tumblr media
Current beacon placement at Yunit R&D Department.
0 notes
pi-pixel · 14 years
Video
vimeo
Sequence:
Full lights on
Color Cycle
White bar cycle
Normal: All green, wave cycling
Nagios: Warning - Orange
Normal: All green
Build running: Second bar blinking
Build failure: Hudson bars red
Build running: Second bar blinking
Normal: All green
Nagios itself down: Nagios bars pulsating blue
Control script down: All bars pulsating red (This is detected by the arduino)
0 notes
pi-pixel · 14 years
Link
Beacon presentation at Opensoft Barcamp 2010
0 notes
pi-pixel · 14 years
Quote
First post!
Eponymous Anonymous
0 notes