~ekez/tui-webpage

7931fdb9ceb38055deeac0d37d7539dc961e2fce — Zeke Medley 8 days ago 4ae79c8
Add code examples for Thursday lab 2
2 files changed, 124 insertions(+), 0 deletions(-)

A examples/getch.py
A examples/pyserial.py
A examples/getch.py => examples/getch.py +59 -0
@@ 0,0 1,59 @@
# This file exports a function called `getch` which will read a single
# character of user input from the terminal without waiting for a
# newline. In theory this ought to be Windows compatable but I am
# unable to verify this as I (Zeke) do not own a Windows machine.
#
# To use this file place it in the same directory as the file that you
# would like to use it in is in and add:
# ```
# from <NAME OF THIS FILE> import getch
# ```
#
# Note that when using this `getch` function sending ^C to the console
# will not cause the program to end like you might expect as the ^C
# interrupt will be read in. To avoid a program that is impossible to
# exit you may want to configure a specific character that when read
# in will terminate the program.

class _Getch:
    """Gets a single character from standard input.  Does not echo to
    the screen.

    Source:
    https://code.activestate.com/recipes/134892-getch-like-unbuffered-character-reading-from-stdin/
    """
    def __init__(self):
        try:
            self.impl = _GetchWindows()
        except ImportError:
            self.impl = _GetchUnix()

    def __call__(self): return self.impl()


class _GetchUnix:
    def __init__(self):
        import tty, sys

    def __call__(self):
        import sys, tty, termios
        fd = sys.stdin.fileno()
        old_settings = termios.tcgetattr(fd)
        try:
            tty.setraw(sys.stdin.fileno())
            ch = sys.stdin.read(1)
        finally:
            termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
        return ch


class _GetchWindows:
    def __init__(self):
        import msvcrt

    def __call__(self):
        import msvcrt
        return msvcrt.getch()


getch = _Getch()

A examples/pyserial.py => examples/pyserial.py +65 -0
@@ 0,0 1,65 @@
# This file contains a number of functions which you can use to
# interact with your Arduino via its serial communication
# system. Example usage with an echo program loaded onto the Arduino:
#
# Python program:
#
# ```
# serial = prompt_for_and_get_serial()
#
# while True:
#     send = input('>> ')
#     serial.write(bytes(send, 'utf-8'))
#     print(serial.readline().decode('utf-8')[:-1])
# ```
#
# Arduino program:
#
# ```
# void setup() {
#   Serial.begin(9600);
# }
#
# void loop() {
#   if (Serial.available()) {
#     String message = Serial.readStringUntil('\n');
#     Serial.print(": " + message + "\n");
#   }
# }
# ```

import serial

from getch import getch

def get_ports():
    """List all of the avaliable ports on the device."""
    import serial.tools.list_ports
    return serial.tools.list_ports.comports()

def prompt_for_and_get_port():
    """Prompts the user to select a port. Returns the selected
    one.

    Input is expected to be a number in [0, num_ports) and is
    read from standard in. An input outside of that range will result
    in re-prompting until a valid input is provided.
    """
    ports = get_ports()
    for index, port in enumerate(ports):
        print("{}) {}\t{}".format(index, port.device, port.description))
    selection = int(input("please input the port number that your port is on: "))
    while selection < 0 or selection >= len(ports):
        print("error: {} is not between 0 and {}".format(selection, len(ports) - 1))
        selection = int(input("please input the port number that your port is on: "))
    return ports[selection]

def prompt_for_and_get_serial(baudrate=9600):
    """Prompts the user to select a port and returns a serial object
    connected to that port.

    By default the returned serial object uses a 9600 baudrate but
    this can be modified by passing one to the function.
    """
    port = prompt_for_and_get_port()
    return serial.Serial(port=port.device, baudrate=baudrate)