MSP430F67791: Can't see EVM430-F6779 data through my own GUI

Part Number: MSP430F67791


Hello, 

I made my own GUI for displaying with python just voltages, currents and active powers, however, when I press the "Connect" button, it connects but shows all results on 0. How can I correct this problem? Or can anyone help me with all the parameters for making my own GUI?

"""
EMDC GUI - Simple Working Version
Based on actual hardware architecture:
PC ← HID → F5529 Bridge ← UART → F6779 EVM

This version:
- Uses HID (like original GUI)
- Reads UART packets from HID reports
- Simple tkinter GUI (no freezing)
- 1 Hz refresh rate
"""

import tkinter as tk
from tkinter import ttk, messagebox
import hid
import struct
import time
import threading

# HID Device
VID = 0x2047
PID = 0x0965
REPORT_ID = 0x3F

# Protocol
PACKET_SYNC = 0x55
PACKET_BLANK = 0xAA
CMD0_READ = 0x80
CMD1_VRMS = 0x04
CMD1_IRMS = 0x05
CMD1_ACTIVE_POWER = 0x0A
MODE_ACTIVE = 0x01

PHASE_A = 0x01
PHASE_B = 0x02
PHASE_C = 0x03
PHASE_TOTAL = 0x04


class EMDCApp:
    def __init__(self, root):
        self.root = root
        self.root.title("EMDC Energy Monitor")
        self.root.geometry("800x600")
       
        self.device = None
        self.running = False
        self.thread = None
       
        # Data storage
        self.data = {
            PHASE_A: {'vrms': 0.0, 'irms': 0.0, 'power': 0.0},
            PHASE_B: {'vrms': 0.0, 'irms': 0.0, 'power': 0.0},
            PHASE_C: {'vrms': 0.0, 'irms': 0.0, 'power': 0.0},
            PHASE_TOTAL: {'power': 0.0}
        }
       
        self.setup_ui()
   
    def setup_ui(self):
        # Connection frame
        conn_frame = ttk.LabelFrame(self.root, text="Connection", padding=10)
        conn_frame.pack(fill=tk.X, padx=10, pady=5)
       
        self.status_label = ttk.Label(conn_frame, text="Status: Disconnected", foreground="red")
        self.status_label.pack()
       
        btn_frame = ttk.Frame(conn_frame)
        btn_frame.pack(pady=5)
       
        self.connect_btn = ttk.Button(btn_frame, text="Connect", command=self.connect)
        self.connect_btn.pack(side=tk.LEFT, padx=5)
       
        self.disconnect_btn = ttk.Button(btn_frame, text="Disconnect", command=self.disconnect, state=tk.DISABLED)
        self.disconnect_btn.pack(side=tk.LEFT, padx=5)
       
        # Measurements frame
        meas_frame = ttk.LabelFrame(self.root, text="Measurements", padding=10)
        meas_frame.pack(fill=tk.BOTH, expand=True, padx=10, pady=5)
       
        # Create table
        columns = ("Parameter", "Phase A", "Phase B", "Phase C", "Total")
        self.tree = ttk.Treeview(meas_frame, columns=columns, show='headings', height=8)
       
        for col in columns:
            self.tree.heading(col, text=col)
            self.tree.column(col, width=150)
       
        self.tree.pack(fill=tk.BOTH, expand=True)
       
        # Insert rows
        self.rows = {}
        self.rows['vrms'] = self.tree.insert("", tk.END, values=("VRMS (V)", "-", "-", "-", "-"))
        self.rows['irms'] = self.tree.insert("", tk.END, values=("IRMS (A)", "-", "-", "-", "-"))
        self.rows['power'] = self.tree.insert("", tk.END, values=("Active Power (W)", "-", "-", "-", "-"))
       
        # Start GUI update loop
        self.update_display()
   
    def connect(self):
        try:
            # Find device
            devices = hid.enumerate(VID, PID)
            if not devices:
                messagebox.showerror("Error", "No EMDC device found!")
                return
           
            # Open device (try interface 0 first)
            self.device = hid.device()
            target = devices[0]
            self.device.open_path(target['path'])
            self.device.set_nonblocking(1)  # Non-blocking
           
            print(f"Connected to: {target['product_string']}")
           
            # Send CONFIG_MODE(ACTIVE)
            cmd = bytes([0x01, CMD0_READ, MODE_ACTIVE])
            checksum = sum(cmd) & 0xFFFF
            packet = bytes([len(cmd) + 2]) + cmd + struct.pack('<H', checksum)
           
            # Send via HID
            report = bytes([REPORT_ID]) + packet
            self.device.write(report)
           
            # Update UI
            self.status_label.config(text="Status: Connected", foreground="green")
            self.connect_btn.config(state=tk.DISABLED)
            self.disconnect_btn.config(state=tk.NORMAL)
           
            # Start reading thread
            self.running = True
            self.thread = threading.Thread(target=self.read_loop, daemon=True)
            self.thread.start()
           
        except Exception as e:
            messagebox.showerror("Error", f"Connection failed: {e}")
            print(f"Error: {e}")
   
    def disconnect(self):
        self.running = False
        if self.thread:
            self.thread.join(timeout=1.0)
       
        if self.device:
            self.device.close()
            self.device = None
       
        self.status_label.config(text="Status: Disconnected", foreground="red")
        self.connect_btn.config(state=tk.NORMAL)
        self.disconnect_btn.config(state=tk.DISABLED)
   
    def read_loop(self):
        """Background thread to read HID data"""
        buffer = bytearray()
       
        while self.running:
            try:
                # Read HID report
                data = self.device.read(255)
               
                if data and len(data) > 0:
                    # Remove report ID
                    if data[0] == REPORT_ID:
                        uart_data = bytes(data[1:])
                    else:
                        uart_data = bytes(data)
                   
                    # Add to buffer
                    buffer.extend(uart_data)
                   
                    # Look for packets in buffer
                    self.process_buffer(buffer)
               
                time.sleep(0.01)  # Small delay
               
            except Exception as e:
                print(f"Read error: {e}")
                time.sleep(0.1)
   
    def process_buffer(self, buffer):
        """Process UART packets from buffer"""
        while len(buffer) >= 2:
            # Look for sync bytes
            if buffer[0] == PACKET_SYNC and buffer[1] == PACKET_BLANK:
                # Found sync
                if len(buffer) < 3:
                    break
               
                length = buffer[2]
                total_len = 3 + length  # sync(2) + length(1) + data(length)
               
                if len(buffer) < total_len:
                    break  # Wait for more data
               
                # Extract packet
                packet_data = buffer[3:3+length]
               
                # Remove from buffer
                del buffer[:total_len]
               
                # Parse packet
                if len(packet_data) >= 2:
                    payload = packet_data[:-2]  # Remove checksum
                    self.parse_measurement(payload)
            else:
                # Remove first byte and try again
                del buffer[0]
   
    def parse_measurement(self, payload):
        """Parse measurement from payload"""
        if len(payload) < 4:
            return
       
        cmd0 = payload[0]
        cmd1 = payload[1]
       
        if cmd0 != CMD0_READ:
            return
       
        # Parse based on command
        if cmd1 == CMD1_VRMS and len(payload) >= 8:
            phase_id = payload[3]
            value = struct.unpack('<f', payload[4:8])[0]
            if phase_id in self.data:
                self.data[phase_id]['vrms'] = value
       
        elif cmd1 == CMD1_IRMS and len(payload) >= 8:
            phase_id = payload[3]
            value = struct.unpack('<f', payload[4:8])[0]
            if phase_id in self.data:
                self.data[phase_id]['irms'] = value
       
        elif cmd1 == CMD1_ACTIVE_POWER and len(payload) >= 12:
            phase_id = payload[3]
            value = struct.unpack('<q', payload[4:12])[0]  # int64
            if phase_id in self.data:
                self.data[phase_id]['power'] = float(value)
   
    def update_display(self):
        """Update GUI display (1 Hz)"""
        if self.device:
            # Update table
            d = self.data
           
            self.tree.item(self.rows['vrms'], values=(
                "VRMS (V)",
                f"{d[PHASE_A]['vrms']:.1f}",
                f"{d[PHASE_B]['vrms']:.1f}",
                f"{d[PHASE_C]['vrms']:.1f}",
                "-"
            ))
           
            self.tree.item(self.rows['irms'], values=(
                "IRMS (A)",
                f"{d[PHASE_A]['irms']:.3f}",
                f"{d[PHASE_B]['irms']:.3f}",
                f"{d[PHASE_C]['irms']:.3f}",
                "-"
            ))
           
            self.tree.item(self.rows['power'], values=(
                "Active Power (W)",
                f"{d[PHASE_A]['power']:.2f}",
                f"{d[PHASE_B]['power']:.2f}",
                f"{d[PHASE_C]['power']:.2f}",
                f"{d[PHASE_TOTAL]['power']:.2f}"
            ))
       
        # Schedule next update (1000ms = 1 Hz)
        self.root.after(1000, self.update_display)
   
    def on_closing(self):
        if self.device:
            self.disconnect()
        self.root.destroy()


def main():
    print("=" * 60)
    print("EMDC Energy Monitor - Simple Version")
    print("=" * 60)
    print("Architecture: PC <-HID-> F5529 Bridge <-UART-> F6779 EVM")
    print()
   
    root = tk.Tk()
    app = EMDCApp(root)
    root.protocol("WM_DELETE_WINDOW", app.on_closing)
    root.mainloop()


if __name__ == "__main__":
    main()

I'll wait for your response, because I have done one more question before, and had no response.

Thank you for your help.
  • Hi Juan,

    We have no support on custom GUI development.

    I also have no expertise on the GUI side. I will keep the thread open to see if there anyone could help.

    B.R.

    Sal

  • Hi Sal,

    Thank you.

    Can you help me by giving me information about what should I consider about the actual EMDC GUI or where can I find the files related to it?

    I need to build a new GUI, because the EMDC's one only works with 4096 samples per second; when I change this value to 8192 it shows nothing.

**Attention** This is a public forum