个人工具

UbuntuHelp:1wireAppCountermoon.org

来自Ubuntu中文

跳转至: 导航, 搜索

Now that I've laid some groundwork explaining 1wire hardware and software, I'd like to show off my own use of that, here on my trailer-building project, http://CounterMoon.org.

Introduction

1wireAppCountermoon.org?action=AttachFile&do=get&target=dcp_0392.png The GodSail is a custom-built trailer where I intend to spend the rest of my life, on the road. I love to travel, love to compute, and love to live simple. From it's inception in 1978, the project has undergone myriad changes, from chassis selection to carpet colors. It's without question the longest project I've ever attempted. When I started I was anything but a church member, but two years ago I had an encounter with the eternal entity known as Jesus Christ and now I look at the world in a very different way. The strange circumstances that permit construction to continue are regular verification that He wants me to take the road in His service...and that I'm 'hoisting the GodSail' in creating this trailer. It's all very new and exciting to me. In 1978 there were no ATMs. In fact, there wasn't even an IBM PC. And Microsoft was a fledgling company trying to make it's mark with DOS. I dreamed of a vehicle that would take me from site to site, allowing me to work from there, programming (or whatever) and getting money 'downloaded' to me for use on the road. Needless to say, it's been interesting watching the technology creeping up towards my needs, as time goes by. I finally got the chassis of a Pace 14-foot "cargo trailer" and started designing. I taped off the floors to see where the walls would go, and spent a great deal of time dreaming about it. In 2001 when Mom fell and had a stroke, I came home from my career to take care of her, but despite going from $40,000 a year to less than $5,000, development still continued. I managed to locate the basics to continue building.

The Layout

It has three sections, fore, mid and aft. It's designed to have a very public area near the aft-mounted door, a more private area in the midsection where the queen-sized bed is, and a most-private section where the toilet and shower will be. The aft is nearly done. It has a workstation on the port (left) side, and on the starboard is a closet, toolchest, and bays for a fridge, microwave, and batteries.

The computer

1wireAppCountermoon.org?action=AttachFile&do=get&target=DCP_1997.png A computer lives in the top of the fridge bay; it's a Celeron 400 (fanless) PC running Ubuntu Dapper, with OWFS, a one-wire filesystem, and a 1wire network to various fans and voltage/current references. It's in it's infancy, but at some future point the same machine will do security, auto-leveling of the vehicle at dock-time, and things I've not yet imagined. Right now I like to vent the bays when the temperature inside gets over 80 degrees (F), and control an overhead vent I have to manually extend. I'm using Perl; not because it's a be-all, end-all language, though it's very nice, but primarily because it's easier to handle floating-point math in it, than Bash.

Sensorproc

The main software there is called sensorproc. It's a perl program that does the work. It's amazingly trivial, by comparison:

# Second attempt at controlling the 1-wire bus
#
# 07/14/07 Brian Fahrlander
#
use strict;
use warnings;

# Program setup
# Since an association between devices and their jobs is required, and
# finding them is non-trivial, we'll skip the autodetection and use
# hard-coded values anyway.

# The display buffer- 4 lines of exactly 20 characters long
our $line1 ="                   ";
our $line2 ="                   ";
our $line3 ="                   ";
our $line4 ="                   ";
our $eq_ambient;
our $eq_humidity;
our $battery_volts;

# Comfort Norms and other values initialization

# Equipment Room Values:
# One day these will be auto-configured to some degree
our $DEV_EQ_AMB=   "/var/1wire/1F.1DBC04000000/main/26.AFBBA8000000";
our $DEV_EQ_HUMID= "/var/1wire/1F.1DBC04000000/main/26.AFBBA8000000";
our $DEV_EQ_FAN=   "/var/1wire/1F.38C704000000/main/05.880032000000";
our $DEV_LCD=      "/var/1wire/1F.1DBC04000000/aux/29.128703000000";
our $DEV_VENT_FAN= "/var/1wire/1F.38C704000000/main/05.62E531000000";
our $DEV_12VV =    "/var/1wire/1F.B9C604000000/main/20.E74009000000";

# Subroutines Here

sub shutdown {
# Tell the operator what we're doing
$line1=" Shutting down...  ";
$line2="                   ";
$line3="                   ";
$line4="                   ";
&display;

# Shut down the equipment fan
putval("0", $DEV_EQ_FAN . "/PIO");

sleep(5);
lcd_clear();
exit;
}

sub lcd_clear {
  # To clear it, we use the built-in clear function
  putval("1", $DEV_LCD . "/LCD_H/clear");

  # Now, clear the buffer so re-printing it won't mess things up
  $line1="                   ";
  $line2="                   ";
  $line3="                   ";
  $line4="                   ";
}

sub display {
  # Here, we take whatever is in the buffer and shove it to the screen in
  # 80-character format.  We do this all at once because we don't have
  # control over indivudual lines.
  #
  # We also don't fiddle with the string; just send it on out.
  open (LCD, ">" . $DEV_LCD . "/LCD_H/screen");

  printf LCD  "%20s", (substr($line1, 0, 20));
  printf LCD  "%20s", (substr($line3, 0, 20));
  printf LCD  "%20s", (substr($line2, 0, 20));
  printf LCD  "%20s", (substr($line4, 0, 20));

  close LCD;
}

# Write data to a file/device
sub putval {
  my ($data, $address) = @_;
  open (HANDLE, ">" . $address);
  print HANDLE $data;
  close (HANDLE);
}

# Get value from file/device
sub getval {
  my ($address) = @_;
  open (HANDLE, "<" . $address);
  return <HANDLE>;
  close (HANDLE);
}

# Program startup
# We'll leave the fans in their current state; the program will know what
# to do with them in the main loop.

# Clear the LCD
lcd_clear;

# Trap interrupts here for shutdown
$SIG{'INT' } = 'shutdown';
$SIG{'QUIT'} = 'shutdown';
$SIG{'HUP' } = 'shutdown';
$SIG{'TRAP'} = 'shutdown';
$SIG{'ABRT'} = 'shutdown';
$SIG{'STOP'} = 'shutdown';

# Main Loop
# Here's where we do whatever needs to be done in this non-interrupt
# driven sequence of events, display them, and call display();
#
while (1) {

  ###################################################################
  # Time Display (line 1)
  ###################################################################

  # Rather than investing a year with localtime(), let's just do this
  $line1 = qx/date +'%a %b %d     %H\:%M'/;

  ######################################################################
  #  Eq temperature and reporting (line 2)
  ######################################################################


  # If the ambient temperature inside the equipment closet is > 80, turn
  # on the fan:
  $eq_ambient = getval($DEV_EQ_AMB . "/temperature");

  # Report the ambient temperature there
  $line2= sprintf("Ambient:     %.3fF", $eq_ambient);

  # Take one action or the other

  if ($eq_ambient > 80) {
    putval("1", $DEV_EQ_FAN . "/PIO");
  }
  else {
    putval("0", $DEV_EQ_FAN . "/PIO");
  }

  ######################################################################
  # Humidity is figured here
  ######################################################################
  $eq_humidity = getval($DEV_EQ_HUMID. "/humidity");
  $line3= sprintf("Humidity:     %.2f%%", $eq_humidity);

  ######################################################################
  # Battery voltage figured here
  ######################################################################
  $battery_volts = (getval($DEV_12VV . "/volt.B") * 10) +1;
  $line4= sprintf("Battery:    %f", $battery_volts);


  # Update the buffer to the screen
  display();
  sleep (3);
}

The only trick involved was the LCD, really. It's a 2x40 screen, but it displays the 80-character string as lines...and in an odd order, due to the design of the LCD alone, not OWFS or anything else. The order is line1,line3,line2,line4. A perl subroutine does this massage and the whole thing is written every time display() is called. In fact, the output looks an awful lot like this: 1wireAppCountermoon.org?action=AttachFile&do=get&target=DCP_1992.png That's the time/date on the top line, the temperature of the bay (F), the humidity of that section, followed by the battery voltage. The computer takes some minimal steps when the power gets low, but again, this is just an infant of the future system. I really get jazzed watching the numbers change; I'm such a kid!

Pictures

It's kinda hard to relate where this unit is; it's near the ceiling, inside something that looks a lot like a closet. The black frame is the control panel which gets a re-vamp as soon as I can locate the proper photographic background to put under the plexiglas. Later, a navy-blue vinyl covered door will fit into this space, and around the small fridge, and everything gray will be hidden from view. 1wireAppCountermoon.org?action=AttachFile&do=get&target=DCP_1997.png It's possible one day you just might see this unit in person. Be sure to knock and say hello! 1wireAppCountermoon.org?action=AttachFile&do=get&target=dcp_0400.png See also: 1wire 1wireHardware 1wireSoftware