import sys from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout, QLabel, QPushButton, QLineEdit, QPlainTextEdit, QComboBox, QMessageBox from PyQt5.QtCore import QProcess, QSize from everywhereml.arduino import Sketch, Ino, H import platform import os class LogView(QPlainTextEdit): def __init__(self, parent=None): super().__init__(parent) self.setReadOnly(True) self._process = QProcess() self._process.readyReadStandardOutput.connect(self.handle_stdout) self._process.readyReadStandardError.connect(self.handle_stderr) def start_log(self, program, arguments=None): if arguments is None: arguments = [] self._process.start(program, arguments) def add_log(self, message): self.appendPlainText(message.rstrip()) def handle_stdout(self): message = self._process.readAllStandardOutput().data().decode() self.add_log(message) def handle_stderr(self): message = self._process.readAllStandardError().data().decode() self.add_log(message) def flash(log_view, led1, led2, port): """ Create a sketch object. A sketch is defined by: - a name (required) - a folder (optional) If you leave the folder empty, the current working directory will be used. You can use the special name ':system:' to use the default Arduino sketches folder (as reported by the command `arduino-cli config dump`) """ showdialog() sketch = Sketch(name="hemocube", folder=":system:") """ Then you can add files to the project (either the .ino main file or C++ header files) """ sketch += Ino(""" void setup() {{ // put your setup code here, to run once: Serial.begin(115200); }} void loop() {{ // put your main code here, to run repeatedly: }} """.format(led1dac=led1, led2dac=led2)) sketch += H("hello.h", """ void hello() { Serial.println("HemoCube QC"); } """) """ Compile sketch for Arduino Nano 33 BLE board. The board you target must appear in the `arduino-cli board listall` command. If you know the FQBN (Fully Qualified Board Name), you can use that too. """ if sketch.compile(board='arduino:avr:nano:cpu=atmega328old').is_successful: # log_view.add_log("Log: \n\n" + sketch.output) # log_view.add_log("Sketch stats: \n\n" + sketch.stats) print('Log', sketch.output) print('Sketch stats', sketch.stats) else: log_view.add_log("ERROR: \n\n" + sketch.output) print('ERROR', sketch.output) """ You can specify the exact port """ # sketch.upload(port='/dev/cu.usbmodem14201') sketch.upload(port=port) # """ # Or even part of it. # The library will look for the best match. # """ # sketch.upload(port='ttyUSB') # sketch.upload(port='/dev/cu.usbserial-1420') #/dev/cu.usbmodem log_view.add_log("upload: \n\n" + sketch.output) print(sketch.output) def showdialog(): msg = QMessageBox() msg.setIcon(QMessageBox.Information) msg.setText("HemoCube flashing") msg.setInformativeText("HemoCube device will be flashed with new values") msg.setWindowTitle("Flashing") msg.setDetailedText("The LED dac values will be set. Wait for sometime.") msg.setStandardButtons(QMessageBox.Ok | QMessageBox.Cancel) msg.buttonClicked.connect(msgbtn) retval = msg.exec_() print("value of pressed message box button:", retval) def msgbtn(i): print("Button pressed is:",i.text()) def get_port(): ports = [] if platform.system() == 'Darwin': ports = list(filter(lambda x: "cu" in x, os.listdir("/dev"))) else: import serial.tools.list_ports # ports = ['COM%s' % (i + 1) for i in range(256)] serial_ports = list(serial.tools.list_ports.comports()) for port, desc, hwid in sorted(serial_ports): ports.append(port) return ports # 1. Import QApplication and all the required widgets # from PyQt5.QtWidgets import QApplication, QLabel, QWidget def addLabel(layout, text): layout.addWidget(QLabel(text)) if __name__ == "__main__": app = QApplication(sys.argv) window = QWidget() layout = QVBoxLayout(window) # Create a label Widget and add it to the layout labelLed1 = QLabel('Enter LED1 value (1500-3000)') layout.addWidget(labelLed1) line_edit_led1 = QLineEdit() line_edit_led1.setFixedSize(QSize(150, 30)) layout.addWidget(line_edit_led1) labelLed2 = QLabel('Enter LED2 value (1500-3000)') left = 0 top = 25 right = 0 bottom = 0 labelLed2.setContentsMargins(left, top, right, bottom) layout.addWidget(labelLed2) line_edit_led2 = QLineEdit() line_edit_led2.setFixedSize(QSize(150, 30)) layout.addWidget(line_edit_led2) labelPort = QLabel('Select a port') layout.addWidget(labelPort) cb = QComboBox() cb.setFixedSize(QSize(150, 30)) ports = get_port() cb.addItem("Select") for port in ports: cb.addItem(port) layout.addWidget(cb) flash_port = "" def selectionchange(i): flash_port = cb.currentText() print("flash_port", flash_port) cb.currentIndexChanged.connect(selectionchange) # Create a QPushButton object with a caption on it qbtn = QPushButton('Flash') qbtn.setFixedSize(QSize(150, 40)) # Add the QPushButton to the layout layout.addWidget(qbtn) w = LogView() w.resize(640, 480) # w.show() # w.start_log("adb", ["logcat", "*:I"]) # w.start_log("arduino-cli", ["monitor", "-p /dev/cu.Bluetooth-Incoming-Port"]) # w.start_log("arduino-cli", ["lib", "install", "ADS1X15"]) w.handle_stdout() layout.addWidget(w) # Close the application when the button is pressed # Here I am using slots & signals, which I will demonstrate later in this tutorial # qbtn.clicked.connect(lambda:addLabel(layout, "Flashing...")) qbtn.clicked.connect(lambda: flash(w, line_edit_led1.text(), line_edit_led2.text(), cb.currentText())) window.setWindowTitle("HemoCube QC") window.setGeometry(400, 400, 800, 600) # helloMsg = QLabel("