06 Retrieving Chassis Feedback Information

From Waveshare Wiki
Revision as of 08:04, 21 March 2024 by Eng52 (talk | contribs) (→‎Overview)
Jump to: navigation, search

How to Retrievie Chassis Feedback Information

Upon startup, the lower-level systems of the product continuously send various types of feedback information to the upper-level systems. This feedback can be utilized to ascertain the current operational status of the product.

Typically, you would continuously monitor the feedback information from the lower-level systems. However, in this example, we will retrieve a single piece of JSON feedback information from the lower-level systems (you can continuously receive feedback information by commenting out or deleting the break line).

Select the code block below and run it using Ctrl + Enter. The loop will exit and display the feedback information after receiving the first complete JSON message with a "T" value of 1001. The feedback information includes the current wheel speed, IMU data, gimbal angle (if installed), arm angle (if installed), power voltage, and other data.

from base_ctrl import BaseController
import json

# Function for Detecting Raspberry Pi
def is_raspberry_pi5():
    with open('/proc/cpuinfo', 'r') as file:
        for line in file:
            if 'Model' in line:
                if 'Raspberry Pi 5' in line:
                    return True
                else:
                    return False

# Determine the GPIO Serial Device Name Based on the Raspberry Pi Model
if is_raspberry_pi5():
    base = BaseController('/dev/ttyAMA0', 115200)
else:
    base = BaseController('/dev/serial0', 115200)

# Implement an infinite loop to continuously monitor serial port data.
while True:
    try:
        # Read a line of data from the serial port, decode it into a 'utf-8' formatted string, and attempt to convert it into a JSON object.
        data_recv_buffer = json.loads(base.rl.readline().decode('utf-8'))
        # Check if the parsed data contains the key 'T'.
        if 'T' in data_recv_buffer:
            # If the value of 'T' is 1001, print the received data and break out of the loop.
            if data_recv_buffer['T'] == 1001:
                print(data_recv_buffer)
                break
    # If an exception occurs while reading or processing the data, ignore the exception and continue to listen for the next line of data.
    except:
        pass

Non-Blocking Method for Receiving JSON Information via Serial Port

The following code is intended for understanding the underlying principles of reading JSON information from a serial port and should not be executed.

class ReadLine:
    # Construct a constructor to initialize an instance of the ReadLine class.
    # s: The serial port object passed in for communication with the serial port.
    def __init__(self, s):
        self.buf = bytearray()  # Initialize a byte array to store data that has been read from the serial port but not yet processed.
        self.s = s  # Store the passed-in serial port object for subsequent use in reading serial port data.

	def readline(self):
		i = self.buf.find(b"\n") # Check if there is a newline character in the buffer.
		if i >= 0:
			r = self.buf[:i+1] # If there is a newline character, extract the data before the newline character.
			self.buf = self.buf[i+1:] # Update the buffer by removing the data that has been processed.
			return r
		while True:
			i = max(1, min(512, self.s.in_waiting)) # Retrieve the number of bytes available for reading, up to a maximum of 512 bytes.
			data = self.s.read(i) # Read data from the serial port.
			i = data.find(b"\n") # Search for a newline character.
			if i >= 0:
				r = self.buf + data[:i+1] # If a newline character is found, merge the data that has been read with the data in the buffer.
				self.buf[0:] = data[i+1:] # Update the buffer by removing the processed data.
				return r
			else:
				self.buf.extend(data) # If a newline character is not found, add the data to the buffer.
  • This method is designed for reading data from a serial port and returning a complete line of JSON data, delimited by a newline character (\n).
  • If there's already a complete line of data in the buffer, it returns that line directly.
  • If the buffer does not contain a complete line, the method uses the in_waiting function to check the number of bytes available for reading in the serial port's buffer, reading up to 512 bytes at a time.
  • The data read from the serial port is then merged with the data in the buffer.
  • The method checks the newly read data for a newline character. If found, it extracts the complete line of data and updates the buffer.
  • If no newline character is found, the new data is added to the buffer, and the method continues reading until a newline character is found.

Function Characteristics

  • Non-blocking: This function employs a non-blocking reading approach, meaning it does not halt the program's execution even if there's no data to read from the serial port. It waits until data is available.
  • Efficient: By using a small buffer and limiting the read amount to a maximum of 512 bytes at a time, the function reduces memory consumption and promptly processes data to prevent buffer overflow.
  • Flexible: The function can flexibly read data of any length and automatically deals with data split by newline characters. This makes it particularly suitable for reading structured data like JSON.
  • Reliable: The function is designed to account for various scenarios, such as insufficient buffer data or absence of newline characters in the read data, ensuring the accuracy and stability of the read operations.
  • Ideal for Real-time Use: This function is especially well-suited for real-time reading of JSON data from a serial port, especially in scenarios where non-blocking reads are required.