Showing posts with label Programming. Show all posts
Showing posts with label Programming. Show all posts

Tuesday, September 4, 2012

How to connect a cellular modem on your Android and BeagleBoard on boot up

Last week, I wrote a tutorial about how to get a 3G/4G cellular modem working on my Android/BeagleBoard setup. The next question (after everything works) is, how can I get this running automatically every time I boot up my Android device?

image
Boot scripts are nothing too fancy, and anyone with some basic Linux or Android experience can navigate this process pretty easily. But I always find it helpful to have the actual scripts written out. As a beginner, it’s a great way to figure out what the commands actually mean, and as an advanced developer, it’s a huge timesaver to copy and paste what’s already been done.

As a quick recap, I'm running all of this off my BeagleBoard xM, BeagleTouch, and Android Ambrosia SD card/image. I decided to use a T-Mobile 4G Rocket 3.0 USB cellular modem, but any USB cellular modem should work, with some tweaks to the vendor/product ID as well as the chat script (more on that in the previous post).

Outline the process

Looking through the original 3G/4G cellular modem integration process, I needed to do 4 things:

1) Get usb_modeswitch and usbserial.ko onto your Android setup

2) Execute usb_modeswitch using the correct usb_modeswitch.conf config file

3) Once modeswitch was successful, install usbserial.ko module to the correct vendor and product ID for the device

4) Execute chat script using pppd command

Wrap up relevant components into a script

I created a file called init_cellular_pppd.sh, which contains the relevant content and commands to create the usb_modeswitch.conf file as well as the dialtest.chat script.

#!/system/bin/sh
#This is a wrapper script to enable cellular wireless
TAG="Cellular"

#
# echo usb modeswitch config
#
echo_modeswitch_conf_zte() {
echo "$TAG building modeswitch config"
cat > /system/etc/usb_modeswitch.conf << EOF

########################################################
# ZTE devices

DefaultVendor=  0x19d2
DefaultProduct= 0x2000
TargetVendor=   0x19d2
TargetProductList="0001,0002,0015,0016,0017,0031,0037,0052,0055,0063,0064,0066,0091,0108,0117,0128,0157,2002,2003"
MessageContent="5553424312345678000000000000061e000000000000000000000000000000"
MessageContent2="5553424312345679000000000000061b000000020000000000000000000000"
MessageContent3="55534243123456702000000080000c85010101180101010101000000000000"

NeedResponse=1
CheckSuccess=20
EOF
}

#
# echo chatscript
#
echo_chatscript_tmobile() {
echo "$TAG building chatscript"
cat > /system/etc/ppp/dialtest.chat << EOF
TIMEOUT 10
ABORT 'BUSY'
ABORT 'NO ANSWER'
ABORT 'ERROR'
SAY 'Starting GPRS connect script\n'

""'ATZ'
SAY 'Setting APN\n'
OK 'AT+CGDCONT=1,"IP","wap.voicestream.com"'

ABORT 'NO CARRIER'
SAY 'Dialing...\n'
OK 'ATD*99***1#'
CONNECT
EOF
}

#
# Switch USB modes
#
switch_usb() {
    echo "$TAG switching USB mode" && \
    usb_modeswitch -I -W -c /system/etc/usb_modeswitch.conf && \
    sleep 5 && \
    echo "$TAG mode switch success" && \
    return 0
}

#
# Start T Mobile firmware
#
start_tmobile() {
    rmmod usbserial
    echo "$TAG tmobile firmware provider"

    echo_modeswitch_conf_zte
    echo_chatscript_tmobile

    switch_usb
    echo "$TAG installing firmware"
    busybox insmod /system/etc/firmware/usbserial.ko vendor=0x19d2 product=0x0157
   
    echo "$TAG starting pppd"
    /system/bin/pppd /dev/ttyUSB1 persist defaultroute usepeerdns -detach crtscts noauth debug connect "/system/xbin/chat -v -s -f /system/etc/ppp/dialtest.chat" &
}


Insert command to run script into Android’s init.rc bootup commands

You’ll find init.rc in the root folder on your Android device.

I placed the init_cellular_pppd.sh script in /system/etc/ppp, though it could technically go anywhere – as long as it’s being called in the right location, and the files it generates are going to the right places as well.

Then I just added these two lines to Android’s init.rc bootup script:

service cellular_up /system/bin/logwrapper /system/xbin/busybox sh -c /system/etc/ppp/init_cellular_pppd.sh
    oneshot


This ensures that I execute init_cellular_pppd.sh every time I boot, which in turn generates the files I need and executes the commands required to have a fully functional 3G/4G cellular connection every time I boot up my Android device, provided I have the modem plugged in.

In my last blog post, I cover which parameters you’ll want to tweak if you’re using a different modem or cellular provider, but if you have any questions or suggestions, I’d love to hear it.

Email me at justin@liquidware.com or follow me on twitter @liquidware

Thursday, August 30, 2012

How to install a 3G/4G cellular modem on my Android BeagleBoard setup

A lot of folks have been asking me about this one, so I figured it’s about time to pull together my notes on the tutorial and get started…

In this case, I used an Android Ultimate Pro Kit, which runs Android 2.3.4 on the BeagleBoard xM/BeagleTouch/BeagleJuice, 2nd Gen.
Note: There’s a much sleeker (beta) way to get cell modems running in Android with the new PPP widget from Draisberghof. I haven’t tried it out yet, and hooking up modems the old-fashioned way helped me learn a few useful tips and tricks in navigating ADB, so I’m writing it all out here. Enjoy!

Hardware I used
1 BeagleBoard xM
1 BeagleTouch
1 BeagleJuice, 2nd Gen (optional – a 5V power supply works fine too)
1 Android Ambrosia SD card
1 Linux or Mac computer (cygwin for Windows could also do the job, with a little bit of toolchain setup. I used a dedicated Ubuntu EeePC)
1 T-mobile Rocket 3.0 4G laptop stick (but most will work – see below)
1 Type B-mini USB cable for connecting the computer to Amber

Software I used
Android SDK with Android Debug Bridge
Linux terminal (Asus Eee PC is *perfect* for this)

This tutorial assumes that you already have Android SDK with Android Debug Bridge set up, and that you’re communicating to the BeagleBoard/Android device from a Terminal program.

Connecting your Android device
1. Switch on your BeagleJuice, 2nd Gen to power on the Android Ultimate Pro Kit.

2. Once the BeagleBoard is booted into Android, plug in a USB cable from the Linux terminal to the BeagleBoard’s OTG type B-mini port.

3. Open up Terminal in Linux.

4. I have the Android SDK and Android Platform Tools installed, so I can access Android Debug Bridge right from the prompt. The first thing I do is make sure my device is connected by typing:

adb devices

A list of connected and available Android devices should come up.

Tools you’ll need on the Android device

Most USB 3G/4G cellular modems are actually several “devices” rolled into one – the most notable being some form of onboard data storage.

USB_ModeSwitch is a fantastic utility that essentially does the heavy lifting of separating all these devices, so we can talk to the modem over USB serial directly.

5. Download and unzip the static binary for ARM processors: usb_modeswitch-1.1.9-arm-static.bz2

From your working directory, push the usb_modeswitch application to /system/xbin/ on your Android device:

adb push usb_modeswitch-1.1.9-arm-static /system/xbin/usb_modeswitch

6. Download the usbserial.ko kernel module from the Liquidware site. The reason I have it set up as a separate module is so that we can install usbserial as the driver for our modem, which is necessary to communicate. Then push usbserial.ko to your Android device:

adb push usbserial.ko usbserial.ko

This will put the usbserial.ko file in the root folder on your Android device, which is fine for our purposes.
We’ll create the usb_modeswitch config file you’ll need later.

Find your modem identification information

7. Go into Android shell:

adb shell

Now you can issue commands as if you’re in a terminal application on the Android device.

8. To see details about attached USB devices, first mount the usbfs file system.

mount -t usbfs usbfs /proc/bus/usb

Now type in:

cat /proc/bus/usb/devices

You should see a list of devices appear. Each USB device will have a Vendor ID and a Product ID. This detailed information also clues you in by telling you what Driver the USB device is currently using.

image

The one I’m looking for is the T-Mobile Rocket 4G, made by ZTE. Three relevant pieces of information:

Vendor=19d2
ProdID=2000
Driver=usb-storage

Each device has a vendor and product code identifier. The Driver is “usb-storage”, meaning that the composite modem is recognized as a USB mass storage device. Not very useful for our purposes. That’s where USB ModeSwitch comes in. You’ll tell USB ModeSwitch to send a special string of characters, which then splits the composite device into 6 independently communicating USB serial devices – one of which is our modem.

Write down your Vendor and Product ID, as well as your Manufacturer, Product, and SerialNumber info. These will all be helpful in finding the correct string that you’ll need to send to the modem via ModeSwitch.

7. In order for USB ModeSwitch to run properly, you’ll need to create USB modeswitch config file in the right format that has the correct string of characters. I started by looking on Draisberghof’s extensive list of device references. For the T-Mobile Rocket 4G 3.0 by ZTE, copy the following text into gedit on your Linux terminal, and create a file called usb_modeswitch.conf

########################################################
# ZTE devices
DefaultVendor=  0x19d2
DefaultProduct= 0x2000
TargetVendor=   0x19d2
TargetProductList="0001,0002,0015,0016,0017,0031,0037,0052,0055,0063,0064,0066,0091,0108,0117,0128,0157,2002,2003"
MessageContent="5553424312345678000000000000061e000000000000000000000000000000"
MessageContent2="5553424312345679000000000000061b000000020000000000000000000000"
MessageContent3="55534243123456702000000080000c85010101180101010101000000000000"
NeedResponse=1
CheckSuccess=20

8. Push usb_modeswitch.conf down to your Android device.

adb push usb_modeswitch.conf /system/xbin/usb_modeswitch.conf

9. There is one additional file you’ll need, which is known as a chat script. It secures the connection with T-Mobile. Open up gedit again and copy the following text, creating a file called dialtest.chat: 

TIMEOUT 10
ABORT 'BUSY'
ABORT 'NO ANSWER'
ABORT 'ERROR'
SAY 'Starting GPRS connect script\n'
""'ATZ'
SAY 'Setting APN\n'
OK 'AT+CGDCONT=1,"IP","wap.voicestream.com"'
ABORT 'NO CARRIER'
SAY 'Dialing...\n'
OK 'ATD*99***1#'
CONNECT 

10. Push the file down to your Android device:

adb push dialtest.chat dialtest.chat

This will put dialtest.chat into your root directory.

Turn on your 3G/4G cellular modem for Android

image

Now that all the right files are in the right places, we can execute all the commands at once.

11. Plug in your 3G/4G USB cellular modem. It should start blinking

12. Go into shell on your Android device:

adb shell

13. At the Android shell prompt, enter the following:

/system/xbin/usb_modeswitch -I -W -c usb_modeswitch.conf

image

The output will tell me whether the operation was successful, and if it was, you’ll see something like the above screenshot.

14. Notice that the “matching” vendor/product ID is 19d2:0157. We can now install the usbserial kernel directly to that device. Make sure you are in the root directory, since that’s where we put the kernel file. The vendor ID and product ID need to be written in hex.

insmod usbserial.ko vendor=0x19d2 product=0x0157

15. Now check to see what devices are attached to USB at this point:

cat /proc/bus/usb/devices

You should see something like the following:

image

Compare this to the original screenshot, where usb-storage was the only device and driver under this product.

If you’d like, you can check this under the list of serial devices by typing:

ls /dev/tty*

image

If you see ttyUSB0-5, you’re good to go!

16. This part usually takes a little experimenting to figure out which USB device you want to call with the pppd command. This is the correct one. It will execute the dialtest.chat script that you put on the device earlier. (If you’re looking closely, I put my dialtest.chat script in a different folder, but that’s not really a big issue as long as you have the right path)

pppd /dev/ttyUSB1 persist defaultroute usepeerdns -detach crtscts noauth debug connect "/system/xbin/chat -v -s -f dialtest.chat"

image

Be sure to leave this terminal window open to maintain the connection.

The above screen shot shows what happens on a successful initiation of the chat script. You are now ready to go online. ifconfig tells me what my network connections are. Note that ppp0 has an IP address, which means we’re connected to T-Mobile.

ifconfig

image

And the beautiful turquoise beacon, and CNN.com confirms that I’m online!

image

I’m sure there are going to be questions – email me at justin@liquidware.com or find me on twitter @liquidware. Or just comment below, and I’ll get back to you immediately.

Next up after the Labor Day Weekend, I’ll explain how to roll this all up into a boot script, so it can run instantly, every time you power on the Android device.

A big thanks to freedune for an excellent and well-written blog post, which steered me through most of this effort!

Friday, July 13, 2012

How to read Arduino sensors with Adobe AIR Flex on Android


Android now supports Adobe AIR / Flex apps. The main benefit to using Flex over Java is that it specifically facilitates rapid story boarding of mobile user experiences. Coding Adobe Flex is similar to the Visual Basic observer design pattern of push-based actions. Add a button, right click to edit the action.

I decided to show how one could access the serial port using the Amber Android handheld, Arduino, AMBI light sensor using Adobe Flex.

Arduino Code

Upload this simple sketch to the Arduino.

void setup() {
    Serial.begin(115200);//setup a serial port with a baud of 115200

    pinMode(18, OUTPUT);
    pinMode(19, OUTPUT);
    digitalWrite(18, HIGH);
    digitalWrite(19, LOW);
}

void loop() {
    int value = analogRead(3); //read arduino analog pin 3 and save it as an int to value
    delay(1000);//delay 1,000ms
    char out[200];//create a 200 integer array

    sprintf(out, "hi\nLight=%d\n", value);//prep the out file
    Serial.print(out);//print the out array
}


Android Java Code

Android must forward serial messages to a local network socket so Adobe flex can handle the data. This is accomplished using the amber-serial app. 

Get the amber-serial source code on github, import this into a new project in Eclipse. Upload to Amber and keep the it running in the background.


Adobe AIR Flex Code

Create a flex app in the Adobe Flex builder through the wizard. Add a button to window and use the following code to read Arduino messages from a local network socket. I used port 8888, but you can use anything you'd like, just make sure to open the port in your firewall with iptables, if used.

socket = new Socket();
socket.addEventListener(Event.CONNECT, onConnect);
socket.addEventListener(ProgressEvent.SOCKET_DATA, onSocketData);
socket.connect("127.0.0.1", 8888);

private function onConnect(e:Event):void {
textarea1.text = textarea1.text + "Connected to server";
}

private function onSocketData(event:ProgressEvent):void
{
textarea1.text = textarea1.text + "[" + event.type + "] " + socket.readUTF();
}


App design tools have come a long way, now you can rapid prototype low-level sensors all the way up to the UI design.