#!/usr/bin/python
"""This utility reads the serial port data from the
RadioShack Digital Multimeter 22-812
and translates it into human-readable output.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
Copyright 2006,2008 Eli Carter, retracile@gmail.com
"""
import sys
import time
import termios
# The elements of each LCD digit are labeled as A-G and the PERIOD:
# A
# --
# F | | B
# -- G
# E | | C
# . --
# P D
# Those map to the bits in a byte:
A = 1 << 0
B = 1 << 4
C = 1 << 6
D = 1 << 7
E = 1 << 2
F = 1 << 1
G = 1 << 5
# Characters marked as "speculation" are combinations I have not seen used by
# the multimeter, but I have added to avoid "?" output if that combination does
# get used in some case.
byte_digit_mapping = {
0: " ",
B+C: "1",
A+B+G+E+D: "2",
A+B+G+C+D: "3",
F+G+B+C: "4",
A+F+G+C+D: "5", # Doubles as "S"
A+F+G+E+D+C: "6",
A+B+C: "7",
A+B+C+D+E+F+G: "8",
A+B+C+D+F+G: "9",
A+B+C+D+E+F: "0", # Doubles as "O"
G: "-",
A+F+E+G+B+C: "A", # speculation
F+G+C+D+E: "b", # speculation
A+F+E+C: "C",
E+G+B+C+D: "d", # speculation
A+F+G+E+D: "E",
A+F+G+E: "F",
A+F+E+D+C: "G", # speculation
F+E+G+C: "h",
F+B+G+E+C: "H", # speculation
C: "i", # speculation
B+C+D: "J", # speculation
F+E+D: "L",
E+G+C: "n",
E+G+C+D: "o",
F+E+A+B+G: "P",
E+G: "r",
F+G+E+D: "t",
E+D+C: "u", # speculation
F+E+D+C+B: "U", # speculation
}
def byte_to_digit(b):
"""Interpret the LCD elements into something meaningful such as digits and
letters.
"""
PERIOD = 1 << 3
# The period comes before the digit
if b & PERIOD: # decimal?
digit = "."
else:
digit = ""
try:
# Mask out the decimal point indicator
digit += byte_digit_mapping[b & ~PERIOD]
except KeyError:
# TODO: it might be helpful to say which elements were lit...
digit += "?"
return digit
class BitMapper:
"""Given a byte of output, provide a string of lit LCD elements."""
def __init__(self, mapping):
self.mapping = mapping
def __call__(self, value):
# Each bit of the given value represents the item in the mapping list;
# return a string
output = []
for i in range(8):
if value & (1<