1313
1414from breadboard import Breadboard
1515
16+ from dataCDLT import INPUT , OUTPUT
17+
18+ MICROCONTROLLER_PINS = {
19+ "Arduino Mega" : {
20+ "input_pins" : [22 , 23 , 24 , 25 , 26 , 27 , 28 , 29 ],
21+ "output_pins" : [32 , 33 , 34 , 35 , 36 , 37 ],
22+ "clock_pin" : 2 ,
23+ },
24+ "Arduino Uno" : {
25+ "input_pins" : [2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 ],
26+ "output_pins" : [10 , 11 , 12 , 13 ],
27+ "clock_pin" : 2 ,
28+ },
29+ "Arduino Micro" : {
30+ "input_pins" : [2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 ],
31+ "output_pins" : [10 , 11 , 12 , 13 ],
32+ "clock_pin" : 2 ,
33+ },
34+ "Arduino Mini" : {
35+ "input_pins" : [2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 ],
36+ "output_pins" : [10 , 11 , 12 , 13 ],
37+ "clock_pin" : 2 ,
38+ },
39+ "STM32" : {
40+ "input_pins" : ["PA0" , "PA1" , "PA2" , "PA3" , "PB0" , "PB1" , "PB2" , "PB3" ],
41+ "output_pins" : ["PC0" , "PC1" , "PC2" , "PC3" , "PC4" , "PC5" ],
42+ "clock_pin" : "PA0" ,
43+ },
44+ "NodeMCU ESP8266" : {
45+ "input_pins" : ["D1" , "D2" , "D3" , "D4" , "D5" , "D6" , "D7" , "D8" ],
46+ "output_pins" : ["D0" , "D1" , "D2" , "D3" , "D4" , "D5" ],
47+ "clock_pin" : "D2" ,
48+ },
49+ "NodeMCU ESP32" : {
50+ "input_pins" : [32 , 33 , 34 , 35 , 25 , 26 , 27 , 14 ],
51+ "output_pins" : [23 , 22 , 21 , 19 , 18 , 5 ],
52+ "clock_pin" : 2 ,
53+ },
54+ }
55+
1656
1757class Menus :
1858 """
@@ -57,6 +97,8 @@ def __init__(
5797 """The zoom function to adjust the canvas."""
5898 self .com_port : str | None = None
5999 """The selected COM port."""
100+ self .selected_microcontroller = None
101+ """The selected microcontroller."""
60102
61103 # Create the menu bar frame (do not pack here)
62104 self .menu_bar = tk .Frame (parent , bg = "#333333" )
@@ -65,8 +107,17 @@ def __init__(
65107 # Define menu items and their corresponding dropdown options
66108 menus = {
67109 "File" : ["New" , "Open" , "Save" , "Exit" ],
68- "Controllers" : ["Arduino" , "ESP32" ],
110+ "Controllers" : [
111+ "Arduino Mega" ,
112+ "Arduino Uno" ,
113+ "Arduino Micro" ,
114+ "Arduino Mini" ,
115+ "STM32" ,
116+ "NodeMCU ESP8266" ,
117+ "NodeMCU ESP32"
118+ ],
69119 "Ports" : ["Configure Ports" ],
120+ "Export" : ["Show Correspondence Table" ],
70121 "Help" : ["Documentation" , "About" ],
71122 }
72123
@@ -76,9 +127,15 @@ def __init__(
76127 "Open" : self .open_file ,
77128 "Save" : self .save_file ,
78129 "Exit" : self .parent .quit ,
79- "Arduino" : self .Arduino ,
80- "ESP32" : self .ESP32 ,
130+ "Arduino Mega" : lambda : self .select_microcontroller ("Arduino Mega" ),
131+ "Arduino Uno" : lambda : self .select_microcontroller ("Arduino Uno" ),
132+ "Arduino Micro" : lambda : self .select_microcontroller ("Arduino Micro" ),
133+ "Arduino Mini" : lambda : self .select_microcontroller ("Arduino Mini" ),
134+ "STM32" : lambda : self .select_microcontroller ("STM32" ),
135+ "NodeMCU ESP8266" : lambda : self .select_microcontroller ("NodeMCU ESP8266" ),
136+ "NodeMCU ESP32" : lambda : self .select_microcontroller ("NodeMCU ESP32" ),
81137 "Configure Ports" : self .configure_ports ,
138+ "Show Correspondence Table" : self .show_correspondence_table ,
82139 "Documentation" : self .open_documentation ,
83140 "About" : self .about ,
84141 }
@@ -90,6 +147,85 @@ def __init__(
90147 # Bind to parent to close dropdowns when clicking outside
91148 self .parent .bind ("<Button-1>" , self .close_dropdown )
92149
150+ def select_microcontroller (self , microcontroller_name ):
151+ """Handler for microcontroller selection."""
152+ print (f"{ microcontroller_name } selected." )
153+ self .selected_microcontroller = microcontroller_name
154+ messagebox .showinfo ("Microcontroller Selected" , f"{ microcontroller_name } has been selected." )
155+
156+ def show_correspondence_table (self ):
157+ """Displays the correspondence table between pin_io objects and microcontroller pins in a table format."""
158+ if self .selected_microcontroller is None :
159+ messagebox .showwarning ("No Microcontroller Selected" , "Please select a microcontroller first." )
160+ return
161+
162+ pin_mappings = MICROCONTROLLER_PINS .get (self .selected_microcontroller )
163+ if not pin_mappings :
164+ messagebox .showerror ("Error" , f"No pin mappings found for { self .selected_microcontroller } ." )
165+ return
166+
167+ input_pins = pin_mappings ["input_pins" ]
168+ output_pins = pin_mappings ["output_pins" ]
169+
170+ # Gather pin_io objects from current_dict_circuit
171+ pin_ios = [value for key , value in self .current_dict_circuit .items () if key .startswith ("_io_" )]
172+
173+ # Separate pin_ios into inputs and outputs
174+ input_pin_ios = [pin for pin in pin_ios if pin ["type" ] == INPUT ]
175+ output_pin_ios = [pin for pin in pin_ios if pin ["type" ] == OUTPUT ]
176+
177+ # Check if we have more pin_ios than available pins
178+ if len (input_pin_ios ) > len (input_pins ):
179+ messagebox .showerror (
180+ "Too Many Inputs" ,
181+ f"You have { len (input_pin_ios )} input pin_ios but only { len (input_pins )} available input pins on the microcontroller." ,
182+ )
183+ return
184+ if len (output_pin_ios ) > len (output_pins ):
185+ messagebox .showerror (
186+ "Too Many Outputs" ,
187+ f"You have { len (output_pin_ios )} output pin_ios but only { len (output_pins )} available output pins on the microcontroller." ,
188+ )
189+ return
190+
191+ # Create a new window for the correspondence table
192+ table_window = tk .Toplevel (self .parent )
193+ table_window .title ("Correspondence Table" )
194+ table_window .geometry ("400x300" )
195+
196+ # Create a Treeview widget for the table
197+ tree = ttk .Treeview (table_window , columns = ("ID" , "Type" , "MCU Pin" ), show = "headings" , height = 10 )
198+ tree .pack (expand = True , fill = "both" , padx = 10 , pady = 10 )
199+
200+ # Define columns and headings
201+ tree .column ("ID" , anchor = "center" , width = 120 )
202+ tree .column ("Type" , anchor = "center" , width = 80 )
203+ tree .column ("MCU Pin" , anchor = "center" , width = 120 )
204+ tree .heading ("ID" , text = "Pin IO ID" )
205+ tree .heading ("Type" , text = "Type" )
206+ tree .heading ("MCU Pin" , text = "MCU Pin" )
207+
208+ # Populate the table with input and output pin mappings
209+ for idx , pin_io in enumerate (input_pin_ios ):
210+ mcu_pin = input_pins [idx ]
211+ last_letter = pin_io ["id" ][- 1 ]
212+ tree .insert ("" , "end" , values = (last_letter , "Input" , mcu_pin ))
213+
214+ for idx , pin_io in enumerate (output_pin_ios ):
215+ mcu_pin = output_pins [idx ]
216+ last_letter = pin_io ["id" ][- 1 ]
217+ tree .insert ("" , "end" , values = (last_letter , "Output" , mcu_pin ))
218+
219+ # Add a scrollbar if the list gets too long
220+ scrollbar = ttk .Scrollbar (table_window , orient = "vertical" , command = tree .yview )
221+ tree .configure (yscroll = scrollbar .set )
222+ scrollbar .pack (side = "right" , fill = "y" )
223+
224+ # Show the table in the new window
225+ table_window .transient (self .parent ) # Set to be on top of the parent window
226+ table_window .grab_set () # Prevent interaction with the main window until closed
227+ table_window .mainloop ()
228+
93229 def create_menu (self , menu_name , options , menu_commands ):
94230 """
95231 Creates a menu button with a dropdown.
0 commit comments