Untitled

 avatar
unknown
plain_text
22 days ago
4.9 kB
2
Indexable
import machine
from machine import Pin, SPI
from utime import sleep

# Pin assignments for the 7-segment display
RCLK = 9  # Register clock pin (latch pin)
SCK = 10  # SPI clock pin
MOSI = 11  # SPI MOSI pin

# LED segment codes (0-9)
SEG8codes = [
    0x3F,  # 0
    0x06,  # 1
    0x5B,  # 2
    0x4F,  # 3
    0x66,  # 4
    0x6D,  # 5
    0x7D,  # 6
    0x07,  # 7
    0x7F,  # 8
    0x6F   # 9
]

# MAX7219 Command Constants
MAX7219_NOOP = 0x00
MAX7219_DIGIT0 = 0x01
MAX7219_DIGIT1 = 0x02
MAX7219_DIGIT2 = 0x03
MAX7219_DIGIT3 = 0x04
MAX7219_DECODE_MODE = 0x09
MAX7219_INTENSITY = 0x0A
MAX7219_SCAN_LIMIT = 0x0B
MAX7219_SHUTDOWN = 0x0C
MAX7219_DISPLAY_TEST = 0x0F

class MAX7219:
    def __init__(self, spi, cs_pin):
        self.spi = spi
        self.cs = Pin(cs_pin, Pin.OUT)
        self.cs.value(1)  # Disable chip select

    def write(self, reg, data):
        self.cs.value(0)  # Enable chip select
        self.spi.write(bytearray([reg, data]))
        self.cs.value(1)  # Disable chip select

    def init_display(self):
        # Initialize the MAX7219
        self.write(MAX7219_SHUTDOWN, 0x01)  # Wake up the display
        self.write(MAX7219_SCAN_LIMIT, 0x03)  # Display 4 digits
        self.write(MAX7219_DECODE_MODE, 0x00)  # No decoding (digits 0-9 only)
        self.write(MAX7219_DISPLAY_TEST, 0x00)  # No display test
        self.write(MAX7219_INTENSITY, 0x0F)  # Set maximum brightness

    def clear_display(self):
        for i in range(4):
            self.write(MAX7219_DIGIT0 + i, 0x00)  # Clear each digit

    def display_digit(self, digit, value):
        # Display a single digit (0-9) on the specified position (0-3)
        self.write(MAX7219_DIGIT0 + digit, SEG8codes[value])

# Set up the SPI for communication with MAX7219
spi = SPI(1, baudrate=1000000, polarity=0, phase=0, sck=Pin(SCK), mosi=Pin(MOSI), miso=None)

# Create MAX7219 instance (assuming CS pin is 9)
display = MAX7219(spi, RCLK)

# Initialize the display
display.init_display()

# Pin setup for rotary encoder
A_PIN = machine.Pin(0, machine.Pin.IN, machine.Pin.PULL_UP)
B_PIN = machine.Pin(1, machine.Pin.IN, machine.Pin.PULL_UP)

# Initialize rotation counters
total_ccw = 0
total_cw = 0

# Interrupt handler for the rotary encoder
def rotary_encoder_irq(pin):
    global total_cw, total_ccw

    A_STATE = A_PIN.value()
    B_STATE = B_PIN.value()

    if A_STATE == 0 and B_STATE == 1:
        # Clockwise rotation
        total_cw += 1
    elif A_STATE == 1 and B_STATE == 0:
        # Counter-clockwise rotation
        total_ccw += 1

# Set up interrupt handlers for rotary encoder
A_PIN.irq(trigger=machine.Pin.IRQ_RISING, handler=rotary_encoder_irq)
B_PIN.irq(trigger=machine.Pin.IRQ_RISING, handler=rotary_encoder_irq)

# Helper functions to extract tens and ones digits
def get_tens(num):
    return (num // 10) % 10

def get_ones(num):
    return num % 10

# Helper function to display rotation direction on LED
def display_direction():
    if total_cw > total_ccw:
        # Display CW as 'C' (using digit '6' to resemble C)
        display.display_digit(0, 6)  # C-like representation (6)
        display.display_digit(1, 3)  # W-like representation (3)
    elif total_ccw > total_cw:
        # Display CCW as 'C' (using digit '6' to resemble C)
        display.display_digit(0, 6)  # C-like representation (6)
        display.display_digit(1, 3)  # C-like representation (3)
    else:
        # No rotations or equal rotations, display "NO" for No movement
        display.display_digit(0, 6)  # 'N' representation (6)
        display.display_digit(1, 0)  # 'O' representation (0)

# Main loop to display CW and CCW on the LED display and send data to PC
time_elapsed = 0
debounce_interval = 0.05

try:
    while True:
        # Debounce the rotary encoder
        sleep(debounce_interval)

        # Every 10 seconds, print the total CW and CCW rotations to the PC
        time_elapsed += debounce_interval
        if time_elapsed >= 10:
            print(f"Total CWs: {total_cw}, Total CCWs: {total_ccw}")
            time_elapsed = 0

        # Display the CCW count (tens and ones) on LED 2 and LED 3
        display.display_digit(2, get_tens(total_ccw))  # Tens digit of CCW
        sleep(0.001)
        display.display_digit(3, get_ones(total_ccw))  # Ones digit of CCW
        sleep(0.001)

        # Display the CW count (tens and ones) on LED 0 and LED 1
        display.display_digit(0, get_tens(total_cw))  # Tens digit of CW
        sleep(0.001)
        display.display_digit(1, get_ones(total_cw))  # Ones digit of CW
        sleep(0.001)

        # Display the current direction (CW/CCW)
        display_direction()

except KeyboardInterrupt:
    pass  # Gracefully exit on keyboard interrupt

Editor is loading...
Leave a Comment