Make a counter

RP2040 based microcontroller boards running MicroPython.
Target audience: MicroPython users with an RP2040 boards.
This does not include conventional Linux-based Raspberry Pi boards.
Post Reply
james_saunders2
Posts: 5
Joined: Wed Jun 09, 2021 1:14 pm

Make a counter

Post by james_saunders2 » Wed Jun 09, 2021 1:22 pm

Hi, I'm new to micropython and the pi pico board, but I'm developing activities for students using basic components, a pi pico and Thonny.
I'm trying to develop a programme that essentially uses a single-digit 7-segment display to count to 5 from 0, and have attached my code so far which works but would like some suggestions on how to make this programme take up fewer lines. Also... is it possible to define the functions for all the numbers in a separate file and then call them in my final counter script?
Apologies if this doesn't make sense - very new to it all!

Code: Select all

import machine
import utime

#The next 8 lines of code assigns each LED to the correct pin on the pico board
dp = machine.Pin(16, machine.Pin.OUT) 
a = machine.Pin(0, machine.Pin.OUT)
b = machine.Pin(1, machine.Pin.OUT)
c = machine.Pin(2, machine.Pin.OUT)
d = machine.Pin(3, machine.Pin.OUT)
e = machine.Pin(4, machine.Pin.OUT)
f = machine.Pin(5, machine.Pin.OUT)
g = machine.Pin(6, machine.Pin.OUT)

def off(): # defines a function for the off state
    # this allows the code to reset the display between each number
    a.value(0)
    b.value(0)
    c.value(0)
    d.value(0)
    e.value(0)
    f.value(0)
    g.value(0)
    dp.value(0)

def zero(): # defines the zero state
    a.value(1)
    b.value(1)
    c.value(1)
    d.value(1)
    e.value(1)
    f.value(1)
    
def one():
    b.value(1)
    c.value(1)

def two():
    a.value(1)
    b.value(1)
    g.value(1)
    e.value(1)
    d.value(1)
    
def three():
    a.value(1)
    b.value(1)
    g.value(1)
    c.value(1)
    d.value(1)
    
def four():
    b.value(1)
    g.value(1)
    f.value(1)
    c.value(1)
    
def five():
    a.value(1)
    f.value(1)
    g.value(1)
    c.value(1)
    d.value(1)
    
off()    
zero()
utime.sleep(1)
off()
one()
utime.sleep(1)
off()
two()
utime.sleep(1)
off()
three()
utime.sleep(1)
off()
four()
utime.sleep(1)
off()
five()

hippy
Posts: 130
Joined: Sat Feb 20, 2021 2:46 pm
Location: UK

Re: Make a counter

Post by hippy » Wed Jun 09, 2021 2:30 pm

One option for minimising lines of code is to define your segment mappings as bits in a byte ...

Code: Select all

from machine import Pin

out = [None] * 8
for n in range(7):
  out[n] = Pin(n, Pin.OUT)
out[7] = Pin(16, Pin.OUT)

def Output(bits):
  for n in range(8):
    out[n].value((bits >> n) & 1)

#                       .GFEDCBA
def Off()   : Output(0b_00000000)
def Zero()  : Output(0b_00111111)
def One()   : Output(0b_00000110)
def Two()   : Output(0b_01011011)
def Three() : Output(0b_01001111)
etc

james_saunders2
Posts: 5
Joined: Wed Jun 09, 2021 1:14 pm

Re: Make a counter

Post by james_saunders2 » Fri Jun 11, 2021 9:28 am

Hi, so I used your suggestion for the counter code. Thanks!
I'm now trying to work out a way to assign the various functions to one matrix so that I can call each successive function at a specific time, e.g. when a button is pressed. I tried the following:

Code: Select all

from machine import Pin
import utime
#            A   G   F   E   D   C   B   DP
GPIO_pins = [16, 15, 17, 18, 19, 13, 12, 14]
out = [None] * 8
for n in range(8):
  out[n] = Pin(GPIO_pins[n], Pin.OUT)
print(out)

def Output(bits):
  for n in range(8):
    out[n].value((bits >> n) & 1)

#                        AGFEDCB.
def Off()    : Output(0b_00000000)
def Zero()   : Output(0b_10111110)
def One()    : Output(0b_00000110)
def Two()    : Output(0b_11011010)
def Three()  : Output(0b_11001110)
def Four()   : Output(0b_01100110)
def Five()   : Output(0b_11101100)
def Six()    : Output(0b_11111100)
def Seven()  : Output(0b_10000110)
def Eight()  : Output(0b_11111110)
def Nine()   : Output(0b_11101110)

counter = [Off(), Zero(), One(), Two(), Three(), Four(), Five(), Six(), Seven(), Eight(), Nine()]
counter(1)

Obviously this didn't work as the "list object isn't callable". How might I make the functions callable from a matrix?

fdufnews
Posts: 76
Joined: Mon Jul 25, 2016 11:31 am

Re: Make a counter

Post by fdufnews » Fri Jun 11, 2021 12:42 pm

You'd better try

Code: Select all

counter = [Off, Zero, One, Two, Three, Four, Five, Six, Seven, Eight, Nine]
counter[1]()

hippy
Posts: 130
Joined: Sat Feb 20, 2021 2:46 pm
Location: UK

Re: Make a counter

Post by hippy » Fri Jun 11, 2021 4:28 pm

Or you can cut out the middle man of naming ...

Code: Select all

#             AGFEDCB.
counter = [0b_10111110, # 0
           0b_00000110, # 1 
           0b_11011010, # 2 
           0b_11001110, # 3 
           0b_01100110, # 4 
           0b_11101100, # 5 
           0b_11111100, # 6
           0b_10000110, # 7 
           0b_11111110, # 8 
           0b_11101110, # 9 
           0b_00000000] # 10 - Off

Output(counter[7])
You can of course move 'counter[]' into the 'Output' routine ...

Code: Select all

counter = ....

def Output(digit):
  bits = counter[digit]
  for n in range(8):
    out[n].value((bits >> n) & 1)
    
Output(7)

Post Reply