Światłolub: OCZY – dobór rezystora do dzielnika napięcia – OCZYWISTY?

Światłolub ma oczy… fotorezystory! Ale Arduino nie odczytuje rezystancji, tylko napięcia. Dlatego wykorzystujemy dzielnik napięcia według schematu:

Analizujemy prosty dzielnik napięcia, wykorzystywany do odczytu wartości z czujnika za pomocą Arduino. Napięcie odczytywane na pinie A0 będzie dane wzorkiem V_A0 (kolor czarny na obrazku powyżej). Celem jest znalezienie takiej wartości rezystora stałego (R_fixed), która zapewni najlepsze rozróżnienie między warunkami jasnymi a ciemnymi, tak aby Arduino mogło najlepiej wykrywać różnicę. Chcemy:

  • Zmierzyć opory R_foto w warunkach jasnych i ciemnych – miernik (multimetr)
  • Obliczyć V_A0 dla różnych wartości R_fixed w dwóch przypadkach: jasno i ciemno
  • Określić różnicę napięć (ΔV)
  • Przeskalować tę różnicę do zakresu analogRead() Arduino (0–1023)
  • Narysować odpowiednie wykresy, aby określić, która wartość rezystora działa najlepiej

Mierzymy opór czujnika w warunkach jasnych i ciemnych – następnie definiujemy stałe: napięcie wejściowe (5V) oraz opór czujnika w warunkach jasnych i ciemnych warunkach.

import matplotlib.pyplot as plt
# Stałe
V_in = 5 # Napięcie wejściowe w woltach
R_sensor_light = 60 # Opór czujnika w jasności (kiloomy)
R_sensor_dark = 180 # Opór czujnika w ciemności (kiloomy)

Przygotowujemy tablice (czyli listy w języku Python) do przechowywania wyników dla każdej testowanej wartości rezystora.

# Listy do przechowywania wyników
R_fixed_values = list(range(1, 1000))
V_out_light_values = []
V_out_dark_values = []
delta_V_values = []

Przechodzimy pętlą przez wartości R_fixed (od 1 do 999 kiloomy) i obliczamy:

  • Napięcie wyjściowe, gdy czujnik jest w jasności (V_out_light)
  • Napięcie wyjściowe, gdy czujnik jest w ciemności (V_out_dark)
  • Różnicę napięć między tymi dwoma wartościami (delta_V)

for R_fixed in R_fixed_values:
V_out_light = V_in * (R_sensor_light / (R_sensor_light + R_fixed))
V_out_dark = V_in * (R_sensor_dark / (R_sensor_dark + R_fixed))
delta_V = V_out_dark - V_out_light
V_out_light_values.append(V_out_light)
V_out_dark_values.append(V_out_dark)
delta_V_values.append(delta_V)

Znajdujemy taką wartość R_fixed, która daje największą różnicę napięć (ΔV). Oznacza to, że czujnik będzie w tym punkcie najbardziej „czuły”.

# Szukanie optymalej wartości R_fixed (maksymalna delta_V)
max_delta = max(delta_V_values)
max_delta_index = delta_V_values.index(max_delta)
optimal_R = R_fixed_values[max_delta_index]

Rysujemy napięcie wyjściowe dla warunków jasnych i ciemnych oraz „cieniujemy” obszar między dwiema funkcjami napięcia. To pokazuje w którym miejscu i jak bardzo zmienia się sygnał z czujnika.

# Wykres 1: V_out dla jasności i ciemności
plt.figure(figsize=(10, 5))
plt.plot(R_fixed_values, V_out_light_values, '--b', label='V_out (Jasność)')
plt.plot(R_fixed_values, V_out_dark_values, '--r', label='V_out (Ciemność)')


# Wypełnienie obszaru między dwiema krzywymi
where_condition = [dark > light for dark, light in zip(V_out_dark_values, _out_light_values)]
plt.fill_between(R_fixed_values, V_out_light_values, V_out_dark_values,where=where_condition,color='gray', alpha=0.3, label='Obszar ΔV')
plt.title('Napięcie wyjściowe dzielnika w warunkach jasnych i ciemnych')
plt.xlabel('R_fixed (kiloomy)')
plt.ylabel('V_out (V)')
plt.legend()
plt.grid(True)
plt.tight_layout()
plt.show()

Rysujemy różnicę napięć (ΔV) i zaznaczamy rezystor, który daje największe rozdzielenie sygnału

# Wykres 2: ΔV z zaznaczoną optymalną wartością R_fixed
plt.figure(figsize=(10, 5))
plt.plot(R_fixed_values, delta_V_values, color='red', label='ΔV (Jasność - Ciemność)')
plt.axvline(optimal_R, color='gray', linestyle=':', label=f'Optymalne R_fixed = {optimal_R} kΩ')
plt.scatter([optimal_R], [max_delta], color='black', zorder=5)plt.text(optimal_R + 10, max_delta, f'Max ΔV ≈ {max_delta:.2f} V\nprzy R = {optimal_R} kΩ', fontsize=9)
plt.title('Różnica napięć (ΔV) w zależności od R_fixed')
plt.xlabel('R_fixed (kiloomy)')
plt.ylabel('ΔV (V)')
plt.legend()
plt.grid(True)
plt.tight_layout()
plt.show()

Mapujemy różnicę napięć ΔV do skali analogRead() Arduino (0–1023)

# Szukanie najlepszej wartości R_fixed pod względem różnicy odczytu ADC
delta_ADC_values = [(v / V_in) * 1023 for v in delta_V_values]
max_delta_ADC = max(delta_ADC_values)
max_adc_index = delta_ADC_values.index(max_delta_ADC)
optimal_R_adc = R_fixed_values[max_adc_index]

Rysujemy ΔV przeskalowaną do zakresu analogRead oraz zaznaczamy rezystor dający największą różnicę odczytu cyfrowego

# Wykres ΔADC
plt.figure(figsize=(10, 5))
plt.plot(R_fixed_values, delta_ADC_values, color='purple', label='ΔADC (przeskalowane z ΔV)')
plt.axvline(optimal_R_adc, color='gray', linestyle=':', label=f'Optymalne R_fixed = {optimal_R_adc} kΩ')
plt.scatter([optimal_R_adc], [max_delta_ADC], color='black', zorder=5)
plt.text(optimal_R_adc + 10, max_delta_ADC, f'Maks. ΔADC ≈ {max_delta_ADC:.0f}\nprzy R = {optimal_R_adc} kΩ', fontsize=9)
plt.title('Różnica odczytu analogRead (ΔADC) w zależności od R_fixed')
plt.xlabel('R_fixed (kiloomy)')
plt.ylabel('ΔADC (0–1023)')
plt.legend()
plt.grid(True)
plt.tight_layout()
plt.show()

Wyświetlamy optymalną wartość rezystora dla skali Arduino, gdzie różnica odczytów analogRead() jest największa.

print(f"Optymalne R_fixed = {optimal_R_adc} kΩ, przy którym maks. ΔADC ≈ {max_delta_ADC:.0f}")
Optymalne R_fixed = 104 kΩ, przy którym maks. ΔADC ≈ 274

(c) Przemysław Baj, K.G. 2025

Posted in FiBot and tagged , , , .