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).

Buy this article as PDF

Express-Checkout as PDF
Price $2.95
(incl. VAT)

Buy Linux Magazine

SINGLE ISSUES
 
SUBSCRIPTIONS
 
TABLET & SMARTPHONE APPS
Get it on Google Play

US / Canada

Get it on Google Play

UK / Australia

Related content

comments powered by Disqus
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.

Learn More

News