IFTTT and Intel Edison, Part 1: Pushbullet and Texts

As a way to create some interesting IoT projects I want to use the IFTTT (If This Than That) cloud service with the Intel Edison through node.js. Depending on latency and other unforeseen issues I am hoping to use this as a catch all IoT API framework. Turn on lights by tweeting at them! Turn on your fan when it gets hot! IoT! Stuff!

Bay Area Maker Faire

This weekend I am lucky enough to be able to attend the Bay Area Maker Faire http://makerfaire.com/. As a way to keep track of the awesome things I see there and have a place to dump photos of said awesome things I will be documenting the trip here. I might go back and edit the post as some point, but for now its going to be fairly stream of consciousness.

Friday 

 Flight delayed due to typical Seattle weather.  

At least the new camera seems to work fine. First time flying Alaska, I hear that their cheese plate has one less cracker than cheese piece.

Saturday 

After staying up way later than I should have the night before enjoying typical San Francisco including but not limited to blow darts (darts with a blow gun) and poi spinning I made it to Maker Faire early enough. Since I don't really know how to explain what I saw there the first day I'm going to post some of the more interesting pictures I have on my camera and give short description...or something.   

A giraffe-mobile complete with a sweet sound system, articulating neck, and a pair of stoked dudes. 

Pedal powered furry creature. His eyes bring nightmares, but his hands bring pretty flowers. .

Awesome old dude in a wooden exo-suit. Nothing more to say about that. 

Nice display of the DF Robot's sensor kit and their robot control break out board. I should ask Intel to send me these two kits. Super nice guys at the booth, thanks for taking time to chat Jose. http://www.dfrobot.com

"Please put down your weapon. You have twenty seconds to comply."

"They've gone to plaid" 

The Superboard III. It features a low power (3.3V) WDC65C02 processor at 1 MHz and includes 32K RAM and 1K video RAM. Snazzy! http://www.brielcomputers.com

Clone of Altair 8800 Microcomputer. Programmed by flipping the switches for 1 and 0 bits. Doesn't get much lower level than that. Also I will never complain about anything ever again. http://www.brielcomputers.com

Guy scooting around in a giant, electric-powered cupcake. They wouldn't let me ride it due to "safety concerns" 

Majestic metal eagle. KAWWWww

I'm rooting for this tree dressed as a super hero. 

Rhino truck. The horn shoots fire (hard to capture in a picture)

TI Sensortag with Intel Edison and gatttool

Outlined below is the method I used to connect and gather sensor data from the TI Sensortag using the Intel Edison. 

TI Sensortag

TI Sensortag

Install gatttool

First of all I will be using gatttool to connect to the server on the Sensortag in order to read sensor values. Gatttool does not come preinstalled on the Yocto image so it will have to be complied. I downloaded the bluez 5.24 source and compiled it with a few configure options:

cd ~ 
mkdir bluez_source
cd bluez_sourcec
wget https://www.kernel.org/pub/linux/bluetooth/bluez-5.24.tar.xz --no-check-certificate
tar -xf bluez-5.24.tar.xz
cd bluez-5.24
./configure --disable-systemd --disable-udev
make
make install

After completing the compile you can now launch gatttool from bluez-5.24/attrib/gatttool. However lets link it to make working with gatttool easier.

export PATH=$PATH:~/bluez-5.24/attrib/

Now you can launch gatttool from anywhere

Scanning and Connecting Sensortag with bluetoothctl

First enable bluetooth

rfkill unblock bluetooth

Launch bluetooth ctl

bluetoothctl

Register an agent and set it to default, note: the following commands are launched from the [bluetooth]# shell (i.e. dont type in [bluetooth]#)

[bluetooth]# agent KeyboardDisplay
[bluetooth]# default-agent

Perform a scan, pair with the Sensortag and connect to the Sensortag

[bluetooth]# scan on

If the SensorTag does not show up, make sure to hit the pair button on the side of the SensorTag. Make a note of the MAC address of the SensorTag when it appears in the scan list, you will use this address to pair the device. Note: You can tab complete the MAC address.

[bluetooth]# pair 34:B1:F7:D5:15:38

the [agent] will ask for a passkey, enter 0

[bluetooth]# connect 34:B1:F7:D5:15:38
[bluetooth]# scan off
 
What your terminal output should look like after complete the steps above

What your terminal output should look like after complete the steps above

You can check the details of the connected device to see the name, alias, and UUIDs of device specific elements. 

[bluetooth]# info 34:B1:F7:D5:15:38

You can now exit the bluetooth utility 

[bluetooth]# exit

Using gatttool to read sensor values 

gatttool can now be used to read sensor data from the SensorTag

Connect to the sensor tag with gatttool in interactive mode:

 gatttool -b 34:B1:F7:D5:15:38 -I

Connect to the device, turn on the temperature sensor by writing 01 to  the configure handle 0x29 , and read out the value from the temperature handle 0x25.  

[34:B1:F7:D5:15:38][LE]> connect
[34:B1:F7:D5:15:38][LE]> char-write-cmd 0x29 01
[34:B1:F7:D5:15:38][LE]> char-read-hnd 0x25

The handle values corresponding to the temperature sensor were pulled from the Sensor Tag attribute table http://processors.wiki.ti.com/images/a/a8/BLE_SensorTag_GATT_Server.pdf

Gatttool output

Gatttool output

The output is two 16 bit unsigned values, in order to convert these values to a temperature reading they must be fed into a script that uses the conversion algorithm outlined in the SensorTag wiki: http://processors.wiki.ti.com/index.php/SensorTag_User_Guide#Sensors_2

In order to do this I used python and the pexpect module which can create a child process that can be written to and read from. I used the python script from https://github.com/msaunby/ble-sensor-pi/blob/master/sensortag/sensortag_test.py,
however I had to change line 62 from:

tool.expect('\[CON\].*>')
to
tool.expect('Connection successful')

Installing pip and required python modules 

In order to run the python script using pexpect, pexpect must be installed which is easiest done with pip. Pip however is not installed on Edison by default and is not present in the official opkg repo. Pip is however present in the unofficial Intel Edison repo compiled by Michael Hirsch. The following is an exerpt from his guide on using the unofficial repo from http://blogs.bu.edu/mhirsch/2014/11/getting-started-with-intel-edison/. 

vi /etc/opkg/base-feeds.conf

and paste in

src/gz all http://repo.opkg.net/edison/repo/all
src/gz edison http://repo.opkg.net/edison/repo/edison
src/gz core2-32 http://repo.opkg.net/edison/repo/core2-32

Then hit your Escape key and type

:wq

opkg update 

opkg install python-pip 

 At this point when I tried to run pip I encountered the error: 

ImportError: No module named pkg_resources

To fix this I ran the setup script for setuptools by:

wget https://bitbucket.org/pypa/setuptools/raw/bootstrap/ez_setup.py -O - | python

At this point I was able to run sensortag_test.py and receive temperature data out:

./sensortag_test.py34:B1:F7:D5:15:38

 

I2C Seeed Motor Driver on Intel Edison using UPM with Javascript

Outlined below is the method I am using for driving a pair of Seeed I2C motor drivers v1.3 (http://www.seeedstudio.com/wiki/Grove_-_I2C_Motor_Driver_V1.3) using the Intel Edison and the UPM repository for MRAA. 

It is assumed that you are fairly comfortable with using the Intel Edison and Intel XDK. Mainly you should know how to connect to your Edison via a serial connection using Putty or Screen and connect to the Intel XDK to the Edison via wifi. If you are unsure how to do this please go through the getting started documentation for the Edsion.

Installing MRAA and UPM

To install the latest version of MRAA and the UPM repository enter the following into the command line on the Edsion:

echo "src mraa-upm http://iotdk.intel.com/repos/1.1/intelgalactic" > /etc/opkg/mraa-upm.conf
opkg update
opkg install libmraa0
opkg install upm

Wiring up Motor Drivers

To wire up the pair motor driver boards I am connecting both board's SCL and SDA to the SCL and SDA pins on the Edison breakout board (running the SCL and SDA pins to a breadboard and running the connections out to the motor drivers) . Likewise the power and ground run to a common 5v and ground rail on the breadboard. 

One of the boards is set to address 1010, the other is set to 1111 using the switches on the board.

NOTE:
1010 is 0x0a or 10 in hexadecimal and decimal  representation. 
1111 is 0x0f or 15 in hexadecimal and decimal  representation. 

IMPORTANT: If you switch the address on a board that is powered on you must reset the board for the address change to take effect using either the reset switch or doing a power cycle. 

Running motor driver via Javascript 

To run the driver I am using Javascript through the Intel XDK. The sample code below is a stripped down version of the UPM example on their Github.

 var groveMotorDriver_lib = require('jsupm_grovemd'); //require motor driver library

var i2c_addr1 = 15; // set address of board 1 to 15, or 1111 on the switches 
var i2c_addr2 = 10; // set address of board 2 to 10, or 1010 on the switches

// Initiate two I2C Grove Motor Drivers on I2C bus 0
var my_MotorDriver_obj1 = new groveMotorDriver_lib.GroveMD(
groveMotorDriver_lib.GROVEMD_I2C_BUS, 
i2c_addr1
);

var my_MotorDriver_obj2 = new groveMotorDriver_lib.GroveMD(
groveMotorDriver_lib.GROVEMD_I2C_BUS, 
i2c_addr2
);

//Set the states of the motor drivers
my_MotorDriver_obj1.setMotorDirections(groveMotorDriver_lib.GroveMD.DIR_CCW, groveMotorDriver_lib.GroveMD.DIR_CW); //set the directions of the motors on board 1
my_MotorDriver_obj1.setMotorSpeeds(127, 255); //set the speeds of the motors on board 1

my_MotorDriver_obj2.setMotorDirections(groveMotorDriver_lib.GroveMD.DIR_CW, groveMotorDriver_lib.GroveMD.DIR_CCW); //set the directions of the motors on board 2
my_MotorDriver_obj2.setMotorSpeeds(127, 255); //set the speeds of the motors on board 1

In the code above the motors are set to:

Board 1 (1111): Channel 1 speed: 127, Channel 1 direction: clockwise
                          Channel 2 speed: 255, Channel 2 direction: counter-clockwise

Board 2 (1010): Channel 1 speed: 127, Channel 1 direction: clockwise
                            Channel 2 speed: 255, Channel 2 direction: counter-
clockwise

Where channel 1 is the output in line with the channel switches 

Troubleshooting

If you receive an error such as:

ERROR: writePacket: mraa_i2c_write() failed: MRAA: Unrecognised error. 

You have either entered an i2c address that does not correspond to the switch settings on your board, have not reset the board after changing the channel switches, or the pins have not been unexported through MRAA. 

The simplest way is to force MRAA to unexport pins is to launch the Arduino IDE and run the blink example. https://software.intel.com/en-us/articles/intel-iot-platforms-blink-led-arduino-ide

ROS on Intel Edison using Ubilinux and Porting to Yocto

In order to expand the robotics capabilities of the Intel Edison integrating a Robot Operating System (ROS) is necessary. While Node.js has many modules like Johnny5 and Cylon.js, they are still limited when compared to ROS in terms of computer vision processing and sensor integration. I will be starting with the install instructions for Ubilinux at: http://wiki.ros.org/wiki/edison . Once I have an idea of the packages that are needed and the installation procedure I can begin considering how to install ROS on Yocto. Ubilinux was installed on the Edsion following: https://learn.sparkfun.com/tutorials/loading-debian-ubilinux-on-the-edison

First step is installing screen and git to make life easier. I'm also creating a new user and installing sudo so that I won't have to use root to install.

First enter root by typing su and enter "edison" as the password.

apt-get install screen git sudo
adduser edison sudo
exit
logout

You can now log in with username edison password edison and have access to sudo.

Ok then, lets dive into it. I'm going to be following the instructions for installing ROS Indigo on Raspbian: http://wiki.ros.org/ROSberryPi/Installing%20ROS%20Indigo%20on%20Raspberry%20Pi (Debian for Raspberry Pi) with the suggested changes of:

edit /etc/apt/sources.list and add line:

deb http://http.debian.net/debian wheezy-backports main

and install liblz4 with:

sudo apt-get update
sudo apt-get install liblz4-dev

1. Prerequisites

Any commands with the code font are what I imputed into the terminal
sudo sh -c 'echo "deb http://packages.ros.org/ros/ubuntu wheezy main" > /etc/apt/sources.list.d/ros-latest.list'

wget https://raw.githubusercontent.com/ros/rosdistro/master/ros.key -O - | apt-key add -
sudo apt-get update
sudo apt-get upgrade
sudo apt-get install python-setuptools python-pip python-yaml python-argparse python-distribute python-docutils python-dateutil python-setuptools python-six
sudo pip install rosdep rosinstall_generator wstool rosinstall
sudo rosdep init
rosdep update
sudo apt-get install liblz4-dev

2. Installation

mkdir ~/ros_catkin_ws
cd ~/ros_catkin_ws
rosinstall_generator ros_comm --rosdistro indigo --deps --wet-only --exclude roslisp --tar > indigo-ros_comm-wet.rosinstall
wstool init src indigo-ros_comm-wet.rosinstall

terminal outputs: update complete

Since I will be using ROS_Comm I only need to install libconsole-bridge-dev and liblz4-dev and since linlz-dev was installed earlier I will only install libconsole-bridge-dev.

mkdir ~/ros_catkin_ws/external_src
sudo apt-get install checkinstall cmake
sudo sh -c 'echo "deb-src http://mirrordirector.raspbian.org/raspbian/ testing main contrib non-free rpi" >> /etc/apt/sources.list'
sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 9165938D90FDDD2E
sudo apt-get update
cd ~/ros_catkin_ws/external_src
sudo apt-get build-dep console-bridge
apt-get source -b console-bridge
sudo dpkg -i libconsole-bridge0.2_*.deb libconsole-bridge-dev_*.deb
cd ~/ros_catkin_ws
rosdep install --from-paths src --ignore-src --rosdistro indigo -y -r --os=debian:wheezy

 

ERROR: the following rosdeps failed to install
  apt: command [sudo -H apt-get install -y python-rospkg] failed
  apt: command [sudo -H apt-get install -y python-catkin-pkg] failed
  apt: command [sudo -H apt-get install -y python-rosdep] failed
  apt: Failed to detect successful installation of [python-rospkg]
  apt: Failed to detect successful installation of [python-catkin-pkg]
  apt: Failed to detect successful installation of [python-rosdep]

From wiki: Note: Rosdep may report that python-rosdep, python-catkin-pkg, python-rospkg, and python-rosdistro failed to install; however, you can ignore this error because they have already been installed with pip.

Now time to install ROS:

sudo ./src/catkin/bin/catkin_make_isolated --install -DCMAKE_BUILD_TYPE=Release --install-space /opt/ros/indigo

Once complete source the ROS install:

source /opt/ros/indigo/setup.bash

ROS is now installed and ready to use