A good cents exit survey
Display Class
In Python, a class is a group of functions and variables that operate as a set. When a class is created, it is an independent copy that starts with all of the default values of the prototype; then, each copy can be customized as needed. In Listing 2, I use the display
class to talk to the LCD display. Instead of having to remember all of the hex codes to control the display each time, I can use human-friendly terms (e.g., clear
and write
), which make a lot more sense than something like 0xFE 0X01 0x7C 128
.
Listing 2
The display Class
The __init__
function in Listing 2 is called automatically when the class is created. You can do all of your setup here. Notice that all the lines start with self.
; by default, variables in Python are contained within their parent function. Once you exit the function those variables cease to exist, so self
stores the variables inside the class instead of the function; in this way, other members of the class can access the same values.
The clear
, position
, backlightOn
, and backlightOff
LCD control functions (Listing 2) work identically, but the data itself is modified for each function. The hex value 0xFE
indicates a control command and 0x7C
indicates a backlight command.
The clear
command, which clears the display and resets the position to 0,0 (upper left of the display), is hex 0x01
. The position
command (where to place the cursor) takes the row
and column
arguments and calculates the corresponding position. (See the "LCD Display Mapping" box for more information.) On lines 22 and 27, I send either a 157
(backlight on) or 128
(backlight off) for the corresponding action.
LCD Display Mapping
The HD44780 LCD driver chip is generically able to control many configurations of text-based LCD displays (up to 80 characters). Specific addresses in the display RAM are mapped to character cells in the display itself. Writing an ASCII-encoded character into the display memory causes that ASCII character to display immediately. However a gap in the end of the first line and the beginning of the second line explains the 64-byte difference (line 17) in the addresses of the first and second lines of 40 bytes each.
All of the functions end with time.sleep ( self.delay )
, which pauses the program for the sleep duration defined on line 5 and gives the LCD enough time to catch up and be ready for the next command.
The write
function displays text on the LCD and sends string
out the UART. Without any preceding control characters, the display interprets the string as text to be displayed.
Menu Class
The menu
class holds all of the major code that allows the Penny Counter to function properly. It integrates the LCD display, the slot sensors, and the buttons that form the user interface.
Listing 3 initializes the menuItems
list that will become the menu descriptions displayed as the user scrolls through and creates each entry with append
. The self.menuIndex
holds the menu item currently being displayed. Initializing it to 0
starts with assigning the show for which the pennies are to be counted.
Listing 3
Menu Items
Lines 14-17 set a couple of default values that are updated as selections are made in the menu. The time values will be used to build the display strings.
Lines 19-24 set up another Python list to monitor the slot sensors. After creating the list on line 19, I add five zeros, which increments repeatedly when the slot sensor is blocked (i.e., a penny is stuck in the slot).
Listing 4 sets up the GPIO to monitor the slot sensors and user interface buttons. Lines 1-5 define the GPIO pins to which each sensor is attached; then, line 7 sets the numbering mode of the GPIO pins. Lines 8-12 configure each pin with GPIO.setup
, which takes three arguments: the GPIO pin of interest, the direction of pin traffic (GPIO.IN
defines it as an input), and whether it is a pull-up or pull-down resistor (pull_up_down=GPIO.PUD_UP
specifies a pull-up resistor connected to the input). These settings are the electrical equivalent of a default value. In the absence of an external signal, the input will read as high, or logic 1.
Listing 4
Setting Up the GPIO
For the user interface buttons, lines 14-18 mirror lines 1-5, and lines 20-24 mirror lines 8-12 for the slot sensors.
Finally, lines 26 and 27 initialize the user interface so that button presses are processed relative to the main menu and update the LCD display to reflect any changes made with button presses (or the initial menu).
Counting Pennies
The countPennies
function (Listing 5) monitors the slot detectors and increments the counts whenever a penny is deposited into the counter. Each block of code is identical, except for the slot number and associated indexes, so I'll just describe the first one.
Listing 5
countPennies
First, I check to see whether the sensor is currently blocked by a penny (line 2). GPIO.input
returns 1
for clear or 0
for blocked. I also check self.slotSeen
. If this is not 0
, then I've already seen this penny. Assuming both values are 0
, I process the count.
On line 3, I increment the counter by one; on line 4, I assign self.slotSeen
the value 300
; then, I increment self.slotReset
(line 5). I set it to 300
based on experimentation with the hardware. This is how long (in loop iterations) to ignore the slot once any given penny has been detected. This is the time for the penny to pass through the slot. Just like any switch or detector it will bounce momentarily as the penny enters (and leaves) the slot. The penny is counted when initially detected and then all fluctuations are ignored until the penny has passed completely through. Then it's ready for the next penny to repeat the process. Finally, if the menu item currently being displayed is 3
, I call self.showCount
to update the display with the current counts (line 6).
If either condition from the if
on line 2 wasn't 0
, I clear self.slotReset
on line 7. If this number gets too high, the counter assumes a penny is stuck and alerts the operator.
Lines 37-41 check to see that each slot sensor is clear (returning 1
). If so, the associated self.slotReset
is reset to 0
; however, if the return value is greater than 5
, self.stuck()
is called (lines 43-47).
« Previous 1 2 3 4 Next »
Buy this article as PDF
(incl. VAT)
Buy Linux Magazine
Subscribe to our Linux Newsletters
Find Linux and Open Source Jobs
Subscribe to our ADMIN Newsletters
Support Our Work
Linux Magazine content is made possible with support from readers like you. Please consider contributing when you’ve found an article to be beneficial.
News
-
Canonical Releases Ubuntu 24.04
After a brief pause because of the XZ vulnerability, Ubuntu 24.04 is now available for install.
-
Linux Servers Targeted by Akira Ransomware
A group of bad actors who have already extorted $42 million have their sights set on the Linux platform.
-
TUXEDO Computers Unveils Linux Laptop Featuring AMD Ryzen CPU
This latest release is the first laptop to include the new CPU from Ryzen and Linux preinstalled.
-
XZ Gets the All-Clear
The back door xz vulnerability has been officially reverted for Fedora 40 and versions 38 and 39 were never affected.
-
Canonical Collaborates with Qualcomm on New Venture
This new joint effort is geared toward bringing Ubuntu and Ubuntu Core to Qualcomm-powered devices.
-
Kodi 21.0 Open-Source Entertainment Hub Released
After a year of development, the award-winning Kodi cross-platform, media center software is now available with many new additions and improvements.
-
Linux Usage Increases in Two Key Areas
If market share is your thing, you'll be happy to know that Linux is on the rise in two areas that, if they keep climbing, could have serious meaning for Linux's future.
-
Vulnerability Discovered in xz Libraries
An urgent alert for Fedora 40 has been posted and users should pay attention.
-
Canonical Bumps LTS Support to 12 years
If you're worried that your Ubuntu LTS release won't be supported long enough to last, Canonical has a surprise for you in the form of 12 years of security coverage.
-
Fedora 40 Beta Released Soon
With the official release of Fedora 40 coming in April, it's almost time to download the beta and see what's new.