Python: interfacing with an arduino

February 3rd, 2010 mat 2 comments

So what is an arduino?
An arduino is an open source open hardware programmable controller with several inputs and outputs. The image below shows an Ardunio Dicemella.

Ardunio Dicemella Annotated Photo

Ardunio Dicemella Annotated Photo

It (Arduino Dicemella) has 14 digital input/output pins (of which 6 can be used as PWM outputs), 6 analog inputs, a 16 MHz crystal oscillator, a USB connection, a power jack, an ICSP header, and a reset button. It contains everything needed to support the microcontroller; simply connect it to a computer with a USB cable or power it with a AC-to-DC adapter or battery to get started.

They are very useful for people who know how to program but have little experience with hardware interaction.

Programming the arduino
This post will not contain in-depth detail on how to program the arduino, instead focussing briefly on setting up serial (over serial or usb cable) communications in order to talk to a python script. The arduino can be programmed via a IDE provided by the creators in a C-style hardware language.

Code example

int ledPin = 13;            // choose the pin for the LED
int inputPin = 2;          // choose the input pin (for a pushbutton)
int val = 0;                // variable for reading the pin status

void setup() {
  pinMode(ledPin, OUTPUT);      // declare LED as output
  pinMode(inputPin, INPUT);     // declare pushbutton as input
}

void loop(){
  val = digitalRead(inputPin);  // read input value
  if (val == HIGH) {            // check if the input is HIGH
    digitalWrite(ledPin, HIGH);  // turn LED ON
  } else {
    digitalWrite(ledPin, LOW); // turn LED OFF
  }
}
Arduino LED switch circuit off

Arduino LED switch circuit off

Arduino LED switch circuit on

Arduino LED switch circuit on

Now we add a few lines to enable the writing of information from our arduino over the serial connection. We first need to set up the transfer speed in our setup (Serial.begin(9600);). Then we can simply send messages over serial using Serial.print(“message\n”);. You can choose between print and println with the difference been that the latter automatically appends the newline char, so we would use the former to write multiple things to the same line. Below is our modified code:

Serial write example

int ledPin = 13;           // choose the pin for the LED
int inputPin = 2;         // choose the input pin (for a pushbutton)
int val = 0;               // variable for reading the pin status

void setup() {
  pinMode(ledPin, OUTPUT);      // declare LED as output
  pinMode(inputPin, INPUT);     // declare pushbutton as input
  Serial.begin(9600);
  Serial.print("Program Initiated\n");
}

void loop(){
  val = digitalRead(inputPin);  // read input value
  if (val == HIGH) {            // check if the input is HIGH
    digitalWrite(ledPin, HIGH);  // turn LED ON
    Serial.print("LED Activated\n");
  } else {
    digitalWrite(ledPin, LOW); // turn LED OFF
  }
}

We now add into this code the ability to receive information via serial. Below is the modified example which removes the action of the button and replaces it by activating the LED when ‘Y’ is sent via serial.

Serial read example

int ledPin = 13;  // choose the pin for the LED
int val = 0;      // variable for reading the pin status
char msg = '  ';   // variable to hold data from serial

void setup() {
  pinMode(ledPin, OUTPUT);      // declare LED as output
  Serial.begin(9600);
  Serial.print("Program Initiated\n");
}

void loop(){
        // While data is sent over serial assign it to the msg
	while (Serial.available()>0){
		msg=Serial.read();
	}

  // Turn LED on/off if we recieve 'Y'/'N' over serial
  if (msg=='Y') {
    digitalWrite(ledPin, HIGH);  // turn LED ON
    Serial.print("LED Activated\n");
    msg=' ';
  } else if (msg=='N') {
    digitalWrite(ledPin, LOW); // turn LED OFF
  }
}

Interaction with python

First we import the serial library to python in order to communicate with the arduino (this includes talking over usb).

import serial

We then attempt to connect to our arduino on /dev/ttyUSB0, using try and except to catch an exception if we are unable to find the arduino on USB0. The 9600 corresponds to the baud rate (speed of communication) that we are using with the arduino and should be the same as set in the program on the arduino otherwise your communication may appear garbled.

try:
	arduino = serial.Serial('/dev/ttyUSB0', 9600)
except:
	print "Failed to connect on /dev/ttyUSB0"

The address will be /dev/ttyUSB# where # is replaced by a number for arduinos connected via usb and /dev/ttyS# where # is replaced by a number for arduinos connected via serial. If you are not sure of the location of your arduino, it can be found in the arduino IDE or you can write some python to scroll through possible locations until a response is found

locations=['/dev/ttyUSB0','/dev/ttyUSB1','/dev/ttyUSB2','/dev/ttyUSB3',
'/dev/ttyS0','/dev/ttyS1','/dev/ttyS2','/dev/ttyS3']

for device in locations:
	try:
		arduino = serial.Serial(device, 9600)
	except:
		print "Failed to connect on",device

You may need to be careful as other devices can be connected. For example if I try to connect to /dev/ttyS0 I will connect to the wacom tablet on my laptop.

Once you have connected to your arduino successfully you can write information to it using write and read information sent from it using read (you will need to import time to use the sleep function). If your arduino does not send any messages via serial then attempting to readline will result in your program hanging until it receives a message.

try:
	arduino.write('Y')
	time.sleep(1)
	print arduino.readline()
except:
	print "Failed to send!"

So the python code should now look like the following and we should be able to control the LED over serial.

import serial
import time

locations=['/dev/ttyUSB0','/dev/ttyUSB1','/dev/ttyUSB2','/dev/ttyUSB3',
'/dev/ttyS0','/dev/ttyS1','/dev/ttyS2','/dev/ttyS3']  

for device in locations:
	try:
		print "Trying...",device
		arduino = serial.Serial(device, 9600)
		break
	except:
		print "Failed to connect on",device   

try:
    arduino.write('Y')
    time.sleep(1)
    print arduino.readline()
except:
    print "Failed to send!"

The above will send the character ‘Y’ (Y for Yes please turn on the LED) to the arduino wait for 1 second and then read from the arduino which will have hopefully posted a response to our ‘Y’. Using the program on this should turn the LED on, and report LED Activated back via serial to our python program. This should be enough for people to get started with ardunios and communicating with them in python.

References

  • Arduino – The arduino website with everything you are likely to need (programming examples and reference guide, and hardware information)
  • Arduino tutorial – a basic and easy to understand tutorial on programming the arduino
  • Python port of arduino-serial.c – By John Wiseman from which I based my program.
  • original arduino-serial.c – by Tod E. Kurt.
  • Sparkfun – Here is a good place to purchase ardunio and other electronics parts. Try coolcomponents if your from the uk like me
  • Dealextreme – Hong Kong based retailer that sells a lot of cheap DIY electronics and also has worldwide free delivery with no min spend (crazy). Does take about two weeks to arrive though (uk).
  • Share/Bookmark
Categories: arduino, python Tags: , ,

How to tell android which volume (media/ringtone etc.) should be controlled by your app

February 1st, 2010 mat 2 comments

In my android apps I was getting annoying problems that whilst playing sound the volume buttons would control the media volume, but when no sound was playing they would control the ringtone volume. I found the following by trial and error, hopefully this post will help people with the same problem.

This is done by placing a call of setVolumeControlStream in the onCreate part of your activity which takes on of the following values

  • AudioManager.STREAM_MUSIC
  • AudioManager.STREAM_RING
  • AudioManager.STREAM_ALARM
  • AudioManager.STREAM_NOTIFICATION
  • AudioManager.STREAM_SYSTEM
  • AudioManager.STREAM_VOICECALL

Below shows the code required to set your applications default volume control to any of the above values:

Media Volume

this.setVolumeControlStream(AudioManager.STREAM_MUSIC);

Ringtone Volume

this.setVolumeControlStream(AudioManager.STREAM_RING);

Alarm Volume

this.setVolumeControlStream(AudioManager.STREAM_ALARM);

Notification Volume

this.setVolumeControlStream(AudioManager.STREAM_NOTIFICATION);

System Volume

this.setVolumeControlStream(AudioManager.STREAM_SYSTEM);

Voicecall Volume

this.setVolumeControlStream(AudioManager.STREAM_VOICECALL);

I imagine this is also possible via and XML settings, if anyone knows of this I’d be very grateful to know how!

  • Share/Bookmark
Categories: Android Tags: , ,

Bash: Script to find active computers in a subnet using ping

January 27th, 2010 mat 2 comments

The following is a simple bash script that will scan each ip address in a give subnet and report if they are alive (or accepting ping requests). The code creates processes for each ping so that it completes quickly rather than scanning each ip address sequentially.

Create a text file called “pinger.sh” and paste the following into it:

#!/bin/sh

: ${1?"Usage: $0 ip subnet to scan. eg '192.168.1.'"}

subnet=$1
for addr in `seq 0 1 255 `; do
#   ( echo $subnet$addr)
( ping -c 3 -t 5 $subnet$addr > /dev/null && echo $subnet$addr is Alive ) &
done

Save and close, then it can be called from the command line like so:

sh pinger.sh 192.168.1.

This will scan from 192.168.1.0 to 192.168.1.255 and will return something like the following:

192.168.1.1 is Alive
192.168.1.105 is Alive
192.168.1.112 is Alive
192.168.1.149 is Alive
  • Share/Bookmark
Categories: bash Tags: , ,

Android: Unreal Tournament SoundBoard

January 27th, 2010 mat No comments

Following the popularity of my counter-strike 1.6 soundboard and requests for the “HEADSHOT” noise for it, I have created an Unreal Tournament soundboard (from which the headshot sound originates).

Sounds:
Features all of the following sounds:

  • dominating
  • double kill
  • first blood
  • god like
  • headshot
  • holy shit
  • killing spree
  • ludicrous kill
  • mega kill
  • monster kill
  • multi kill
  • play
  • rampage
  • ultra kill
  • unstoppable
  • wicked sick

Screenshots
The following are screenshots from the application:

unreal tournament soundboard

unreal tournament soundboard

Unreal tournament soundboard

Unreal Tournament Soundboard 2

Download
Unreal Tournament SoundBoard can be downloaded from the market on your android phone either by searching or following the android link below. Alternativly you can download the apk file from this website using the download link

Android: UTsoundboard
Download: UTsoundboard download

If you enjoyed this please leave feedback for me either here or on the market. Comments, suggestions and constructive criticism is also welcome.

  • Share/Bookmark
Categories: Android Tags:

Android: Saving a sound file to SD from resource and setting as ringtone

January 26th, 2010 mat 4 comments

Quite a few people have been asking how to save a file to the SD card in order to register it as a ringtone. The following example creates a function that will save a resource to the SD card (ie: from R.raw.soundfile to /sdcard/media/audio/ringtones/soundfile.wav) and register it as a ringtone.

I have split this example into two parts, the first part goes through the code a section at a time with a brief explanation of what it does, the second half is just the code that you can copy and paste and then edit to your hearts content.

Parts

We first setup our function to return a boolean depicting if we have failed or if we are successful. We accept in an integer which corresponds to the raw sound file.

public boolean saveas(int ressound){

}

So this function would be called in the following fashion:

saveas(R.raw.soundfile);

or utilising its boolean return:

if (saveas(R.raw.soundfile)){
// Code if successful
}
else
{
// Code if unsuccessful
}

The following chunk of code creates an inputstream from the raw sound resource and loads it into a buffer. We add in the mandatory try/catch clause around these operations and return false if an exception is raised (to indicate failure to the rest of our program and to prevent trying to continue act upon this sound).

 byte[] buffer=null;
 InputStream fIn = getBaseContext().getResources().openRawResource(ressound);
 int size=0;

 try {
  size = fIn.available();
  buffer = new byte[size];
  fIn.read(buffer);
  fIn.close();
 } catch (IOException e) {
  // TODO Auto-generated catch block
  return false;
 }

The following saves the buffer to a file on the SD card. It first ensures the folder exists and if not it is created. Then as before the writing operations are surrounded with try/catches

 String path="/sdcard/media/audio/ringtones/";
 String filename="examplefile"+".wav";

 boolean exists = (new File(path)).exists();
 if (!exists){new File(path).mkdirs();}

 FileOutputStream save;
 try {
  save = new FileOutputStream(path+filename);
  save.write(buffer);
  save.flush();
  save.close();
 } catch (FileNotFoundException e) {
  // TODO Auto-generated catch block
  return false;
 } catch (IOException e) {
  // TODO Auto-generated catch block
  return false;
 }

The following code sends an intent to tell the Media Scanner that we have added a new file, and sets up its properties in the media database:

 sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.parse("file://"+path+filename)));

 File k = new File(path, filename);

 ContentValues values = new ContentValues();
 values.put(MediaStore.MediaColumns.DATA, k.getAbsolutePath());
 values.put(MediaStore.MediaColumns.TITLE, "exampletitle");
 values.put(MediaStore.MediaColumns.MIME_TYPE, "audio/wav");
 values.put(MediaStore.Audio.Media.ARTIST, "cssounds ");
 values.put(MediaStore.Audio.Media.IS_RINGTONE, true);
 values.put(MediaStore.Audio.Media.IS_NOTIFICATION, true);
 values.put(MediaStore.Audio.Media.IS_ALARM, true);
 values.put(MediaStore.Audio.Media.IS_MUSIC, false);

 //Insert it into the database
 this.getContentResolver().insert(MediaStore.Audio.Media.getContentUriForPath(k.getAbsolutePath()), values);

Final code
Putting all this code together gives us our final functions:

public boolean saveas(int ressound){
 byte[] buffer=null;
 InputStream fIn = getBaseContext().getResources().openRawResource(ressound);
 int size=0;

 try {
  size = fIn.available();
  buffer = new byte[size];
  fIn.read(buffer);
  fIn.close();
 } catch (IOException e) {
  // TODO Auto-generated catch block
  return false;
 }

 String path="/sdcard/media/audio/ringtones/";
 String filename="examplefile"+".wav";

 boolean exists = (new File(path)).exists();
 if (!exists){new File(path).mkdirs();}

 FileOutputStream save;
 try {
  save = new FileOutputStream(path+filename);
  save.write(buffer);
  save.flush();
  save.close();
 } catch (FileNotFoundException e) {
  // TODO Auto-generated catch block
  return false;
 } catch (IOException e) {
  // TODO Auto-generated catch block
  return false;
 }    

 sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.parse("file://"+path+filename)));

 File k = new File(path, filename);

 ContentValues values = new ContentValues();
 values.put(MediaStore.MediaColumns.DATA, k.getAbsolutePath());
 values.put(MediaStore.MediaColumns.TITLE, "exampletitle");
 values.put(MediaStore.MediaColumns.MIME_TYPE, "audio/wav");
 values.put(MediaStore.Audio.Media.ARTIST, "cssounds ");
 values.put(MediaStore.Audio.Media.IS_RINGTONE, true);
 values.put(MediaStore.Audio.Media.IS_NOTIFICATION, true);
 values.put(MediaStore.Audio.Media.IS_ALARM, true);
 values.put(MediaStore.Audio.Media.IS_MUSIC, false);

 //Insert it into the database
 this.getContentResolver().insert(MediaStore.Audio.Media.getContentUriForPath(k.getAbsolutePath()), values);

 return true;
}

Comments, suggestions etc. are always welcome. Hope this has been helpful.

  • Share/Bookmark
Categories: Android Tags: , , ,

Android: Opening a webpage in your app using Intents

January 25th, 2010 mat 2 comments

Opening up a website from an application in android is very simple thanks to “Intents”. An Intent is a request to android use an application to preform a task. The code below shows a very simple example of launching a browser to go to the wordcube website.

Context context = getApplicationContext();
String url = "http://www.stealthcopter.com/wordcube";
Intent i = new Intent(Intent.ACTION_VIEW);
Uri u = Uri.parse(url);
i.setData(u);
try {
  // Start the activity
  startActivity(i);
} catch (ActivityNotFoundException e) {
  // Raise on activity not found
  Toast toast = Toast.makeText(context, "Browser not found.", Toast.LENGTH_SHORT);
}

As pointed out in the comments, the context can be replaced by the activity itself, such as TestApp.this. eg:

Toast toast = Toast.makeText(TestApp.this, "Browser not found.", Toast.LENGTH_SHORT);

We have surrounded the activity with a try/catch which will be raised if android cannot find an application that will accept this intent, in this case a web-browser. It is highly unlikely that an android phone will not have a web-browser installed but it is a good practise to get into.

  • Share/Bookmark
Categories: Android Tags: , ,

Android: WordCube – Daily puzzle game

January 23rd, 2010 mat No comments

Due to the success (and small amount of addiction) of my browser-based wordcube game (see here), I decided to make a WordCube application for android.

Features

  • Anagram / Wordsearch based puzzle
  • Small file size (~100kb) and footprint
  • Updated daily
  • Share score with twitter integration (compete with friends)
  • Saves your last attempts so you can continue at later time
  • This also means you can continue your last game offline
  • Several achievements can be unlocked (more to come, also looking for suggestions for achievements)
wordcube screenshot

screenshot of wordcube

Gameplay
Find as many words as possible using letters from the grid. The words must be 4 letters or more, contain the central letter and each letter may not be used more than once. There is at least one word that uses all of the letters in the cube.

The main interface is by tapping the letters in order to construct a word, but keyboards (and on screen keyboards) are also supported.

wordcube screenshot 2

Another wordcube screenshot

Twitter Integration
Once you have attained all the words that you can, you can post your score to twitter and then compare with your friends to see how they did in comparison. In order to use this feature you need to have a twitter client installed, I would recommend twidroid.

wordcube twitter integration

Twitter integration in wordcube

Download
WordCube can be downloaded from the market on your android phone either by searching for wordcube or following one the two android links below. To download the WordCube app from this website, follow the Web link.

Android: WordCube Free
Android: WordCube Pro (only £1)
Web: WordCube Free

The pro version is available for £1, with the money going to support the developer and the development and maintenance of this application. The pro version features all of the latest features and in the near future will support personal statistics to keep track of performance.

If you enjoyed this please leave feedback for me either here or on the market. Comments, suggestions and constructive criticism is also welcome.

  • Share/Bookmark
Categories: Android Tags: , ,

Stealthbomber pillow (not quite a stealthcopter…)

January 22nd, 2010 mat No comments

Using a V-Shaped pillow extended by your feet kinda makes it look like a stealthbomber:

stealthcopter pillow

stealthbomber pillow

  • Share/Bookmark
Categories: misc Tags: ,

Android: Eclipse and problems with dynamic tables (adding rows)

January 20th, 2010 mat 1 comment

When using TableLayout with LayoutParams Eclipse will automatically (and wrongly) add the following import:

import android.view.ViewGroup.LayoutParams;

However if you try to use this you will notice that nothing changes. You need to replace the import with the ollowingL

import android.widget.TableRow.LayoutParams;

Now if you rerun your code, you will see that your tables are updating. See below for an example of the code to generate a table

int sizey=10;
int sizex=10;
int btnwidth=24;
TableLayout tl = (TableLayout)findViewById(R.id.MyTableLayout); 

for (int y=0;y<sizey;y++){

// Rows
TableRow tr = new TableRow(this);
tr.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.WRAP_CONTENT));

//Cells
for (int x=0;x<sizex;x++){
// Create new cell
	// new button
	Button b = new Button(this);
	b.setText(x+""+y);
	b.setLayoutParams(new LayoutParams(
		LayoutParams.FILL_PARENT,
		LayoutParams.WRAP_CONTENT));
	b.setHeight(btnwidth);
	b.setBackgroundResource(R.drawable.btn_blue);
	b.setOnClickListener(new PegOnClickListener(y,x));
	// add button to row
	tr.addView(b);
	}
// add row to layout
tl.addView(tr,new TableLayout.LayoutParams(
LayoutParams.FILL_PARENT,
LayoutParams.WRAP_CONTENT));
}
}
  • Share/Bookmark
Categories: Android Tags: , ,

Bash: Script to convert .flv to mp3

January 18th, 2010 mat No comments

Flash Video (.FLV) is currently a very popular format of online videos, inparticular youtube. This post explains how to use a simple script to extract the sound from a flash video file and turn it into an mp3.

In order for the script to work you will need to download ffmpeg (to decode the video) and lame (to encode the mp3). This can be achieve in ubuntu by opening a terminal and running the following or alternatively you can use your package manager GUI to search and download the packages for you.

sudo apt-get install ffmpeg lame

You then need to create a new file named “flv2mp3.sh” and paste the following into it using your preferred text editor (which hopefully isn’t VI). Save the file and then change the file permissions so that it is executable (by running:`chmod a+x flv2mp3.sh` in the terminal or via the gui in you file browser)

#!/bin/sh
# this script should convert files from FLV to WAV and then to MP3
echo " "
echo "  Welcome to FLV to MP3 converter!  version 0.1"
echo " "
infile_name="$@"
# exit if the user did not enter anything:
if [ -z "$infile_name" ]; then
    echo " "
    echo "You did not tell me the file name, so I will exit now."
    echo " "
    exit
fi
echo " "
ffmpeg -i "$infile_name" -acodec pcm_s16le -ac 2 -ab 128k -vn -y "${infile_name%.flv}.wav"
lame --preset cd "${infile_name%.flv}.wav" "${infile_name%.flv}.mp3"
rm "${infile_name%.flv}.wav"
echo " "
echo "OK. I'm done! Have fun!"
echo " "
exit

You should now be able to convert a flashvideo into an mp3 by running the following command (changing the filenames to fit your purpose):
sh flv2mp3.sh videofilename.flv mp3audiofilename.mp3

Extra: Youtube
In linux it might be worth noting that youtube downloads the flv’s to your /tmp folder and you can easily copy them or convert to mp3’s (Ensure video is completly finished loading).

Also there is an application called ‘youtube-dl’ which can be installed from the repositories

sudo apt-get install youtube-dl

and then run using

youtube-dl http://www.youtube.com/video_to_borrow

Of course it’s up to your moral guidance to decide what you can and can’t download.

  • Share/Bookmark
Categories: Linux, bash, web Tags: , , , ,