MonsterBoyTabs commited on
Commit
7eee483
·
verified ·
1 Parent(s): d92700d

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +155 -87
app.py CHANGED
@@ -1,105 +1,173 @@
1
  import streamlit as st
2
  import numpy as np
 
3
  import plotly.graph_objects as go
4
  from scipy.signal import square, sawtooth
5
 
6
- # Diode voltage drops
7
- DIODE_VOLTAGES = {
8
- "Ideal": 0.0,
9
- "Silicon": 0.7,
10
- "Germanium": 0.3
 
 
11
  }
12
 
13
- def generate_waveform(wave_type, freq, amplitude, duration=0.05):
14
- t = np.linspace(0, duration, 1000)
15
- if wave_type == "Sine":
16
- y = amplitude * np.sin(2 * np.pi * freq * t)
17
- elif wave_type == "Square":
18
- y = amplitude * square(2 * np.pi * freq * t)
19
- elif wave_type == "Triangular":
20
- y = amplitude * sawtooth(2 * np.pi * freq * t, width=0.5)
21
- return t, y
22
 
23
- def simulate_circuit(input_wave, diode_type, resistance):
24
- v_diode = DIODE_VOLTAGES[diode_type]
25
- output_wave = np.zeros_like(input_wave)
 
 
 
 
 
 
 
26
 
27
- for i in range(len(input_wave)):
28
- if input_wave[i] > v_diode:
29
- output_wave[i] = input_wave[i] - v_diode
30
- elif input_wave[i] < -v_diode:
31
- output_wave[i] = input_wave[i] + v_diode
32
- else:
33
- output_wave[i] = 0
 
 
 
 
 
 
 
 
 
 
 
 
 
34
 
35
- current = output_wave / resistance # I = V/R
36
- return output_wave, current
37
-
38
- # Streamlit UI
39
- st.title("📈 Electronic Waveform Simulator")
40
- st.markdown("Simulate circuit behavior with different diodes and waveforms")
41
-
42
- col1, col2 = st.columns(2)
43
- with col1:
44
- diode_type = st.selectbox("Diode Type", ["Ideal", "Silicon", "Germanium"])
45
- waveform_type = st.selectbox("Waveform Type", ["Sine", "Square", "Triangular"])
46
 
47
- with col2:
48
- freq = st.slider("Frequency (Hz)", 1, 1000, 50)
49
- amplitude = st.slider("Amplitude (V)", 1.0, 20.0, 12.0)
50
- resistance = st.slider("Resistance (Ω)", 1, 1000, 100)
51
-
52
- # Generate waveforms
53
- t, input_wave = generate_waveform(waveform_type, freq, amplitude)
54
- output_wave, current = simulate_circuit(input_wave, diode_type, resistance)
55
 
56
- # Create plots
57
- fig = go.Figure()
58
- fig.add_trace(go.Scatter(x=t, y=input_wave, name="Input Voltage", line=dict(color='blue')))
59
- fig.add_trace(go.Scatter(x=t, y=output_wave, name="Output Voltage", line=dict(color='red')))
60
- fig.update_layout(title="Voltage Waveforms",
61
- xaxis_title="Time (s)",
62
- yaxis_title="Voltage (V)",
63
- hovermode="x unified")
64
 
65
- fig2 = go.Figure()
66
- fig2.add_trace(go.Scatter(x=t, y=current*1000, name="Current", line=dict(color='green')))
67
- fig2.update_layout(title="Circuit Current",
68
- xaxis_title="Time (s)",
69
- yaxis_title="Current (mA)",
70
- hovermode="x unified")
 
 
 
 
 
 
 
 
 
 
 
71
 
72
- # Display results
73
- st.plotly_chart(fig, use_container_width=True)
74
- st.plotly_chart(fig2, use_container_width=True)
 
 
 
75
 
76
- # Circuit analysis
77
- st.subheader("Circuit Analysis")
78
- col3, col4, col5 = st.columns(3)
79
- with col3:
80
- st.metric("Peak Input Voltage", f"{np.max(input_wave):.2f} V")
81
- with col4:
82
- st.metric("Peak Output Voltage", f"{np.max(output_wave):.2f} V")
83
- with col5:
84
- st.metric("Max Current", f"{np.max(current)*1000:.2f} mA")
 
 
 
 
85
 
86
- # Circuit diagram
87
- st.subheader("Circuit Diagram")
88
- st.code(f"""
89
- AC Source ({amplitude}V {waveform_type})
90
- ────┤ Diode ({diode_type}) ├─── Resistor ({resistance}Ω) ────
91
- """)
 
 
 
92
 
93
- # Theory explanation
94
- st.subheader("Theory Overview")
95
- st.markdown(f"""
96
- This simulator shows a simple diode-resistor circuit:
97
- - **Input**: {waveform_type} wave at {freq}Hz with {amplitude}V amplitude
98
- - **Diode**: {diode_type} (Forward voltage: {DIODE_VOLTAGES[diode_type]}V)
99
- - **Load**: {resistance}Ω resistor
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
100
 
101
- The output waveform shows:
102
- - Positive half-cycles reduced by {DIODE_VOLTAGES[diode_type]}V diode drop
103
- - Negative half-cycles {'clipped' if diode_type == 'Ideal' else 'partially conducted'}
104
- - Current calculated using Ohm's Law (I = V/R)
105
- """)
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  import streamlit as st
2
  import numpy as np
3
+ import pandas as pd
4
  import plotly.graph_objects as go
5
  from scipy.signal import square, sawtooth
6
 
7
+ # Component configurations
8
+ DIODE_DROPS = {"Silicon": 0.7, "Germanium": 0.3, "Ideal": 0.0}
9
+ COMPONENT_ICONS = {
10
+ "AC Source": "⚡",
11
+ "DC Source": "⎓",
12
+ "Resistor": "🛑",
13
+ "Diode": "↘️"
14
  }
15
 
16
+ # Initialize session state
17
+ if "circuit" not in st.session_state:
18
+ st.session_state.circuit = []
19
+ if "waveform_type" not in st.session_state:
20
+ st.session_state.waveform_type = "Sine"
 
 
 
 
21
 
22
+ def calculate_voltage_drop(component, voltage, current):
23
+ if component["type"] == "Resistor":
24
+ return current * component["value"]
25
+ elif component["type"] == "Diode":
26
+ return DIODE_DROPS[component["subtype"]] if voltage > DIODE_DROPS[component["subtype"]] else 0
27
+ return 0
28
+
29
+ def simulate_circuit(circuit, waveform, freq, amplitude):
30
+ time = np.linspace(0, 0.05, 1000)
31
+ results = []
32
 
33
+ for t_idx, t in enumerate(time):
34
+ entry = {"Time": t}
35
+ if circuit[0]["type"] == "AC Source":
36
+ if st.session_state.waveform_type == "Sine":
37
+ v_in = amplitude * np.sin(2 * np.pi * freq * t)
38
+ elif st.session_state.waveform_type == "Square":
39
+ v_in = amplitude * square(2 * np.pi * freq * t)
40
+ else: # Triangular
41
+ v_in = amplitude * sawtooth(2 * np.pi * freq * t, width=0.5)
42
+ else: # DC Source
43
+ v_in = circuit[0]["value"]
44
+
45
+ current = 0
46
+ remaining_voltage = v_in
47
+ entry["Source Voltage"] = v_in
48
+
49
+ for comp in circuit[1:]:
50
+ v_drop = calculate_voltage_drop(comp, remaining_voltage, current)
51
+ entry[f"{comp['type']} {comp.get('subtype', '')}"] = v_drop
52
+ remaining_voltage -= v_drop
53
 
54
+ if comp["type"] == "Resistor" and remaining_voltage > 0:
55
+ current = remaining_voltage / comp["value"]
56
+
57
+ entry["Current"] = current
58
+ entry["Output Voltage"] = remaining_voltage
59
+ results.append(entry)
 
 
 
 
 
60
 
61
+ return pd.DataFrame(results)
 
 
 
 
 
 
 
62
 
63
+ # App layout
64
+ st.title("🔌 Interactive Circuit Simulator")
65
+ st.markdown("Build your circuit and analyze its behavior")
 
 
 
 
 
66
 
67
+ # Circuit Builder
68
+ with st.expander("🛠️ Circuit Builder", expanded=True):
69
+ col1, col2, col3 = st.columns(3)
70
+ with col1:
71
+ comp_type = st.selectbox("Component Type", ["AC Source", "DC Source", "Resistor", "Diode"])
72
+ with col2:
73
+ if comp_type in ["Resistor"]:
74
+ value = st.number_input("Value (Ω)", 1, 1000, 100)
75
+ elif comp_type in ["DC Source"]:
76
+ value = st.number_input("Voltage (V)", 1.0, 24.0, 12.0)
77
+ else:
78
+ value = None
79
+ with col3:
80
+ if comp_type == "Diode":
81
+ subtype = st.selectbox("Diode Type", list(DIODE_DROPS.keys()))
82
+ else:
83
+ subtype = None
84
 
85
+ if st.button("Add Component"):
86
+ st.session_state.circuit.append({
87
+ "type": comp_type,
88
+ "value": value,
89
+ "subtype": subtype
90
+ })
91
 
92
+ # Display Circuit
93
+ st.subheader("Your Circuit")
94
+ if not st.session_state.circuit:
95
+ st.warning("No components in circuit!")
96
+ else:
97
+ circuit_display = " → ".join([
98
+ f"{COMPONENT_ICONS[comp['type']]} {comp['type']}" +
99
+ (f" ({comp['subtype']})" if comp.get('subtype') else "") +
100
+ (f" {comp['value']}Ω" if comp['type'] == "Resistor" else "") +
101
+ (f" {comp['value']}V" if comp['type'] == "DC Source" else "")
102
+ for comp in st.session_state.circuit
103
+ ])
104
+ st.markdown(f"`{circuit_display}`")
105
 
106
+ # Simulation Controls
107
+ st.subheader("Simulation Parameters")
108
+ if st.session_state.circuit and st.session_state.circuit[0]["type"] == "AC Source":
109
+ st.session_state.waveform_type = st.selectbox("Waveform Type", ["Sine", "Square", "Triangular"])
110
+ freq = st.slider("Frequency (Hz)", 1, 1000, 50)
111
+ amplitude = st.slider("Amplitude (V)", 1.0, 24.0, 12.0)
112
+ else:
113
+ freq = None
114
+ amplitude = None
115
 
116
+ if st.button("▶️ Run Simulation") and st.session_state.circuit:
117
+ # Run simulation
118
+ df = simulate_circuit(
119
+ st.session_state.circuit,
120
+ st.session_state.waveform_type,
121
+ freq,
122
+ amplitude
123
+ )
124
+
125
+ # Display Results
126
+ st.subheader("📊 Simulation Results")
127
+
128
+ # Observation Table
129
+ with st.expander("📋 Point-to-Point Analysis", expanded=True):
130
+ st.dataframe(df.style.format("{:.4f}"), height=300)
131
+
132
+ # Waveform Visualization
133
+ fig = go.Figure()
134
+ fig.add_trace(go.Scatter(x=df["Time"], y=df["Source Voltage"], name="Input Voltage"))
135
+ fig.add_trace(go.Scatter(x=df["Time"], y=df["Output Voltage"], name="Output Voltage"))
136
+ fig.update_layout(
137
+ title="Voltage Waveforms",
138
+ xaxis_title="Time (s)",
139
+ yaxis_title="Voltage (V)",
140
+ hovermode="x unified"
141
+ )
142
+ st.plotly_chart(fig, use_container_width=True)
143
+
144
+ # Current Visualization
145
+ fig2 = go.Figure()
146
+ fig2.add_trace(go.Scatter(x=df["Time"], y=df["Current"]*1000, name="Current"))
147
+ fig2.update_layout(
148
+ title="Circuit Current",
149
+ xaxis_title="Time (s)",
150
+ yaxis_title="Current (mA)",
151
+ hovermode="x unified"
152
+ )
153
+ st.plotly_chart(fig2, use_container_width=True)
154
+ elif not st.session_state.circuit:
155
+ st.error("Please build a circuit first!")
156
 
157
+ # Help Section
158
+ with st.expander("❓ How to use"):
159
+ st.markdown("""
160
+ 1. **Build Circuit**:
161
+ - Select component type from dropdown
162
+ - Configure parameters (resistance, voltage, diode type)
163
+ - Click 'Add Component' to add to circuit
164
+ - First component must be a power source (AC/DC)
165
+
166
+ 2. **Set Simulation Parameters**:
167
+ - For AC circuits: select waveform type and parameters
168
+
169
+ 3. **Run Simulation**:
170
+ - Click 'Run Simulation' to see results
171
+ - View point-to-point analysis in table
172
+ - Observe voltage and current waveforms
173
+ """)