Sunday, February 24, 2013

Database for Home Monitor: sqlite3 on Raspberry Pi

Thinking a database would be preferable to simple files for storing monitor-specific data, I installed it using sudo apt-get install sqlite3. I'm now trying the command line shell:


pi@raspberrypi ~ $ sqlite3
SQLite version 3.7.13 2012-06-11 02:05:22
Enter ".help" for instructions
Enter SQL statements terminated with a ";"
sqlite> 

Logitech USB Video Camera on Raspberry Pi

Yesterday I connected my Logitech, Inc. Webcam C210 USB camera to my Raspi, and after installing fswebcam (sudo apt-get install fswebcam) the camera was fully operational and would record pictures as required:



To make it more useful in home monitoring, I installed motion, which runs the camera unattended, noticing motion in the picture and taking different user-configurable actions, like recording frames and running user-specified scripts, when it does.

Although I can't send pictures as text messages (yet, you need a data plan which I don't have) with my GSM modem, I can send events I've set the motion program up to notice, so it might be useful.

Adding tcllib to Raspberry Pi

Eventually I hope to change over to Javascript using nodejs, but until then I need to run my existing software, written in Tcl and for this I had to install tcllib1.14. Tcl/Tk was already installed in my drop of raspian. Tcllib is a library of very handy packages written in pure Tcl.

I downloaded the library from http://sourceforge.net/projects/tcllib/files/tcllib/1.14/

I moved it to the Pi using sftp (WinSCP)  from my Windows 7 computer. The Pi has an sftp daemon running by default.

I also moved the latest drop of my software to the Pi from Dropbox/Beaglebone-monitor/BeagleboneBackup.

I gunzipped and tar'ed it, and from the tarred directory did a ./configure and make install.

Make takes a while as it generates lots of man files. (In fact its still going as I write this.)

To be continued....

New Raspberry Pi Home Monitor Approach

I have lax in working with the Raspi lately (but the beaglebone monitor has been working flawlessly for a month now in Maryland) so I started experimenting with configuring the Raspi differently than beaglebone to do the monitoring job.

With beaglebone I wrote one large Tcl program that ran almost as a daemon (it was actually started at boot time via cron @reboot and kept running) that did everything from data gathering (temperature, A/C power status, etc.) to sending SMS messages. When the modem acted up as mentioned in previous posts, the beaglebone watchdog timer would cause the system to reboot. Part of the reboot process involved resetting the modem by power cycling the USB +5V line to circumvent certain problems specific to this modem.

The central concept of the new approach is to implement home monitoring functions in a more "Unix-like" way by using multiple small programs (commands) run in combination as processes to get larger jobs done. Additionally, I am shifting to the use of cron to provide time-dependent behavior on the minute-day-week-month time scale instead of building a single large program that runs continually as a daemon. The programs can be written in multiple different languages, but I plan to use multi-platform scripting languages like Tcl, javascript, shell script, perl, python wherever possible.

The most critical component in the monitor is the GSM modem used for all communications with the outside world, since I want it to be useful in remote locations where internet is unavailable but cell coverage is. So this component and its software have to be very reliable.

All interfacing with the GSM modem is done through a fairly small Tcl program I wrote (currently called gsm.)  gsm is invoked with arguments for reading and sending SMS (text) messages, and obtaining and controlling the state of the modem. Confining the modem interface to this one program designed to do one thing well makes it small so I can analyse and thoroughly test it, making it more reliable. In the home monitor gsm is run when needed, such as when an SMS is to be sent, and it opens, operates, then closes the modem each time cleanly. Having only one program run the modem makes it possible to rewrite it in different languages and refine and test it separately from the rest of the system.

With this approach a simple home monitoring system can be as simple as a cron job that periodically runs a shell script which, via different helper programs like gsm, gathers household data, tests it for various conditions and sends SMS messages when appropriate using gsm.

For example here is a script called periodically by cron to tweet house status. I've commented out sections that actually gather data and handle incoming text messages for testing purposes. In addition I've embedded calls to gsm in the handledata.tcl program in the form of running gsm as a process:


#!/bin/bash

# Name
#     monitor-cron.sh - Shell script version of home monitor - experimental

# Usage
#     Run as cron job
#
# Idea is to use multiple dedicated programs in series,
# using gsm Tcl program to perform all GSM modem functions,
# like sending and receiving SMS text messages. Series programs
# communicate via files.

cd /home/pi/gsm-monitor/CommandLine

# Get data to report on and put in data.txt
#./getdata.tcl >data.txt

# Handle house data

# ./handledata <data.txt

# Get all new SMS messgaes from modem and put in messages.txt
./gsm listall >messages.txt

# Also catenate to database
cat messages.txt >>mdatabase.txt

# Erase read messages from modem
./gsm eraseread

# Process received messages
#./handlesms.tcl <messages.txt

# Now, tweet something...

./gsm tweet "House monitor reporting on `date`" >>monitor.output.txt



Here's the crontab to run it every 1/2 hour on the 22nd and 23rd of February (I wanted to have it only run a couple of days this month):



# Edit this file to introduce tasks to be run by cron.
#
# Each task to run has to be defined through a single line
# indicating with different fields when the task will be run
# and what command to run for the task
#
# To define the time you can provide concrete values for
# minute (m), hour (h), day of month (dom), month (mon),
# and day of week (dow) or use '*' in these fields (for 'any').
#
# Notice that tasks will be started based on the cron's system
# daemon's notion of time and timezones.
#
# Output of the crontab jobs (including errors) is sent through
# email to the user the crontab file belongs to (unless redirected).
#
# For example, you can run a backup of all your user accounts
# at 5 a.m every week with:
# 0 5 * * 1 tar -zcf /var/backups/home.tgz /home/
#
# For more information see the manual pages of crontab(5) and cron(8)
#
# Run the monitor to report (null data at this time) every 30 minutes
# just today (Feb 23, 2013) and tomorrow costing $0.02 per hour
# at $0.01 per text message with my AT&T 1000 SMS for $10 pckage:
#

# m  h  dom   mon dow   command


*/30 *  23,24 2   *     ./monitor-cron.sh







Saturday, February 2, 2013

Nokia CS 12 GSM Modem Quick Notes

To test the Raspberry Pi as a text (SMS) message device for home monitoring I bought a used Nokia CS-12 USB GSM modem and a gophone SIM card via Amazon.

I set up the SIM card account using AT&T's web pages, setting up an account and buying a 1000 SMS message package for $10.

Windows 7

To use it in Windows 7 I ran the install program on the USB modem. It appeared as a serial device (com21) when plugged in, and communication could be had via putty. Some stuff id different from the Option Icon modem, mainly there is no way I could find to get the ICCID number from the SIM card using 'AT' commands.

Ubuntu

On Ubuntu the modem did not get handled by usb_modeswitch so no /dev/tty* entries were created for use in communicating with it. After some hours of frustration I downloaded the new version (1.2.5) of the program and did a make install, which failed because usb.h was missing. So I did an 'sudo apt-get install libusb-dev' to get a new library and that fixed the install. After the install, plugging in the modem resulted in devices /dev/ttyACM0 and /dev/ttyACM1.

A quick test using 'screen' ('screen /dev/ttyACM0') to connect to the modem as a serial device was successful (a few 'AT' commands worked as expected.)

Raspberry Pi


Download program:

$ sudo apt-get install usb-modeswitch

Add lines to usb rules file: /lib/udev/rules.d/40-usb_modeswitch.rules:

# Nokia CS-12  zouck 2/1/2013
ATTRS{idVendor}=="0421", ATTRS{idProduct}=="0618", RUN+="usb_modeswitch '%b/%k'"


Add file named 0421:0618 to /usr/share/usb_modeswitch. This can be a copy of the file 0421:0610 with 0610 changed to 0618. The same mode change string seems to work fine:


File 0421:0618:


# Nokia CS-12

DefaultVendor=  0x0421
DefaultProduct= 0x0618

TargetVendor=  0x0421
# Changed this from 0618 due to debug output indicating resulting target product
# is 0619.
TargetProduct= 0x0619

MessageContent="5553424312345678000000000000061b000000020000000000000000000000"



Turn on debugging by setting config file line in /etc/usb_modeswitch.conf:

...

# Enable logging (results in a extensive report file in /var/log, named
# "usb_modeswitch_<interface-name>" and probably others

EnableLogging=1
...

Log will be in file:

/var/log/usb_modeswitch_1-1.3.3:1.0

The log says the modeswitch may have failed, but it seemed to create the right /dev/ttyACM0 and 1 files and they seemed to work.

I used minicom from the command line on the Raspberry Pi to communicate AT commands to the modem:

$ minicom /dev/ttyACM0

Welcome to minicom 2.6.1

OPTIONS: I18n 
Compiled on Apr 28 2012, 19:24:31.
Port /dev/ttyACM0

Press CTRL-A Z for help on special keys

at
OK






Wednesday, January 30, 2013

Watchdog timer for Raspberry Pi

Just a quick note: I set up the watchdog timer facility on the Raspberry Pi this evening following the directions at http://raspberrypi.stackexchange.com/questions/1401/how-do-i-hard-reset-a-raspberry-pi pretty much verbatim. Here's an excerpt from the blog, signature at end:



You can use the BCM2708's hardware watchdog.
To use it begin by loading the module:
sudo modprobe bcm2708_wdog
Then edit the /etc/modules file:
sudo nano /etc/modules
and add the following line:
bcm2708_wdog
Next you will need to setup the watchdog daemon.
Install and confiigure it to start on bootup:
sudo apt-get install watchdog chkconfig
chkconfig watchdog on
sudo /etc/init.d/watchdog start
Next configure watchdog:
sudo nano /etc/watchdog.conf
# Uncomment the line watchdog-device = /dev/watchdog
The watchdog daemon will send /dev/watchdog a heartbeat every 10 seconds. If /dev/watchdog does not receive this signal it will restart your Raspberry Pi.



The daemon monitors the state of various things defined in the file /etc/watchdog.conf, including the existence of several files,  successful pings, etc. and stops signaling the watchdog timer if they don't exist, which resets the Raspberry Pi.

Thursday, January 24, 2013

New Raspbian “wheezy” installed on 8 GB SanDisk SDHC card

I obtained an 8 GB SD card and downloaded and installed using windows 7 a later drop of wheezy (2012-12-16-wheezy-raspbian.zip) on it using Win32DiskImager.

After booting I had to download and install avahi-daemon ('sudo apt-get install avahi-daemon') as before, but unlike with the previous version first I had update using 'apt-get update' due to some daemon libraries being missing.

Remote logins to the pi account were blocked due to a host key problem in the Pi. Here's the error message:


john@john-ThinkPad-T42:~$ ssh pi@raspberrypi.local
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@    WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!     @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
Someone could be eavesdropping on you right now (man-in-the-middle attack)!
It is also possible that a host key has just been changed.
The fingerprint for the ECDSA key sent by the remote host is
d4:21:93:57:3e:18:79:9f:d3:f4:99:00:9a:c1:fe:59.
Please contact your system administrator.
Add correct host key in /home/john/.ssh/known_hosts to get rid of this message.
Offending ECDSA key in /home/john/.ssh/known_hosts:12
  remove with: ssh-keygen -f "/home/john/.ssh/known_hosts" -R raspberrypi.local
ECDSA host key for raspberrypi.local has changed and you have requested strict checking.
Host key verification failed.
john@john-ThinkPad-T42:~$ ^C



The new version has no root account, so privileged operations require sudo, which the 'pi' user has the ability to use.

I used raspi-config to change the keyboard to the 104 key pc style and expand the disk partition to the full 8 GB available on the SD card. 

The new version also shows the full 512 MB of ram, unlike the previous version.

Tuesday, January 22, 2013

Raspberry Pi Received

I just got a Raspberry Pi, model B, and am trying some stuff. The idea is to use it instead of the Beaglebone in a less expensive home monitor.

I received from MCM Electronics Inc a "Raspberry Pi cased product", which is a Pi in a clear plastic case, a 4 GB SD card with Debian 6 for Linux already installed, and a 5V 1A power adapter with a micro USB connector. Total including shipping was $76.80.

I had an HP LCD monitor with an HDMI cable, a USB mouse and a USB keyboard.

I simply connected these to the Pi, powered it on, and it booted to a text-based shell. Running startx brought up the windowing system.

I had a wireless adapter with an ethernet cable, and after connecting this to to Pi ethernet jack I had to do an ifup command to eth0 to bring up the network (only the first time, however.)

So, the board had access to the network, but addressing it (for ssh use) required knowing its IP address. the ifconfig command provided that, and I could ssh to it.

Zero config allows addressing it using local names like raspberrypi.local, and it seems that avahi-daemon was not installed. So I did apt-get install avahi-daemon to get it, and that seemed to install and run the daemon:

$ sudo apt-get install avahi-daemon

The network name is raspberrypi.local. From another computer, such as my laptop running Ubuntu, you can log on to the board thusly:

$ ssh pi@raspberrypi.local

The pi password is raspberry.

The next thing was to get the host-based javascript engine node.js running, since I'd like to program in javascript. (My monitor software is currently written in tcl, which comes preinstalled on the Pi, but I plan to transition to javascript.) There is a package for node:

$ sudo apt-get install nodejs

After installing node, I wrote the standard web server using the http module, and ran it:

$ nodejs webserver.js

Server running at http://raspberrypi.local:1337/

webserver.js:

var http = require('http');
var counter = 0;
http.createServer(function (req, res) {
  counter = counter + 1;
  res.writeHead(200, {'Content-Type': 'text/plain'});
  res.end('From Raspberry pi for the ' + counter + ' time: Hello World\n');
}).listen(1337);
console.log('Server running at http://raspberrypi.local:1337/');

The next job will be to install the usb-modeswitch software so I can run the USB GSM modem as a serial device (HSO.) I don't have a modem here, since I am in New Hampshire and the modem is doing its job back in Maryland, so I'll delay installing that software until I get a modem and sim card to play with.


Wednesday, November 21, 2012

Watchdog timer again

The last post outlined a code change that pinged a watchdog timer periodically so that when the program hung the system would reboot. That has been working well so far.

However, it also allowed the system to be reset/rebooted via a command, which I was unable to do via any previously known method. Simply put, to reset the board, while the /dev/watchdog file is still open, simply delay for more than the timer timeout period (about 60 seconds.) The timer will go off and cause a board reset.

I added a command, sent via a text message, that causes just this timeout and subsequent reset/reboot. So, now I can reset/reboot the board by simply sending that command.

Monday, November 5, 2012

Further Bullet Proofing: watchdog timer

Having implemented the previously described circuit and associated code to reset the GSM modem via a USB power cycle when communications with it shut down, there were still occasions when the beaglebone board would lock up, and cease further communications with either the network or the USB-based terminal gadget.

So, I decided that a watchdog timer would provide a last line defense against this sort of "crash." The beaglebone has a special watchdog timer that can be used for just this purpose. When the file /dev/watchdog is open, absence of a write to it for more then about one minute will cause the entire board to reset and reboot.

I added code to beagelgsm.tcl that opened the file just after startup, and then wrote to it once each main loop, which seemed from inspection to provide much more frequent writes than required to keep the watchdog timer from timing out and resetting the board. I added code to measure loop time and log any times greater than about 30 seconds, to get a sense of what the loop times were.

The system is now up and running, as of about 6 PM November 5, 2012.

Tuesday, August 14, 2012

Beaglebone Analog Input read() results in 4 bytes

After writing some C code to read the analog inputs, it became clear that reading analog inputs via the file system (.../ain1, etc.), the system returns 4 bytes for each read. The bytes are the ASCII characters for the digits 0-9 (values got from 0-4095), and if the reading is less than 4 digits, the byte = \x00 is placed in trailing locations. The \x00 byte is the string terminator for C, and is not present for readings that are 4 digits long. This could explain why channels shift when reading the analog values via Tcl reads: the area the 4-byte value is read into might not have a string terminator.

So, the technique is to read into a buffer of 5 or more bytes, then make sure the 5th byte is a \x00 by either setting the whole area to \x00 first or storing \x00 there after the read, then the C string will be properly terminated.

Friday, August 10, 2012

Recoding Analog and GSM Modem drivers in C

I have referred to problems with the analog inputs shifting channels and GSM modem hangups often in the blog. Since I've been coding in Tcl, I thought that it might be hiding some behavior or data behind its own layer of software. To investigate this I recoded the analog input and GSM modem interface in C language. Since I've done so I've not seen any problems, but then I've only written test programs. I still need to rewrite the bulk of the monitor in C.

I've been off doing other stuff here in New Hampshire and will not be back to this for a week or so. More then hopefully.

Monday, July 23, 2012

Very strange Beaglebone analog input behavior

As mentioned some time ago, the analog channels seem to shift with time. The input connected to channel 3 (ain3) for instance shifts to ain4 after some time (maybe days.) Rebooting the beaglebone seems to restore correct operation. This shifting makes the board analog inputs worthless for reading sensors, due to the unreliability.

I tried various workarounds, and the latest is to read each channel twice in a row, separated by an 'lseek()' on the channel. It works so far.

Here's the code (tcl) for a library with two functions that read 7 analog inputs, returning either raw bits (0-4095) or voltages (0-1.8V):


;# Read 7 analog inputs of beaglebone board and
;# return as either list of 8 decimal values as voltages,
;# or list of raw bit values from 0-4095.
;# Note pin on P9 vs ain* and return list index correspondence:
;#
;# 0 ain1  Not connected to pin
;# 1 ain2  P9-39
;# 2 ain3  P9-40
;# 3 ain4  p9-37
;# 4 ain5  p9-38
;# 5 ain6  p9-33
;# 6 ain7  p9-36
;#...

package provide beagleio 0.1
namespace eval beagleio {

    variable initialized 0
    variable fds

    # Open all analog 'channels' (actually files in Angstrom)

    proc init {} {
        variable fds
        for {set i 1} {$i < 7} {incr i} {
            set fds($i) [open /sys/devices/platform/tsc/ain$i r]
        }
    }

    proc beaglearead_v {} {
        variable fds
        variable initialized
        if {$initialized == 0} {
            beagleio::init
            set initialized 1
        }
        set vl {}
        for {set i 1} {$i < 7} {incr i} {
            ;# Who the hell knows why we need to do this twice to read the right channel
            ;# consistently? But we do...
            seek $fds($i) 0
            set val [read $fds($i)]
            seek $fds($i) 0
            set val [read $fds($i)]
            ;#puts "Debug: beaglearead_b: read (length [string length $val]) value $val from channel $i"
            ;# delete characters = 0x0 ,since these get sent back when analog file is read.
            regexp {(\d+)} $val all val
            ;#puts "Debug: beaglearead_b: modified value (length [string length $val]) is $val from channel $i"
            ;# Convert to voltages: 0-4095 full scale = 1.8 volts.
            lappend vl [format %6.3f [expr 1.8 * $val/4096]]
        }
        return $vl
    }
    proc beaglearead_b {} {
        variable fds
        variable initialized
        if {$initialized == 0} {
            beagleio::init
            set initialized 1
        }
        set vl {}
        for {set i 1} {$i < 7} {incr i} {
            # Who the hell knows why we need to do this twice to read the right channel
            # consistently? But we do...
            seek $fds($i) 0
            set val [read $fds($i)]
            seek $fds($i) 0
            set val [read $fds($i)]
            #puts "Debug: beaglearead_b: read (length [string length $val]) value $val from channel $i"
            ;# delete characters = 0x0 ,since these get sent back when analog file is read.
            regexp {(\d+)} $val all value
            ;#regsub -all {\x000} $val {} val
            ;#puts "Debug: beaglearead_b: modified value (length [string length $val]) is $val from channel $i"
            lappend vl $value
        }
        return $vl
    }
}


Tuesday, July 17, 2012

Connecting to Beaglebone USB Serial port from Ubuntu


Open a Ubuntu termial window, resize it to whatever you want it to be while logged on to the Beaglebone, find the LINES and COLUMNS ($ echo $LINES $COLUMNS) and remember them, then run screen command to get connection to Beaglebone USB serial port:

john@john-ThinkPad-T42:~$ screen /dev/ttyUSB1 115200
.---O---.                                          
|       |                  .-.           o o       
|   |   |-----.-----.-----.| |   .----..-----.-----.
|       |     | __  |  ---'| '--.|  .-'|     |     |
|   |   |  |  |     |---  ||  --'|  |  |  '  | | | |
'---'---'--'--'--.  |-----''----''--'  '-----'-'-'-'
                -'  |
                '---'

The Angstrom Distribution beaglebone ttyO0

Angstrom v2012.03-core - Kernel 3.2.13

beaglebone login: 


After logging on, run the 'stty' command to set lines and columns, like:


$ stty rows 30
$ stty columns 109 


When logging on using ssh, if Beaglebone is on the network, the stty commands are unnecessary. BTW, I use and Asus portable wireless access point connected to the Beaglebone ethernet connector to get on the net.

Wednesday, July 4, 2012

Upgrade notes

Problems with reading analog channels consistently made the current system unreliable. So, I tried a new Angstrom drop (dated June 18th, 2012.) That did not work due to GSM modem (/dev/ttyHS*) problems, whereby the system somehow kept doing something to the Icon modem keeping it from registering with AT&T. The new drop was:

Angstrom-Cloud9-IDE-GNOME-eglibc-ipk-v2012.05-beaglebone-2012.06.18.img.xz

So, I decided to just try upgrading the current system. I copied an image of the current working system from the 4GB microSD card to a new card (using linux 'dd if=/dev/sdb of=/dev/sdc', where /dev/sdb is the original microsd card and /dev/sdc is the new fresh card) , then tried doing 'opkg update', 'opkg upgrade' with the new microsd card copy. I moved the new kernel (3.2.14) to the right place as discussed in this blog previously. Then I installed from ipk files tcl, tcllib and modeswitch. Modeswitch install  failed due to problems with the names of perl package files, so I added perl package links:

ln -s /var/lib/opkg/info/perl-module-build.list /var/lib/opkg/info/perl-module-build.pm.list
ln -s /var/lib/opkg/info/perl-module-load.list /var/lib/opkg/info/perl-module-load.pm.list


which made the modeswitch opkg install of modeswitch work.
 

After all that, the analog channel shifting seems to still be a problem. So, on the hunch that a delay was needed between reading channels I added 0.1 seconds in the loop that reads channels. We will see how this turns out.


Later: Badly. Problem still there. Channel 1 is at ain1 at first, then ain2 later.  So, on the hunch that the problem had something to do with the files descriptor pointer, I tried doing a 'seek()' to rewind file and that has worked so far.

Wednesday, June 6, 2012

Why am I bothering to Blog this?

I sometimes ask myself this question, since there are few readers other than myself, and writing it takes some energy. Is it wasted? The answer no.  It's a way of documenting what I've done for my own future reference, and at the same time makes it possible for others to comment or add to the conversation and/or design. I really believe in documenting stuff so I can go back and reproduce what I've done. I could write this in a google document, but a web log is really easier, since it date stamps stuff, and makes it public at the same time. I've nothing to sell, so don't expect to see fancy writing promoting a product here.

Hope that helps fill in the background.

Still running after all these days

I haven't actually done anything with the Beaglebone monitor, except to start laying out a PC board to contain the relatively simple circuitry that feeds two NTC thermistors, a powerline indicator, and a switch to allow the program via a GPIO bit to connect and disconnect the Icon modem from the USB bus to circumvent software/hardware modem problems.

The system is still running and tweeting status. Follow @zouckhome to see what it's sending. It has not restarted due to a timeout in 7 days. I'm sort fo looking forward to when it times out and restarts so I can see if that still works.

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.