Raspberry Pi + Arduino + SPI

8
  This worked for me.

This tutorial will show you how to communicate from your raspberry pi to your arduino using 3-wire SPI.

Requirements

  • 1 Raspberry pi (running Raspbian)
  • 1 Arduino
  • 4 wires

Your raspberry pi should be running the newest version of Raspbian.  To ensure your system is up-to-date please download and run rpi-update.

Wiring

 

Arduino

Open your Arduino ide and flash the below code to your Arduino.

Arduino code

Raspberry Pi

With your updated rasbian system you should have the drivers that you need. Now it’s time to load them.

modprobe spi_bcm2708
modprobe spidev

Check to be sure the modules loaded:

lsmod
Module Size Used by
spidev 5944 0
spi_bcm2708 5350 0
snd_bcm2835 21681 0
snd_pcm 81170 1 snd_bcm2835
snd_seq 59528 0
snd_timer 21602 2 snd_seq,snd_pcm
snd_seq_device 6924 1 snd_seq
snd 57427 5 snd_seq_device,snd_timer,snd_seq,snd_pcm,snd_bcm2835
snd_page_alloc 5343 1 snd_pcm
i2c_bcm2708 3822 0

Raspberry Pi Code

Save the below code as spidev_test.c on to your Raspberry Pi and compile it

gcc spidev_test.c -o spidev_test

Running

Plug your Arduino to your desktop via the serial cable. Open the arduino Serial Monitor and set the bitrate to 115200. Now, on the Raspberry Pi, run the compiled code

sudo ./spidev_test

You should see HELLO WORLD print in the Arduino IDE Serial Monitor.

Debugging

    • Make sure that your kernel has the required drivers (spi-bcm2708.ko and spidev.ko)

pi@raspberrypi ~/spi $ ls -al /lib/modules/`uname -r`/kernel/drivers/spi/
total 64
drwxrwxr-x 2 pi pi 4096 Aug 10 10:53 .
drwxrwxr-x 23 pi pi 4096 Aug 10 10:53 ..
-rw-rw-r– 1 pi pi 14428 Aug 10 10:53 spi-bcm2708.ko
-rw-rw-r– 1 pi pi 10852 Aug 10 10:53 spi-bitbang.ko
-rw-rw-r– 1 pi pi 15803 Aug 10 10:53 spidev.ko
-rw-rw-r– 1 pi pi 10693 Aug 10 10:53 spi-gpio.ko

Thanks to Nick Gammon for the SPI slave code.

Thanks to Anton Vorontsov for the kernel Documentation spidev_test.c example code.

 

Arduino Poor Man’s Oscilloscope

3
  This worked for me.

This tutorial will show you how to use your Arduino as an oscilloscope.  We end the tutorial with a verification portion that uses the Arduino to generate a square wave, requiring a single wire.

lxardoscope

Lxardoscope is another Arduino + real-time graphing project that has the potential to turn an Arduino into an oscilloscope.  Unfortunately, I was unable to get any readings (the visual graph remained static).

Poor Man’s Oscilloscope

First, download processing.

http://processing.googlecode.com/files/processing-1.5.1-linux.tgz
gzip -d processing-1.5.1-linux.tgz
tar -xf processing-1.5.1-linux.tar

Desktop Application

Arduino uses a modified RXTXcomm.jar library.  This causes a problem when the processing project runs poor man’s oscilloscope and loads the RXTXcomm.jar library bundles with the processing project.  Instead, we wish for process to load the modified Arduino RXTXcomm.jar library.  To remedy this problem we simply replace processing RXTXcomm.jar with the Android specific RXTXcomm.jar.

rm processing-1.5.1/modes/java/libraries/serial/library/linux64/librxtxSerial.so
rm processing-1.5.1/modes/java/libraries/serial/library/RXTXcomm.jar
ln -s /usr/share/arduino/lib/RXTXcomm.jar processing-1.5.1/modes/java/libraries/serial/library/

Run processing

cd processing-1.5.1
./processing

Running the processing command should result in a GUI application launching that looks a lot like the Arduino idea.  Download and open the below code in processing and click play.

  /*
 * Oscilloscope
 * Gives a visual rendering of analog pin 0 in realtime.
 * 
 * This project is part of Accrochages
 * See http://accrochages.drone.ws
 * 
 * (c) 2008 Sofian Audry (info@sofianaudry.com)
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */ 
import processing.serial.*;

Serial port;  // Create object from Serial class
int val;      // Data received from the serial port
int[] values;
float zoom;

void setup() 
{
  size(1280, 480);
  // Open the port that the board is connected to and use the same speed (9600 bps)
  port = new Serial(this, Serial.list()[0], 9600);
  values = new int[width];
  zoom = 1.0f;
  smooth();
}

int getY(int val) {
  return (int)(height - val / 1023.0f * (height - 1));
}

int getValue() {
  int value = -1;
  while (port.available() >= 3) {
    if (port.read() == 0xff) {
      value = (port.read() << 8) | (port.read());
    }
  }
  return value;
}

void pushValue(int value) {
  for (int i=0; i<width-1; i++)
    values[i] = values[i+1];
  values[width-1] = value;
}

void drawLines() {
  stroke(255);
  
  int displayWidth = (int) (width / zoom);
  
  int k = values.length - displayWidth;
  
  int x0 = 0;
  int y0 = getY(values[k]);
  for (int i=1; i<displayWidth; i++) {
    k++;
    int x1 = (int) (i * (width-1) / (displayWidth-1));
    int y1 = getY(values[k]);
    line(x0, y0, x1, y1);
    x0 = x1;
    y0 = y1;
  }
}

void drawGrid() {
  stroke(255, 0, 0);
  line(0, height/2, width, height/2);
}

void keyReleased() {
  switch (key) {
    case '+':
      zoom *= 2.0f;
      println(zoom);
      if ( (int) (width / zoom) <= 1 )
        zoom /= 2.0f;
      break;
    case '-':
      zoom /= 2.0f;
      if (zoom < 1.0f)
        zoom *= 2.0f;
      break;
  }
}

void draw()
{
  background(0);
  drawGrid();
  val = getValue();
  if (val != -1) {
    pushValue(val);
  }
  drawLines();
}

Arduino Code

Arduinoscope has a simple arduino component to poll and forward analog 0 to the desktop via the serial connection.  Save the below code and flash it to your Arduino.

#define ANALOG_IN 0

void setup() {
  Serial.begin(9600); 
  //Serial.begin(115200); 
}

void loop() {
  int val = analogRead(ANALOG_IN);                                              
  Serial.write( 0xff );                                                         
  Serial.write( (val >> 8) & 0xff );                                            
  Serial.write( val & 0xff );
}

 

Verifying the Oscilloscope

To test the oscilloscope we will generate data using the Arduino and feed it in to the analog A0 port to be viewed on our Desktop.  Flash the code below to your Arduino.

// The Arduino code.                                                            
                                                                                
#define ANALOG_IN 0                                                             
int outPin=13;                                                                  
int outPinState = LOW;                                                          
int count = 1;                                                                  
int every = 10000;                                                              
                                                                                
void setup() {                                                                  
  //Serial.begin(9600);                                                         
  Serial.begin(115200);                                                         
}                                                                               
                                                                                
void loop() {                                                                   
  int val = analogRead(ANALOG_IN);                                              
  Serial.write( 0xff );                                                         
  Serial.write( (val >> 8) & 0xff );                                            
  Serial.write( val & 0xff );                                                   
                                                                                
  /* Generate signal to test oscilloscope */                                    
  if ((count % every) == 0) {                                                   
    if (outPinState == LOW) {                                                   
      outPinState = HIGH;                                                       
    } else {                                                                    
      outPinState = LOW;                                                        
    }                                                                           
    digitalWrite(outPin, outPinState);                                          
    count = 0;                                                                  
  }                                                                             
  count++;                                                                      
}

Connect pin digital pin 13 on the Arduino to analog pin A0.  The above code will turn on and off the digital pin to produce a square wave.

Extras

  • You can alter the baud rate from 9600 to 115200 in the arduino code as well as the processing code.
  • Plus sign zooms in (shift and =) while – zooms out (just -, no shift)
  • PWM at a normal 50 HZ is easily observable
  • Raspberry Pi pin 18 can generate PWM and the arduino can be used to test it.
  • An idle capture looks like:

Dropbox on Raspberry Pi via SSHFS

4
  This worked for me.

This tutorial will demonstrate how to mount Dropbox (or any filesystem) over the network on the Raspberry Pi using SSHFS (Secure SHell FileSystem). For this procedure to work for your Dropbox share, you will need another machine somewhere that is running Dropbox, and is accessible to the Raspberry Pi via SSH.

Note: The following is not actually specific to the Raspberry Pi, nor to Dropbox. The tutorial generalizes for other systems and architectures that are not officially supported by Dropbox, as well as for mounting of other non Dropbox shares over the network.

How it works

SSH is a secure protocol for communicating between machines. SSHFS is a tool that uses SSH to enable mounting of a remote filesystem on a local machine; the network is (mostly) transparent to the user.

On the local computer where the SSHFS is mounted, the implementation makes use of the FUSE (Filesystem in Userspace) kernel module. The practical effect of this is that the end user can seamlessly interact with remote files being securely served over SSH just as if they were local files on his/her computer.

Installation (remote host)

The first step is to configure the remote host that the Raspberry Pi will connect to via SSH.  It will need to be running Dropbox, if you need to install it, follow the instructions for your respective OS here. If you are not yet a Dropbox user, and this has finally persuaded you to join, signup for Dropbox here.

Next, the remote machine will need to be running OpenSSH server. For Windows and Mac instructions on how to set up OpenSSH server, I recommend this tutorial on Lifehacker.  For Linux users, OpenSSH server is available in most every package manager. To install on Ubuntu, for example:

sudo apt-get install openssh-server

 

Installation (Raspberry Pi)

Now that the remote host is configured, you can setup the mount on the Pi.  This first requires installation of the sshfs package.  Open a terminal on the Pi and install it like this:

sudo apt-get install sshfs

Then add the user pi to the FUSE users group:

sudo gpasswd -a pi fuse

Once added to the fuse group, log out and log back in again for the change to take effect. Next, create a directory to mount Dropbox (or other remote share)

mkdir ~/Dropbox

Now use sshfs to mount the remote share on the newly created mountpoint. Be sure to change the user@remote-host and path to Dropbox to match your own settings:

sshfs -o idmap=user user@remote-host:/home/user/Dropbox ~/Dropbox

For example, connecting to another machine on your local network will look something like this:

sshfs -o idmap=user michael@192.168.1.100:/home/michael/Dropbox ~/Dropbox

The idmap=user option ensures that files owned by the remote user are owned by the local user. If you don’t use idmap=user, files in the mounted directory might appear to be owned by someone else, because your computer and the remote computer have different ideas about the numeric user ID associated with each user name. idmap=user will not translate UIDs for other users.

That’s all there is to it! To unmount,

fusermount -u ~/Dropbox

Automount Dropbox on boot

To configure the Dropbox SSHFS to automatically mount at startup, we first need to enable SSH keyless remote login.  The first part of this task is to generate an RSA crypto key so we can securely login to the remote machine running Dropbox without entering a password.  In a terminal on the Pi, run:

ssh-keygen -t rsa

Hit enter three times when prompted, accepting the default settings for the RSA ssh keys. Now copy the public part of the key to the remote host using the ssh-copy-id command:

ssh-copy-id -i ~/.ssh/id_rsa.pub user@remote-host

You will be prompted for the password on the remote one last time. Once entered, terminal output will confim the key was added sucessfully.

Now that you can login remotely without password, the final task is to configure the share to automatically mount on startup. There are a few ways this could be accomplished, I decided to use cron for the task. Open the global crontab for editing:

sudo crontab -e

And add a line to the end like this:

@reboot sshfs user@remote-host:/home/user/Dropbox /home/pi/Dropbox

Then press CTRL and X to exit the editor, then Y to confirm the changes (if using nano, the default text editior).

That’s it! Reboot the Pi, and your Dropbox share will mount automatically on startup.

Another method to accomplish this task would be to add a line to /etc/fstab to automatically mount the Dropbox SSHFS share.

Reference: https://help.ubuntu.com/community/SSHFS

 

MSP430 Launchpad + PWM

2
  This worked for me.

Inspired by this tutorial.

The following tutorial will describe how perform pulse width modulation using a MSP430g2553 TI Launchpad to control a sparkfun servo motor.

 

Prerequisites

Please see Cross-Compiling for TI MSP430 Launchpad to setup your development environment.

 

Hardware

  • Servo motor
  • MSP430
  • Power

I’m using the Arduino to power the servo motors. Alternatively you may use USB, a wall plug, or a battery. The MSP430 is being used to generate the PWM for control.

Connect your servo control wire to MSP430 pin P1.2.

 

Software

Save the below code as pwm.c

#include "msp430g2553.h" // make sure you change the header to suit your particular device.
 
// Connect the servo SIGNAL wire to P1.2 through a 1K resistor.
 
#define MCU_CLOCK           1100000
#define PWM_FREQUENCY       46      // In Hertz, ideally 50Hz.
 
#define SERVO_STEPS         180     // Maximum amount of steps in degrees (180 is common)
#define SERVO_MIN           700     // The minimum duty cycle for this servo
#define SERVO_MAX           3000    // The maximum duty cycle
 
unsigned int PWM_Period     = (MCU_CLOCK / PWM_FREQUENCY);  // PWM Period
unsigned int PWM_Duty       = 0;                            // %
 
void main (void){
 
    unsigned int servo_stepval, servo_stepnow;
    unsigned int servo_lut[ SERVO_STEPS+1 ];
    unsigned int i;
 
    // Calculate the step value and define the current step, defaults to minimum.
    servo_stepval   = ( (SERVO_MAX - SERVO_MIN) / SERVO_STEPS );
    servo_stepnow   = SERVO_MIN;
 
    // Fill up the LUT
    for (i = 0; i < SERVO_STEPS; i++) {
        servo_stepnow += servo_stepval;
        servo_lut[i] = servo_stepnow;
    }
 
    // Setup the PWM, etc.
    WDTCTL  = WDTPW + WDTHOLD;     // Kill watchdog timer
    TACCTL1 = OUTMOD_7;            // TACCR1 reset/set
    TACTL   = TASSEL_2 + MC_1;     // SMCLK, upmode
    TACCR0  = PWM_Period-1;        // PWM Period
    TACCR1  = PWM_Duty;            // TACCR1 PWM Duty Cycle
    P1DIR   |= BIT2;               // P1.2 = output
    P1SEL   |= BIT2;               // P1.2 = TA1 output
 
    // Main loop
    while (1){
 
        // Go to 0°
        TACCR1 = servo_lut[0];
        __delay_cycles(100000);

        // Go to 45°
        TACCR1 = servo_lut[45];
        __delay_cycles(100000);
 
        // Go to 90°
        TACCR1 = servo_lut[90];
        __delay_cycles(100000);
 
        // Go to 180°
        TACCR1 = servo_lut[179];
        __delay_cycles(100000);
 
        // Move forward toward the maximum step value
        for (i = 0; i < SERVO_STEPS; i++) {
            TACCR1 = servo_lut[i];
            __delay_cycles(20000);
        }               
        // Move backward toward the minimum step value
        for (i = SERVO_STEPS; i > 0; i--) {
            TACCR1 = servo_lut[i];
            __delay_cycles(20000);
        }
   }
}

Compile install and run the code!

sudo mspdebug rf2500
erase
prog pwm.elf
run

If your lucky then your device will have moved a bit and you might notice that the device didn’t reach its full range of motion.  You will need to play with the SERVO_MIN and SERVO_MAX constants to achieve the devices full range of motion.

 

Debugging

This section contains hints and debug strategies if things didn’t just magically work for you.

 

Header File

The biggest trouble I had was getting the correct header file. An incorrect header file did not produce any warnings.  The only feedback for a header file that didn’t match my board was the device moving less than 1 degree and behaving non-deterministic.  Look at the documentation that came with your board to find the exact device. A list of device headers can be found in the directory /usr/msp430/include/.

 

Erase

The mspdebug program hosts a suite of commands.  A list of commands can be gotten by typing help.  The erase command is one that I found late into the night. Be sure to issue the erase command before you issue the load command.

 

Is it broke?

Often times when things aren’t working you will wonder if you broke the board because you touched some pin, got pissed off and threw it across the room, or your kitty cat Mr. Bigglesworth played kitty frisbee with it.  Regardless of the reason you want some feedback that the board is still alive.  I like to reload a piece of code that blinks the development board built-in lights LED blinking tutorial.

 

Peer Guardian on Raspberry Pi

2
  This worked for me.

This tutorial will show how to compile and install Peer Guardian on a Raspberry Pi.  The process requires the at least the 2012-06-18-wheezy-beta.zip or newer Debian image (or manual kernel re-compilation).  This will NOT work with debian6-19-04-2012.zip since the kernel does not have net filtering enabled. Also, you will need a decent sized SD card (4GB at least) … the dependencies alone require 382 MB.

First, install the required package dependencies. In a terminal on the Raspberry Pi:

sudo apt-get install libnetfilter-queue-dev lsb-qt4 libdbus-1-dev qt4-dev-tools libdbus-1-dev libdbus-glib-1-dev firehol firestarter ufw zlib1g-dev

Next, download and extract the Peer Guardian source archive, then change directory to the root of the tree:

wget http://downloads.sourceforge.net/project/peerguardian/PeerGuardian%20Linux/2.1.3/pgl-2.1.3.tar.gz

tar -xvf pgl-2.1.3.tar.gz

cd pgl-2.1.3/

Now we are finally ready to start the build! To compile, run make, then install Peer Guardian with make install:

make

sudo make install

Finally,

sudo /usr/lib/lsb/install_initd /etc/init.d/pgl

Now reboot the Pi:

sudo reboot

And on start-up you will see the confirmation that it starts:

Starting PeerGuardian Linux: pgld.

Note: this takes much longer than usual for the first boot, be patient!

To start the GUI from the LXDE menu, select Internet -> pgl-gui

The default settings are very strict and you will likely want to change them.  It even blocks access to the apt sources, so until you changes the settings, even ‘apt-get update’ will fail.

 

Arduino Physical CPU Gauges

1
  This worked for me.

Use Arduino and two hobby servos to control physical servo gauges for cpu activity, memory usage, bandwidth, and more. The script uses the python psutil and pyserial modules. The psutil module provides an interface for retrieving information on all running processes and system utilization (CPU, disk, memory, network) providing service similar to command line tools such as ps, top, iostat, and netstat. The servo control portion of the project is based on Arduino-Python 4-Axis Servo Controlby Brian Wendt, and the Arduino sketch is essentially unmodified from the SerialServoControl Sketch on Sparkfun.

Hardware

Connect the red, power lines of the servos to +5v, the black ground lines to GND, and the yellow signal lines to the desired output pins, 5 and 6 in the example (others can be used, but must be PWM capable

You can download my cheesy gauge overlay from here:

http://mitchtech.net/arduino-physical-cpu-gauges/gauges/

Print it out, cut out the gauges, and poke a hole in the lower center of the gauge.  Remove the servo horn, slide the shaft through the hole in the gauge printout, and reconnect the servo horn on top of it.

 

Software

The first step is to install the python psutil and pyserial modules. The easiest way to install it is using the python pip package manager. If you don’t have it installed already, you can install it using apt-get:

sudo apt-get install python-pip

Then install the psutil and pyserial modules:

sudo pip install psutil pyserial

Next, flash the sketch to the Arduino board. You can download it or copy and paste into the Arduino IDE.

 

Then download or copy and paste the Python script:

 

That’s it! To run the script:

python  cpu_serial_servo.py

 

Note:If you receive this error:

raise SerialException(“could not open port %s: %s” % (self._port, msg)) serial.serialutil.SerialException: could not open port /dev/ttyUSB0: [Errno 13] Permission denied: ‘/dev/ttyUSB0′

The problem is the default permissions of the /dev/ttyUSB0 (or /dev/ttyACM0) device. This can be fixed by running the command:

sudo chmod 777 /dev/ttyUSB0

 

Raspberry Pi Physical Gmail Notifier

3
  This worked for me.

This tutorial will demonstrate how to easily turn your Raspberry Pi into a physical Gmail notifier, in only 10 lines of python! If the configured Gmail account has unread messages, the LED will be illuminated, otherwise dim.  The project was inspired by the Arduino/Mac version by J4mie adapted for use on the Raspberry Pi.

Here is a diagram of the wiring of the LED with a 330 ohm resistor in series (created with Fritzing):

raspi_gmail_led

The python script uses the feedparser module to simplify interaction with Gmail and the RPi.GPIO module to control the GPIO pins. The easiest way to install these is using the python pip package manager. If you don’t have it installed, you can install the pip package manager using apt-get. In a terminal on the Pi:

EDIT: For 2012-07-15-wheezy-raspbian.zip and newer, the Python development headers (python2.7-dev) are also required:

sudo apt-get install python-pip python2.7-dev

Next, for pip to work correctly you will need to update to a newer version of distribute using easy_install:

sudo easy_install -U distribute

Then install the feedparser and GPIO modules with pip:

sudo pip install feedparser RPi.GPIO

Once the pre-requisites have been installed, download , or copy and paste the following Python script to the Raspberry Pi:

The final step is to configure the script to run every minute as a cron job. To do so, open the global crontab for editing:

sudo crontab -e

Then add this line to the end of the file (adjust to the location of the python script):

* * * * * python /home/pi/raspi_gmail.py

That’s it! From now on, cron will execute the script once every minute.  If you have unread messages, the GPIO pin will be pulled high, lighting the LED, otherwise, it will be disabled, dimming the LED.

 

Switch to our mobile site