Tuesday, May 29, 2012

Beaglebone Support Board Schematic using ExpressSCH

The home monitor based on the Beaglebone can measure and report on two temperatures and one A/C power present signal. The external circuitry required to do this includes two negative temperature coefficient temperature-sensitive resistors and bridge resistors, some optical isolators, a wall wart power supply (for A/C detection), and a special circuit that uses one Beaglebone GPIO output bit to switch on and off the +5V power line in the USB connection to the Option Icon modem, simulating plugging and unplugging it under program control. This is to correct for some obscure problems where the modem times out and seems to require power cycling to fix.

The USB power switch also uses a separate power supply for the modem, so it acts sort of like a powered hub, and has plenty of power. (Limited power is a chief suspect in a previously reported problem where the modem would stop working very frequently.)

I actually have this stuff wired up on a couple of breadboards, mounted with the Beaglebone on a piece of foam. Might see about making a PC board (shield or whatever Beaglebone people call the boards that mate with the Beaglebone external expansion connectors.)

I published an informal hand-drawn schematic in the last post here. This is a better schematic of the support circuitry that does this:




Monday, May 28, 2012

Beaglebone Start-up Script, with GSM modem reconnect

This script is run via cron using the @reboot time. It handles unplugging and replugging the modem, and restarting the 'tclsh beagelgsm.tcl' script command when it exits.

#!/bin/sh
#
# beaglegsm.sh - SHell script to run beaglegsm.tcl from
#                cron job.
#
# This script is meant to run 'tclsh beaglegsm.tcl' on a Beaglebone
# board, using an Option Icon 322 USB modem, connected to a UAB port with
# a special cable and circuit that allows a program to disconnect and reconnect the modem
# using the Beaglebone GPIO bit on pin 3 of the P8 expansion connector to disconnect and
# reconnect +5V USB power to the modem via the USB cable. The GPIO bit is named gpio1_6
# in the P8 connector pinout table in the Beaglebone System Reference Manual (A5).
#
# The need to disconnect and reconnect is due to some obscure bug that ocassionally
# makes the modem time-out during operations in the TCL script beaglegsm.tcl. It seems
# that the disconnect/reconnect is needed to reset the modem.


# We assume the gpio pin multiplexer is set up for pin 3 of P8
# to be a gpio bit (mode 7). This state seems to be maintained after power-down
# and rebooting.
#
# Check this using:
#
#    root@beaglebone:~/work# cat /sys/kernel/debug/omap_mux/gpmc_ad6
#    name: gpmc_ad6.gpio1_6 (0x44e10818/0x818 = 0x0037), b NA, t NA
#    mode: OMAP_PIN_OUTPUT | OMAP_MUX_MODE7
#    signals: gpmc_ad6 | mmc1_dat6 | NA | NA | NA | NA | NA | gpio1_6


# Export bit and set direction to out.

function setupgpio {
    # Export gpio1_6 so we can manipulate it
    # (38 = 1 * 32 + 6)
    echo 38 > /sys/class/gpio/export
    echo out >/sys/class/gpio/gpio38/direction
}

# Set gpio1_6 so that USB cuts power to modem

function cut_usbpower {
    echo 1 >/sys/class/gpio/gpio38/value
}

# Set gpio1_6 so that USB supplies power to the modem.

function apply_usbpower {
    echo 0 >/sys/class/gpio/gpio38/value
}

cd /home/root/tcl-from-beaglebone/tcl/

setupgpio
apply_usbpower
sleep 15


while [ true ]; do

    echo "(`date`) Running beaglegsm.tcl"
    tclsh beaglegsm.tcl &>beaglegsm-tclsh.out
    echo "Beaglegsm.tcl exited. Resetting modem and restarting"

    cut_usbpower
    sleep 20
    apply_usbpower
    sleep 30
done





Rough Hand-drawn Schematic

Here's a rough schematic of my home monitor setup. The Beaglebone is the box in the middle.

At the top is the isolated USB power switch to simulate unplugging and replugging the GSM modem. A relay is used to switch power, with the normally closed contacts used, so that power is not consumed by the relay (100 ma current draw) except in the short time the relay is actuated to remove power from the modem.

At the bottom is the basic sensor circuit. Two 10K NTC thermistors measure temperature, and with the accompanying 10 K resistors result in a variable voltage fed into AIN0 and AIN1 on the Beagleboard. A/C power presence is detected by the 'wall wart' on the left, feeding an isolator (the PS2501 quad opto isolator), which feeds AIN2 on the Beagleboard. It does not attempt to measure A/C voltage, but just determines if there is any. I was lazy when I designed it and had not figured out how to configure and read gpio bits yet, so I solved it by just measuring voltage.




Sunday, May 27, 2012

The Strange World of Beaglebone GPIO

In the last post I mentioned that I was going to investigate a workaround for the problem of a non-responsive GSM modem, based on unplugging, then replugging it in, simulated by switching the +5V USB line connected to pin 1 of the USN connector. I modified a USB cable, breaking the red +5V line, and connecting and disconnecting it to simulate plugging and unplugging the GSM mode.

The results were as expected: when disconnected, the software disabled the ttyHS* ports, and reconnecting the line caused the software to reestablish them. This demonstrated we can reset the modem under program control. All that remains is to design a circuit that switched the +5V USB line under program control, using spare GPIO bits. And, of course writing software to sense when the modem is misbehaving, and toggle the +5V control bit to simulate the unplug/plug operation.

As many people have noted, managing the GPIO bits is a little complicated. Nathan Dumont has provided a good overview of the process in his blog. I followed his general instructions and wanted to quickly record what I did here.  These are some commands entered from the bash command line to control gpio1_7, which is on pin 4 of expansion connector P8. The name format gpiox_y is how the system codes bit y of gpio bank x.

Check that the multiplexer has gpio1_7 (which is called gpmc_ad7 in the mux directory and tables) set for mode7, which is a GPIO bit:

root@beaglebone:~/work# cat /sys/kernel/debug/omap_mux/gpmc_ad7
name: gpmc_ad7.gpio1_7 (0x44e1081c/0x81c = 0x0007), b NA, t NA
mode: OMAP_PIN_OUTPUT | OMAP_MUX_MODE7
signals: gpmc_ad7 | mmc1_dat7 | NA | NA | NA | NA | NA | gpio1_7





It's set right, so no need to change it.

Now, to be able to control the pin we need to write the number representing the gpio bit, computed by taking the gpio bank (1), multiplying by 32 (bits per bank) and adding the bit number (7), giving 2*32+7 = 39, to the export 'file' in  /sys/class/gpio:

root@beaglebone:~/work# echo 39 > /sys/class/gpio/export'



We want to use it as an output, so write 'out' to the 'file /sys/class/gpio/gpio39/direction:

root@beaglebone:~/work# echo out >/sys/class/gpio/gpio39/direction


Set the bit to 1:

root@beaglebone:~/work# echo 1 >/sys/class/gpio/gpio39/value

Then 0:

 root@beaglebone:~/work# echo 0 >/sys/class/gpio/gpio39/value

And when done, unexport so other programs can use it:

root@beaglebone:~/work# echo 39 > /sys/class/gpio/unexport



Thursday, May 24, 2012

Bullet-proofing the Monitor Software

There have been a number of issues regarding the Icon GSM/GPRS USB modem in the home monitor. The main two are (1) that it does not get recognized and switched to serial-port mode on power-up boot (but does on subsequent command line reboots) and (2) that it sometimes (but rarely) stops responding to sending AT commands, and must be unplugged and plugged in again (or the system must be rebooted.)

I believe I can solve both problems without having to physically unplug and replug in the modem, which is impossible when I'm away. A software way to do this eludes me at this time, and I'm running out of time, so I will try a partly hardware way to do this: by disconnecting the USB 5V power line to the modem and reconnecting it. I will use an output bit (GPIO) on the Beaglebone to switch the 5V under program control.

The idea is to set the bit set by default so as not to supply power to the modem on reboot, or initial boot up. Then, later, when I run the  monitor program I will set the bit to supply power to the modem and wait for the five devices /dev/ttyHS0-4 to appear in the file system. If this is like plugging in the modem, I should see the /dev/ttyHS0-4 devices in the file system, after the usb-modeswitch software recognizes the modem and >switches it to the serial port USB device, creating the five devices.

To recover from timeouts when the modem refuses to respond to commands while running, I will recover by turning off, then on the modem power, and proceed as on boot up to wait for the devices and open the /dev/ttyHS1 port.

Here is an outline of the program at startup:
  1. Switch power to the GSM USB modem off, then on with a 30 second delay using the GPIO bit that controls modem USB power.
  2. Wait until the five /dev/ttyHS* devices appear in the file system.
  3. Open the modem as usual and test it by issuing a plain 'AT' command.
  4. If either of these steps do not work, go back to step 1.
When we get a timeout, simply restart the program, which should go thru the steps above.

For reference, here is the pin-out for the USB cable:

Pin Name Cable color Description
1 VCC Red +5 VDC
2 D- White Data -
3 D+ Green Data +
4 GND Black Ground

Notes on Setting up Console Screen Size using 'stty'

Using PuTTY to open a console to the USB slave port on the Beaglebone (say COM20 on Windows 7), you specify to PuTTY the screen size you want, say 100 columns by 40 rows, before opening the console. Then, when logged in to the Beaglebone shell via the console, to make things like 'vi' and 'less' work right, you need to issue the stty commands:

$ stty columns 100
$ stty rows 40

Then screen-size sensitive programs like 'vi' and 'less' will work right. After resizing the screen console window (say, by dragging corners of the windows), the programs will not work correctly again until the stty commands are given with the new sizes.

Thursday, May 17, 2012

Using cron to Start Monitor Program at Boot Time

The idea is to run the tcl program beaglegsm.tcl at boot time, using tclsh of course. To do this edit the root cron entries using the 'crontab -e' command. The crontab entries for root are as follows. Note the complete path entries for program script and log files.

30 * * * *    /usr/bin/ntpdate -b -s -u pool.ntp.org
@reboot /home/root/tcl-from-beaglebone/tcl/beaglegsm.sh >/home/root/tcl-\
          from-beaglebone/tcl/cronout.log

File beaglegsm.sh:

#!/bin/sh

cd /home/root/tcl-from-beaglebone/tcl/

sleep 120

while [ true ]; do
        echo "(`date`) Running beaglegsm.tcl"
        tclsh beaglegsm.tcl &>beaglegsm-tclsh.out
        insmod /lib/modules/3.2.13/kernel/drivers/net/usb/hso.ko
        echo "Beaglegsm.tcl exited. Delaying then restarting"
        sleep 120
done



The 120 second delay is to let the modem power up and be recognized by Linux as /dev/ttyHS0-3. If the program faults (due lately to the modem somehow timing out), the insmod tries to re-establish the /dev/ttyHS- device, but this feature is experimental and will likely go away soon. 

When power is disconnected and comes back up, the modem seems not to be recognized correctly. But, after a reboot command it seems to be recognized OK. I may add a reboot text message to reboot, and also have the unit do a reboot automatically when the modem is not recognized.
 
Since the beaglebone is off the network, ntp will not set the time, and since it has no clock, time will default to something like  'Fri Apr 13 16:43:26 EDT 2012'. I will try to fix this by having the unit set time on ceceipt of the first text message, getting the time from the date message field.