Arduino Yún + Twitter Streaming API blink example

This is a simple example on how to run some code on the Arduino side of the Arduino Yún on specific events fired through the Twitter Streaming API

i.e. when a tweet containing a specific #hashtag is twitted, Arduino blinks an LED

I love this experiment because it’s near real time and it gives a lot of possibilities, and it’s very easy to set up

Requirements

  • An Arduino Yún (obviously) with an external SD card (required for hosting the Python libraries you’ll need)
  • A twitter app you own
  • The Tweepy library for Python
  • And, finally… this code
  • 🙂

Instructions

“I love instructions, they give me confidence.”
me

  1. In case you haven’t done it yet, upgrade your Arduino Yún to the latest version and expand it’s disk space using the SD card
  2. Log to your Arduino using ssh
  3. Install a bunch of useful stuff
     $ opkg update
     $ opkg install git
     $ opkg install python-expat
     $ opkg install python-openssl
     $ opkg install python-bzip2
    

    easy_install

     $ opkg install distribute
    

    pip

     $ easy_install pip
    

    tweepy

     $ pip install tweepy
    

    or install it manually cloning it from github

      $ git clone https://github.com/tweepy/tweepy.git
      $ cd tweepy
      $ python setup.py install
    
  4. If you don’t have one, create your twitter app
    and get your consumer key and consumer secret. Then, generate an access token and get your access token and access token secret

  5. Create a working folder for all the scripts (i.e. /root/python)

     $ mkdir /root/python
     $ cd /root/python
    

    and, while in the python folder, clone the Twitter Blink example

      $ git clone git@github.com:amicojeko/TwitterBlink.git
    

    don’t forget to make the kill_processes.sh script executable!

      $ chmod +x kill_processes.sh
    
  6. Then use vi or nano (I personally installed vim) to put your twitter app configuration data into the streaming.py script, and to configure the string to be searched inside the Twitter Stream Maelstrom
     $ nano streaming.py
    

    now everything should be ready.

  7. Open the Arduino IDE and load the TwitterBlink.ino script that is in the Arduino folder (you can download it from GitHub )

  8. Configure the script folder (in case you created a folder different from root/python/ in the previuos steps)

    You can customize the script for your needings, in it’s initial configuration it will blink the LED attached to pin 13 (and the built in LED as well) so it’s perfect for testing

  9. Upload the script to Arduino, it should start working as soon as it’s uploaded

  10. Have fun!!

cheers!

Jeko

Opal under a microscope: Object creation in Ruby and JavaScript

In this post we’ll learn how Ruby objects are mapped in JavaScript-land by the Opal compiler, how to call methods on them and how object instantiation works for both Ruby and JavaScript.

The basics: constants, methods and instance variables

The rule by which Ruby objects are compiled into JavaScript by Opal is quite simple. Constants are registered with their regular name under the window.Opal (i.e. the Opal property on the JavaScript window object). Methods are mapped to properties prefixed by a $ (dollar sign). Instance variables are just regular properties.

Example:

The following Ruby code:

class Foo
  def initialize
    @bar = 'BAR!'
  end

  def bar
    @bar
  end

  def baz
    'BAZ!'
  end
end

can be used from JavaScript in this way:

var Foo = Opal.Foo; // Constant lookup
obj = Foo.$new();   // calling method on class Foo

obj.bar             // accessing @bar      => 'BAR!
obj.$bar();         // another method call => 'BAR!'

obj.baz;            // a js property => undefined
obj.$baz();         // another method call => 'BAZ!'

As a Ruby developer you may be surprised that obj.baz returns undefined and not nil (actually window.Opal.nil) as that’s the value that you would expect to find while reading an instance variable for the first time.

What happens is that the Opal compiler will do just that, as long as you access those instance variables from Ruby code. In fact it statically analyzes the class’ code and pre-initializes to nil any instance variable for which it can find a reference.

Now that we have the basics let’s go further and put Foo.new under the microscope for both Opal and CRuby.

The birth of an object in 3 steps

By looking in detail how object instantiation is done in JavaScript by the Opal compiled code we’ll have a chance to learn how it actually works in CRuby.

The implementation of .new

At the cost of oversimplifying here’s the rough implementation of the #new method available to all classes in Ruby:

class Class
  def new(*args, &block)
    obj = allocate # allocates the memory in CRuby
    obj.send(:initialize, *args, &block) # forwards all arguments to #initialize
    return obj
  end
end

Breaking it down we see that:

  1. it calls #allocate in order to setup a raw object (in C it will also allocate the necessary memory)
  2. it forwards all arguments and block to #initialize
  3. it returns the object

Here’s how it looks in Opal (the code inside %x{} is JavaScript):

class Class
  def new(*args, &block)
    %x{
      var obj = self.$allocate();
      obj.$initialize.$$p = block;
      obj.$initialize.apply(obj, args);
      return obj;
    }
  end
end

(Class#new source)

As you can see the the only notable difference is in how the block is passed. Opal will store any block call on the method itself under the $$p property. This way blocks can’t be confused with regular arguments. Apart from that it’s clear that it’s fundamentally the same code.

Uncovering Class#allocate

The curious reader at this point is wondering what the allocate method does in JavaScript because surely it can’t manage memory. Let’s see the implementation:

class Class
  def allocate
    %x{
      var obj = new self.$$alloc;
      obj.$$id = Opal.uid();
      return obj;
    }
  end
end

(Class#allocate source)

Let’s break it down by line, but this time we’ll go in reverse order:

  1. The last line is the easiest one in which the code just returns the object: return obj.
  2. The middle one is still quite clear and seems to just assign a unique identifier to the object. That value will be the one returned by #object_id.
  3. The first and most important one is where stuff actually happens. The JavaScript new keyword is used to create an object whose constructor seem to be stored in $$alloc.

For those not very familiar with JavaScript I’ll show how objects are usually created:

// this function acts as the MyClass constructor
function MyClass() { this.foo = 'bar'; }

var obj = new MyClass;
obj.foo         // => 'bar'
obj.constructor // => MyClass

The awesome thing to me is that Opal manages to have an implementation that is really idiomatic in both Ruby and JavaScript.

Learning D3.js basics with Ruby (and Opal)

I always wanted to learn D3.js, problem is JavaScript is too awesome and that kept turning me off… till now!

Let’s take a random tutorial that we will attempt to translate into Ruby, for example this: http://bl.ocks.org/mbostock/3883245.

A couple of thing we need to bear in mind are these: D3 is not object-oriented and it’s a pretty complex library. We’re expecting some problems.

To have something to compare it to we may note, for example, that JQuery is basically a class ($) that exposes methods that returns other instances of the same class. That makes things easy enough when we try to use it from an OO language like Ruby.

Part I — The Setup

Following the tutorial, let’s setup the HTML page:

<!DOCTYPE html>
<html>
<meta charset="utf-8">
<style>
/* …uninteresting CSS from the tutorial here… */
</style>
<body>
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>

<!-- OUR ADDITIONS HERE -->
<script src="http://cdn.opalrb.org/opal/current/opal.js"></script>
<script src="http://cdn.opalrb.org/opal/current/native.js"></script>
<script src="http://cdn.opalrb.org/opal/current/opal-parser.js"></script>

<script type="text/ruby" src="./app.rb"></script>

</body>
</html>

As you probably have noted we added a couple of libraries from the Opal CDN.

First we added opal.js, that is the runtime and core library that are necessary to run code compiled with Opal.

Then there’s native.js that we’ll use to interact with native objects (more details in this other post).

And last we have opal-parser.js and app.rb (that is declared as type="text/ruby"). The parser will look for all script tags marked as text/ruby and will load, parse and run them.

In additon we’re also providing a data.tsv file as described in the tutorial.

Part II — Code Ungarbling

About the process of translating

The approach I used to translate this code is quite simple, I copy/pasted all the JavaScript from the tutorial into app.rb and commented it out. Then I translated one line (or sentence) at a time tackling errors as they came.

Using Native

The first thing we need to do is to wrap the d3 global object with Native, so that is ready for Ruby consumption.

d3 = Native(`window.d3`)

Now let’s look at the first chunk of code

original code:

var parseDate = d3.time.format("%d-%b-%y").parse;

var x = d3.time.scale()
    .range([0, width]);

var y = d3.scale.linear()
    .range([height, 0]);

var xAxis = d3.svg.axis()
    .scale(x)
    .orient("bottom");

var yAxis = d3.svg.axis()
    .scale(y)
    .orient("left");

converted code

d3 = Native(window.d3)
time  = d3[:time]
scale = d3[:scale]
svg   = d3[:svg]

date_parser = time.format("%d-%b-%y")

x = time.scale.range([0, width])
y = scale.linear.range([height, 0])

x_axis = svg.axis.scale(x).orient(:bottom)
y_axis = svg.axis.scale(y).orient(:left)

By trying to run this code we discover early on that somehow Native is failing to deliver calls via method missing.

The reason is that bridged classes are a kind of their own and turns out that D3 tends to return augmented anonymous functions and arrays. Now both Array and Proc are bridged classes. That means that they are the same as their JS counterparts: Array and Function.

Native will have no effect on bridged classes (no wrapping) and therefore all calls to properties added by D3 will end in calls on undefined.

To solve this we’ll manually expose the methods on those classes, the final code looks like this:

module Native::Exposer
  def expose(*methods)
    methods.each do |name|
      define_method name do |*args,&block|
        args << block if block_given?
        `return #{self}[#{name}].apply(#{self},#{args.to_n})`
      end
    end
  end
end

Proc.extend Native::Exposer
Array.extend Native::Exposer

Proc.expose :range, :axis, :scale, :orient, :line, :x, :y, :parse, :domain
Array.expose :append, :attr, :call, :style, :text, :datum

The complete code can be found in this gist.

UPDATE: see the code in action on Ju-Jist, and read about building ju-jist in this article

A better solution

Let’s hope that in the future the Opal team (me included) will add method missing stubs1 to all bridged classes (instead of just adding them BasicObject).

Conclusion

We probably didn’t learn very much about how to use D3.js, but we discovered a bit of its internals, exposing an interesting style of JavaScript.


  1. (which is the underlying mechanism that powers method_missing support in Opal) 

Arduino Yún Extra WiFi Reset Button

One of the biggest problems with Arduino Yún is that the WiFi reset button is embedded on the board, and it’s very difficult to reach. Once you have packed you project in an enclosure, there’s no way to reset the wifi settings, unless the wifi reset button is reachable through a pinhole.

But how does the integrated wifi reset button work? When it’s pressed for more than 5 seconds, Arduino calls a little script: /usr/bin/wifi-reset-and-reboot

So I’ve made a very simple sketch that does exactly the same: it waits for our extra reset button to be pressed for more than 5 seconds, and when it happens it calls the same exact script using the Yún’s Bridge library.

So you can add your extra wifi reset button, and put it where you want!

Here’s the code

#include <Process.h>

const int  buttonPin = 7;  // the pin that the pushbutton is attached to
const int ledPin = 13;     // the pin that the LED is attached to

int buttonPushTimer = 0;   // timer for the reset button
int buttonState = 0;       // current state of the button
int lastButtonState = 0;   // previous state of the button

void setup() {
  Bridge.begin();
  pinMode(buttonPin, INPUT);
  pinMode(ledPin, OUTPUT);
}

void loop() {
  // read the pushbutton input pin:
  buttonState = digitalRead(buttonPin);
  // compare the buttonState to its previous state
  if (buttonState != lastButtonState) {
    // if the state has changed, start the timer
    if (buttonState == LOW) {
      buttonPushTimer = millis();
    }
  }
  else {
    // if the state has changed, and the button is still pressed, check the timer
    if (buttonState == LOW) {
      if (millis() > buttonPushTimer + 5000) {
        // if the button has been pressed for 5 seconds, reset arduino wifi
        wifi_reset();
      }
    }
    // Delay a little bit to avoid bouncing
    delay(50);
  }
  lastButtonState = buttonState;
}



void wifi_reset() {
  //blink led 10 times
  for (int i = 0; i < 10; i++) {
    digitalWrite(ledPin, HIGH);
    delay(50);
    digitalWrite(ledPin, LOW);
    delay(50);
  }
  // call the wifi reset script
  Process p;
  p.runShellCommand("wifi-reset-and-reboot");
}

I Hope it was useful!

Happy resetting!

Jeko

Arduino Yún with SOUND the supereasy way

At the Codemotion in Milano, I had a chat with Federico Vanzati from Officine Arduino, and he gave me the fantastic idea to try to use a supercheap USB Audio card with Arduino Yún to give to it full audio capabilities with zero effort.

And suddenly I was like…

image

I mean, it’s awesome! It could give me (and hopefully to you) infinite new possibilities! Sound with Arduino with no external libraries or crappy MP3 shields? How great could it be? Now that we have a great Wi-Fi support thanks to the Yún, this was the real missing feature!

I started with buying this sound card (http://www.manhattan-products.com/hi-speed-usb-3-d-sound-adapter)

Then, all I had to do was plug the sound card in, open an ssh session to the yun, and type:

opkg update
opkg install kmod-usb-audio
opkg install madplay

End of the story. Now you have sound support on the Arduino Yún. I only tried MP3 playback, I didn’t try to record some audio yet, but I’ll try soon!

To test it just copy an mp3 audio file (I named it ItCouldWork.mp3) in the root folder, or, even better, in the SD card, then upload this sketch

#include <Process.h>

const int buttonPin = 2;
const int ledPin =  13;

int buttonState = 0;
Process p;

void setup() {
  Bridge.begin();
  pinMode(ledPin, OUTPUT);      
  pinMode(buttonPin, INPUT);     
  Serial.begin(57600);
}

void loop(){
  buttonState = digitalRead(buttonPin);
  if (buttonState == HIGH) {     
    digitalWrite(ledPin, HIGH);  
    p.runShellCommand("madplay /root/ItCouldWork.mp3");
    while(p.running());  
    Serial.println("it works!");
  } 
  else {
    digitalWrite(ledPin, LOW); 
  }
}

It’s based on the button example, so you have to connect a pushbutton to the digital Pin 2.

image

Now, connect the sound card to the speakers and… push the button!

Magic, isn’t it?

It doesn’t sound too bad, actually the sound quality is good! And the delay is very short! I mean, it’s just the first experiment, we can work on it!

I really hope this will amaze you as it amazed me… I’m superhappy!

Many thanks to my friend and coworker Massimo, that knows Linux better than I know myself.

Bye!

Jeko

Intel Galileo: Getting Started with Mac OS X

A step-by-step tutorial by jeko

IMPORTANT: Connect your intel Galileo to the 5V power supply before any other connection or you will damage the board.

During the Rome Maker Faire, I was lucky to get an Intel Galileo. But when I had to use it, it was suddenly clear that it’s not as straightforward as Arduino. I had to resort to desperate measures and do something that really only a very restricted class of noble people do, I had to read the manual.

image

The getting started guide by Intel really helped, but the problem is that it’s clearly written by engineers, while the Galileo board wants to attract makers, designers, artists and many people that are used to the “tutorial” or “step by step” approach and are not really into manual reading.

I used to be an RTFM fanatic, but I’m getting old, and I have learned to appreciate when people help me, so I’m very happy to contribute and give some help to those in need.

So. You have an Intel Galileo board, a Mac (I assume you have Mac OS X Mavericks installed), and you want to run the very first basic example: the “Blink” sketch from the Arduino examples. Right?

image

This is what you have to do, straight and easy.

So, let’s start:

  1. Download the Galileo software from the Intel website. If you already have the Arduino IDE, don’t overwrite it. Even if the Intel software is based on the Arduino IDE, it is not 100% identical, and it will only manage the Galileo board, so if you want to use them both, simply unzip the Intel software, rename it into “Galileo”, and move it into your Application folder. Don’t rename it into something with spaces, and do not put it into folders with a space in their name, because it won’t work.
  2. Plug the 5V adapter, wait 10 seconds and then connect the USB client (the little usb port next to the ethernet plug) to your Mac’s USB port
  3. You have to wait a minute: it takes a little while for the USB stack to start on the Galileo board, then you can start the Galileo IDE
  4. Go to Tools > Port menu and select the /dev/cuXXX serial port. If you don’t see the port, close the IDE, wait a minute, and open it again.
  5. Now, you have to update the Galileo’s firmware, so, go on Help > Firmware Upgrade. If everything is ok, you should see a message asking for confirmation if the 5V power cable is plugged in. Since you have followed these instructions, it should be, so click yes, do the same on the next dialog and the process should begin. It will take 5-6 minutes. During the process, avoid touching the cables or the board or the IDE. Just sit down and relax.
  6. When the process is complete, the “Target Firmware upgraded successfully.” message is displayed. Click OK to close the message.
  7. Now choose the blink example from File > Examples > 01.Basics > Blink

Upload the blink sketch and you’re done! It’s time to celebrate! 🙂

Jeko

P.S. The Quark processor can become very hot, don’t worry it’s normal.