Python 2 on Raspberry Pi Linux 7

Projects involving robots
tahanson43206
Site Admin
Posts: 493
Joined: Wed Apr 10, 2024 11:24 pm
Location: Earth
Contact:

Re: Python 2 on Raspberry Pi Linux 7

Post by tahanson43206 »

FreeFormV05.py adds save command

Code: Select all

# FreeFormV05.py ChatGPT on 2026/04/07 
# Python 2 utility for SSC-32U
# Features:
#   a <cmd>       - free-form send
#   f <file>      - load & send first line
#   s <file>      - save current pose
#   <ch> <pw>     - simple move
#   NO automatic Q polling

import serial
import time
import re

ROBOT_PORT = "/dev/ttyUSB1"
BAUD = 9600
TIMEOUT = 0.2

# -------------------------------
# Global pose tracking
# -------------------------------
current_pose = [1500,1500,1500,1500,1500,1500]

# -------------------------------
# Utility functions
# -------------------------------
def to_hex(data):
    return " ".join(["%02X" % ord(ch) for ch in data])

def to_printable(data):
    out = []
    for ch in data:
        o = ord(ch)
        if 32 <= o <= 126:
            out.append(ch)
        elif ch == "\r":
            out.append("\\r")
        elif ch == "\n":
            out.append("\\n")
        else:
            out.append(".")
    return "".join(out)

def show_response(label, data):
    print label
    if data:
        print "ASCII:", to_printable(data)
        print "HEX  :", to_hex(data)
        print "LEN  :", len(data)
    else:
        print "ASCII: <none>"
        print "HEX  : <none>"
        print "LEN  : 0"

def read_available(ser, settle_time=0.1, max_bytes=256):
    time.sleep(settle_time)
    chunks = []
    total = 0

    while total < max_bytes:
        n = ser.inWaiting()
        if n <= 0:
            break
        chunk = ser.read(n)
        if not chunk:
            break
        chunks.append(chunk)
        total += len(chunk)
        time.sleep(0.02)

    return "".join(chunks)

def ensure_cr(cmd):
    if cmd.endswith("\r"):
        return cmd
    if cmd.endswith("\n"):
        cmd = cmd[:-1]
    return cmd + "\r"

# -------------------------------
# Pose tracking
# -------------------------------
def update_pose_from_command(cmd):
    global current_pose
    matches = re.findall(r'#(\d+)P(\d+)', cmd)

    for ch, pw in matches:
        ch = int(ch)
        pw = int(pw)
        if 0 <= ch < len(current_pose):
            current_pose[ch] = pw

def build_pose_command(T=2000):
    cmd = ""
    for i, val in enumerate(current_pose):
        cmd += "#%dP%d " % (i, val)
    cmd += "T%d" % T
    return cmd

# -------------------------------
# Serial send
# -------------------------------
def send_and_report(ser, cmd, label):
    print
    print "Sending", label
    print "ASCII:", to_printable(cmd)
    print "HEX  :", to_hex(cmd)
    print "LEN  :", len(cmd)

    ser.write(cmd)
    response = read_available(ser)
    show_response(label + " response:", response)

# -------------------------------
# Main
# -------------------------------
def main():
    global current_pose

    try:
        bot = serial.Serial(ROBOT_PORT, BAUD, timeout=TIMEOUT)
    except Exception as e:
        print "ERROR opening port:", str(e)
        return

    print "Connected to:", ROBOT_PORT

    # Initial VER check
    send_and_report(bot, "VER\r", "VER")

    print
    print "FreeFormV05"
    print "Commands:"
    print "  a <cmd>       free form"
    print "  f <file>      run file"
    print "  s <file>      save pose"
    print "  <ch> <pw>     move servo"
    print "  9             exit"

    try:
        while True:
            print
            user_input = raw_input("Next Command: ").strip()

            if not user_input:
                continue

            if user_input == "9":
                break

            parts = user_input.split()

            # ---------------------------
            # FILE COMMAND
            # ---------------------------
            if parts[0].lower() == "f":
                if len(parts) < 2:
                    print "Use: f <filename>"
                    continue

                filename = " ".join(parts[1:])

                try:
                    fh = open(filename, "r")
                    line = fh.readline()
                    fh.close()

                    if not line:
                        print "File empty"
                        continue

                    cmd = ensure_cr(line.strip())
                    update_pose_from_command(cmd)
                    send_and_report(bot, cmd, "file command")

                except Exception as e:
                    print "File error:", str(e)

                continue

            # ---------------------------
            # SAVE COMMAND
            # ---------------------------
            if parts[0].lower() == "s":
                if len(parts) < 2:
                    print "Use: s <filename>"
                    continue

                filename = " ".join(parts[1:])

                try:
                    cmd = build_pose_command()
                    fh = open(filename, "w")
                    fh.write(cmd + "\n")
                    fh.close()

                    print "Saved pose to", filename
                    print cmd

                except Exception as e:
                    print "Save error:", str(e)

                continue

            # ---------------------------
            # FREE FORM
            # ---------------------------
            if parts[0].lower() == "a":
                if len(parts) < 2:
                    print "Use: a <command>"
                    continue

                cmd = ensure_cr(" ".join(parts[1:]))
                update_pose_from_command(cmd)
                send_and_report(bot, cmd, "free-form")

                continue

            # ---------------------------
            # SIMPLE MOVE
            # ---------------------------
            if len(parts) == 2:
                try:
                    ch = int(parts[0])
                    pw = int(parts[1])

                    if pw < 500: pw = 500
                    if pw > 2500: pw = 2500

                    current_pose[ch] = pw

                    cmd = "#%dP%d T2000\r" % (ch, pw)
                    send_and_report(bot, cmd, "move")

                except:
                    print "Invalid input"

                continue

            print "Invalid command"

    except KeyboardInterrupt:
        print "\nExiting"

    finally:
        bot.close()
        print "Port closed"

if __name__ == "__main__":
    main() # 249 
	
(th)
tahanson43206
Site Admin
Posts: 493
Joined: Wed Apr 10, 2024 11:24 pm
Location: Earth
Contact:

Re: Python 2 on Raspberry Pi Linux 7

Post by tahanson43206 »

FreeFormV04.py ... enhanced to deliver entire command strings to the robot arm

Code: Select all

# FreeFormV04.py by ChatGPT 2026/04/07 
# Python 2 utility for testing SSC-32U commands on /dev/ttyUSB1
# Adds:
#   - free-form command mode: a <text>
#   - file command mode:      f <filename>
#   - repeated Q polling after move commands until '.' or timeout

import serial
import time
import re

ROBOT_PORT = "/dev/ttyUSB1"
BAUD = 9600
TIMEOUT = 0.2

def to_hex(data):
    return " ".join(["%02X" % ord(ch) for ch in data])

def to_printable(data):
    out = []
    for ch in data:
        o = ord(ch)
        if 32 <= o <= 126:
            out.append(ch)
        elif ch == "\r":
            out.append("\\r")
        elif ch == "\n":
            out.append("\\n")
        else:
            out.append(".")
    return "".join(out)

def show_response(label, data):
    print label
    if data:
        print "ASCII:", to_printable(data)
        print "HEX  :", to_hex(data)
        print "LEN  :", len(data)
    else:
        print "ASCII: <none>"
        print "HEX  : <none>"
        print "LEN  : 0"

def read_available(ser, settle_time=0.05, max_bytes=256):
    time.sleep(settle_time)

    chunks = []
    total = 0

    while total < max_bytes:
        n = ser.inWaiting()
        if n <= 0:
            break

        chunk = ser.read(n)
        if not chunk:
            break

        chunks.append(chunk)
        total += len(chunk)
        time.sleep(0.02)

    return "".join(chunks)

def send_and_report(ser, cmd, label, settle_time=0.1, max_bytes=256):
    print
    print "Sending", label
    print "ASCII:", to_printable(cmd)
    print "HEX  :", to_hex(cmd)
    print "LEN  :", len(cmd)

    ser.write(cmd)
    response = read_available(ser, settle_time=settle_time, max_bytes=max_bytes)
    show_response(label + " response:", response)
    return response

def extract_t_value(cmd):
    """
    Look for Tnnn in a move command.
    Returns integer milliseconds if found, otherwise None.
    """
    m = re.search(r'T(\d+)', cmd, re.IGNORECASE)
    if m:
        return int(m.group(1))
    return None

def poll_q_until_done(ser, max_wait_ms, poll_interval=0.05):
    """
    Poll with Q until '.' is seen or timeout expires.
    Reports '+' '.' or any other response.
    """
    start = time.time()
    attempt = 0

    print
    print "Beginning Q polling for up to %d ms" % max_wait_ms

    while True:
        elapsed_ms = int((time.time() - start) * 1000)
        if elapsed_ms > max_wait_ms:
            print "Q polling timed out after %d ms" % elapsed_ms
            break

        attempt += 1
        ser.write("Q\r")
        resp = read_available(ser, settle_time=0.03, max_bytes=32)

        if resp:
            print
            print "Q poll attempt %d at %d ms:" % (attempt, elapsed_ms)
            print "ASCII:", to_printable(resp)
            print "HEX  :", to_hex(resp)
            print "LEN  :", len(resp)

            if "." in resp:
                print "Motion complete '.' received."
                break
            elif "+" in resp:
                print "Motion still in progress '+' received."
            else:
                print "Response did not contain '+' or '.'."
        else:
            print "Q poll attempt %d at %d ms: <none>" % (attempt, elapsed_ms)

        time.sleep(poll_interval)

def ensure_cr(cmd_text):
    """
    Ensure outgoing command ends with carriage return.
    """
    if cmd_text.endswith("\r"):
        return cmd_text
    if cmd_text.endswith("\n"):
        cmd_text = cmd_text[:-1]
    return cmd_text + "\r"

def main():
    try:
        bot = serial.Serial(ROBOT_PORT, BAUD, timeout=TIMEOUT)
    except Exception as e:
        print "ERROR: Could not open serial port:", str(e)
        return

    print "Connected to port:", ROBOT_PORT
    print "Baud rate        :", BAUD

    # Initial VER test
    send_and_report(bot, "VER\r", "VER", settle_time=0.1, max_bytes=256)

    print
    print "  - FREE FORM SSC-32U TEST UTILITY V04 -"
    print "Enter 9 to Exit"
    print
    print "Normal move mode:"
    print "  <channel> <pulse>"
    print "  Example: 0 1500"
    print
    print "Free-form mode:"
    print "  a <text to send>"
    print "  Example: a VER"
    print "  Example: a Q"
    print "  Example: a VA"
    print "  Example: a VG"
    print "  Example: a VH"
    print "  Example: a #0P2500T3000"
    print
    print "File mode:"
    print "  f <filename>"
    print "  Example: f home.cmd"
    print
    print "After a move command, program polls Q until '.' or timeout."

    try:
        while True:
            print
            user_input = raw_input("Next Command: ").strip()

            if not user_input:
                continue

            if user_input == "9":
                break

            parts = user_input.split()

            # --------------------------------------------------
            # File mode
            # --------------------------------------------------
            if parts[0].lower() == "f":
                if len(parts) < 2:
                    print "Use: f <filename>"
                    continue

                filename = " ".join(parts[1:])

                try:
                    fh = open(filename, "r")
                    first_line = fh.readline()
                    fh.close()

                    if not first_line:
                        print "ERROR: File is empty:", filename
                        continue

                    cmd = ensure_cr(first_line.rstrip("\r\n"))

                    response = send_and_report(bot, cmd, "file command", settle_time=0.1, max_bytes=256)

                    t_ms = extract_t_value(cmd)
                    if t_ms is not None:
                        poll_q_until_done(bot, max_wait_ms=t_ms + 500)

                except Exception as e:
                    print "ERROR opening/reading file:", filename
                    print str(e)

                continue

            # --------------------------------------------------
            # Free-form mode
            # --------------------------------------------------
            if parts[0].lower() == "a":
                if len(parts) < 2:
                    print "Use: a <text to send>"
                    continue

                free_text = " ".join(parts[1:])
                cmd = ensure_cr(free_text)

                response = send_and_report(bot, cmd, "free-form", settle_time=0.1, max_bytes=256)

                # If free-form command looks like a move, poll Q
                t_ms = extract_t_value(free_text)
                if t_ms is not None:
                    poll_q_until_done(bot, max_wait_ms=t_ms + 500)

                continue

            # --------------------------------------------------
            # Normal numeric move mode
            # --------------------------------------------------
            if len(parts) != 2:
                print "Use either:"
                print "  <channel> <pulse>"
                print "  a <text to send>"
                print "  f <filename>"
                continue

            try:
                ch = int(parts[0])
                pw = int(parts[1])
            except ValueError:
                print "Input error. Use numeric channel/pulse, a <text>, or f <filename>"
                continue

            if pw < 500:
                pw = 500
            if pw > 2500:
                pw = 2500

            cmd = "#" + str(ch) + "P" + str(pw) + "T3000\r"

            print
            print "Sending move command:"
            print "ASCII:", to_printable(cmd)
            print "HEX  :", to_hex(cmd)
            print "LEN  :", len(cmd)

            bot.write(cmd)

            # Poll Q up to commanded time plus margin
            poll_q_until_done(bot, max_wait_ms=3500)

    except KeyboardInterrupt:
        print
        print "Ctrl+C received. Exiting cleanly."

    finally:
        if bot.isOpen():
            bot.close()
        print "Serial port closed."

if __name__ == "__main__":
    main() # 284
	
(th)
tahanson43206
Site Admin
Posts: 493
Joined: Wed Apr 10, 2024 11:24 pm
Location: Earth
Contact:

Re: Python 2 on Raspberry Pi Linux 7

Post by tahanson43206 »

Improved FreeForm utility to interact with robot arm via RP2...

Code: Select all

# FreeFormV02.py Prepared by ChatGPT 2026/04/04
# Python 2 utility for testing SSC-32U commands on /dev/ttyUSB1
# Adds repeated Q polling after a move until '.' or timeout

import serial
import time
import re

ROBOT_PORT = "/dev/ttyUSB1"
BAUD = 9600
TIMEOUT = 0.2

def to_hex(data):
    return " ".join(["%02X" % ord(ch) for ch in data])

def to_printable(data):
    out = []
    for ch in data:
        o = ord(ch)
        if 32 <= o <= 126:
            out.append(ch)
        elif ch == "\r":
            out.append("\\r")
        elif ch == "\n":
            out.append("\\n")
        else:
            out.append(".")
    return "".join(out)

def show_response(label, data):
    print label
    if data:
        print "ASCII:", to_printable(data)
        print "HEX  :", to_hex(data)
        print "LEN  :", len(data)
    else:
        print "ASCII: <none>"
        print "HEX  : <none>"
        print "LEN  : 0"

def read_available(ser, settle_time=0.05, max_bytes=256):
    time.sleep(settle_time)

    chunks = []
    total = 0

    while total < max_bytes:
        n = ser.inWaiting()
        if n <= 0:
            break

        chunk = ser.read(n)
        if not chunk:
            break

        chunks.append(chunk)
        total += len(chunk)
        time.sleep(0.02)

    return "".join(chunks)

def send_and_report(ser, cmd, label, settle_time=0.1, max_bytes=256):
    print
    print "Sending", label
    print "ASCII:", to_printable(cmd)
    print "HEX  :", to_hex(cmd)
    print "LEN  :", len(cmd)

    ser.write(cmd)
    response = read_available(ser, settle_time=settle_time, max_bytes=max_bytes)
    show_response(label + " response:", response)
    return response

def extract_t_value(cmd):
    """
    Look for Tnnn in a move command.
    Returns integer milliseconds if found, otherwise None.
    """
    m = re.search(r'T(\d+)', cmd, re.IGNORECASE)
    if m:
        return int(m.group(1))
    return None

def poll_q_until_done(ser, max_wait_ms, poll_interval=0.05):
    """
    Poll with Q until '.' is seen or timeout expires.
    Reports '+' '.' or any other response.
    """
    start = time.time()
    attempt = 0

    print
    print "Beginning Q polling for up to %d ms" % max_wait_ms

    while True:
        elapsed_ms = int((time.time() - start) * 1000)
        if elapsed_ms > max_wait_ms:
            print "Q polling timed out after %d ms" % elapsed_ms
            break

        attempt += 1
        ser.write("Q\r")
        resp = read_available(ser, settle_time=0.03, max_bytes=32)

        if resp:
            print
            print "Q poll attempt %d at %d ms:" % (attempt, elapsed_ms)
            print "ASCII:", to_printable(resp)
            print "HEX  :", to_hex(resp)
            print "LEN  :", len(resp)

            if "." in resp:
                print "Motion complete '.' received."
                break
            elif "+" in resp:
                print "Motion still in progress '+' received."
            else:
                print "Response did not contain '+' or '.'."
        else:
            print "Q poll attempt %d at %d ms: <none>" % (attempt, elapsed_ms)

        time.sleep(poll_interval)

def main():
    try:
        bot = serial.Serial(ROBOT_PORT, BAUD, timeout=TIMEOUT)
    except Exception as e:
        print "ERROR: Could not open serial port:", str(e)
        return

    print "Connected to port:", ROBOT_PORT
    print "Baud rate        :", BAUD

    # Initial VER test
    send_and_report(bot, "VER\r", "VER", settle_time=0.1, max_bytes=256)

    print
    print "  - FREE FORM SSC-32U TEST UTILITY V02 -"
    print "Enter 9 to Exit"
    print
    print "Normal move mode:"
    print "  <channel> <pulse>"
    print "  Example: 0 1500"
    print
    print "Free-form mode:"
    print "  a <text to send>"
    print "  Example: a VER"
    print "  Example: a Q"
    print "  Example: a VA"
    print "  Example: a VG"
    print "  Example: a VH"
    print "  Example: a #0P2500T3000"
    print
    print "After a move command, program polls Q until '.' or timeout."

    try:
        while True:
            print
            user_input = raw_input("Next Command: ").strip()

            if not user_input:
                continue

            if user_input == "9":
                break

            parts = user_input.split()

            # Free-form mode
            if parts[0].lower() == "a":
                if len(parts) < 2:
                    print "Use: a <text to send>"
                    continue

                free_text = " ".join(parts[1:])
                cmd = free_text + "\r"

                response = send_and_report(bot, cmd, "free-form", settle_time=0.1, max_bytes=256)

                # If free-form command looks like a move, poll Q
                t_ms = extract_t_value(free_text)
                if t_ms is not None:
                    poll_q_until_done(bot, max_wait_ms=t_ms + 500)

                continue

            # Normal numeric move mode
            if len(parts) != 2:
                print "Use either:"
                print "  <channel> <pulse>"
                print "or"
                print "  a <text to send>"
                continue

            try:
                ch = int(parts[0])
                pw = int(parts[1])
            except ValueError:
                print "Input error. Use numeric channel/pulse or: a <text>"
                continue

            if pw < 500:
                pw = 500
            if pw > 2500:
                pw = 2500

            cmd = "#" + str(ch) + "P" + str(pw) + "T3000\r"

            print
            print "Sending move command:"
            print "ASCII:", to_printable(cmd)
            print "HEX  :", to_hex(cmd)
            print "LEN  :", len(cmd)

            bot.write(cmd)

            # Poll Q up to commanded time plus margin
            poll_q_until_done(bot, max_wait_ms=3500)

    except KeyboardInterrupt:
        print
        print "Ctrl+C received. Exiting cleanly."

    finally:
        if bot.isOpen():
            bot.close()
        print "Serial port closed."

if __name__ == "__main__":
    main() # 230 lines for V01
	
(th)
tahanson43206
Site Admin
Posts: 493
Joined: Wed Apr 10, 2024 11:24 pm
Location: Earth
Contact:

Re: Python 2 on Raspberry Pi Linux 7

Post by tahanson43206 »

FreeForm test program to interrogate LynxMotion ssc32u controller

Code: Select all

 cat FreeFormV01.py 
# FreeFormV01.py
# Python 2 utility for testing SSC-32U commands on /dev/ttyUSB1

import serial
import time

ROBOT_PORT = "/dev/ttyUSB1"
BAUD = 9600
TIMEOUT = 0.5

def to_hex(data):
    return " ".join(["%02X" % ord(ch) for ch in data])

def to_printable(data):
    out = []
    for ch in data:
        o = ord(ch)
        if 32 <= o <= 126:
            out.append(ch)
        elif ch == "\r":
            out.append("\\r")
        elif ch == "\n":
            out.append("\\n")
        else:
            out.append(".")
    return "".join(out)

def show_response(label, data):
    print label
    if data:
        print "ASCII:", to_printable(data)
        print "HEX  :", to_hex(data)
        print "LEN  :", len(data)
    else:
        print "ASCII: <none>"
        print "HEX  : <none>"
        print "LEN  : 0"

def read_available(ser, settle_time=0.2, max_bytes=256):
    """
    Wait briefly, then collect whatever bytes are available.
    Works with older pySerial on Python 2.
    """
    time.sleep(settle_time)

    chunks = []
    total = 0

    while total < max_bytes:
        n = ser.inWaiting()
        if n <= 0:
            break

        chunk = ser.read(n)
        if not chunk:
            break

        chunks.append(chunk)
        total += len(chunk)

        time.sleep(0.05)

    return "".join(chunks)

def send_and_report(ser, cmd, label, settle_time=0.2, max_bytes=256):
    print
    print "Sending", label
    print "ASCII:", to_printable(cmd)
    print "HEX  :", to_hex(cmd)
    print "LEN  :", len(cmd)

    ser.write(cmd)
    response = read_available(ser, settle_time=settle_time, max_bytes=max_bytes)
    show_response(label + " response:", response)

def main():
    try:
        bot = serial.Serial(ROBOT_PORT, BAUD, timeout=TIMEOUT)
    except Exception as e:
        print "ERROR: Could not open serial port:", str(e)
        return

    print "Connected to port:", ROBOT_PORT
    print "Baud rate        :", BAUD

    # Initial VER test
    send_and_report(bot, "VER\r", "VER", settle_time=0.2, max_bytes=256)

    print
    print "  - FREE FORM SSC-32U TEST UTILITY -"
    print "Enter 9 to Exit"
    print
    print "Normal move mode:"
    print "  <channel> <pulse>"
    print "  Example: 0 1500"
    print
    print "Free-form mode:"
    print "  a <text to send>"
    print "  Example: a VER"
    print "  Example: a Q"
    print "  Example: a AL BL CL DL EL FL VG VH"
    print "  Example: a #0P1500T1000"

    try:
        while True:
            print
            user_input = raw_input("Next Command: ").strip()

            if not user_input:
                continue

            if user_input == "9":
                break

            parts = user_input.split()

            # Free-form mode
            if parts[0].lower() == "a":
                if len(parts) < 2:
                    print "Use: a <text to send>"
                    continue

                free_text = " ".join(parts[1:])
                cmd = free_text + "\r"
                send_and_report(bot, cmd, "free-form", settle_time=0.2, max_bytes=256)
                continue

            # Normal numeric move mode
            if len(parts) != 2:
                print "Use either:"
                print "  <channel> <pulse>"
                print "or"
                print "  a <text to send>"
                continue

            try:
                ch = int(parts[0])
                pw = int(parts[1])
            except ValueError:
                print "Input error. Use numeric channel/pulse or: a <text>"
                continue

            # Clamp pulse width
            if pw < 500:
                pw = 500
            if pw > 2500:
                pw = 2500

            cmd = "#" + str(ch) + "P" + str(pw) + "T3000\r"

            print
            print "Sending move command:"
            print "ASCII:", to_printable(cmd)
            print "HEX  :", to_hex(cmd)
            print "LEN  :", len(cmd)

            bot.write(cmd)

            # Brief pause, then a single Q query
            time.sleep(0.1)

            qcmd = "Q\r"
            print
            print "Polling once with Q:"
            print "ASCII:", to_printable(qcmd)
            print "HEX  :", to_hex(qcmd)
            print "LEN  :", len(qcmd)

            bot.write(qcmd)
            qresp = read_available(bot, settle_time=0.2, max_bytes=256)
            show_response("Q response:", qresp)

    except KeyboardInterrupt:
        print
        print "Ctrl+C received. Exiting cleanly."

    finally:
        if bot.isOpen():
            bot.close()
        print "Serial port closed."

if __name__ == "__main__":
    main()
# 184 lines
	
(th)
tahanson43206
Site Admin
Posts: 493
Joined: Wed Apr 10, 2024 11:24 pm
Location: Earth
Contact:

Re: Python 2 on Raspberry Pi Linux 7

Post by tahanson43206 »

Version of ssc32u on LynxMotion arm

Code: Select all

cat robot_sniff.log
PC: 'V'
PC: 'E'
PC: 'R'
PC: '\r'
BOT: 'S'
BOT: 'S'
BOT: 'C'
BOT: '3'
BOT: '2'
BOT: '-'
BOT: 'V'
BOT: '2'
BOT: '.'
BOT: '5'
BOT: '0'
BOT: 'U'
BOT: 'SB'
BOT: '\r'
PC: 'V'
PC: 'E'
PC: 'R'
PC: '\r'
BOT: 'SS'
BOT: 'C'
BOT: '3'
BOT: '2'
BOT: '-'
BOT: 'V'
BOT: '2'
BOT: '.5'
BOT: '0'
BOT: 'U'
BOT: 'S'
BOT: 'B'
BOT: '\r'

(th)
tahanson43206
Site Admin
Posts: 493
Joined: Wed Apr 10, 2024 11:24 pm
Location: Earth
Contact:

Re: Python 2 on Raspberry Pi Linux 7

Post by tahanson43206 »

Revised test servo program (ChatGPT versiion)

Code: Select all

cat ChatGPTtestssc32u_servoV03.py
# ssc32u_testservoV03.py

import serial
import time

robot_port = "/dev/ttyUSB1"

def to_hex(data):
    return " ".join(["%02X" % ord(ch) for ch in data])

def to_printable(data):
    out = []
    for ch in data:
        o = ord(ch)
        if 32 <= o <= 126:
            out.append(ch)
        else:
            out.append(".")
    return "".join(out)

try:
    bot = serial.Serial(robot_port, 9600, timeout=0.5)
    print "Connected to port: " + robot_port

    # --------------------------------------------------
    # Version query
    # --------------------------------------------------
    print "Querying SSC-32U for Version..."
    bot.write("VER\r")
    time.sleep(0.2)

    response = bot.readline()
    if response:
        print "VER raw response:"
        print "ASCII:", to_printable(response)
        print "HEX  :", to_hex(response)
        print "LEN  :", len(response)
    else:
        print "No response to VER."

except Exception as e:
    print "ERROR: Could not open serial port: " + str(e)
    raise SystemExit

print
print "  - AL5D JOG UTILITY WITH Q REPORTING -"
print "Enter 9 to Exit"

while True:
    try:
        user_input = raw_input("\nNext Move (Ch Pulse): ")
        if user_input == "9":
            break

        parts = user_input.split()
        if len(parts) != 2:
            print "Use: channel pulse"
            print "Example: 0 1500"
            continue

        ch = int(parts[0])
        pw = int(parts[1])

        # Safety limits
        if pw < 500:
            pw = 500
        if pw > 2500:
            pw = 2500

        # Build and send motion command
        cmd = "#" + str(ch) + "P" + str(pw) + "T3000\r"
        print
        print "Sending move command:"
        print "ASCII:", to_printable(cmd)
        print "HEX  :", to_hex(cmd)
        print "LEN  :", len(cmd)

        bot.write(cmd)

        # Give motion command a moment to register
        time.sleep(0.1)

        # Poll with Q and report exactly what comes back
        print "Polling with Q..."
        got_done = False

        for attempt in range(1, 41):   # about 2 seconds total
            bot.write("Q\r")
            resp = bot.read(1)

            if resp:
                print "Attempt %d response:" % attempt
                print "ASCII:", to_printable(resp)
                print "HEX  :", to_hex(resp)
                print "LEN  :", len(resp)

                if resp == ".":
                    print "Motion complete response received."
                    got_done = True
                    break
            else:
                print "Attempt %d response: <none>" % attempt

            time.sleep(0.05)

        if got_done:
            print "Done."
        else:
            print "No '.' response seen after polling."

    except Exception as e:
        print "Error: " + str(e)

bot.close()
print "Serial port closed." #115 lines

(th)
tahanson43206
Site Admin
Posts: 493
Joined: Wed Apr 10, 2024 11:24 pm
Location: Earth
Contact:

Re: Python 2 on Raspberry Pi Linux 7

Post by tahanson43206 »

Data from test of revised TwoWay program ... arm moved and responses were sent

Code: Select all

 head -n100  serial_bridge_20260403_175847.log 
Serial bridge log started: 2026-04-03 17:58:47
Log file: ./serial_bridge_20260403_175847.log
Bridge mode active
FLOWARM: /dev/ttyUSB0 @ 9600
LYNXARM: /dev/ttyUSB1 @ 9600

Opened FLOWARM on /dev/ttyUSB0 @ 9600
Opened LYNXARM on /dev/ttyUSB1 @ 9600
Forwarding traffic both directions...

[2026-04-03 18:00:26] FLOWARM -> LYNXARM
ASCII:  #0 P1500 #1 P1738 #2 P1779 #3 P521 #4 P500 #5 P1500 #6 P1500 #7 P1500 T1000
HEX  : 20 23 30 20 50 31 35 30 30 20 23 31 20 50 31 37 33 38 20 23 32 20 50 31 37 37 39 20 23 33 20 50 35 32 31 20 23 34 20 50 35 30 30 20 23 35 20 50 31 35 30 30 20 23 36 20 50 31 35 30 30 20 23 37 20 50 31 35 30 30 20 54 31 30 30 30
LEN  : 76

[2026-04-03 18:00:26] FLOWARM -> LYNXARM
ASCII: #1:0
HEX  : 23 31 3A 30
LEN  : 4

[2026-04-03 18:00:26] FLOWARM -> LYNXARM
ASCII: AL BL CL DL EL FL VG VH
HEX  : 41 4C 20 42 4C 20 43 4C 20 44 4C 20 45 4C 20 46 4C 20 56 47 20 56 48
LEN  : 23

[2026-04-03 18:00:26] LYNXARM -> FLOWARM
ASCII: 111111
HEX  : 31 31 31 31 31 31
LEN  : 6
Board type is: ssc32u_
tahanson43206
Site Admin
Posts: 493
Joined: Wed Apr 10, 2024 11:24 pm
Location: Earth
Contact:

Re: Python 2 on Raspberry Pi Linux 7

Post by tahanson43206 »

Correction/update to TwoWay program

Code: Select all

TwoWayMonitorPrintV02.py

import serial
import time
import threading
import os
import sys

# ------------------------------------------------------------
# Configuration - baud set to 9600 2026/04/03 = added FA FD code
# ------------------------------------------------------------
PORT_A_NAME = "FLOWARM"
PORT_A_DEV  = "/dev/ttyUSB0"
PORT_A_BAUD = 9600

PORT_B_NAME = "LYNXARM"
PORT_B_DEV  = "/dev/ttyUSB1"
PORT_B_BAUD = 9600

LOG_DIR = "."
LOG_FILENAME = "serial_bridge_%s.log" % time.strftime("%Y%m%d_%H%M%S")
LOG_PATH = os.path.join(LOG_DIR, LOG_FILENAME)

# ------------------------------------------------------------
# Shared state
# ------------------------------------------------------------
print_lock = threading.Lock()
stop_flag = False


def to_hex(data):
    return " ".join(["%02X" % ord(ch) for ch in data])


def to_printable(data):
    out = []
    for ch in data:
        o = ord(ch)
        if 32 <= o <= 126:
            out.append(ch)
        else:
            out.append(".")
    return "".join(out)


def log_message(logfile, text):
    with print_lock:
        print text
        logfile.write(text + "\n")
        logfile.flush()


def log_packet(logfile, direction, packet):
    timestamp = time.strftime("%Y-%m-%d %H:%M:%S")
    lines = []
    lines.append("[%s] %s" % (timestamp, direction))
    lines.append("ASCII: %s" % to_printable(packet))
    lines.append("HEX  : %s" % to_hex(packet))
    lines.append("LEN  : %d" % len(packet))
    lines.append("")
    block = "\n".join(lines)

    with print_lock:
        print block
        logfile.write(block + "\n")
        logfile.flush()


class BridgeThread(threading.Thread):
    def __init__(self, src_ser, dst_ser, direction_label, logfile):
        threading.Thread.__init__(self)
        self.src_ser = src_ser
        self.dst_ser = dst_ser
        self.direction_label = direction_label
        self.logfile = logfile
        self.buffer = []

        self.last_was_cr = False
        self.last_was_fd = False

    def flush_packet(self):
        if self.buffer:
            packet = "".join(self.buffer)
            log_packet(self.logfile, self.direction_label, packet)
            self.buffer = []

    def run(self):
        global stop_flag

        while not stop_flag:
            try:
                ch = self.src_ser.read(1)

                if not ch:
                    continue

                # Forward immediately to destination
                self.dst_ser.write(ch)
                self.dst_ser.flush()

                # Ignore NUL in monitor display
                if ch == "\x00":
                    continue

                # If CR was just seen, ignore following LF
                if self.last_was_cr and ch == "\n":
                    self.last_was_cr = False
                    continue

                # If FD was just seen, ignore following FA
                if self.last_was_fd and ch == "\xFA":
                    self.last_was_fd = False
                    continue

                # End of packet on CR or LF
                if ch in ("\r", "\n"):
                    self.flush_packet()
                    self.last_was_cr = (ch == "\r")
                    self.last_was_fd = False
                    continue

                # End of packet on FD
                # If FA follows, it will be ignored by the rule above
                if ch == "\xFD":
                    self.flush_packet()
                    self.last_was_fd = True
                    self.last_was_cr = False
                    continue

                # A bare FA may also appear as a terminator in some captures
                if ch == "\xFA":
                    self.flush_packet()
                    self.last_was_fd = False
                    self.last_was_cr = False
                    continue

                self.last_was_cr = False
                self.last_was_fd = False
                self.buffer.append(ch)

            except Exception as e:
                log_message(self.logfile,
                    "ERROR in %s: %s" % (self.direction_label, str(e)))
                break

        self.flush_packet() # class replaced 2026/04/03 use x'FA' x'FD'

def main():
    global stop_flag

    ser_a = None
    ser_b = None
    logfile = None

    try:
        logfile = open(LOG_PATH, "w")

        header = []
        header.append("Serial bridge log started: %s" % time.strftime("%Y-%m-%d %H:%M:%S"))
        header.append("Log file: %s" % LOG_PATH)
        header.append("Bridge mode active")
        header.append("%s: %s @ %d" % (PORT_A_NAME, PORT_A_DEV, PORT_A_BAUD))
        header.append("%s: %s @ %d" % (PORT_B_NAME, PORT_B_DEV, PORT_B_BAUD))
        header.append("")
        header_text = "\n".join(header)

        print header_text
        logfile.write(header_text + "\n")
        logfile.flush()

        ser_a = serial.Serial(PORT_A_DEV, PORT_A_BAUD, timeout=1)
        ser_b = serial.Serial(PORT_B_DEV, PORT_B_BAUD, timeout=1)

        log_message(logfile, "Opened %s on %s @ %d" % (PORT_A_NAME, PORT_A_DEV, PORT_A_BAUD))
        log_message(logfile, "Opened %s on %s @ %d" % (PORT_B_NAME, PORT_B_DEV, PORT_B_BAUD))
        log_message(logfile, "Forwarding traffic both directions...")
        log_message(logfile, "")

        t_ab = BridgeThread(
            ser_a, ser_b,
            "%s -> %s" % (PORT_A_NAME, PORT_B_NAME),
            logfile
        )

        t_ba = BridgeThread(
            ser_b, ser_a,
            "%s -> %s" % (PORT_B_NAME, PORT_A_NAME),
            logfile
        )

        t_ab.daemon = True
        t_ba.daemon = True

        t_ab.start()
        t_ba.start()

        while True:
            time.sleep(0.2)

    except KeyboardInterrupt:
        print
        print "Ctrl+C received. Shutting down cleanly..."
        if logfile:
            logfile.write("\nCtrl+C received. Shutting down cleanly...\n")
            logfile.flush()
        stop_flag = True

    except Exception as e:
        print "Fatal error:", str(e)
        if logfile:
            logfile.write("Fatal error: %s\n" % str(e))
            logfile.flush()
        stop_flag = True

    finally:
        time.sleep(0.5)

        if ser_a and ser_a.isOpen():
            ser_a.close()
        if ser_b and ser_b.isOpen():
            ser_b.close()

        if logfile:
            logfile.write("Log closed: %s\n" % time.strftime("%Y-%m-%d %H:%M:%S"))
            logfile.close()

        print "Serial ports closed."
        print "Log saved to:", LOG_PATH


if __name__ == "__main__":
    main()

(th)
tahanson43206
Site Admin
Posts: 493
Joined: Wed Apr 10, 2024 11:24 pm
Location: Earth
Contact:

Re: Python 2 on Raspberry Pi Linux 7

Post by tahanson43206 »

Data from two way run Thursday 2026/04/02 ...

Code: Select all

cat serial_bridge_20260403_012524.log 
Serial bridge log started: 2026-04-03 01:25:24
Log file: ./serial_bridge_20260403_012524.log
Bridge mode active
FLOWARM: /dev/ttyUSB0 @ 9600
LYNXARM: /dev/ttyUSB1 @ 9600

Opened FLOWARM on /dev/ttyUSB0 @ 9600
Opened LYNXARM on /dev/ttyUSB1 @ 9600
Forwarding traffic both directions...

[2026-04-03 01:28:12] FLOWARM -> LYNXARM
ASCII:  #0 P1500 #1 P2068 #2 P1790 #3 P202 #4 P500 #5 P1500 #6 P1500 #7 P1500 T1000
HEX  : 20 23 30 20 50 31 35 30 30 20 23 31 20 50 32 30 36 38 20 23 32 20 50 31 37 39 30 20 23 33 20 50 32 30 32 20 23 34 20 50 35 30 30 20 23 35 20 50 31 35 30 30 20 23 36 20 50 31 35 30 30 20 23 37 20 50 31 35 30 30 20 54 31 30 30 30
LEN  : 76

[2026-04-03 01:28:12] FLOWARM -> LYNXARM
ASCII: #1:0
HEX  : 23 31 3A 30
LEN  : 4

[2026-04-03 01:28:12] FLOWARM -> LYNXARM
ASCII: AL BL CL DL EL FL VG VH
HEX  : 41 4C 20 42 4C 20 43 4C 20 44 4C 20 45 4C 20 46 4C 20 56 47 20 56 48
LEN  : 23

[2026-04-03 01:28:13] FLOWARM -> LYNXARM
ASCII: AL BL CL DL EL FL VG VH
HEX  : 41 4C 20 42 4C 20 43 4C 20 44 4C 20 45 4C 20 46 4C 20 56 47 20 56 48
LEN  : 23

[2026-04-03 01:28:13] FLOWARM -> LYNXARM
ASCII: AL BL CL DL EL FL VG VH
HEX  : 41 4C 20 42 4C 20 43 4C 20 44 4C 20 45 4C 20 46 4C 20 56 47 20 56 48
LEN  : 23

[2026-04-03 01:28:14] FLOWARM -> LYNXARM
ASCII: AL BL CL DL EL FL VG VH
HEX  : 41 4C 20 42 4C 20 43 4C 20 44 4C 20 45 4C 20 46 4C 20 56 47 20 56 48
LEN  : 23

[2026-04-03 01:28:14] FLOWARM -> LYNXARM
ASCII: AL BL CL DL EL FL VG VH
HEX  : 41 4C 20 42 4C 20 43 4C 20 44 4C 20 45 4C 20 46 4C 20 56 47 20 56 48
LEN  : 23

[2026-04-03 01:28:15] FLOWARM -> LYNXARM
ASCII: AL BL CL DL EL FL VG VH
HEX  : 41 4C 20 42 4C 20 43 4C 20 44 4C 20 45 4C 20 46 4C 20 56 47 20 56 48
LEN  : 23

[2026-04-03 01:28:15] FLOWARM -> LYNXARM
ASCII: AL BL CL DL EL FL VG VH
HEX  : 41 4C 20 42 4C 20 43 4C 20 44 4C 20 45 4C 20 46 4C 20 56 47 20 56 48
LEN  : 23

[2026-04-03 01:28:16] FLOWARM -> LYNXARM
ASCII: AL BL CL DL EL FL VG VH
HEX  : 41 4C 20 42 4C 20 43 4C 20 44 4C 20 45 4C 20 46 4C 20 56 47 20 56 48
LEN  : 23

[2026-04-03 01:28:16] FLOWARM -> LYNXARM
ASCII: AL BL CL DL EL FL VG VH
HEX  : 41 4C 20 42 4C 20 43 4C 20 44 4C 20 45 4C 20 46 4C 20 56 47 20 56 48
LEN  : 23

[2026-04-03 01:28:16] FLOWARM -> LYNXARM
ASCII: AL BL CL DL EL FL VG VH
HEX  : 41 4C 20 42 4C 20 43 4C 20 44 4C 20 45 4C 20 46 4C 20 56 47 20 56 48
LEN  : 23

[2026-04-03 01:28:17] FLOWARM -> LYNXARM
ASCII: AL BL CL DL EL FL VG VH
HEX  : 41 4C 20 42 4C 20 43 4C 20 44 4C 20 45 4C 20 46 4C 20 56 47 20 56 48
LEN  : 23

[2026-04-03 01:28:17] FLOWARM -> LYNXARM
ASCII: AL BL CL DL EL FL VG VH
HEX  : 41 4C 20 42 4C 20 43 4C 20 44 4C 20 45 4C 20 46 4C 20 56 47 20 56 48
LEN  : 23

[2026-04-03 01:28:18] FLOWARM -> LYNXARM
ASCII: AL BL CL DL EL FL VG VH
HEX  : 41 4C 20 42 4C 20 43 4C 20 44 4C 20 45 4C 20 46 4C 20 56 47 20 56 48
LEN  : 23

[2026-04-03 01:28:18] FLOWARM -> LYNXARM
ASCII: AL BL CL DL EL FL VG VH
HEX  : 41 4C 20 42 4C 20 43 4C 20 44 4C 20 45 4C 20 46 4C 20 56 47 20 56 48
LEN  : 23

[2026-04-03 01:28:19] FLOWARM -> LYNXARM
ASCII: AL BL CL DL EL FL VG VH
HEX  : 41 4C 20 42 4C 20 43 4C 20 44 4C 20 45 4C 20 46 4C 20 56 47 20 56 48
LEN  : 23

[2026-04-03 01:28:19] FLOWARM -> LYNXARM
ASCII: AL BL CL DL EL FL VG VH
HEX  : 41 4C 20 42 4C 20 43 4C 20 44 4C 20 45 4C 20 46 4C 20 56 47 20 56 48
LEN  : 23

[2026-04-03 01:28:20] FLOWARM -> LYNXARM
ASCII: AL BL CL DL EL FL VG VH
HEX  : 41 4C 20 42 4C 20 43 4C 20 44 4C 20 45 4C 20 46 4C 20 56 47 20 56 48
LEN  : 23

[2026-04-03 01:28:20] FLOWARM -> LYNXARM
ASCII: AL BL CL DL EL FL VG VH
HEX  : 41 4C 20 42 4C 20 43 4C 20 44 4C 20 45 4C 20 46 4C 20 56 47 20 56 48
LEN  : 23

[2026-04-03 01:28:21] FLOWARM -> LYNXARM
ASCII: AL BL CL DL EL FL VG VH
HEX  : 41 4C 20 42 4C 20 43 4C 20 44 4C 20 45 4C 20 46 4C 20 56 47 20 56 48
LEN  : 23

[2026-04-03 01:28:21] FLOWARM -> LYNXARM
ASCII:  #0 P1500 #1 P2121 #2 P1878 #3 P236 #4 P500 #5 P1500 #6 P1500 #7 P1500 T1000
HEX  : 20 23 30 20 50 31 35 30 30 20 23 31 20 50 32 31 32 31 20 23 32 20 50 31 38 37 38 20 23 33 20 50 32 33 36 20 23 34 20 50 35 30 30 20 23 35 20 50 31 35 30 30 20 23 36 20 50 31 35 30 30 20 23 37 20 50 31 35 30 30 20 54 31 30 30 30
LEN  : 76

[2026-04-03 01:28:21] FLOWARM -> LYNXARM
ASCII: #1:0
HEX  : 23 31 3A 30
LEN  : 4

[2026-04-03 01:28:21] FLOWARM -> LYNXARM
ASCII: AL BL CL DL EL FL VG VH
HEX  : 41 4C 20 42 4C 20 43 4C 20 44 4C 20 45 4C 20 46 4C 20 56 47 20 56 48
LEN  : 23

[2026-04-03 01:28:21] FLOWARM -> LYNXARM
ASCII: AL BL CL DL EL FL VG VH
HEX  : 41 4C 20 42 4C 20 43 4C 20 44 4C 20 45 4C 20 46 4C 20 56 47 20 56 48
LEN  : 23

[2026-04-03 01:28:22] FLOWARM -> LYNXARM
ASCII:  #0 P1500 #1 P2112 #2 P1870 #3 P238 #4 P500 #5 P1500 #6 P1500 #7 P1500 T1000
HEX  : 20 23 30 20 50 31 35 30 30 20 23 31 20 50 32 31 31 32 20 23 32 20 50 31 38 37 30 20 23 33 20 50 32 33 38 20 23 34 20 50 35 30 30 20 23 35 20 50 31 35 30 30 20 23 36 20 50 31 35 30 30 20 23 37 20 50 31 35 30 30 20 54 31 30 30 30
LEN  : 76

[2026-04-03 01:28:22] FLOWARM -> LYNXARM
ASCII: #1:0
HEX  : 23 31 3A 30
LEN  : 4

[2026-04-03 01:28:22] FLOWARM -> LYNXARM
ASCII:  #0 P1500 #1 P2081 #2 P1805 #3 P204 #4 P500 #5 P1500 #6 P1500 #7 P1500 T1000
HEX  : 20 23 30 20 50 31 35 30 30 20 23 31 20 50 32 30 38 31 20 23 32 20 50 31 38 30 35 20 23 33 20 50 32 30 34 20 23 34 20 50 35 30 30 20 23 35 20 50 31 35 30 30 20 23 36 20 50 31 35 30 30 20 23 37 20 50 31 35 30 30 20 54 31 30 30 30
LEN  : 76

[2026-04-03 01:28:22] FLOWARM -> LYNXARM
ASCII: #1:0
HEX  : 23 31 3A 30
LEN  : 4

[2026-04-03 01:28:22] FLOWARM -> LYNXARM
ASCII: AL BL CL DL EL FL VG VH
HEX  : 41 4C 20 42 4C 20 43 4C 20 44 4C 20 45 4C 20 46 4C 20 56 47 20 56 48
LEN  : 23

[2026-04-03 01:28:22] FLOWARM -> LYNXARM
ASCII:  #0 P1500 #1 P2077 #2 P1776 #3 P178 #4 P500 #5 P1500 #6 P1500 #7 P1500 T1000
HEX  : 20 23 30 20 50 31 35 30 30 20 23 31 20 50 32 30 37 37 20 23 32 20 50 31 37 37 36 20 23 33 20 50 31 37 38 20 23 34 20 50 35 30 30 20 23 35 20 50 31 35 30 30 20 23 36 20 50 31 35 30 30 20 23 37 20 50 31 35 30 30 20 54 31 30 30 30
LEN  : 76

[2026-04-03 01:28:22] FLOWARM -> LYNXARM
ASCII: #1:0
HEX  : 23 31 3A 30
LEN  : 4

[2026-04-03 01:28:22] FLOWARM -> LYNXARM
ASCII:  #0 P1500 #1 P2082 #2 P1753 #3 P151 #4 P500 #5 P1500 #6 P1500 #7 P1500 T1000
HEX  : 20 23 30 20 50 31 35 30 30 20 23 31 20 50 32 30 38 32 20 23 32 20 50 31 37 35 33 20 23 33 20 50 31 35 31 20 23 34 20 50 35 30 30 20 23 35 20 50 31 35 30 30 20 23 36 20 50 31 35 30 30 20 23 37 20 50 31 35 30 30 20 54 31 30 30 30
LEN  : 76

[2026-04-03 01:28:22] FLOWARM -> LYNXARM
ASCII: #1:0
HEX  : 23 31 3A 30
LEN  : 4

[2026-04-03 01:28:22] FLOWARM -> LYNXARM
ASCII: AL BL CL DL EL FL VG VH
HEX  : 41 4C 20 42 4C 20 43 4C 20 44 4C 20 45 4C 20 46 4C 20 56 47 20 56 48
LEN  : 23

[2026-04-03 01:28:22] FLOWARM -> LYNXARM
ASCII: AL BL CL DL EL FL VG VH
HEX  : 41 4C 20 42 4C 20 43 4C 20 44 4C 20 45 4C 20 46 4C 20 56 47 20 56 48
LEN  : 23

[2026-04-03 01:28:22] FLOWARM -> LYNXARM
ASCII:  #0 P1500 #1 P2084 #2 P1748 #3 P144 #4 P500 #5 P1500 #6 P1500 #7 P1500 T1000
HEX  : 20 23 30 20 50 31 35 30 30 20 23 31 20 50 32 30 38 34 20 23 32 20 50 31 37 34 38 20 23 33 20 50 31 34 34 20 23 34 20 50 35 30 30 20 23 35 20 50 31 35 30 30 20 23 36 20 50 31 35 30 30 20 23 37 20 50 31 35 30 30 20 54 31 30 30 30
LEN  : 76

[2026-04-03 01:28:23] FLOWARM -> LYNXARM
ASCII: #1:0
HEX  : 23 31 3A 30
LEN  : 4

[2026-04-03 01:28:23] FLOWARM -> LYNXARM
ASCII:  #0 P1500 #1 P2086 #2 P1743 #3 P136 #4 P500 #5 P1500 #6 P1500 #7 P1500 T1000
HEX  : 20 23 30 20 50 31 35 30 30 20 23 31 20 50 32 30 38 36 20 23 32 20 50 31 37 34 33 20 23 33 20 50 31 33 36 20 23 34 20 50 35 30 30 20 23 35 20 50 31 35 30 30 20 23 36 20 50 31 35 30 30 20 23 37 20 50 31 35 30 30 20 54 31 30 30 30
LEN  : 76

[2026-04-03 01:28:23] FLOWARM -> LYNXARM
ASCII: #1:0
HEX  : 23 31 3A 30
LEN  : 4

[2026-04-03 01:28:23] FLOWARM -> LYNXARM
ASCII: AL BL CL DL EL FL VG VH
HEX  : 41 4C 20 42 4C 20 43 4C 20 44 4C 20 45 4C 20 46 4C 20 56 47 20 56 48
LEN  : 23

[2026-04-03 01:28:23] FLOWARM -> LYNXARM
ASCII:  #0 P1500 #1 P2088 #2 P1737 #3 P128 #4 P500 #5 P1500 #6 P1500 #7 P1500 T1000
HEX  : 20 23 30 20 50 31 35 30 30 20 23 31 20 50 32 30 38 38 20 23 32 20 50 31 37 33 37 20 23 33 20 50 31 32 38 20 23 34 20 50 35 30 30 20 23 35 20 50 31 35 30 30 20 23 36 20 50 31 35 30 30 20 23 37 20 50 31 35 30 30 20 54 31 30 30 30
LEN  : 76

[2026-04-03 01:28:23] FLOWARM -> LYNXARM
ASCII: #1:0
HEX  : 23 31 3A 30
LEN  : 4

[2026-04-03 01:28:23] FLOWARM -> LYNXARM
ASCII: AL BL CL DL EL FL VG VH
HEX  : 41 4C 20 42 4C 20 43 4C 20 44 4C 20 45 4C 20 46 4C 20 56 47 20 56 48
LEN  : 23

[2026-04-03 01:28:23] FLOWARM -> LYNXARM
ASCII:  #0 P1500 #1 P2086 #2 P1724 #3 P118 #4 P500 #5 P1500 #6 P1500 #7 P1500 T1000
HEX  : 20 23 30 20 50 31 35 30 30 20 23 31 20 50 32 30 38 36 20 23 32 20 50 31 37 32 34 20 23 33 20 50 31 31 38 20 23 34 20 50 35 30 30 20 23 35 20 50 31 35 30 30 20 23 36 20 50 31 35 30 30 20 23 37 20 50 31 35 30 30 20 54 31 30 30 30
LEN  : 76

[2026-04-03 01:28:23] FLOWARM -> LYNXARM
ASCII: #1:0
HEX  : 23 31 3A 30
LEN  : 4

[2026-04-03 01:28:23] FLOWARM -> LYNXARM
ASCII: AL BL CL DL EL FL VG VH
HEX  : 41 4C 20 42 4C 20 43 4C 20 44 4C 20 45 4C 20 46 4C 20 56 47 20 56 48
LEN  : 23

[2026-04-03 01:28:23] FLOWARM -> LYNXARM
ASCII:  #0 P1500 #1 P2084 #2 P1712 #3 P107 #4 P500 #5 P1500 #6 P1500 #7 P1500 T1000
HEX  : 20 23 30 20 50 31 35 30 30 20 23 31 20 50 32 30 38 34 20 23 32 20 50 31 37 31 32 20 23 33 20 50 31 30 37 20 23 34 20 50 35 30 30 20 23 35 20 50 31 35 30 30 20 23 36 20 50 31 35 30 30 20 23 37 20 50 31 35 30 30 20 54 31 30 30 30
LEN  : 76

[2026-04-03 01:28:24] FLOWARM -> LYNXARM
ASCII: #1:0
HEX  : 23 31 3A 30
LEN  : 4

[2026-04-03 01:28:24] FLOWARM -> LYNXARM
ASCII:  #0 P1500 #1 P2093 #2 P1701 #3 P88 #4 P500 #5 P1500 #6 P1500 #7 P1500 T1000
HEX  : 20 23 30 20 50 31 35 30 30 20 23 31 20 50 32 30 39 33 20 23 32 20 50 31 37 30 31 20 23 33 20 50 38 38 20 23 34 20 50 35 30 30 20 23 35 20 50 31 35 30 30 20 23 36 20 50 31 35 30 30 20 23 37 20 50 31 35 30 30 20 54 31 30 30 30
LEN  : 75

[2026-04-03 01:28:24] FLOWARM -> LYNXARM
ASCII: #1:0
HEX  : 23 31 3A 30
LEN  : 4

[2026-04-03 01:28:24] FLOWARM -> LYNXARM
ASCII: AL BL CL DL EL FL VG VH
HEX  : 41 4C 20 42 4C 20 43 4C 20 44 4C 20 45 4C 20 46 4C 20 56 47 20 56 48
LEN  : 23

[2026-04-03 01:28:24] FLOWARM -> LYNXARM
ASCII:  #0 P1500 #1 P2089 #2 P1694 #3 P85 #4 P500 #5 P1500 #6 P1500 #7 P1500 T1000
HEX  : 20 23 30 20 50 31 35 30 30 20 23 31 20 50 32 30 38 39 20 23 32 20 50 31 36 39 34 20 23 33 20 50 38 35 20 23 34 20 50 35 30 30 20 23 35 20 50 31 35 30 30 20 23 36 20 50 31 35 30 30 20 23 37 20 50 31 35 30 30 20 54 31 30 30 30
LEN  : 75

[2026-04-03 01:28:24] FLOWARM -> LYNXARM
ASCII: #1:0
HEX  : 23 31 3A 30
LEN  : 4

[2026-04-03 01:28:24] FLOWARM -> LYNXARM
ASCII:  #0 P1500 #1 P2096 #2 P1682 #3 P65 #4 P500 #5 P1500 #6 P1500 #7 P1500 T1000
HEX  : 20 23 30 20 50 31 35 30 30 20 23 31 20 50 32 30 39 36 20 23 32 20 50 31 36 38 32 20 23 33 20 50 36 35 20 23 34 20 50 35 30 30 20 23 35 20 50 31 35 30 30 20 23 36 20 50 31 35 30 30 20 23 37 20 50 31 35 30 30 20 54 31 30 30 30
LEN  : 75

[2026-04-03 01:28:24] FLOWARM -> LYNXARM
ASCII: #1:0
HEX  : 23 31 3A 30
LEN  : 4

[2026-04-03 01:28:24] FLOWARM -> LYNXARM
ASCII: AL BL CL DL EL FL VG VH
HEX  : 41 4C 20 42 4C 20 43 4C 20 44 4C 20 45 4C 20 46 4C 20 56 47 20 56 48
LEN  : 23

[2026-04-03 01:28:24] FLOWARM -> LYNXARM
ASCII:  #0 P1500 #1 P2098 #2 P1669 #3 P51 #4 P500 #5 P1500 #6 P1500 #7 P1500 T1000
HEX  : 20 23 30 20 50 31 35 30 30 20 23 31 20 50 32 30 39 38 20 23 32 20 50 31 36 36 39 20 23 33 20 50 35 31 20 23 34 20 50 35 30 30 20 23 35 20 50 31 35 30 30 20 23 36 20 50 31 35 30 30 20 23 37 20 50 31 35 30 30 20 54 31 30 30 30
LEN  : 75

[2026-04-03 01:28:24] FLOWARM -> LYNXARM
ASCII: #1:0
HEX  : 23 31 3A 30
LEN  : 4

[2026-04-03 01:28:25] FLOWARM -> LYNXARM
ASCII:  #0 P1500 #1 P2119 #2 P1637 #3 P-2 #4 P500 #5 P1500 #6 P1500 #7 P1500 T1000
HEX  : 20 23 30 20 50 31 35 30 30 20 23 31 20 50 32 31 31 39 20 23 32 20 50 31 36 33 37 20 23 33 20 50 2D 32 20 23 34 20 50 35 30 30 20 23 35 20 50 31 35 30 30 20 23 36 20 50 31 35 30 30 20 23 37 20 50 31 35 30 30 20 54 31 30 30 30
LEN  : 75

[2026-04-03 01:28:25] FLOWARM -> LYNXARM
ASCII: #1:0
HEX  : 23 31 3A 30
LEN  : 4

[2026-04-03 01:28:25] FLOWARM -> LYNXARM
ASCII: AL BL CL DL EL FL VG VH
HEX  : 41 4C 20 42 4C 20 43 4C 20 44 4C 20 45 4C 20 46 4C 20 56 47 20 56 48
LEN  : 23

[2026-04-03 01:28:25] FLOWARM -> LYNXARM
ASCII:  #0 P1500 #1 P2119 #2 P1637 #3 P-2 #4 P500 #5 P1500 #6 P1500 #7 P1500 T1000
HEX  : 20 23 30 20 50 31 35 30 30 20 23 31 20 50 32 31 31 39 20 23 32 20 50 31 36 33 37 20 23 33 20 50 2D 32 20 23 34 20 50 35 30 30 20 23 35 20 50 31 35 30 30 20 23 36 20 50 31 35 30 30 20 23 37 20 50 31 35 30 30 20 54 31 30 30 30
LEN  : 75

[2026-04-03 01:28:25] FLOWARM -> LYNXARM
ASCII: #1:0
HEX  : 23 31 3A 30
LEN  : 4

[2026-04-03 01:28:25] FLOWARM -> LYNXARM
ASCII: AL BL CL DL EL FL VG VH
HEX  : 41 4C 20 42 4C 20 43 4C 20 44 4C 20 45 4C 20 46 4C 20 56 47 20 56 48
LEN  : 23

[2026-04-03 01:28:25] FLOWARM -> LYNXARM
ASCII:  #0 P1500 #1 P2162 #2 P1544 #3 P-137 #4 P500 #5 P1500 #6 P1500 #7 P1500 T1000
HEX  : 20 23 30 20 50 31 35 30 30 20 23 31 20 50 32 31 36 32 20 23 32 20 50 31 35 34 34 20 23 33 20 50 2D 31 33 37 20 23 34 20 50 35 30 30 20 23 35 20 50 31 35 30 30 20 23 36 20 50 31 35 30 30 20 23 37 20 50 31 35 30 30 20 54 31 30 30 30
LEN  : 77

[2026-04-03 01:28:25] FLOWARM -> LYNXARM
ASCII: #1:0
HEX  : 23 31 3A 30
LEN  : 4

[2026-04-03 01:28:25] FLOWARM -> LYNXARM
ASCII: AL BL CL DL EL FL VG VH
HEX  : 41 4C 20 42 4C 20 43 4C 20 44 4C 20 45 4C 20 46 4C 20 56 47 20 56 48
LEN  : 23

[2026-04-03 01:28:25] FLOWARM -> LYNXARM
ASCII:  #0 P1500 #1 P2162 #2 P1544 #3 P-137 #4 P500 #5 P1500 #6 P1500 #7 P1500 T1000
HEX  : 20 23 30 20 50 31 35 30 30 20 23 31 20 50 32 31 36 32 20 23 32 20 50 31 35 34 34 20 23 33 20 50 2D 31 33 37 20 23 34 20 50 35 30 30 20 23 35 20 50 31 35 30 30 20 23 36 20 50 31 35 30 30 20 23 37 20 50 31 35 30 30 20 54 31 30 30 30
LEN  : 77

[2026-04-03 01:28:25] FLOWARM -> LYNXARM
ASCII: #1:0
HEX  : 23 31 3A 30
LEN  : 4

[2026-04-03 01:28:25] FLOWARM -> LYNXARM
ASCII:  #0 P1500 #1 P2175 #2 P1487 #3 P-207 #4 P500 #5 P1500 #6 P1500 #7 P1500 T1000
HEX  : 20 23 30 20 50 31 35 30 30 20 23 31 20 50 32 31 37 35 20 23 32 20 50 31 34 38 37 20 23 33 20 50 2D 32 30 37 20 23 34 20 50 35 30 30 20 23 35 20 50 31 35 30 30 20 23 36 20 50 31 35 30 30 20 23 37 20 50 31 35 30 30 20 54 31 30 30 30
LEN  : 77

[2026-04-03 01:28:26] FLOWARM -> LYNXARM
ASCII: #1:0
HEX  : 23 31 3A 30
LEN  : 4

[2026-04-03 01:28:26] FLOWARM -> LYNXARM
ASCII: AL BL CL DL EL FL VG VH
HEX  : 41 4C 20 42 4C 20 43 4C 20 44 4C 20 45 4C 20 46 4C 20 56 47 20 56 48
LEN  : 23

[2026-04-03 01:28:26] FLOWARM -> LYNXARM
ASCII:  #0 P1500 #1 P2172 #2 P1477 #3 P-214 #4 P500 #5 P1500 #6 P1500 #7 P1500 T1000
HEX  : 20 23 30 20 50 31 35 30 30 20 23 31 20 50 32 31 37 32 20 23 32 20 50 31 34 37 37 20 23 33 20 50 2D 32 31 34 20 23 34 20 50 35 30 30 20 23 35 20 50 31 35 30 30 20 23 36 20 50 31 35 30 30 20 23 37 20 50 31 35 30 30 20 54 31 30 30 30
LEN  : 77

[2026-04-03 01:28:26] FLOWARM -> LYNXARM
ASCII: #1:0
HEX  : 23 31 3A 30
LEN  : 4

[2026-04-03 01:28:26] FLOWARM -> LYNXARM
ASCII: AL BL CL DL EL FL VG VH
HEX  : 41 4C 20 42 4C 20 43 4C 20 44 4C 20 45 4C 20 46 4C 20 56 47 20 56 48
LEN  : 23

[2026-04-03 01:28:26] FLOWARM -> LYNXARM
ASCII:  #0 P1500 #1 P2185 #2 P1397 #3 P-308 #4 P500 #5 P1500 #6 P1500 #7 P1500 T1000
HEX  : 20 23 30 20 50 31 35 30 30 20 23 31 20 50 32 31 38 35 20 23 32 20 50 31 33 39 37 20 23 33 20 50 2D 33 30 38 20 23 34 20 50 35 30 30 20 23 35 20 50 31 35 30 30 20 23 36 20 50 31 35 30 30 20 23 37 20 50 31 35 30 30 20 54 31 30 30 30
LEN  : 77

[2026-04-03 01:28:26] FLOWARM -> LYNXARM
ASCII: #1:0
HEX  : 23 31 3A 30
LEN  : 4

[2026-04-03 01:28:26] FLOWARM -> LYNXARM
ASCII: AL BL CL DL EL FL VG VH
HEX  : 41 4C 20 42 4C 20 43 4C 20 44 4C 20 45 4C 20 46 4C 20 56 47 20 56 48
LEN  : 23

[2026-04-03 01:28:26] FLOWARM -> LYNXARM
ASCII:  #0 P1500 #1 P2185 #2 P1397 #3 P-308 #4 P500 #5 P1500 #6 P1500 #7 P1500 T1000
HEX  : 20 23 30 20 50 31 35 30 30 20 23 31 20 50 32 31 38 35 20 23 32 20 50 31 33 39 37 20 23 33 20 50 2D 33 30 38 20 23 34 20 50 35 30 30 20 23 35 20 50 31 35 30 30 20 23 36 20 50 31 35 30 30 20 23 37 20 50 31 35 30 30 20 54 31 30 30 30
LEN  : 77

[2026-04-03 01:28:26] FLOWARM -> LYNXARM
ASCII: #1:0
HEX  : 23 31 3A 30
LEN  : 4

[2026-04-03 01:28:26] FLOWARM -> LYNXARM
ASCII:  #0 P1500 #1 P2193 #2 P1386 #3 P-326 #4 P500 #5 P1500 #6 P1500 #7 P1500 T1000
HEX  : 20 23 30 20 50 31 35 30 30 20 23 31 20 50 32 31 39 33 20 23 32 20 50 31 33 38 36 20 23 33 20 50 2D 33 32 36 20 23 34 20 50 35 30 30 20 23 35 20 50 31 35 30 30 20 23 36 20 50 31 35 30 30 20 23 37 20 50 31 35 30 30 20 54 31 30 30 30
LEN  : 77

[2026-04-03 01:28:26] FLOWARM -> LYNXARM
ASCII: #1:0
HEX  : 23 31 3A 30
LEN  : 4

[2026-04-03 01:28:27] FLOWARM -> LYNXARM
ASCII: AL BL CL DL EL FL VG VH
HEX  : 41 4C 20 42 4C 20 43 4C 20 44 4C 20 45 4C 20 46 4C 20 56 47 20 56 48
LEN  : 23

[2026-04-03 01:28:27] FLOWARM -> LYNXARM
ASCII:  #0 P1500 #1 P2195 #2 P1383 #3 P-331 #4 P500 #5 P1500 #6 P1500 #7 P1500 T1000
HEX  : 20 23 30 20 50 31 35 30 30 20 23 31 20 50 32 31 39 35 20 23 32 20 50 31 33 38 33 20 23 33 20 50 2D 33 33 31 20 23 34 20 50 35 30 30 20 23 35 20 50 31 35 30 30 20 23 36 20 50 31 35 30 30 20 23 37 20 50 31 35 30 30 20 54 31 30 30 30
LEN  : 77

[2026-04-03 01:28:27] FLOWARM -> LYNXARM
ASCII: #1:0
HEX  : 23 31 3A 30
LEN  : 4

[2026-04-03 01:28:27] FLOWARM -> LYNXARM
ASCII:  #0 P1500 #1 P2195 #2 P1383 #3 P-331 #4 P500 #5 P1500 #6 P1500 #7 P1500 T1000
HEX  : 20 23 30 20 50 31 35 30 30 20 23 31 20 50 32 31 39 35 20 23 32 20 50 31 33 38 33 20 23 33 20 50 2D 33 33 31 20 23 34 20 50 35 30 30 20 23 35 20 50 31 35 30 30 20 23 36 20 50 31 35 30 30 20 23 37 20 50 31 35 30 30 20 54 31 30 30 30
LEN  : 77

[2026-04-03 01:28:27] FLOWARM -> LYNXARM
ASCII: #1:0
HEX  : 23 31 3A 30
LEN  : 4

[2026-04-03 01:28:27] FLOWARM -> LYNXARM
ASCII: AL BL CL DL EL FL VG VH
HEX  : 41 4C 20 42 4C 20 43 4C 20 44 4C 20 45 4C 20 46 4C 20 56 47 20 56 48
LEN  : 23

[2026-04-03 01:28:27] FLOWARM -> LYNXARM
ASCII: AL BL CL DL EL FL VG VH
HEX  : 41 4C 20 42 4C 20 43 4C 20 44 4C 20 45 4C 20 46 4C 20 56 47 20 56 48
LEN  : 23

[2026-04-03 01:28:27] FLOWARM -> LYNXARM
ASCII:  #0 P1500 #1 P2201 #2 P1371 #3 P-350 #4 P500 #5 P1500 #6 P1500 #7 P1500 T1000
HEX  : 20 23 30 20 50 31 35 30 30 20 23 31 20 50 32 32 30 31 20 23 32 20 50 31 33 37 31 20 23 33 20 50 2D 33 35 30 20 23 34 20 50 35 30 30 20 23 35 20 50 31 35 30 30 20 23 36 20 50 31 35 30 30 20 23 37 20 50 31 35 30 30 20 54 31 30 30 30
LEN  : 77

[2026-04-03 01:28:27] FLOWARM -> LYNXARM
ASCII: #1:0
HEX  : 23 31 3A 30
LEN  : 4

[2026-04-03 01:28:27] FLOWARM -> LYNXARM
ASCII:  #0 P1500 #1 P2212 #2 P1344 #3 P-387 #4 P500 #5 P1500 #6 P1500 #7 P1500 T1000
HEX  : 20 23 30 20 50 31 35 30 30 20 23 31 20 50 32 32 31 32 20 23 32 20 50 31 33 34 34 20 23 33 20 50 2D 33 38 37 20 23 34 20 50 35 30 30 20 23 35 20 50 31 35 30 30 20 23 36 20 50 31 35 30 30 20 23 37 20 50 31 35 30 30 20 54 31 30 30 30
LEN  : 77

[2026-04-03 01:28:27] FLOWARM -> LYNXARM
ASCII: #1:0
HEX  : 23 31 3A 30
LEN  : 4

[2026-04-03 01:28:28] FLOWARM -> LYNXARM
ASCII: AL BL CL DL EL FL VG VH
HEX  : 41 4C 20 42 4C 20 43 4C 20 44 4C 20 45 4C 20 46 4C 20 56 47 20 56 48
LEN  : 23

[2026-04-03 01:28:28] FLOWARM -> LYNXARM
ASCII:  #0 P1500 #1 P2217 #2 P1325 #3 P-411 #4 P500 #5 P1500 #6 P1500 #7 P1500 T1000
HEX  : 20 23 30 20 50 31 35 30 30 20 23 31 20 50 32 32 31 37 20 23 32 20 50 31 33 32 35 20 23 33 20 50 2D 34 31 31 20 23 34 20 50 35 30 30 20 23 35 20 50 31 35 30 30 20 23 36 20 50 31 35 30 30 20 23 37 20 50 31 35 30 30 20 54 31 30 30 30
LEN  : 77

[2026-04-03 01:28:28] FLOWARM -> LYNXARM
ASCII: #1:0
HEX  : 23 31 3A 30
LEN  : 4

[2026-04-03 01:28:28] FLOWARM -> LYNXARM
ASCII: AL BL CL DL EL FL VG VH
HEX  : 41 4C 20 42 4C 20 43 4C 20 44 4C 20 45 4C 20 46 4C 20 56 47 20 56 48
LEN  : 23

[2026-04-03 01:28:28] FLOWARM -> LYNXARM
ASCII:  #0 P1500 #1 P2217 #2 P1325 #3 P-411 #4 P500 #5 P1500 #6 P1500 #7 P1500 T1000
HEX  : 20 23 30 20 50 31 35 30 30 20 23 31 20 50 32 32 31 37 20 23 32 20 50 31 33 32 35 20 23 33 20 50 2D 34 31 31 20 23 34 20 50 35 30 30 20 23 35 20 50 31 35 30 30 20 23 36 20 50 31 35 30 30 20 23 37 20 50 31 35 30 30 20 54 31 30 30 30
LEN  : 77

[2026-04-03 01:28:28] FLOWARM -> LYNXARM
ASCII: #1:0
HEX  : 23 31 3A 30
LEN  : 4

[2026-04-03 01:28:28] FLOWARM -> LYNXARM
ASCII: AL BL CL DL EL FL VG VH
HEX  : 41 4C 20 42 4C 20 43 4C 20 44 4C 20 45 4C 20 46 4C 20 56 47 20 56 48
LEN  : 23

[2026-04-03 01:28:28] FLOWARM -> LYNXARM
ASCII: AL BL CL DL EL FL VG VH
HEX  : 41 4C 20 42 4C 20 43 4C 20 44 4C 20 45 4C 20 46 4C 20 56 47 20 56 48
LEN  : 23

[2026-04-03 01:28:28] FLOWARM -> LYNXARM
ASCII: AL BL CL DL EL FL VG VH
HEX  : 41 4C 20 42 4C 20 43 4C 20 44 4C 20 45 4C 20 46 4C 20 56 47 20 56 48
LEN  : 23

[2026-04-03 01:28:28] FLOWARM -> LYNXARM
ASCII: AL BL CL DL EL FL VG VH
HEX  : 41 4C 20 42 4C 20 43 4C 20 44 4C 20 45 4C 20 46 4C 20 56 47 20 56 48
LEN  : 23

[2026-04-03 01:28:28] FLOWARM -> LYNXARM
ASCII: AL BL CL DL EL FL VG VH
HEX  : 41 4C 20 42 4C 20 43 4C 20 44 4C 20 45 4C 20 46 4C 20 56 47 20 56 48
LEN  : 23

[2026-04-03 01:28:28] FLOWARM -> LYNXARM
ASCII: AL BL CL DL EL FL VG VH
HEX  : 41 4C 20 42 4C 20 43 4C 20 44 4C 20 45 4C 20 46 4C 20 56 47 20 56 48
LEN  : 23

[2026-04-03 01:28:28] FLOWARM -> LYNXARM
ASCII: AL BL CL DL EL FL VG VH
HEX  : 41 4C 20 42 4C 20 43 4C 20 44 4C 20 45 4C 20 46 4C 20 56 47 20 56 48
LEN  : 23

[2026-04-03 01:28:29] FLOWARM -> LYNXARM
ASCII: AL BL CL DL EL FL VG VH
HEX  : 41 4C 20 42 4C 20 43 4C 20 44 4C 20 45 4C 20 46 4C 20 56 47 20 56 48
LEN  : 23

[2026-04-03 01:28:29] FLOWARM -> LYNXARM
ASCII: AL BL CL DL EL FL VG VH
HEX  : 41 4C 20 42 4C 20 43 4C 20 44 4C 20 45 4C 20 46 4C 20 56 47 20 56 48
LEN  : 23

[2026-04-03 01:28:30] FLOWARM -> LYNXARM
ASCII: AL BL CL DL EL FL VG VH
HEX  : 41 4C 20 42 4C 20 43 4C 20 44 4C 20 45 4C 20 46 4C 20 56 47 20 56 48
LEN  : 23

[2026-04-03 01:28:30] FLOWARM -> LYNXARM
ASCII: AL BL CL DL EL FL VG VH
HEX  : 41 4C 20 42 4C 20 43 4C 20 44 4C 20 45 4C 20 46 4C 20 56 47 20 56 48
LEN  : 23

[2026-04-03 01:28:31] FLOWARM -> LYNXARM
ASCII: AL BL CL DL EL FL VG VH
HEX  : 41 4C 20 42 4C 20 43 4C 20 44 4C 20 45 4C 20 46 4C 20 56 47 20 56 48
LEN  : 23

[2026-04-03 01:28:31] FLOWARM -> LYNXARM
ASCII: AL BL CL DL EL FL VG VH
HEX  : 41 4C 20 42 4C 20 43 4C 20 44 4C 20 45 4C 20 46 4C 20 56 47 20 56 48
LEN  : 23

[2026-04-03 01:28:32] FLOWARM -> LYNXARM
ASCII: AL BL CL DL EL FL VG VH
HEX  : 41 4C 20 42 4C 20 43 4C 20 44 4C 20 45 4C 20 46 4C 20 56 47 20 56 48
LEN  : 23

[2026-04-03 01:28:32] FLOWARM -> LYNXARM
ASCII: AL BL CL DL EL FL VG VH
HEX  : 41 4C 20 42 4C 20 43 4C 20 44 4C 20 45 4C 20 46 4C 20 56 47 20 56 48
LEN  : 23

[2026-04-03 01:28:33] FLOWARM -> LYNXARM
ASCII: AL BL CL DL EL FL VG VH
HEX  : 41 4C 20 42 4C 20 43 4C 20 44 4C 20 45 4C 20 46 4C 20 56 47 20 56 48
LEN  : 23

[2026-04-03 01:28:33] FLOWARM -> LYNXARM
ASCII: AL BL CL DL EL FL VG VH
HEX  : 41 4C 20 42 4C 20 43 4C 20 44 4C 20 45 4C 20 46 4C 20 56 47 20 56 48
LEN  : 23

[2026-04-03 01:28:34] FLOWARM -> LYNXARM
ASCII: AL BL CL DL EL FL VG VH
HEX  : 41 4C 20 42 4C 20 43 4C 20 44 4C 20 45 4C 20 46 4C 20 56 47 20 56 48
LEN  : 23

[2026-04-03 01:28:34] FLOWARM -> LYNXARM
ASCII: AL BL CL DL EL FL VG VH
HEX  : 41 4C 20 42 4C 20 43 4C 20 44 4C 20 45 4C 20 46 4C 20 56 47 20 56 48
LEN  : 23

[2026-04-03 01:28:34] FLOWARM -> LYNXARM
ASCII: AL BL CL DL EL FL VG VH
HEX  : 41 4C 20 42 4C 20 43 4C 20 44 4C 20 45 4C 20 46 4C 20 56 47 20 56 48
LEN  : 23

[2026-04-03 01:28:35] FLOWARM -> LYNXARM
ASCII: AL BL CL DL EL FL VG VH
HEX  : 41 4C 20 42 4C 20 43 4C 20 44 4C 20 45 4C 20 46 4C 20 56 47 20 56 48
LEN  : 23

[2026-04-03 01:28:35] FLOWARM -> LYNXARM
ASCII: AL BL CL DL EL FL VG VH
HEX  : 41 4C 20 42 4C 20 43 4C 20 44 4C 20 45 4C 20 46 4C 20 56 47 20 56 48
LEN  : 23

[2026-04-03 01:28:36] FLOWARM -> LYNXARM
ASCII: AL BL CL DL EL FL VG VH
HEX  : 41 4C 20 42 4C 20 43 4C 20 44 4C 20 45 4C 20 46 4C 20 56 47 20 56 48
LEN  : 23

[2026-04-03 01:28:36] FLOWARM -> LYNXARM
ASCII: AL BL CL DL EL FL VG VH
HEX  : 41 4C 20 42 4C 20 43 4C 20 44 4C 20 45 4C 20 46 4C 20 56 47 20 56 48
LEN  : 23

[2026-04-03 01:28:37] FLOWARM -> LYNXARM
ASCII: AL BL CL DL EL FL VG VH
HEX  : 41 4C 20 42 4C 20 43 4C 20 44 4C 20 45 4C 20 46 4C 20 56 47 20 56 48
LEN  : 23

[2026-04-03 01:28:37] FLOWARM -> LYNXARM
ASCII: AL BL CL DL EL FL VG VH
HEX  : 41 4C 20 42 4C 20 43 4C 20 44 4C 20 45 4C 20 46 4C 20 56 47 20 56 48
LEN  : 23


Ctrl+C received. Shutting down cleanly...
[2026-04-03 01:30:06] LYNXARM -> FLOWARM
ASCII: 111111..111111..111111..111111..111111..111111..111111..111111..111111..111111..111111..111111..111111..111111..111111..111111..111111..111111..111111..111111..111111..111111..111111..111111..111111..111111..111111..111111..111111..111111..111111..111111..111111..111111..111111..111111..111111..111111..111111..111111..111111..111111..111111..111111..111111..111111..111111..111111..111111..111111..111111..111111..111111..111111..111111..111111..111111..111111..111111..111111..111111..111111..111111..111111..111111..111111..
HEX  : 31 31 31 31 31 31 FD FA 31 31 31 31 31 31 FD FA 31 31 31 31 31 31 FD FA 31 31 31 31 31 31 FD FA 31 31 31 31 31 31 FD FA 31 31 31 31 31 31 FD FA 31 31 31 31 31 31 FD FA 31 31 31 31 31 31 FD FA 31 31 31 31 31 31 FD FA 31 31 31 31 31 31 FD FA 31 31 31 31 31 31 FD FA 31 31 31 31 31 31 FD FA 31 31 31 31 31 31 FD FA 31 31 31 31 31 31 FD FA 31 31 31 31 31 31 FD FA 31 31 31 31 31 31 FD FA 31 31 31 31 31 31 FD FA 31 31 31 31 31 31 FD FA 31 31 31 31 31 31 FD FA 31 31 31 31 31 31 FD FA 31 31 31 31 31 31 FD FA 31 31 31 31 31 31 FD FA 31 31 31 31 31 31 FD FA 31 31 31 31 31 31 FD FA 31 31 31 31 31 31 FD FA 31 31 31 31 31 31 FD FA 31 31 31 31 31 31 FD FA 31 31 31 31 31 31 FD FA 31 31 31 31 31 31 FD FA 31 31 31 31 31 31 FD FA 31 31 31 31 31 31 FD FA 31 31 31 31 31 31 FD FA 31 31 31 31 31 31 FD FA 31 31 31 31 31 31 FD FA 31 31 31 31 31 31 FD FA 31 31 31 31 31 31 FD FA 31 31 31 31 31 31 FD FA 31 31 31 31 31 31 FD FA 31 31 31 31 31 31 FD FA 31 31 31 31 31 31 FD FA 31 31 31 31 31 31 FD FA 31 31 31 31 31 31 FD FA 31 31 31 31 31 31 FD FA 31 31 31 31 31 31 FD FA 31 31 31 31 31 31 FD FA 31 31 31 31 31 31 FD FA 31 31 31 31 31 31 FD FA 31 31 31 31 31 31 FD FA 31 31 31 31 31 31 FD FA 31 31 31 31 31 31 FD FA 31 31 31 31 31 31 FD FA 31 31 31 31 31 31 FD FA 31 31 31 31 31 31 FD FA 31 31 31 31 31 31 FD FA 31 31 31 31 31 31 FD FA 31 31 31 31 31 31 FD FA 31 31 31 31 31 31 FD FA 31 31 31 31 31 31 FD FA 31 31 31 31 31 31 FD FA 31 31 31 31 31 31 FD FA 31 31 31 31 31 31 FD FA 31 31 31 31 31 31 FD FA 31 31 31 31 31 31 FD FA 31 31 31 31 31 31 FD FA 31 31 31 31 31 31 FD FA 31 31 31 31 31 31 FD FA
LEN  : 528

Log closed: 2026-04-03 01:30:06
pi@raspberrypi ~/raspberryPi2 $ 
	
(th)
tahanson43206
Site Admin
Posts: 493
Joined: Wed Apr 10, 2024 11:24 pm
Location: Earth
Contact:

Re: Python 2 on Raspberry Pi Linux 7

Post by tahanson43206 »

Program to send test commands to LynxMotion control board

Code: Select all

cat ssc32u_testservoV02.py 
# ssc32u_testservoV02.py

# ssc32u_handshakeV02.py

import serial
import time

# Identify the port connected to the SSC-32U
# On the RP2, this is typically /dev/ttyUSB1
robot_port = "/dev/ttyUSB1" 
try:
    bot = serial.Serial(robot_port, 9600, timeout=1)
    print "Connected to port: " + robot_port
    
    # Step 1: Send the Version Query to the SSC-32U
    print "Querying SSC-32U for Version  ."
    bot.write("VER\r")
    
    # Give the board a millisecond to breathe
    time.sleep(0.1)
    
    # Step 2: Read the response
    response = bot.readline().strip()
    
    if response:
        print "SUCCESS! SSC-32U Reports: " + response
    else:
        print "FAILURE: No response from SSC-32U. Check power/cable."
        
except Exception as e:
    print "ERROR: Could not open serial port: " + str(e)

# Use the confirmed port and 9600 baud rate

# bot = serial.Serial("/dev/ttyUSB1", 9600, timeout=1)

print "  - AL5D JOG UTILITY   -"
print "Enter 9 to Exit"

while True:
    try:
        user_input = raw_input("\nNext Move (Ch Pulse): ")
        if user_input == "9":
            break

        parts = user_input.split()
        if len(parts) != 2:
            print "Use: channel pulse << enter number space number"
            continue

        ch = int(parts[0])
        pw = int(parts[1])

        # Safety limits
        if pw < 500: pw = 500
        if pw > 2500: pw = 2500

        # Build the SSC-32U command T1000 fast T3000 slow
        cmd = "#" + str(ch) + "P" + str(pw) + "T3000\r"
        bot.write(cmd)

        # Query for completion
        while True:
            bot.write("Q\r")
            if bot.read(1) == ".":
                break
            time.sleep(0.05)
        print "Done."

    except Exception as e:
        print "Error: " + str(e)

bot.close()

This program works with the LynxMotion AL5D connected to RP2 via USB cable

(th)
Post Reply