Posts filed under ‘Uncategorized’

Bluetooth communication between BlueSMIRF and Ubuntu

A quick post on how to set up the Bluetooth communication between Ubuntu and a BlueSMIRF Modem.

My laptop was broken recently, and after getting a free new motherboard from the kind Sony people I reinstalled Ubuntu and tried to get all my software running again. Today I tried setting up the Bluetooth communication with my toy car’s BlueSMIRF (see previous posts) and  my laptop, and decided on documenting it. So here’s how to do it:

  1. (optional) It’s easiest if you can see what is happening on the BlueSMIRF side. Therefore, you’ll need a serial (TTL) to USB convertor like this one. Alternatively, if you have a Dwengo board (or similar), you can use that one by simly removing the PIC18F chip for a while:

    Now you can monitor the commands and data passing through the BlueSMIRF by opening “serial port terminal” (install it through the Ubuntu Software Center) on /dev/usbtty0 at the speed of your BlueSmirf (default 115200 baud)

    Details on the commands available are available in the Roving Networks Command datasheet.

  2. I didn’t get the default Ubuntu Bluetooth tool (the B in the taskbar) to play nice with the BlueSMIRF, so I installed “Bluetooth Manager” (BlueMan) through the Software Center.
  3. Power the BlueSMIRF, it should start blinking rapidly for about a minute. This means it is waiting for a connection. Once the rapid blinking stops, you can’t connect anymore!
  4. Click on the B in your taskbar of BlueMan, a window should open showing the Bluetooth devices in your environment. One of them should be FireFly (the BlueSMIRF). Right click on it an select “connect to SPP”:

    (the name in the screenshot is robot-719A instead of Firefly because I changed it earlier)
  5. Because this is the first time you connect to the BlueSMIRF, it needs to be paired. Therefore, Blueman will ask you the pass phrase. Enter “1234” (without quotes), this is the default passphrase of the BlueSMIRF.
  6. The bottom of the Blueman screen should now say “Serial port connected to /dev/rfcomm0”. Now you can open a serial connection to /dev/rfcomm0 using serial port manager (or from within a script) and start communicating 🙂
    The LED on the BlueSMIRF should turn green.

That’s it! Now the pairing is done, and you won’t need to enter the passphrase the next time you connect to the BlueSMIRF.

    Advertisements

    December 19, 2010 at 11:15 am Leave a comment

    Communication with Pinguino via Bluetooth

    I bought a BlueSMIRF Bluetooth module a few weeks ago, and this weekend I’ve finally had some time to put it in action 🙂

    Connecting the BlueSMIRF module is really easy. The BlueSMIRF module has 6 pins: CTS-I, VCC, GND, TX-0, RX-1 and RTS-0. You have to connect CTS-I to RTS-0, connect VCC to the supply voltage and GND to ground. The TX-0 pin is connected to the RX pin of the microprocessor, while the RX-1 pin is connected to the TX pin of the microprocessor. On the PIC18F4455 these are pins 26 and 25 (pinguino pins 9 and 8). s

    CTS-I  O----------------
    VCC    O--5V           |
    GND    O--0V (gnd)     |
    TX-0   O-- to RX PIC   |
    RX-1   O-- to TX PIC   |
    RTS-0  O----------------

    As explained in a previous post, I am using a Pinguino board, so the code should work on Arduino as well without needing too many modifications. This is the code I used for writing some text:

    #define PIC18F4550
    char incomingByte = 'K';	// for incoming serial data
    
    void setup() {
      Serial.begin(115200);
    }
    
    void loop() {
    	// send data only when you receive a C character
    	if (Serial.available() > 0) {
    		// read the incoming byte:
    		incomingByte = Serial.read();
    		if (incomingByte == 'C') {
    			Serial.print("I received: ");
    			Serial.print(incomingByte, DEC);
    		}
    	}
    }
    In the setup routine I connect to the serial port at 115200 bauds. The bluetooth module is just used as a regular serial cable, so no fancy tricks are necessary.
    On my Ubuntu laptop, I had to do the following to get things running:
    • first connect your Bluetooth dongle to the BlueSMIRF (mine appeared as FireFLY-719A)
    • sudo hcitool scan #so we know the MAC address of the FireFLY
    • rfcomm connect 0 00:06:66:03:72:9A #substitute with your BlueSMIRF’s MAC address
    • sudo gtkterm -p /dev/rfcomm0 -s 115200 #start gtkterm to read/write to the serial port

    Of course we don’t want to interact through gtkterm with our microcontroller. I wanted to employ Processing, but this gave some additional difficulties in my setup. In Processing, Serial.list() is used to list all available serial ports. The Bluetooth serial port /dev/rfcomm0 does not appear in the list though. A dirty hack to solve the issue is symlinking /dev/ttyS0 to /dev/rfcomm0:

    sudo rm /dev/ttyS0
    sudo ln -s /dev/rfcomm0 /dev/ttyS0

    If anyone knows a better way to solve the issue, please mention so in the comments! This is the Processing code:

    import processing.serial.*;
    
    Serial myPort;                // Create object from Serial class
    
    void setup()
    {
      size(200, 200);
      myPort = new Serial(this, Serial.list()[0], 115200);  //the first port in the list is /dev/ttyS0 which we symlinked to /dev/rfcomm0
    }
    
    void draw()
    {
      while (myPort.available() > 0) {                      //if something was received via serial port
        String inBuffer = myPort.readString();
        print(inBuffer);
      }
    }
    
    void keyPressed() {
      print(key);
      myPort.write(key);
    }
    
    void stop() {
      myPort.stop();
    }

    February 22, 2010 at 6:12 pm 3 comments

    Synergy rocks

    Just used the open-source software Synergy to share my mouse and keyboard between three laptops with different Operating Systems (Vista, Ubuntu, Xubuntu)!

    You’ll have to start Synergy on all computers (on Ubuntu / Xubuntu I installed the GUI QuickSynergy from the software management). The computer with the keyboard and mouse you want to share will be the server, the other the clients. On the server, enter the position of the different screens (laptop1 is on the left of laptop2 etc.). Click start on all Synergy’s and now the desktop will extend to the other screens!

    January 9, 2010 at 12:09 pm Leave a comment

    Using Dwengo board as a Pinguino

    The Pinguino project is a relatively new project that tries to build an Arduino-like project with a PIC processor. The project comes with a nice and simple IDE and a bootloader so programs can be placed on the PIC very easy.  I found the Dwengo board I own is compatible with the Tiny-4550 Pinguino board, so it is possible to use the Pinguino IDE and bootloader with the Dwengo board. 

    Here are the steps I followed on my Ubuntu (Karmic) machine to get things fired up:

    • Install wxPython as explained here
    • Download the latest Pinguino IDE from the hackinglab dowload index. Extract the archive. Run the IDE by running the pinguinobetax.py Python script from the terminal. Put sudo before it to run it with administrator rights, because otherwise you’ll get a ”Could not change device” error! The IDE looks like this:

    • With the PIC18F4550 we need the second version of the bootloader (see Pinguino tutorial site). It can be dowloaded here. To put the bootloader on your PIC, I used xwisp, which is a Windows program (I ran it in a Virtualbox virtual machine).
    • Once the bootloader is on your PIC, connect your board via a USB cable to your PC. Hold the reset button and the “up” button on your board, then release the reset button. The bootloader program knows you want to place a program on it now.
    • Open up the Pinguino IDE and type e.g. this program in it:
    // Testing input with Pinguino
    // jean-pierre MANDON 2008
    // modified kr3l for DWENGO
    #define PIC18F4550
    void setup() 
    {
    pinMode(0,INPUT);         //button
    pinMode(21,OUTPUT);    //led
    }
    void loop() 
    {
    if (digitalread(0)) digitalWrite(21,HIGH);
    else digitalWrite(21,LOW);
    }
    The pin numbers used here are as in the Tiny-4550 schematic:
    so pin 21 as used in the program is actually pin 19 of the PIC processor.
    • press the compile button, then the “put program on pinguino” button. The program starts running after a few seconds. If you press the center button one of the leds will go off.

    I think the Pinguino project is a really cool initiative and I hope they keep working on it. More experiments will be conducted soon!

    December 31, 2009 at 3:35 pm 1 comment

    Use Google Docs for generating live reports on your Ruby scripts

    I have to transfer and convert a lot of files this week, and in order not to loose track, I created a spreadsheet that summarizes which files are transferred and converted. Because it was a pain to keep the spreadsheet up to date I wrote a Ruby script that monitors the files written and writes the results back to a Google docs spreadsheet.

    To monitor the files I use the so-called backtick quote, which reads the output of a command to a variable:

    res = `cd /home/thefolder;ls -l`
    res.each_line do |line|
      cols = line.split(' ')
      if cols.length<9  #probably a header row
        next
      end
      if File.file?('/home/thefolder/'+cols[8])
        #the file exists, your code here
        #my code writes to a hash called items
      end
    end
    To write the results back I used gimite’s google-spreadsheet-ruby gem (http://github.com/gimite/google-spreadsheet-ruby) that makes it trivially easy to connect to a Google spreadsheet (just follow the “how to use” on the first page).
    def dump_to_google(items)
      session = GoogleSpreadsheet.login("user@gmail.com", password)
      ws = session.spreadsheet_by_key("YOURKEYYOURKEYYOURKEY").worksheets[0]
      col = 1 
      row = 1
      ws[row,1] = 'ID'
      ws[row,2] = 'Filename'
      ...
      row+=1
      items.each do |id,itm|
        ws[row,1] = id
        ws[row,2] = itm[:filename]
    
         ...
        row+=1
      end
      ws.save()
    end
    
    The end result is pretty cool, a spreadsheet that is updated every minute (or whatever interval you decide). You can also create graphs that are updated automatically with the new data:
    
    
    
    
    

    December 10, 2009 at 9:13 pm Leave a comment

    Extract a keyframe from a video with FFMpeg

    If you want to extract a particular frame from a video, you can use the following ffmpeg command:

    ffmpeg -i INPUTPATH -vframes 1 -ss TIMESTAMP -f image2 -vcodec mjpeg OUTPUTPATH.jpg

    where TIMESTAMP is in the format hh:mm:ss.ff

    If you have the frame number instead of the timestamp, you can use the following Ruby script to convert the frame number to the timestamp (for a framerate of 25fps) – there’s probably a better way for formatting a number to have two digits though :-):

    def self.profile_thumbnail(frame_nr = nil)
    #calculate timestamp
    begin
      if frame_nr.nil?
        framenr = 25*60*2
      else
        framenr = frame_nr.to_i
      end
    
    rescue
      framenr = 25*60*2
    end
    
    uur = (framenr/(60*60*25))
    min = ((framenr-uur*60*60*25)/(60*25))
    sec = ((framenr-uur*60*60*25-min*60*25)/25)
    frame = ((framenr-uur*60*60*25-min*60*25-sec*25))
    uur_s = uur.to_s
    if uur<10
      uur_s = '0'+uur_s
    end
    min_s = min.to_s
    if min<10
      min_s = '0'+min_s
    end
    sec_s = sec.to_s
    if sec<10
      sec_s='0'+sec_s
    end
    frame_s = frame.to_s
    if frame<10
      frame_s = '00'+frame_s
    elsif frame<100
      frame_s = '0'+frame_s
    end
    
    stamp = uur_s+':'+min_s+':'+sec_s+'.'+frame_s
    return  ' -vframes 1 -ss '+stamp+' -f image2 -vcodec mjpeg '
    
    end

    December 3, 2009 at 9:07 pm Leave a comment

    Using Hudson for a Ruby project

    This post explains how to let Hudson automatically run your unit tests / rspec tests upon pushing code to your git repository.

    Installing and running Hudson is easy:

    wget http://hudson-ci.org/latest/hudson.war
    nohup java -jar hudson.war --httpPort=7080 --prefix=/hudson >> "hudson.log" 2>&1 &

    If you browse to localhost:7080/hudson you’ll be greeted by the user interface of Hudson. I’ve explicitly set the port to 7080 because the default port (8080) was already used by tomcat in my case. Now we’ll add some plugins. In Hudson’s user interface click on “manage Hudson” and click on “add plugins”. Install the following plugins: git, ruby, ruby metrics, rake. Click on “restart Hudson when no jobs are running” after the plugins are installed.

    We’ll use rake for defining our test tasks. Make a rake file (named Rakefile) in your project root folder.

    require ‘rake’
    require 'rake/testtask'
    require 'rake/packagetask'
    require 'rake'
    require 'rake/testtask'
    require 'rake/packagetask'
    require 'spec/version'
    require 'spec/rake/spectask'
    require 'rcov'
    gem 'ci_reporter'
    require 'ci/reporter/rake/test_unit'	#http://juretta.com/log/2008/11/11/hudson_test_drive_part_1_rails/
    require 'ci/reporter/rake/rspec'
    desc 'do unit tests'
    Rake::TestTask.new(:test) do |t|
        t.libs << 'lib'
        t.pattern = 'test/test_*.rb'
        t.verbose = true
    end
    
    namespace :spec do
      desc "do rspec tests and test coverage"
      Spec::Rake::SpecTask.new('rcov') do |t|
        t.spec_files = FileList['spec/**/*_spec.rb']
        t.spec_opts = ['--format html:results/spec_results.html']
        t.warning = true
        t.rcov = true
        t.rcov_dir = 'coverage'
        t.rcov_opts = ['--exclude', "kernel,load-diff-lcs\.rb,instance_exec\.rb,lib/spec.rb,lib/spec/runner.rb,^spec/*,bin/spec,examples,/gems,/Library/Ruby,\.autotest,#{ENV['GEM_HOME']}",                  '-I', 'lib/']
    end
    
    end
    Take a look at the following sites for more info on the Rakefile:
    Now create a new Hudson job (freestyle project) that checks out the code from your repository. Add two build steps of the type “execute shell command”:
    1. GEM_HOME=/opt/myproject/shared/gems rake ci:setup:testunit test CI_REPORTS=results
    2. GEM_HOME=/opt/myproject/shared/gems SPEC_OPTS=”–format html:resultsspec/spec_results.html” rake ci:setup:rspec spec:rcov CI_REPORTS=resultsspec

    The GEM_HOME=… part is only necessary if you install your gems locally in you project folder instead of system-wide. In the first job we call the take task ci:setup:testunit which is defined in the ci_reporter gem. This gem will create Hudson-compatible reports out of the reports generated by test unit or rspec. Next we call the rake test task which will actually run the unit tests. We also pass a variable CI_REPORTS which tells ci_reporter where to create the reports.

    The second job first runs the ci:setup:rspec task which again prepares ci_reporter. Then we call spec:rcov which will run the rspec tests and create the coverage reports. Note the SPEC_OPTS variable in which we tell rspec to create an html report (which will be converted to xml files by ci_reporter).

    Now check the post build actions “publish JUnit reports” and “publish coverage reports”, save the Hudson project and build it!

    If all went well, Hudson will create some nice reports out of the test and coverage reports:

    Because sometimes you want all the detail you can get, you might want to add links to the original (html) test and coverage reports in the description of your project. Click “Change description” and enter something like:

    <a href="http://localhost:7080/hudson/job/myproject/ws/resultsspec/spec_results.html" target="_blanc">detailed spec results</a><br>
    
    <a href="http://localhost:7080/hudson/job/myproject/ws/coverage/index.html" target="_blanc">detailed code coverage report</a>
    
    Et voila! You now have a butler running your tests and creating nice reports as soon as you commit code to your repository!

    December 3, 2009 at 8:44 pm Leave a comment

    Older Posts


    Feeds

    Articles to be written…

    Twitter – kr3l

    my del.icio.us

    RSS Google Reader Shared Stuff

    • An error has occurred; the feed is probably down. Try again later.

    RSS Listening to..

    • An error has occurred; the feed is probably down. Try again later.