I'm Not Texting I'm Programming!

Update: This app is available now as Physics Gizmo on Google Play.

No less than a century ago, it was possible to learn everything we knew about science. The only requirements were an ability to read, an extensive library, and perhaps the equipment to carry out your own experiments. Now we have entered a new era of science where literacy is more widespread and between the Internet and Libraries we have every resource imaginable at our fingertips.

Two big problems remain, science has diversified and grown so much that it is difficult for scientists to know everything about their own field let alone another. The other issue is how science equipment remains financially out of reach of amateurs and explorers. The major scientific research is driven by that which will have a financial return and so science for its own sake is limited. This is even more evident in schools who are cutting science to save the rest of their budgets and focus on less expensive (and more tested) subjects This must change if a steady stream of innovation is to continue.

The hacker spirit is a deeply embedded part of science. Now out of necessity and pure enjoyment, many are directing their attention away from software development but to hardware. In the August issue of Wired, the BioHacker movement features those who wish to reduce the cost of doing Genetic analysis.

Do you know where these DIY Biologists expect to see the most impact? Schools! For students to do science instead of just reading about it. Arduinos, Makerbots, Robotics, and more are forever changing the opportunities students have to create.

At my school we spent a lot of time in labs and projects. What was lacking was quality data. Unfortunately the tools and sensors available to students are expensive and limited. So I did what I always do, I sat down and wrote some code :)

I love my Android phone and each day I hear about the insane number of new activations everyday. The smart phone is getting smarter and cheaper just as technology always does. Just as we saw an explosion of Desktops and later Laptops in the 1990-2000s, we are seeing an even speedier rate of adoption of smart phones. While looking at my phone one day, I realized how many sensors/tools it has built in seamlessly to its interface (Internet, Accelerometer (motion sensor), Gyroscope, Light, Sound) which if purchased separately would be thousands of dollars and would not play well with each other.

So I wrote a program which logs motion and then uploads it to your Google Docs account. You can see some screenshots below of the results.

Jumping up and down

Dropping my phone (onto a pillow)

To do this, I used sl4a (Scripting Language for Android). With this you can code in Python, Ruby, Javascript (and more) and do almost anything with your Android phone. It has a built in editor so you can quickly type code into the phone (hence this post's name) or you can code it in your favorite editor and then transfer it to the SD card on your phone.

Why did I use sl4a instead of making a nice pretty app using Android's SDK? This application uses the Google Doc APIs (basically commands to communicate between an app and and a program like Twitter or Facebook) and Python. If you look at the code it could be done by any of our students with a free weekend. It may look a little complicated at first but there are just a lot of function calls to save code. Just like most other Python code, it reads like a story (login, get the parameters, sense, upload).

I believe sl4a could take students who may or may not have used App Inventor or Scratch to the next level and open up a world of possibilities to them. sl4a has been used to send collect data on a phone being launched into space and many other exciting projects involving Twitter, Robots, Arduino and more!


I wanted to use sl4a so everyone who knows Python could see the code and hopefully improve on it. I don't have the time right now, but I would love to see other sensors added, the ability to review and display the data/graph on the phone, interface with Arduino, and store data on the phone if it logs data longer than 1 minute, and perhaps even add a pretty GUI. I'm hoping that by open sourcing this, others will want to jump on board and help out. Cellbots have set the bar really high and have their own incredible data logging app and if they integrated Google Docs uploading I would say their app is perfection.

My hope is as more educators/students realize their ability to create, scientific tools will become available to all. People like Steve Dickie, the Arduino team, Geogebra, and many others are working really hard to ensure that the cost to do STEM is reduced dramatically.

You could walk into your class on Monday and ask your students how many of them have an Android phone, you may be surprised that there are enough for one per group. Think of all of the experiments you could do with nothing else but your phone. I can't wait for this year's Magic Mountain Physics Day and see how many students could get data from a roller coaster and directly upload it to their Google Docs (and check it while still at the park from the GDocs Android app).

Look how easy it is to make a little popup on your screen!
import android
droid=android.Android()
droid.makeToast("Hello Android")


If you want to give this a shot, go to the sl4a website and download the apk (the installer). Your other options are to click this link, or scan the barcode on the right with your Android phone. Follow the User Guide to get Python (or the other languages) installed on your phone.

Now, you are ready to start coding on/for your phone. There are some great tutorials on the sl4a website, I also recommend the book Pro Android Python with SL4A. In my code below I list a few other resources that were helpful to the doScience project.

If your code is relatively small you can share it via barcode but this app falls just above that threshold. So you can copy and paste it from below (just please respect the Creative Commons licence) into your Python Editor or download the doScience file directly. Save it to your SD card in the sl4a/scripts folder. This code must be run on a phone or a computer connected to a phone running an sl4a server (much simpler than it sounds).

Note: It will ask you to login to your Google account. As you can see from the code below, no one is able to access that information since it is kept hidden from even the developer by the dialogGetPassword method in line 41.

I hope this app inspires you to do something great. If you know how to program, build, create will you please lend your talents to this projects or the many others out there. If you don't know how to create, then learn as it is the most incredible thing to be a Maker and you will inspire others. Before you know it, the revolution will be underway (oh wait it already is, come join us)!

Subscribe and Connect to BrokenAirplane and stay up to date with the best resources for your classroom.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
'''This code is licenced under a Creative Commons
Attribution-NonCommercial-ShareAlike 3.0 Unported Licence.
Created by Phil Wagner 2011 www.brokenairplane.com. This code allows data logging and uploading to Google Spreadsheets.
It exists so students can to do Science when 
the cost of Science Equipment is too expensive. Additional features can be added
but this paragraph should always remain in the code.'''

#Future features - Additional Sensors, Review, Display Data/Graph on Phone
#interface with Arduino/ADK

#Helpful Resources:
#http://code.google.com/p/android-scripting/ (sl4a)
#http://code.google.com/ (Google APIs and resources)
#http://www.adaptcode.com/using-google-spreadsheets-as-a-database-in-the-cloud/
#http://gdata-python-client.googlecode.com/svn/trunk/pydocs/gdata.spreadsheet.text_db.html

import android
import time
import gdata.spreadsheet.service
import gdata.spreadsheet.text_db
import string

droid = android.Android()

dt=100 #Time between sensing

def countdown():
    #3 Second Countdown and Vibrate
    droid.vibrate(100)
    time.sleep(1)
    droid.vibrate(100)
    time.sleep(1)
    droid.vibrate(100)#3 second countdown
    time.sleep(1)
    droid.vibrate(300)
    return

def login(myEmail='example@gmail.com', password=''):    #Get Email and Password and login
    while password == '':
        email = droid.dialogGetInput("Email", "Enter the email account where the Data will be uploaded to:",myEmail).result
        password=droid.dialogGetPassword("Password", "Enter the account password where the Data will be uploaded to:").result
        try:
            client = gdata.spreadsheet.text_db.DatabaseClient()
            client.SetCredentials(username=email, password=password)
        except gdata.spreadsheet.text_db.BadCredentials:
            droid.dialogCreateAlert("Username or password incorrect.")
            droid.dialogSetPositiveButtonText("OK")
            droid.dialogShow()
            redo = droid.dialogGetResponse()
            password =''
            continue
        else:
            return client

def spreadSheetSetup(client, defaultTitle = 'Science Data'):
    versionNumber = client.GetDatabases(name=defaultTitle)
    if len(versionNumber) > 0:
        droid.dialogCreateAlert('Science Data %d' % len(versionNumber))
        droid.dialogSetPositiveButtonText("OK") #Yes option box
        droid.dialogShow()
        understood = droid.dialogGetResponse()
        spreadsheetTitle = defaultTitle+' '+str(len(versionNumber))
    else:
        spreadsheetTitle = defaultTitle
    return client.CreateDatabase(spreadsheetTitle)

def time2Sense(defaultTime=5000):
    maxTime =0
    #Enter time for sensing
    while maxTime == 0: ##How long to sense?
        try:
            maxTime=int(droid.dialogGetInput("Time", "How long to collect data (in milliseconds):",str(defaultTime)).result)
        except TypeError:
            droid.dialogCreateAlert("Please enter a numeric time")
            droid.dialogSetPositiveButtonText("OK")
            droid.dialogShow()
            droid.dialogGetResponse()
            continue
        if maxTime > 30000: #30 seconds max for optimal upload
            droid.dialogCreateAlert("Warning this could take a long time to upload.")
            droid.dialogSetPositiveButtonText("I accept the risks")
            droid.dialogSetNegativeButtonText('New time')
            droid.dialogShow()
            check = droid.dialogGetResponse().result
            if check['which'] == 'positive':
                return maxTime
            else:
                maxTime = 0
                continue
        return maxTime

def doScience():
    droid.dialogCreateAlert('Are you ready', 'Click yes to begin sensing, or no to cancel')
    droid.dialogSetPositiveButtonText("Let's do science!") #Yes option box
    droid.dialogSetNegativeButtonText("Nah let's cancel") #No option box
    droid.dialogShow()
    return droid.dialogGetResponse().result

def senseAccel(endTime,dt=100):    #Sense and store accel data
    timeSensed=0
    tempScience = []
    droid.startSensingTimed(2,dt) #dt = time between sensings
    while timeSensed <= endTime:
        tempScience.append(droid.sensorsReadAccelerometer().result) #add new accel data to list
        time.sleep(dt/1000.0)
        timeSensed+=dt
    #Stop Sensing
    droid.makeToast("Done")
    droid.vibrate(300)
    droid.stopSensing()
    return tempScience

def main():
    db =spreadSheetSetup(login())
    endTime = time2Sense()
    ready = doScience()
    if ready['which'] == 'positive':
        countdown()
        science = senseAccel(endTime,dt)
        table=db.CreateTable('Accelerometer',['t','x','y','z']) #Beware spreadsheet column names cannot be uppercase if you are going to add to them later http://code.google.com/p/gdata-python-client/issues/detail?id=363
        droid.dialogCreateHorizontalProgress('Progress','Uploading to Docs',len(science)*3 )
        droid.dialogShow()
        progress = 0
        time = 0
        for data in science:
            table.AddRecord({'t':str(time),'x':str(data[0]),'y':str(data[1]),'z':str(data[2])}) #AddRecord requires strings as arguements str()
            progress+=3
            time+=dt
            droid.dialogSetCurrentProgress(progress)
        droid.dialogCreateAlert('Done', 'Go check your data on Docs')
        droid.dialogSetPositiveButtonText("OK") #Yes option box
        droid.dialogShow()
        droid.dialogGetResponse()

if __name__ == "__main__":
        main()