Update: 10.5
the current code:we are getting there slowly but we are getting there.
things are moving slow since im building a very rough prototype HAT on some perfboard for AiS and GPS since i will have to use it for my first channel corssing in march/april so yeah one of those boards will see some extra testing on a sailboat. (if a skipper wants to help me cross from Dover to calais please massage me, i will pay of course)
Thats all for today.
Now everything Behaves as planned (I did not plan anything at all) still need to add HDD in % and the alignment is kinda offthe current code:
Code:
import spidevimport RPi.GPIO as GPIOimport timeimport structimport socketimport osclass ST7789Display: def __init__(self, width=240, height=320, dc_pin=24, rst_pin=25, blk_pin=18): self.width = width self.height = height # GPIO Pins self.DC_PIN = dc_pin self.RST_PIN = rst_pin self.BLK_PIN = blk_pin # Setup GPIO GPIO.setmode(GPIO.BCM) GPIO.setwarnings(False) GPIO.setup(self.DC_PIN, GPIO.OUT) GPIO.setup(self.RST_PIN, GPIO.OUT) GPIO.setup(self.BLK_PIN, GPIO.OUT) # Setup PWM for backlight control self.backlight_pwm = GPIO.PWM(self.BLK_PIN, 1000) self.backlight_pwm.start(100) # Setup SPI self.spi = spidev.SpiDev() self.spi.open(0, 1) self.spi.max_speed_hz = 8000000 self.spi.mode = 0 # Character definitions self.chars = { ' ': [0b00000, 0b00000, 0b00000, 0b00000, 0b00000], '0': [0b01110, 0b10001, 0b10001, 0b10001, 0b01110], '1': [0b00100, 0b01100, 0b00100, 0b00100, 0b01110], '2': [0b01110, 0b10001, 0b00010, 0b00100, 0b11111], '3': [0b01110, 0b10001, 0b00110, 0b10001, 0b01110], '4': [0b00100, 0b01100, 0b10100, 0b11111, 0b00100], '5': [0b11111, 0b10000, 0b11110, 0b00001, 0b11110], '6': [0b01110, 0b10000, 0b11110, 0b10001, 0b01110], '7': [0b11111, 0b00001, 0b00010, 0b00100, 0b00100], '8': [0b01110, 0b10001, 0b01110, 0b10001, 0b01110], '9': [0b01110, 0b10001, 0b01111, 0b00001, 0b01110], 'A': [0b01110, 0b10001, 0b10001, 0b11111, 0b10001], 'B': [0b11110, 0b10001, 0b11110, 0b10001, 0b11110], 'C': [0b01110, 0b10001, 0b10000, 0b10001, 0b01110], 'D': [0b11110, 0b10001, 0b10001, 0b10001, 0b11110], 'E': [0b11111, 0b10000, 0b11110, 0b10000, 0b11111], 'F': [0b11111, 0b10000, 0b11110, 0b10000, 0b10000], 'G': [0b01110, 0b10001, 0b10111, 0b10001, 0b01110], 'H': [0b10001, 0b10001, 0b11111, 0b10001, 0b10001], 'I': [0b01110, 0b00100, 0b00100, 0b00100, 0b01110], 'J': [0b00111, 0b00010, 0b00010, 0b10010, 0b01100], 'K': [0b10001, 0b10010, 0b11100, 0b10010, 0b10001], 'L': [0b10000, 0b10000, 0b10000, 0b10000, 0b11111], 'M': [0b10001, 0b11011, 0b10101, 0b10001, 0b10001], 'N': [0b10001, 0b11001, 0b10101, 0b10011, 0b10001], 'O': [0b01110, 0b10001, 0b10001, 0b10001, 0b01110], 'P': [0b11110, 0b10001, 0b11110, 0b10000, 0b10000], 'Q': [0b01110, 0b10001, 0b10101, 0b10011, 0b01101], 'R': [0b11110, 0b10001, 0b11110, 0b10001, 0b10001], 'S': [0b01110, 0b10000, 0b01110, 0b00001, 0b11110], 'T': [0b11111, 0b00100, 0b00100, 0b00100, 0b00100], 'U': [0b10001, 0b10001, 0b10001, 0b10001, 0b01110], 'V': [0b10001, 0b10001, 0b10001, 0b01010, 0b00100], 'W': [0b10001, 0b10101, 0b10101, 0b10101, 0b01010], 'X': [0b10001, 0b01010, 0b00100, 0b01010, 0b10001], 'Y': [0b10001, 0b01010, 0b00100, 0b00100, 0b00100], 'Z': [0b11111, 0b00010, 0b00100, 0b01000, 0b11111], '.': [0b00000, 0b00000, 0b00000, 0b00000, 0b00001], ':': [0b00000, 0b00100, 0b00000, 0b00100, 0b00000], '%': [0b11000, 0b11001, 0b00010, 0b00100, 0b01011] } # Initialize display self.init_display() def reset(self): GPIO.output(self.RST_PIN, GPIO.LOW) time.sleep(0.1) GPIO.output(self.RST_PIN, GPIO.HIGH) time.sleep(0.1) def send_command(self, cmd): GPIO.output(self.DC_PIN, GPIO.LOW) self.spi.writebytes([cmd]) def send_data(self, data): GPIO.output(self.DC_PIN, GPIO.HIGH) chunk_size = 4096 for i in range(0, len(data), chunk_size): chunk = data[i:i + chunk_size] self.spi.writebytes(chunk) def init_display(self): self.reset() init_commands = [ (0x01, b''), # Software reset (0x11, b''), # Sleep Out (0x3A, b'\x05'), # Interface Pixel Format (16-bit) (0x36, b'\x00'), # Memory Data Access Control (0x21, b''), # Display Inversion On (0x13, b''), # Normal Display Mode On (0x29, b'') # Display On ] for cmd, data in init_commands: self.send_command(cmd) if data: self.send_data(list(data)) time.sleep(0.1) def set_window(self, x0, y0, x1, y1): self.send_command(0x2A) self.send_data(list(struct.pack('>HH', x0, x1))) self.send_command(0x2B) self.send_data(list(struct.pack('>HH', y0, y1))) self.send_command(0x2C) def rgb_to_565(self, color): r = (color[0] >> 3) & 0x1F g = (color[1] >> 2) & 0x3F b = (color[2] >> 3) & 0x1F return (r << 11) | (g << 5) | b def fill_screen(self, color): pixel_color = self.rgb_to_565(color) self.set_window(0, 0, self.width - 1, self.height - 1) row_data = struct.pack('>H', pixel_color) * self.width for _ in range(self.height): self.send_data(list(row_data)) def draw_text_line(self, text, x, y, color=(255,255,255), bg_color=(0,0,0)): text = text.upper() for char_index, char in enumerate(text): if char in self.chars: char_data = self.chars[char] for row in range(5): for bit in range(5): color_val = color if (char_data[row] & (1 << (4-bit))) else bg_color pixel_color = self.rgb_to_565(color_val) self.set_window(x + char_index * 10 + bit * 2, y + row * 2, x + char_index * 10 + bit * 2, y + row * 2) self.send_data([pixel_color >> 8, pixel_color & 0xFF]) def close(self): self.backlight_pwm.stop() self.spi.close() GPIO.cleanup()def get_system_info(): hostname = os.uname().nodename try: s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) s.connect(("8.8.8.8", 80)) local_ip = s.getsockname()[0] s.close() except Exception: local_ip = "N/A" try: with open("/sys/class/thermal/thermal_zone0/temp", "r") as temp_file: cpu_temp = int(temp_file.read()) / 1000 except: cpu_temp = 0 try: with open('/proc/stat', 'r') as f: fields = [float(column) for column in f.readline().strip().split()[1:]] total_cpu_time = sum(fields) idle_cpu_time = fields[3] prev_total = total_cpu_time prev_idle = idle_cpu_time time.sleep(0.1) with open('/proc/stat', 'r') as f2: fields = [float(column) for column in f2.readline().strip().split()[1:]] total_cpu_time = sum(fields) idle_cpu_time = fields[3] total_diff = total_cpu_time - prev_total idle_diff = idle_cpu_time - prev_idle cpu_usage = 100 * (1 - idle_diff / total_diff) except: cpu_usage = 0 try: with open('/proc/meminfo', 'r') as f: lines = f.readlines() total_mem = int(lines[0].split()[1]) free_mem = int(lines[1].split()[1]) ram_usage = 100 * (total_mem - free_mem) / total_mem except: ram_usage = 0 try: with open('/proc/net/dev', 'r') as f: for line in f: if 'eth0' in line: parts = line.split() bytes_recv = int(parts[1]) bytes_sent = int(parts[9]) time.sleep(1) with open('/proc/net/dev', 'r') as f2: for line2 in f2: if 'eth0' in line2: parts2 = line2.split() new_bytes_recv = int(parts2[1]) new_bytes_sent = int(parts2[9]) up_speed = (new_bytes_sent - bytes_sent) * 8 / 1_000 down_speed = (new_bytes_recv - bytes_recv) * 8 / 1_000 break except: up_speed = 0 down_speed = 0 return { "hostname": hostname, "ip": local_ip, "cpu_temp": cpu_temp, "cpu_usage": cpu_usage, "ram_usage": ram_usage, "up_speed": up_speed, "down_speed": down_speed }def main(): display = None try: display = ST7789Display() # Fill screen with black initially display.fill_screen((0, 0, 0)) # Store the previous state of displayed information prev_info = {} while True: # Get current system info info = get_system_info() # Define a width for right alignment (adjust as needed) value_width = 15 # Iterate over each key in the info dictionary y_start = 20 updates = [ ("hostname", "HN:", info['hostname'], y_start), ("ip", "IP:", info['ip'], y_start + 40), ("cpu_temp", "TEMP:", f"{round(info['cpu_temp'], 1)} C", y_start + 80), ("cpu_usage", "CPU:", f"{round(info['cpu_usage'], 1)} %", y_start + 120), ("ram_usage", "RAM:", f"{round(info['ram_usage'], 1)} %", y_start + 160), ("up_speed", "UP:", f"{round(info['up_speed'], 1)} KBITS", y_start + 200), ("down_speed", "DN:", f"{round(info['down_speed'], 1)} KBITS", y_start + 240) ] for key, label, value, y in updates: # Only redraw if the value has changed if prev_info.get(key) != value: prev_info[key] = value # White color for label display.draw_text_line(label, 10, y, (255, 255, 255), (0, 0, 0)) # Calculate x position for right-aligned value # Adjust the multiplier (10) if needed to fine-tune positioning value_x = 10 + len(label) * 10 # Orange color for right-aligned value display.draw_text_line(f"{value:>{value_width}}", value_x, y, (255, 165, 0), (0, 0, 0)) # Wait before the next update time.sleep(1) except Exception as e: print(f"An error occurred: {e}") finally: if display: display.close()if __name__ == "__main__": main()
things are moving slow since im building a very rough prototype HAT on some perfboard for AiS and GPS since i will have to use it for my first channel corssing in march/april so yeah one of those boards will see some extra testing on a sailboat. (if a skipper wants to help me cross from Dover to calais please massage me, i will pay of course)
Thats all for today.
Statistics: Posted by MikeGotWine — Sun Dec 15, 2024 7:47 pm