#Ali Rashidi
#t.me\WriteYourWay
'''
MUX1 pin 2 , 3 , 4 , 5 , 6 -----------> s0 , s1 , s2 , s3 , com(SIG)
7seg( [0]0:00 ) & MUX1 --------> 0001(A , I0) , 0010(B , I1) , 0011(C , I2) , 0100(D , I3) , 0101(E , I4) , 0110(F , I5) , 0111(G , I6)
7seg( 0[0]:00 ) & MUX1 --------> 1000(A , I7) , 1001(B , I8) , 1010(C , I9) , 1011(D , I10) , 1100(E , I11) , 1101(F , I12) , 1110(G , I13)
7seg( 00[:]00 ) -------> (:) -------> LED1(pin 14) , LED2(pin 15)
MUX2 pin 28 27 26 22 21 -------> s0 s1 s2 s3 com(SIG)
7seg( 00:[0]0 ) & MUX2 --------> 0001(A , I0) , 0010(B , I1) , 0011(C , I2) , 0100(D , I3) , 0101(E , I4) , 0110(F , I5) , 0111(G , I6)
7seg( 00:0[0] ) & MUX2 --------> 1000(A , I7) , 1001(B , I8) , 1010(C , I9) , 1011(D , I10) , 1100(E , I11) , 1101(F , I12) , 1110(G , I13)
'''
# Ali Rashidi - t.me/WriteYourWay
# پروژه ساعت آنالوگ با سروو و 7 سگمنت - نسخه نهایی
import network
import urequests
import time
from machine import Pin, PWM
import wifi # فایل جداگانه wifi.py
# -------------------------------
# تنظیمات پایههای مالتی پلکسر
# -------------------------------
# MUX1 (ساعت) - پایههای کنترل
mux1_pins = [
Pin(2, Pin.OUT), # S0
Pin(3, Pin.OUT), # S1
Pin(4, Pin.OUT), # S2
Pin(5, Pin.OUT) # S3
]
# MUX2 (دقیقه) - پایههای کنترل
mux2_pins = [
Pin(28, Pin.OUT), # S0
Pin(27, Pin.OUT), # S1
Pin(26, Pin.OUT), # S2
Pin(22, Pin.OUT) # S3
]
def set_mux(mux, channel):
"""تنظیم کانال مالتی پلکسر (0-15)"""
for i in range(4):
mux[i].value((channel >> i) & 1)
# -------------------------------
# تنظیمات PWM برای سرووها
# -------------------------------
servo_hour = PWM(Pin(6)) # PWM برای سرووهای ساعت
servo_min = PWM(Pin(21)) # PWM برای سرووهای دقیقه
servo_hour.freq(50)
servo_min.freq(50)
# -------------------------------
# LEDهای دونقطه (:)
# -------------------------------
colon1 = Pin(14, Pin.OUT)
colon2 = Pin(15, Pin.OUT)
# -------------------------------
# نقشه ارقام 7 سگمنت (زاویه سروو)
# -------------------------------
NUMBERS = [
[0, 0, 0, 0, 0, 0, 90], # 0
[90, 0, 0, 90, 90, 90, 90], # 1
[0, 0, 90, 0, 0, 90, 0], # 2
[0, 0, 0, 0, 90, 90, 0], # 3
[90, 0, 0, 90, 90, 0, 0], # 4
[0, 90, 0, 0, 90, 0, 0], # 5
[0, 90, 0, 0, 0, 0, 0], # 6
[0, 0, 0, 90, 90, 90, 90], # 7
[0, 0, 0, 0, 0, 0, 0], # 8
[0, 0, 0, 0, 90, 0, 0] # 9
]
# -------------------------------
# تبدیل زاویه به Duty Cycle
# -------------------------------
def angle_to_duty(angle):
"""تبدیل زاویه (0-180) به مقدار مناسب برای PWM"""
pulse_us = 500 + (angle * 2000) // 180
duty = (pulse_us * 65535) // 20000 # محاسبه 16-bit
return int(duty)
# -------------------------------
# کنترل سروو از طریق مالتی پلکسر
# -------------------------------
def update_servo(mux, pwm, channel, angle):
if channel < 0 or channel > 15:
raise ValueError("کانال نامعتبر (0-15)")
if angle < 0 or angle > 180:
raise ValueError("زاویه باید بین 0-180 باشد")
set_mux(mux, channel)
pwm.duty_u16(angle_to_duty(angle))
time.sleep(0.01)
# -------------------------------
# نمایش رقم روی 7 سگمنت
# -------------------------------
def show_digit(mux, pwm, number, offset):
if number < 0 or number > 9:
raise ValueError("عدد باید بین 0-9 باشد")
if offset not in (0, 7):
raise ValueError("آفست نامعتبر (0 یا 7)")
for seg in range(7):
update_servo(mux, pwm, offset + seg, NUMBERS[number][seg])
# -------------------------------
# دریافت زمان از اینترنت
# -------------------------------
TIME_API = "http://worldtimeapi.org/api/timezone/Asia/Tehran"
last_time = (0, 0, 0)
last_update = 0
def fetch_time():
global last_time, last_update
try:
print("تلاش برای دریافت زمان...")
headers = {'User-Agent': 'RaspberryPiPico/1.0'}
response = urequests.get(TIME_API, timeout=15, headers=headers)
if response.status_code == 200:
data = response.json()
if 'datetime' not in data:
raise ValueError("فیلد datetime وجود ندارد")
datetime_str = data['datetime']
time_part = datetime_str.split('T')[1]
time_components = time_part.split(':')
if len(time_components) != 3:
raise ValueError("فرمت زمان نامعتبر")
h = int(time_components[0])
m = int(time_components[1])
s = int(time_components[2].split('.')[0])
last_time = (h, m, s)
last_update = time.time()
print(f"زمان به روز شد: {h:02}:{m:02}:{s:02}")
else:
print(f"خطای HTTP: {response.status_code}")
response.close()
except Exception as e:
print(f"خطا در دریافت زمان: {str(e)}")
# -------------------------------
# محاسبه زمان فعلی
# -------------------------------
def calculate_current_time():
global last_time, last_update
if last_update == 0:
return (0, 0, 0)
elapsed = time.time() - last_update
total_seconds = sum(x * y for x, y in zip(last_time, (3600, 60, 1))) + elapsed
h = int(total_seconds // 3600) % 24
remaining = total_seconds % 3600
m = int(remaining // 60)
s = int(remaining % 60)
return (h, m, s)
# -------------------------------
# به روزرسانی نمایشگر
# -------------------------------
def update_display(h, m):
try:
# ساعت
show_digit(mux1_pins, servo_hour, h // 10, 0) # دهگان
show_digit(mux1_pins, servo_hour, h % 10, 7) # یکان
# دقیقه
show_digit(mux2_pins, servo_min, m // 10, 0) # دهگان
show_digit(mux2_pins, servo_min, m % 10, 7) # یکان
# چشمک زدن دونقطه
colon1.toggle()
colon2.toggle()
time.sleep(0.5)
except Exception as e:
print(f"خطا در نمایش: {str(e)}")
# -------------------------------
# اجرای اصلی
# -------------------------------
def main():
# اطمینان از اتصال به WiFi
while not wifi.wlan.isconnected(): # تا زمانی که WiFi متصل نیست
wifi.start() # تلاش برای اتصال به WiFi
time.sleep(2) # زمان انتظار برای تلاش مجدد
# دریافت اولیه زمان
fetch_time()
while True:
try:
# به روزرسانی زمان هر 15 دقیقه
if time.time() - last_update > 900:
fetch_time()
# محاسبه زمان فعلی
h, m, s = calculate_current_time()
print(f"زمان فعلی: {h:02}:{m:02}:{s:02}")
# نمایش زمان
update_display(h, m)
# تاخیر برای کاهش مصرف CPU
time.sleep(1)
except Exception as e:
print(f"خطای اصلی: {str(e)}")
time.sleep(10)
if __name__ == "__main__":
main()