Posts Tagged ‘ Python

Arduino talks to Processing, Python…

Note:  This post has been updated, see notes below.

Been enjoying tinkering around with the Arduino and the Electronic Brick Kit I recently got. It’s easy to send data from the computer to the Arduino and run sketches there, but what about the other way? The Arduino can talk back with the computer over its serial port, so at that point any language that can read the serial port can read the Arduino’s data.  Since I’m most comfortable with Python and Processing, that’s what the below code covers.

Few things to note:

  • Python has no built-in serial modules\packages (to my knowledge), but I found several references to pySerial, that appears to be the go-to source for cross-platform serial info in Python.  So you will need that.
  • Update:  After a bit of thinking, I have got Python working independently from Pygame, see notes below.
    • (Old subject):  I couldn’t get Python working directly:  When I’d run a loop to capture the serial data, it would hang the shell.  I figured this was because it wasn’t ‘advancing in time’ (just looping endlessly on the first item), so I popped the code into Pygame, and it started working flawlessly.  There probably is a way to do this in Python, but this is my first stab at reading any kind of serial data.  So the Python example is implemented via Pygame.
  • This is all authored on  Win2k OS.  Serial ports on different OS’s are handled differently.  For the Python and Processing code I define a variable that sets which com port the Arduino is on (in my case, it’s COM5), which is something that you should have already defined via the Arduino IDE.  Just make sure those values match.  And again, if you’re on Linux of Mac, the serial port values will be different.
  • On both the Processing and (the old)  Python examples, they will draw a window with a circle inside that will change in size based on the passed in serial data. Based on the sensor I was using (twist sensor) on an analog pin, this maps the voltage of the sensor into values 0-1023, which are easy to then map into the on-screen graphics. The code will also print out to the shell\IDE the captured serial values.
  • Finally, I should point out I pulled a lot of info from the book Getting Started with Arduino.

Dependencies:

Begin:

Arduino:

Here is the Arduino code.  I have a rotational sensor on analog pin 5.  But you can use any kind of sensor that you want.  I picked the rotational sensor since it’s easy to see the values change.

/**
serialSensor
Eric Pavey 2009-12-26

Sketch will print the value from the sensor to the serial port
*/

#define SENSOR 5

int val = 0;

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

void loop(){
  val = analogRead(SENSOR);
  // Print to the serial port:
  Serial.println(val);
  delay(100);
}

When that is uploaded to the Arduino you can hit the ‘Serial Monitor’ button in the IDE, which will pop up a new window that shows the values captured from the serial port:  When I twist my rotational sensor, I see the result print in the serial monitor.  Pretty straight-forward.  Be sure to close the serial monitor window before you run any of the below code, or they will be blocked from accessing the serial port.

Processing:

The IDE’s for Processing and Arduino are very similar; the Arduino docs say it was ‘built on’ Processing, and the resembelence is strong.  When executed, will create a window, with a white circle inside thats size is controlled by the sensor data passed through the serial port.

Here is the Processing code:

/**
 * readArduinoSerial
 * Eric Pavey 2009-12-26
 * Read data from the computers serial port, that is being fed
 * by an Arduino sketch.  It's expecting values from 0->1023.
 */

import processing.serial.*;

// Create object from Serial class
Serial myPort;  

// Converted data received from the serial port
float val = 1.0;
float prevVal = 1.0;
int minSerial = 0;
int maxSerial = 1023;
// Define which port the Arduino is on:
String arduino = "COM5";

void setup(){
  smooth();
  frameRate(30);
  size(200, 200);
  myPort = new Serial(this, arduino, 9600);
}

void draw(){
  if ( myPort.available() > 0){
    String portVal = myPort.readString();
    // Trim off any extra chars that have no meaning
    // to our sketch.  If we don't do this, we can get
    // NaN float vals when converted.
    String trimmed = portVal.trim();
    if(trimmed.length() > 0){
      // if we have a valid value, update it:
      val = float(portVal);
    }
  }
  if(val != prevVal){
    println("New val: " + val);
    prevVal = val;
  }

  background(0);
  float mapVal = map(val, minSerial, maxSerial, 1, width);
  fill(255);
  ellipse(width/2, height/2, mapVal, mapVal);
}

Python / Pygame:

Like Processing, when executed, will create a window, with a white circle inside thats size is controlled by the sensor data passed through the serial port.

Here is the Python / Pygame code:

"""
readArduinoSerial.py
Eric Pavey - 2009-12-27

Read data from the computers serial port, that is being fed
by an Arduino sketch.  It's expecting values from 0->1023.
"""

import serial
import pygame
from pygame.locals import *
pygame.init()

WIDTH = 256
HEIGHT = 256
FRAMERATE = 30
# Define which com port the Arduino is on:
ARDUINO = "COM5"

screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Arduino Serial Com.")
clock = pygame.time.Clock()

ser = serial.Serial(ARDUINO, timeout=1)
floatVal = 1.0
prevVal = 1.0

def main():
    global floatVal
    global prevVal
    cirCol = Color("white")
    looping = True

    while looping:
        clock.tick(FRAMERATE)
        screen.fill(0)

        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                looping = False

        # Read the serial value
        ser.flushInput()
        serialValue = ser.readline().strip()

        # Catch any bad serial data:
        try:
            floatVal = float(serialValue)/8.0
            if floatVal != prevVal:
                # Print the value if it differs from the prevVal:
                print "New Val: ", floatVal
                prevVal = floatVal
        except ValueError:
            pass
        pygame.draw.circle(screen, cirCol, (WIDTH/2, HEIGHT/2), floatVal)

        # update our display:
        pygame.display.update()

if __name__ == "__main__":
    main()

Update: Here is the new Python code sans-Pygame. It will print results directly to the shell it was executed from:

import serial

ARDUINO =  "COM4"

def main():
    ser =  serial.Serial(ARDUINO, timeout=1)
    prevVal = None
    while 1:
        # Read the serial value
        ser.flushInput()
        serialValue = ser.readline().strip()
        # Catch any bad serial data:
        try:
            if serialValue != prevVal:
                # Print the value if it differs from the prevVal:
                print "New Val: ", serialValue
                prevVal = serialValue
        except ValueError:
            pass

if __name__ == '__main__':
    main()

In Conclusion…

So while the implementation in Processing \Python is pretty simple, it opens doors into what could be.  Another interesting observation is that the Processing sketch was really ‘jumpy’:  It seems to capture values that aren’t being reported by the Arduino sketch, causing the circle to ‘jump’ in size occasionally.  However, the Pygame (and updated pure Python) app seems pretty rock solid, and no ‘jumping’ is reported.

Compare Jython and Java swing authoring

Since I’m teaching myself Java, and recently installed Jython, I thought it would be interesting to compare the two for authoring swing UI’s.  To aid in this development, I got the PyDev plugin for Eclipse installed, allowing for me to use Eclipse as an IDE for Jython and Python, nice.  FYI, I am by no means an expert at swing, or Java.  But the examples do work :)

Both examples display identical “Hello World!” window.

Here’s the Jython:

# texttest.py
from javax.swing import *
from java.awt import *

class TextTest(JFrame):
    def __init__(self):
        JFrame.__init__(self, "TextTest")
        self.setSize(256, 128)
        self.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE)
        pane = HelloPane()
        self.add(pane)
        self.setVisible(True)

class HelloPane(JPanel):
    def paintComponent(self, comp):
        f = Font("Arial", Font.PLAIN, 32)
        comp.setFont(f)
        comp.drawString("Hello World!", 32, 64)

if __name__ == "__main__":
    tt = TextTest()

And here’s the Java:

// TextTest.java
import javax.swing.*;
import java.awt.*;

public class TextTest extends JFrame {
    public TextTest() {
        super("TextTest");
        setSize(256, 128);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        HelloPane pane = new HelloPane();
        add(pane);
        setVisible(true);
    }

    public static void main(String[] arguments) {
        TextTest frame = new TextTest();
    }
}

class HelloPane extends JPanel {
    public void paintComponent(Graphics comp) {
        Graphics2D comp2D = (Graphics2D)comp;
        Font f = new Font("Arial", Font.PLAIN, 32);
        comp2D.setFont(f);
        comp2D.drawString("Hello World!", 32, 64);
    }
}

Jython

jythonAs I delve deeper into my new ‘Learning Java Book‘, I continue to miss Python more and more.  Not that I don’t find Java an impressive language; it’s amazing what us humans can come up with.  But considering I learned Python first, Java (and every other languange I’ve ran into) seem… less desirable in comparison.  I know them’s fightin’ words in some parts, but hey, this is my blog.

I’d known about Jython for some time, but it finally clicked in my head:  Why not try it?  It’s Java, but it acts like Python.  After an easy download and installation, I fired up it’s ‘jython.bat’ file (on WinXP) and there before me was the Python (er… I mean Jython) prompt.  It was an eerie feeling using an interactive  Jython shell to import ‘javax.swing’ and make a simple UI, but it worked flawlessly.  And so much easier than having to jump through all those Java hoops requiring you to make extraneous classes, etc.

From an online tutorial:

jythonShell

Thus creates:

jythonWindow

I’m not sure where Jython will take me, but it sure makes me warm up to Java more :)  Next step will be to get it running in Eclipse

Installing the Android Scripting Environment on the Android Emulator

Update:  I have a newer post here describing how I got the SL4A installed on an actual phone.  More work than I expected…

Based on my previous post, the thought of being able to run Python on an Android Device via the Android Scripting Environment seems… enticing.  However, I personally do not own an Android Device, nor have plans to get one anytime soon (ah, love those AT&T contracts…).  But there is the Android Emulator which I can run on my PC, why not use that in the meantime?

What I expected to be easy turned into quite a quest.  But I got it working, and the steps are listed below.  Specifically, this is a walkthrough on installing the Android SDK, creating an ‘Android Virtual Device’, launching the Android Emulator, installing the appropriate scripting language data on it, and running that language on the emulator.  This was done on a WinXP system.  I should also point out that this was my first foray into anything Android related, so I am quite a bit of a noob at this point.  My knowledge does not stretch far beyond this tutorial :-)

Finally, while my goal was to get Python running, you can use these steps to (presumably) get other languages (Lua, Perl, jRuby, BeanShell, Rhino) installed as well.  My tutorial below will be based around Python and its associated dependencies, but you should be able to mentally replace that with the language of your choice.

#1: Install the Android SDK:

Based on this post, I got the SDK installed.  I’d recommend you follow it as well.  You can stop at their “Step6: Create a new Android Virtual Device”, since that’s what we’ll cover below.  Note that this install process was done with version Android v2.0, can’t vouch for earlier versions.

  • It ended up being installed here:  C:\android-sdk-windows
  • Not sure of the importance, but I read online that you need to add a Windows System Variable named ‘SDK_ROOT’ with the value of the tools dir in the SDK install location, which for me is ‘C:\android-sdk-windows\tools’

#2: Create an Android Virtual Device (AVD):

  • I first created a shortcut on my desktop to this bat file which I use to launch the ‘Android SDK and AVD Manager’:
    • C:\android-sdk-windows\tools\android.bat
  • Under ‘Virtual Devices’, I created a new AVD, named it ‘ASE_test’.  Specifics in the image:
  • createNewAVD
  • After creation, pick the AVD in the ‘List of existing Android Virtual Devices”, and “Start…”
  • This will launch the Android Emulator:
  • emulatorScreen
  • Getting closer…

#3: Install the Android Scripting Environment (ASE):

It’s important that the Android Emulator is open (& unlocked) and running while the below steps are performed.

I read a lot of documentation about making a disk image of a memory card that the AVD could load in place of a real one.  I spent two hours trying to get this to work… it just didn’t happen.  Then I learned that you can install the ASE via the ‘Android Debug Bridge’ (adb) in a shell, and everything got a lot easier…

  • Download the ASE, and appropriate scripting language data.  Find them at the ‘Android Scripting’ download page here:
  • These files specifically: (note: since the time of authoring this post, the below apk and zip files have been updated… be sure to grab the latest versions)
  • After downloaded, for convenience, copy them to your SDK\tools dir:
    • C:\android-sdk-windows\tools
  • Install the ASE:
    • Make sure the Android Emulator is up and running (& unlocked).
    • In an OS shell, change directory to the SDK\tools directory.
    • Execute these commands to install the ASE on the emulated Android Device (running in the background):
      • C:\android-sdk-windows\tools>adb install ase_r14.apk
    • Then, use these commands to copy the Python data to the virual sdcard on the emulator:
      • C:\android-sdk-windows\tools>adb push python_scripts_r0.zip  /sdcard
        C:\android-sdk-windows\tools>adb push python_extras_r0.zip  /sdcard
        C:\android-sdk-windows\tools>adb push python_r0.zip  /sdcard
    • That should do it!  Your shell should look something like this when complete:
      • C:\android-sdk-windows\tools>adb install ase_r14.apk
        570 KB/s (127785 bytes in 0.218s)  pkg: /data/local/tmp/ase_r14.apk
        Success 
        
        C:\android-sdk-windows\tools>adb push python_scripts_r0.zip  /sdcard
        133 KB/s (4280 bytes in 0.031s)  
        
        C:\android-sdk-windows\tools>adb push python_extras_r0.zip  /sdcard
        502 KB/s (2460097 bytes in 4.781s)  
        
        C:\android-sdk-windows\tools>adb push python_r0.zip  /sdcard
        360 KB/s (1726792 bytes in 4.671s)

#4: Configure the ASE:

At this point, the ASE should be installed in the running Android Emulator, and the Python data (or whatever scripting language you’re using) copied to the virtual SD card.

  • Expand the Application Tab.  You should see the “ASE” icon.  This means a successfull .apk install!
  • aseInstalled
  • Select the ASE icon.  This will launch the Android Scripting Environment, and give you a screen saying “Start adding scripts and Interpreters by pressing the menu button”.  We need to install the Python interpreter, so, press “MENU”.
  • Along the bottom of the UI three buttons will pop up.  Press the middle one “Interpreters”.
  • This will clear the screen with only one option; “Shell”.  Press the “MENU” button again.
  • New buttons along the bottom, press “Add”
  • AH, a big list of stuff to install!  Scroll down to ‘Python 2.6.2’ and press it.
  • This will start an extraction process, and you should see it extract the various Python .zip files you had put on the virtual SD card earlier.
  • Now the UI has two options, “Shell” and “Python 2.6.2”.  Press Python…
  • This launches a Python shell.  Success!
  • pythonShell
  • Hitting the return button twice will take you to another menu that has all the default Python modules previously installed: notify_weather.py, saychat.py, etc.  Press ‘test.py’:
  • This will run that module, executing a variety of test suites on the emulated device.
  • Pressing menu can take you into a module edit mode as well:
  • testPy
  • That’s pretty cool… 😛

In Conclusion…

What to do now?  First step, will be to go over all this info on the ‘Android Scripting Groups Wiki’:  http://code.google.com/p/android-scripting/w/list

I have to say, interaction in the emulator itself  is really slow, with lots of lag.  I also had a weird issue where all the text I tried to type was being converted into Japanese.  I had to go into my emulator’s Settings -> Language Keyboard -> And uncheck the first two options under “Text settings”.  I don’t know what they are, since they’re in JAPANESE.  But that fixed it.

Thus, it begins.

Index of reference pages:

These are pages I pulled a lot of info from to figure all of this out:

Android anyone?

android01While I’ve really been enjoying coding with Pygame and Python… one thing they don’t seem to be able to do is play well with mobile phones.  Specifically things like the iPhone and Android devices.  Everyone I show my BubblePaint Pygame program to has the same comment:  You should put that on the iPhone!  And I’d love to!  But I don’t see Python entering into the iPhone’s future anytime soon, and I have no real want to learn Objective-C or C++ for iPhone dev.  Plus, I really don’t want to have to buy a Mac just to release my iPhone apps :-S

Enter Android.  Can develop for it on the PC (plus!).  Uses Java as its programming language.  And now appears to support Python scripting!  So far so good! (well, other than the fact I signed a 2-year deal with AT&T so my wife could get an iPhone <wink> )

I’m a bit warmer to Java than other languages based on my familiarity with Processing.  But I still really don’t “know Java” (however I have to say that Processing was a gentle introduction).  So I went out this weekend and picked up these books:

Then I:

  • Installed Eclipse IDE, since the Android platform has some Eclipse-specific plugins to aid in it’s development.
  • Installed the Android SDK (thanks to this post)

And finally I:

  • Started reading the Java book.

I’m now on… day 3… of 21.  It’s going pretty fast since Java is not so unlike Python in many regards.  The only thing I find unfortunate is that the more I learn of Java… the more I miss Python.  Python’s dynamic typing is sooooo much more conducive to my brain than Java’s static typing, and the stripped down syntax of Python just makes me feel… cleaner, compared to all the brackets, semi-colons, variable casting and whatnot needed in Java.  Bah!  End rant.

We’ll see where this leads:  I really like the idea of making games on mobile devices, and Android seems like an accessible platform.  I just hope AT&T starts selling the devices soon (the emulator will only get me so far) and learning Java doesn’t  cause me to rant too much….

:-)