Skip to content

Commit

Permalink
Full stack done !
Browse files Browse the repository at this point in the history
Sorry it was late :(
  • Loading branch information
AntonJohnDelMar committed Nov 3, 2024
1 parent 95ddb8a commit a20a8ed
Show file tree
Hide file tree
Showing 3 changed files with 156 additions and 0 deletions.
123 changes: 123 additions & 0 deletions ECE 196 Full Stack.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
# ECE 196 Full Stack

from serial import Serial, SerialException
from serial.tools.list_ports import comports
import time
import tkinter as tk
import tkinter.ttk as ttk
from tkinter.messagebox import showerror
from threading import Thread, Lock

def detached_callback(f):
return lambda *args, **kwargs: Thread(target=f, args=args, kwargs=kwargs).start();

S_OK: int = 0xaa;
S_ERR: int = 0xff;


class LockedSerial(Serial):
_lock: Lock = Lock()

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)

def read(self, size=1) -> bytes:
with self._lock:
return super().read(size)

def write(self, b: bytes, /) -> int | None:
with self._lock:
super().write(b)

def close(self):
with self._lock:
super().close()


class App(tk.Tk):
ser: LockedSerial;

def __enter__(self):
return self;

def __exit__(self, *_):
self.disconnect();

def __init__(self):
super().__init__();

self.title("LED Blinker");

self.port = tk.StringVar();
self.led = tk.BooleanVar();

ttk.Checkbutton(self, text='Toggle LED', variable=self.led, command=self.update_led).pack();
ttk.Button(self, text='Send Invalid', command=self.send_invalid).pack();
ttk.Button(self, text='Disconnect', command=self.disconnect, default='active').pack();

SerialPortal(self);

def write(self, b: bytes):
try:
self.ser.write(b);
response = self.ser.read();
# print(response);
if response[0] == S_ERR:
showerror('Device Error', 'The device reported an invalid command.');
except SerialException:
showerror('Serial Error', 'Write failed.');

def connect(self):
self.ser = Serial(self.port.get());

@detached_callback
def update_led(self):
self.ser.write(bytes([self.led.get()]));

def send_invalid(self):
self.write(bytes([S_ERR]));

def disconnect(self):
self.ser.close()

SerialPortal(self) # display portal to reconnect


class SerialPortal(tk.Toplevel):
def __init__(self, parent: App):
super().__init__(parent);

self.parent = parent;
self.parent.withdraw(); # hide App until connected

ttk.OptionMenu(self, parent.port, '', *[d.device for d in comports()]).pack();
ttk.Button(self, text='Connect', command=self.connect, default='active').pack();

def connect(self):
self.parent.connect();
self.destroy();
self.parent.deiconify(); # reveal App




if __name__ == '__main__':
with App() as app:
app.mainloop();

'''
with Serial('COM3', 9600) as ser:
ser.write(bytes([0x1]));
time.sleep(1);
print("Serial read: ");
print(ser.read());
# assert ser.read() == bytes([0xaa]);
ser.write(bytes([0x0]));
# assert ser.read() == bytes([0xaa]);
ser.write(bytes([0x2]));
# assert ser.read() == bytes([0xff]);
input();
'''
33 changes: 33 additions & 0 deletions FullStack/FullStack.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// ECE 196 Full Stack

const int LED {17};
const char S_OK {0xaa};
const char S_ERR {0xff};

void setup() {
pinMode(LED, OUTPUT);

Serial.onEvent(ARDUINO_HW_CDC_RX_EVENT, on_receive);
Serial.begin(9600);
}

void on_receive(void* event_handler_arg, esp_event_base_t event_base, int32_t event_id, void* event_data) {

char state { Serial.read() };

if(!(state == LOW || state == HIGH)) {
Serial.write(S_ERR);
delay(500);
return;
}

digitalWrite(LED, state);
Serial.write(S_OK);
delay(500);

}

void loop() {

}

Binary file added submission.mp4
Binary file not shown.

0 comments on commit a20a8ed

Please sign in to comment.