اطلاعیه

Collapse
No announcement yet.

درخواست راهنمایی برای بهینه سازی کد بسکام

Collapse
X
 
  • فیلتر
  • زمان
  • Show
Clear All
new posts

    درخواست راهنمایی برای بهینه سازی کد بسکام

    با عرض سلام خدمت دوستان و اساتید عزیز

    یه برنامه توسط هوش مصنوعی برای ساخت یک دزدگیر نوشته شده و خطا میده چندین بار به شکل‌های مختلف تغییرش دادم اما نیاز به دیباگ و بهینه سازی داره
    اگر ممکنه کمک کنید​
    ​​​​​
    دستور ADC خطا داشت
    دستور lcd نیاز نبود و توسط هوش مصنوعی اضافه شده

    این دستور برای هوش مصنوعی ارسال شد:
    کد avr به زبان بیسیک برای میکرو کنترلر اتمگا۱۶a بنویس
    برای ساخت یک دزدگیر حرفه‌ای و حساس دارای دو ورودی سنسور یک ldr با قابلیت تنظیم حساسیت توسط پتانسیومتر ۱۰۰k و یک سنسور رید رله مغناطیسی normaly open
    درصورت تابیده نشدن لیزر بر روی ldr و یا قطع بودن رید رله ابتدا یک led بصورت چشمک زن فعال میشود و یک بازر بصورت آژیر فعال میشود
    یک کلید برای راه اندازی مجدد دزدگیر بر روی یکی از پایه ها وجود دارد ، در صورت فشرده نشدن کلید بعد از ۱ دقیقه یک رله فعال میشود و در صورت قطع نشدن دزدگیر تا دو دقیقه رله دوم فعال میشود و برای قطع شدن دزدگیر یک کلید دیگر را همزمان با کلید راه اندازی مجدد باید فشار داد​
    کد PHP:
    $regfile = "m16adef.dat" ' فایل تعریف رجیسترها برای ATmega16A
    $crystal = 8000000  ' 
    فرکانس کاری میکروکنترلر (کریستال داخلی 8MHz)

    ' تعریف پین‌ها
    Config Porta.0 = Input     ' 
    LDR ADC Input (PA0)
    Config Portd.2 = Input     ' Reed Relay Input (PD2) - INT0
    Config Portd.3 = Input     ' 
    Reset Button Input (PD3) - INT1
    Config Portd.4 
    = Input       ' Alarm Off Button Input (PD4)
    Config Portb.0 = Output       ' 
    LED Output (PB0)
    Config Portb.1 = Output      ' Buzzer Output (PB1)
    Config Portc.0 = Output    ' 
    Relay 1 Output (PC0)
    Config Portc.1 = Output    ' Relay 2 Output (PC1)

    ' 
    تنظیمات ADC
    Config Adc 
    = Single             ' حالت تک‌موجی ADC
    Config Adcres = 10            ' 
    رزولوشن 10 بیت
    Enable Adc                
    ' فعال کردن ADC

    ' 
    تنظیمات وقفه خارجی
    On Int0 Reed_relay_interrupt    
    ' تعریف روتین وقفه برای سنسور رید
    On Int1 Reset_button_interrupt    ' 
    تعریف روتین وقفه برای کلید ریست (که همراه کلید قطع استفاده می‌شود)
    Enable Interrupts                  ' فعال کردن کلی وقفه‌ها

    ' 
    متغیرها
    Dim Ldr_value 
    As Word              ' مقدار خوانده شده از LDR
    Dim Avg_ldr_value As Word          ' 
    مقدار میانگین LDR
    Dim Threshold 
    As Word              ' حد آستانه LDR (تنظیم با پتانسیومتر)
    Dim Led_state As Bit               ' 
    وضعیت LED (روشن/خاموش)
    Dim Buzzer_state As Bit            ' وضعیت Buzzer (روشن/خاموش)
    Dim Relay1_state As Bit            ' 
    وضعیت رله اول
    Dim Relay2_state 
    As Bit            ' وضعیت رله دوم
    Dim Alarm_active As Bit            ' 
    فلگ فعال بودن آلارم
    Dim Timer1_flag 
    As Bit             ' فلگ تایمر اول (1 دقیقه)
    Dim Timer2_flag As Bit             ' 
    فلگ تایمر دوم (2 دقیقه)
    Dim Start_time As Long             ' زمان شروع آلارم
    Dim Current_time As Long           ' 
    زمان فعلی
    Dim Button_pressed_time 
    As Long    ' زمان فشرده شدن دکمه‌ها
    Dim Button_held_time As Long       ' 
    مدت زمان نگه داشتن دکمه‌ها
    Dim Arm_mode 
    As Bit                ' حالت مسلح بودن سیستم (0=غیرمسلح, 1=مسلح)

    ' 
    --- تنظیمات اولیه ---
    Ldr_value = 0
    Avg_ldr_value 
    = 0
    Threshold 
    = 500                    ' مقدار اولیه آستانه (قابل تنظیم با پتانسیومتر) - این مقدار باید با تنظیم پتانسیومتر تنظیم شود.
    Led_state = 0
    Buzzer_state = 0
    Relay1_state = 0
    Relay2_state = 0
    Alarm_active = 0
    Timer1_flag = 0
    Timer2_flag = 0
    Arm_mode = 0           ' 
    سیستم در ابتدا غیرمسلح است

    ' فعال کردن داخلی Pull-up برای پین‌های ورودی دکمه‌ها
    ' 
    برای سنسور رید، فرض می‌کنیم که سنسور NO است و وقتی متصل است، پین را LOW می‌کند.
    ' اگر سنسور NC بود، منطق باید برعکس شود.
    ' 
    اگر نیاز به مقاومت خارجی Pull-up/Pull-down برای دکمه‌ها دارید، آن را اضافه کنید.
    Set Portd.3 ' فعال کردن Pull-up داخلی برای کلید ریست
    Set Portd.4 ' 
    فعال کردن Pull-up داخلی برای کلید قطع

    ' --- تنظیمات تایمرها ---
    ' 
    برای تایمر 1 دقیقه و 2 دقیقه، از تایمر داخلی میکروکنترلر استفاده می‌کنیم.
    ' با فرکانس 8MHz و تقسیم‌کننده 1024، زمان هر تیک حدود 0.128 میلی‌ثانیه است.
    ' 
    برای 1 دقیقه (60 ثانیه)، نیاز به حدود 468750 تیک داریم.
    ' برای 3 دقیقه (180 ثانیه)، نیاز به حدود 1406250 تیک داریم.
    ' 
    این محاسبات نیاز به دقت بیشتری دارد و ممکن است نیاز به تنظیم Prescaler و Mode تایمر باشد.
    ' در این مثال، از منطق ساده‌تر برای نمایش زمان استفاده می‌کنیم.
    ' 
    برای دقت بالا، استفاده از تایمرهای سخت‌افزاری توصیه می‌شود.

    ' --- شروع برنامه اصلی ---
    Cls                            ' 
    پاک کردن صفحه ترمینال (اگر از LCD استفاده می‌کنید)
    Lowerline                      ' رفتن به خط پایین (اگر از LCD استفاده می‌کنید)
    Lcd "Alarm System v1.0"

    Wait 2

    Do
        Gosub Get_sensor_values       ' 
    خواندن مقادیر سنسورها
        Gosub Check_system_state      
    ' بررسی وضعیت سیستم و فعال کردن آلارم در صورت نیاز

        ' 
    --- مدیریت فعال بودن آلارم ---
        If 
    Alarm_active = 1 Then
            Gosub Handle_alarm        
    ' اجرای عملیات مربوط به آلارم فعال
        Else
            ' 
    سیستم در حالت عادی است، همه چیز خاموش
            Set Portb.0 
    = 0           ' خاموش کردن LED
            Set Portb.1 = 0           ' 
    خاموش کردن Buzzer
            Set Portc.0 
    = 0           ' خاموش کردن رله 1
            Set Portc.1 = 0           ' 
    خاموش کردن رله 2
            Led_state 
    = 0
            Buzzer_state 
    = 0
            Relay1_state 
    = 0
            Relay2_state 
    = 0
            Timer1_flag 
    = 0
            Timer2_flag 
    = 0
            
    ' در حالت عادی، سیستم مسلح نیست مگر اینکه دکمه‌ها فشار داده شوند
            ' 
    اگر سیستم مسلح باشد و هیچ خطایی رخ ندهد، همچنان مسلح می‌ماند
            
    ' اگر نیاز دارید در حالت عادی سیستم خودکار غیرمسلح شود، منطق آن را اینجا اضافه کنید
        End If

        Waitms 100                    ' 
    تاخیر کوتاه برای پایداری

    Loop

    ' --- زیربرنامه‌ها ---

    ' 
    زیربرنامه خواندن مقادیر سنسورها و محاسبه میانگین LDR
    Get_sensor_values
    :
        
    Dim I As Integer
        Dim Temp_ldr 
    As Word
        Temp_ldr 
    = 0
        
    For I = 1 To 10               ' 10 بار خواندن مقدار LDR
            Ldr_value = Getadc(0)     ' 
    خواندن از ADC0 (PA0)
            
    Temp_ldr = Temp_ldr + Ldr_value
            Waitms 10                 
    ' تاخیر کوتاه بین خواندن‌ها
        Next I
        Avg_ldr_value = Temp_ldr / 10 ' 
    محاسبه میانگین

        
    ' خواندن وضعیت سنسور رید (INT0)
        ' 
    فرض می‌کنیم سنسور NO است و در حالت عادی وصل است (LOW). اگر قطع شود HIGH می‌شود.
        
    ' اگر سنسور NC بود، منطق باید برعکس شود.
        If Pind.2 = 1 Then            ' 
    اگر سنسور رید قطع شد (HIGH)
            
    ' این یک خطا محسوب می‌شود
        Else                          ' 
    اگر سنسور رید وصل است (LOW)
            
    ' مشکلی نیست
        End If

        ' 
    خواندن وضعیت دکمه‌ها
        
    ' کلید ریست (INT1) و کلید قطع (PD4)
        ' 
    اگر هر دو همزمان فشرده شوند، سیستم قطع می‌شود.
        
    ' برای اطمینان از اینکه دکمه‌ها به درستی کار می‌کنند، از روش Debouncing استفاده می‌شود.

        Return

    ' 
    زیربرنامه بررسی وضعیت سیستم و فعال کردن آلارم
    Check_system_state
    :
        
    ' بررسی شرط فعال شدن آلارم:
        ' 
    1. نور LDR کمتر از حد آستانه باشد (نشان‌دهنده قطع لیزر)
        
    ' 2. سنسور رید قطع شده باشد (PIND.2 = 1)
        ' 
    3. سیستم در حالت مسلح باشد (Arm_mode = 1)

        
    ' ابتدا وضعیت کلیدهای قطع و ریست را بررسی می‌کنیم
        If Pind.3 = 0 And Pind.4 = 0 Then ' 
    اگر هر دو کلید همزمان فشرده شوند
            
    ' سیستم قطع می‌شود، به حالت عادی برمی‌گردد
            Alarm_active = 0
            Arm_mode = 0
            Start_time = 0 ' 
    ریست کردن زمان شروع آلارم
            
    ' کلیدها باید برای مدتی فشرده شوند تا تشخیص داده شوند (Debouncing)
            Waitms 200 ' 
    تاخیر برای Debouncing
            
    If Pind.3 = 0 And Pind.4 = 0 Then ' اگر همچنان فشرده هستند
                 Gosub Reset_system_state
            End If
        End If

        ' 
    اگر سیستم مسلح باشد
        
    If Arm_mode = 1 Then
            
    ' بررسی شرایط خطا
            If Avg_ldr_value < Threshold Or Pind.2 = 1 Then
                ' 
    خطای تشخیص داده شد
                
    If Alarm_active = 0 Then ' اگر آلارم قبلا فعال نبوده است
                    Alarm_active = 1     ' 
    فعال کردن آلارم
                    Start_time 
    = GetTimer ' ثبت زمان شروع آلارم (نیاز به پیاده‌سازی GetTimer با تایمر سخت‌افزاری)
                    ' 
    برای سادگی، از Wait استفاده می‌کنیم که دقیق نیست
                    
    ' Start_time = Timer ' استفاده از تایمر داخلی Bascom (اگر فعال باشد)
                    
    ' باید یک روش دقیق برای ثبت زمان داشته باشید
                End If
            End If
        Else
            ' 
    اگر سیستم غیرمسلح است، آلارم نباید فعال شود
            Alarm_active 
    = 0
        End 
    If

        Return

    ' زیربرنامه مدیریت حالت آلارم فعال
    Handle_alarm:
        ' 
    فعال کردن LED چشمک‌زن
        
    If Led_state = 0 Then
            Set Portb.0 
    = 1
            Led_state 
    = 1
            Waitms 250 
    ' تاخیر برای چشمک زدن
            Set Portb.0 = 0
            Led_state = 0
            Waitms 250
        Else
            ' 
    در حالت عادی چشمک می‌زند
        End 
    If

        
    ' فعال کردن بازر آژیر
        If Buzzer_state = 0 Then
            Set Portb.1 = 1
            Buzzer_state = 1
            ' 
    الگوی آژیر را اینجا تعریف کنید (مثلا چند ثانیه روشن، چند ثانیه خاموش)
            
    ' برای سادگی، آن را همیشه روشن نگه می‌داریم تا زمانی که آلارم فعال است
            ' 
    Set Portb.1 = 1
            
    ' برای ایجاد آژیر واقعی، باید الگو تعریف شود
        Else
            ' 
    Buzzer is already on
        End 
    If

        
    ' --- مدیریت زمان‌بندی فعال شدن رله‌ها ---
        ' 
    فرض می‌کنیم GetTimer زمان را بر اساس میلی‌ثانیه برمی‌گرداند
        
    ' برای 1 دقیقه = 60000 میلی‌ثانیه
        ' 
    برای 3 دقیقه = 180000 میلی‌ثانیه

        
    ' اگر زمان شروع آلارم ثبت شده باشد
        If Start_time > 0 Then
            Current_time = GetTimer ' 
    دریافت زمان فعلی (نیاز به پیاده‌سازی GetTimer)

            
    ' فعال شدن رله اول پس از 1 دقیقه (60000 میلی‌ثانیه)
            If Timer1_flag = 0 And (Current_time - Start_time) >= 60000 Then
                Set Portc.0 = 1          ' 
    فعال کردن رله اول
                Relay1_state 
    = 1
                Timer1_flag 
    = 1          ' فلگ تایمر اول تنظیم شد
                ' 
    برای سادگی، از LCD برای نمایش وضعیت استفاده می‌کنیم
                
    ' Lcd "Relay 1 ON "
            End If

            ' 
    فعال شدن رله دوم پس از 3 دقیقه (180000 میلی‌ثانیه)
            If 
    Timer2_flag = 0 And (Current_time - Start_time) >= 180000 Then
                Set Portc.1 
    = 1          ' فعال کردن رله دوم
                Relay2_state = 1
                Timer2_flag = 1          ' 
    فلگ تایمر دوم تنظیم شد
                
    ' Lcd "Relay 2 ON "
            End If
        End If

        Return

    ' 
    زیربرنامه بازنشانی سیستم به حالت عادی
    Reset_system_state
    :
        
    Alarm_active = 0
        Arm_mode 
    = 0
        Start_time 
    = 0
        Timer1_flag 
    = 0
        Timer2_flag 
    = 0
        Set Portb.0 
    = 0           ' خاموش کردن LED
        Set Portb.1 = 0           ' 
    خاموش کردن Buzzer
        Set Portc.0 
    = 0           ' خاموش کردن رله 1
        Set Portc.1 = 0           ' 
    خاموش کردن رله 2
        Led_state 
    = 0
        Buzzer_state 
    = 0
        Relay1_state 
    = 0
        Relay2_state 
    = 0
        
    ' Lcd "System Reset  "
        Wait 1 ' 
    صبر کوتاه برای نمایش پیام
        Cls
        Lcd 
    "Alarm System v1.0"
        
    Lowerline
        Lcd 
    "Standby..."
        
    Wait 2
        Cls
        Lcd 
    "Standby..."
        
    Lowerline
        Lcd 
    "Armed: NO" ' نمایش اینکه سیستم مسلح نیست

        Return

    ' 
    --- روتین‌های وقفه ---

    ' وقفه برای سنسور رید (INT0)
    Reed_relay_interrupt:
        ' 
    وقتی سنسور رید قطع می‌شود (از LOW به HIGH می‌رود)
        
    ' این وقفه برای تشخیص سریع خطا مفید است.
        ' 
    اگر سیستم مسلح باشد، آلارم را فعال کن.
        If 
    Arm_mode = 1 Then
            Alarm_active 
    = 1
            
    If Start_time = 0 Then ' اگر زمان شروع آلارم هنوز ثبت نشده
                Start_time = GetTimer ' 
    ثبت زمان فعلی
            End 
    If
        
    End If
        
    ' برای جلوگیری از خطاهای مکرر، می‌توان اینجا تاخیر کوتاهی ایجاد کرد یا فلگ تنظیم کرد
        Return

    ' 
    وقفه برای کلید ریست (INT1)
    ' این وقفه برای تشخیص همزمانی با کلید قطع استفاده می‌شود
    Reset_button_interrupt:
        ' 
    اگر این وقفه فعال شد، یعنی کلید ریست فشرده شده است.
        
    ' باید وضعیت کلید قطع (PD4) را نیز بررسی کنیم.
        ' 
    از یک متغیر کمکی برای ثبت اینکه کدام دکمه فشار داده شده استفاده می‌کنیم.
        
    ' یا مستقیماً در حلقه اصلی وضعیت هر دو را چک کنیم.
        ' 
    این روتین وقفه فقط برای فعال کردن یک فلگ یا ثبت زمان استفاده می‌شود.
        
    ' برای سادگی، در حلقه اصلی وضعیت هر دو دکمه را بررسی می‌کنیم.
        ' 
    اگر نیاز به واکنش سریع به فشار دکمه ریست بود، منطق آن را اینجا اضافه کنید.
        
    ' مثلاً اگر دکمه ریست به تنهایی فشار داده شد، سیستم را مسلح کند.
        ' 
    اما طبق درخواست شما، هر دو دکمه باید همزمان فشار داده شوند.

        
    ' برای اطمینان از اینکه این وقفه به درستی کار می‌کند، می‌توانیم سیستم را مسلح کنیم
        ' 
    این بخش باید با دقت بیشتری پیاده‌سازی شود تا با دکمه قطع تداخل نداشته باشد.
        
    ' با توجه به اینکه هر دو دکمه باید همزمان فشرده شوند، منطق اصلی در حلقه Do/Loop بهتر است.

        ' 
    اگر هدف این است که با فشار این دکمه، سیستم مسلح شود (و نه قطع)، باید منطق زیر را اضافه کرد:
        
    ' Arm_mode = 1
        ' 
    Lcd "System Armed"
        ' Wait 1

        Return

    ' 
    --- تابع کمکی برای خواندن زمان (نیاز به پیاده‌سازی دقیق با تایمر سخت‌افزاری) ---
    ' این تابع فقط یک جایگزین ساده است و دقت لازم را ندارد.
    ' 
    برای دقت بالا، باید از تایمرهای سخت‌افزاری ATmega16 استفاده کنید.
    GetTimer:
        
    ' این تابع باید زمان را بر اساس میلی‌ثانیه یا ثانیه برگرداند.
        ' 
    مثال ساده: استفاده از شمارنده داخلی Bascom (اگر فعال شده باشد)
        
    ' Return Timer
        ' 
    مثال دیگر: شمارش تیک‌های یک تایمر سخت‌افزاری.

        
    ' در حال حاضر، یک مقدار ثابت برمی‌گرداند که نشان‌دهنده عدم پیاده‌سازی دقیق است.
        ' 
    باید این بخش را با توجه به نیاز دقیق و تایمرهای سخت‌افزاری ATmega16 تکمیل کنید.
        
    ' برای تست، یک مقدار ثابت را برمی‌گردانیم.
        ' 
    اگر از تایمر 0 در حالت نرمال با prescaler 1024 استفاده کنیم، هر تیک 0.128ms است.
        
    ' برای 1 دقیقه، حدود 46875 تیک نیاز داریم.

        ' 
    یک مثال ساده (غیر دقیق):
        
    Dim Ticks As Long
        Ticks 
    = Ticks + 1 ' هر بار که این تابع فراخوانی می‌شود، یک واحد به شمارنده اضافه می‌شود.
        ' 
    این روش بسیار غیر دقیق است و برای اهداف آموزشی و آزمایشی است.
        Return 
    Ticks * 100 ' ضریب برای شبیه‌سازی زمان (این ضریب باید محاسبه شود)

    ' 
    --- تنظیمات اولیه LCD (اگر از LCD استفاده می‌کنید) ---
    ' Config Lcd = 20 , Lines = 4 ' مثال برای LCD 20x4
    ' Config Lcdpin = Data4lib , E = Portd.5 , Rs = Portd.6 , D4 = Portd.7 , D5 = Portc.2 , D6 = Portc.3 , D7 = Portc.4
    ' 
    Cls
    ' Lcd "Initializing..."
    ' 
    Lowerline
    ' Lcd "Alarm System..."
    ' 
    Wait 2
    ' Cls
    ' 
    Lcd "System Ready"
    ' Lowerline
    ' 
    Lcd "Armed: NO"
    ' Wait 1

    ' 
    --- تنظیمات مربوط به پتانسیومتر برای تنظیم حساسیت ---
    ' این بخش نیاز به یک حلقه یا زیربرنامه جداگانه دارد تا کاربر بتواند حساسیت را تنظیم کند.
    ' 
    برای مثال:
    ' Sub Adjust_sensitivity:
    '   
    While Pind.3 = 0  ' تا زمانی که کلید ریست فشرده است (برای شروع تنظیم)
    '     
    Avg_ldr_value = Getadc(0) ' خواندن مقدار فعلی LDR
    '     
    Threshold = Avg_ldr_value  ' تنظیم آستانه بر اساس مقدار فعلی
    '     ' نمایش مقدار آستانه روی LCD (اختیاری)
    '     ' Lcd "Threshold: " & Threshold
    '     
    Waitms 50
    '   Wend
    '   ' پس از رها کردن دکمه ریست، تنظیمات ذخیره می‌شود
    ' 
    Return

    ' --- تابع برای فعال کردن حالت مسلح شدن سیستم ---
    ' 
    شما می‌توانید این تابع را فراخوانی کنید تا سیستم مسلح شود.
    ' مثلاً با یک دکمه اضافی یا پس از یک دوره زمانی مشخص.
    ' 
    Arm_system:
    '   Arm_mode = 1
    '   ' Lcd "System Armed"
    '   ' Lowerline
    '   ' Lcd "Armed: YES"
    '   ' Wait 1
    '   
    Return
    ​ 
    جدیدترین ویرایش توسط MILAD3410; ۰۱:۵۴ ۱۴۰۴/۱۲/۲۵.
    وقتی بشینی کنار جاده‌ی زندگی چیزهای زیاد جالبی جز
    رفت آمد ماشینهای توی جاده نمیتونی ببینی
    باید بلند بشی و جاده زندگیتو خودت
    قدم بزنی آروم قدم بزنی و
    زیباییهاشو کشف کنی
    بعضی چیزها فقط برای تو آماده شده

    #2
    نوشته اصلی توسط MILAD3410 نمایش پست ها
    با عرض سلام خدمت دوستان و اساتید عزیز

    یه برنامه توسط هوش مصنوعی برای ساخت یک دزدگیر نوشته شده و خطا میده چندین بار به شکل‌های مختلف تغییرش دادم اما نیاز به دیباگ و بهینه سازی داره
    اگر ممکنه کمک کنید​
    ​​​​​
    دستور ADC خطا داشت
    دستور lcd نیاز نبود و توسط هوش مصنوعی اضافه شده



    کد PHP:
    $regfile = "m16adef.dat" ' فایل تعریف رجیسترها برای ATmega16A
    $crystal = 8000000 ' 
    فرکانس کاری میکروکنترلر (کریستال داخلی 8MHz)

    ' تعریف پین‌ها
    Config Porta.0 = Input ' 
    LDR ADC Input (PA0)
    Config Portd.2 = Input ' Reed Relay Input (PD2) - INT0
    Config Portd.3 = Input ' 
    Reset Button Input (PD3) - INT1
    Config Portd.4 
    = Input ' Alarm Off Button Input (PD4)
    Config Portb.0 = Output ' 
    LED Output (PB0)
    Config Portb.1 = Output ' Buzzer Output (PB1)
    Config Portc.0 = Output ' 
    Relay 1 Output (PC0)
    Config Portc.1 = Output ' Relay 2 Output (PC1)

    ' 
    تنظیمات ADC
    Config Adc 
    = Single ' حالت تک‌موجی ADC
    Config Adcres = 10 ' 
    رزولوشن 10 بیت
    Enable Adc 
    ' فعال کردن ADC

    ' 
    تنظیمات وقفه خارجی
    On Int0 Reed_relay_interrupt 
    ' تعریف روتین وقفه برای سنسور رید
    On Int1 Reset_button_interrupt ' 
    تعریف روتین وقفه برای کلید ریست (که همراه کلید قطع استفاده می‌شود)
    Enable Interrupts ' فعال کردن کلی وقفه‌ها

    ' 
    متغیرها
    Dim Ldr_value 
    As Word ' مقدار خوانده شده از LDR
    Dim Avg_ldr_value As Word ' 
    مقدار میانگین LDR
    Dim Threshold 
    As Word ' حد آستانه LDR (تنظیم با پتانسیومتر)
    Dim Led_state As Bit ' 
    وضعیت LED (روشن/خاموش)
    Dim Buzzer_state As Bit ' وضعیت Buzzer (روشن/خاموش)
    Dim Relay1_state As Bit ' 
    وضعیت رله اول
    Dim Relay2_state 
    As Bit ' وضعیت رله دوم
    Dim Alarm_active As Bit ' 
    فلگ فعال بودن آلارم
    Dim Timer1_flag 
    As Bit ' فلگ تایمر اول (1 دقیقه)
    Dim Timer2_flag As Bit ' 
    فلگ تایمر دوم (2 دقیقه)
    Dim Start_time As Long ' زمان شروع آلارم
    Dim Current_time As Long ' 
    زمان فعلی
    Dim Button_pressed_time 
    As Long ' زمان فشرده شدن دکمه‌ها
    Dim Button_held_time As Long ' 
    مدت زمان نگه داشتن دکمه‌ها
    Dim Arm_mode 
    As Bit ' حالت مسلح بودن سیستم (0=غیرمسلح, 1=مسلح)

    ' 
    --- تنظیمات اولیه ---
    Ldr_value = 0
    Avg_ldr_value 
    = 0
    Threshold 
    = 500 ' مقدار اولیه آستانه (قابل تنظیم با پتانسیومتر) - این مقدار باید با تنظیم پتانسیومتر تنظیم شود.
    Led_state = 0
    Buzzer_state = 0
    Relay1_state = 0
    Relay2_state = 0
    Alarm_active = 0
    Timer1_flag = 0
    Timer2_flag = 0
    Arm_mode = 0 ' 
    سیستم در ابتدا غیرمسلح است

    ' فعال کردن داخلی Pull-up برای پین‌های ورودی دکمه‌ها
    ' 
    برای سنسور رید، فرض می‌کنیم که سنسور NO است و وقتی متصل است، پین را LOW می‌کند.
    ' اگر سنسور NC بود، منطق باید برعکس شود.
    ' 
    اگر نیاز به مقاومت خارجی Pull-up/Pull-down برای دکمه‌ها دارید، آن را اضافه کنید.
    Set Portd.3 ' فعال کردن Pull-up داخلی برای کلید ریست
    Set Portd.4 ' 
    فعال کردن Pull-up داخلی برای کلید قطع

    ' --- تنظیمات تایمرها ---
    ' 
    برای تایمر 1 دقیقه و 2 دقیقه، از تایمر داخلی میکروکنترلر استفاده می‌کنیم.
    ' با فرکانس 8MHz و تقسیم‌کننده 1024، زمان هر تیک حدود 0.128 میلی‌ثانیه است.
    ' 
    برای 1 دقیقه (60 ثانیه)، نیاز به حدود 468750 تیک داریم.
    ' برای 3 دقیقه (180 ثانیه)، نیاز به حدود 1406250 تیک داریم.
    ' 
    این محاسبات نیاز به دقت بیشتری دارد و ممکن است نیاز به تنظیم Prescaler و Mode تایمر باشد.
    ' در این مثال، از منطق ساده‌تر برای نمایش زمان استفاده می‌کنیم.
    ' 
    برای دقت بالا، استفاده از تایمرهای سخت‌افزاری توصیه می‌شود.

    ' --- شروع برنامه اصلی ---
    Cls ' 
    پاک کردن صفحه ترمینال (اگر از LCD استفاده می‌کنید)
    Lowerline ' رفتن به خط پایین (اگر از LCD استفاده می‌کنید)
    Lcd "Alarm System v1.0"

    Wait 2

    Do
    Gosub Get_sensor_values ' 
    خواندن مقادیر سنسورها
    Gosub Check_system_state 
    ' بررسی وضعیت سیستم و فعال کردن آلارم در صورت نیاز

    ' 
    --- مدیریت فعال بودن آلارم ---
    If 
    Alarm_active = 1 Then
    Gosub Handle_alarm 
    ' اجرای عملیات مربوط به آلارم فعال
    Else
    ' 
    سیستم در حالت عادی است، همه چیز خاموش
    Set Portb.0 
    = 0 ' خاموش کردن LED
    Set Portb.1 = 0 ' 
    خاموش کردن Buzzer
    Set Portc.0 
    = 0 ' خاموش کردن رله 1
    Set Portc.1 = 0 ' 
    خاموش کردن رله 2
    Led_state 
    = 0
    Buzzer_state 
    = 0
    Relay1_state 
    = 0
    Relay2_state 
    = 0
    Timer1_flag 
    = 0
    Timer2_flag 
    = 0
    ' در حالت عادی، سیستم مسلح نیست مگر اینکه دکمه‌ها فشار داده شوند
    ' 
    اگر سیستم مسلح باشد و هیچ خطایی رخ ندهد، همچنان مسلح می‌ماند
    ' اگر نیاز دارید در حالت عادی سیستم خودکار غیرمسلح شود، منطق آن را اینجا اضافه کنید
    End If

    Waitms 100 ' 
    تاخیر کوتاه برای پایداری

    Loop

    ' --- زیربرنامه‌ها ---

    ' 
    زیربرنامه خواندن مقادیر سنسورها و محاسبه میانگین LDR
    Get_sensor_values
    :
    Dim I As Integer
    Dim Temp_ldr 
    As Word
    Temp_ldr 
    = 0
    For I = 1 To 10 ' 10 بار خواندن مقدار LDR
    Ldr_value = Getadc(0) ' 
    خواندن از ADC0 (PA0)
    Temp_ldr = Temp_ldr + Ldr_value
    Waitms 10 
    ' تاخیر کوتاه بین خواندن‌ها
    Next I
    Avg_ldr_value = Temp_ldr / 10 ' 
    محاسبه میانگین

    ' خواندن وضعیت سنسور رید (INT0)
    ' 
    فرض می‌کنیم سنسور NO است و در حالت عادی وصل است (LOW). اگر قطع شود HIGH می‌شود.
    ' اگر سنسور NC بود، منطق باید برعکس شود.
    If Pind.2 = 1 Then ' 
    اگر سنسور رید قطع شد (HIGH)
    ' این یک خطا محسوب می‌شود
    Else ' 
    اگر سنسور رید وصل است (LOW)
    ' مشکلی نیست
    End If

    ' 
    خواندن وضعیت دکمه‌ها
    ' کلید ریست (INT1) و کلید قطع (PD4)
    ' 
    اگر هر دو همزمان فشرده شوند، سیستم قطع می‌شود.
    ' برای اطمینان از اینکه دکمه‌ها به درستی کار می‌کنند، از روش Debouncing استفاده می‌شود.

    Return

    ' 
    زیربرنامه بررسی وضعیت سیستم و فعال کردن آلارم
    Check_system_state
    :
    ' بررسی شرط فعال شدن آلارم:
    ' 
    1. نور LDR کمتر از حد آستانه باشد (نشان‌دهنده قطع لیزر)
    ' 2. سنسور رید قطع شده باشد (PIND.2 = 1)
    ' 
    3. سیستم در حالت مسلح باشد (Arm_mode = 1)

    ' ابتدا وضعیت کلیدهای قطع و ریست را بررسی می‌کنیم
    If Pind.3 = 0 And Pind.4 = 0 Then ' 
    اگر هر دو کلید همزمان فشرده شوند
    ' سیستم قطع می‌شود، به حالت عادی برمی‌گردد
    Alarm_active = 0
    Arm_mode = 0
    Start_time = 0 ' 
    ریست کردن زمان شروع آلارم
    ' کلیدها باید برای مدتی فشرده شوند تا تشخیص داده شوند (Debouncing)
    Waitms 200 ' 
    تاخیر برای Debouncing
    If Pind.3 = 0 And Pind.4 = 0 Then ' اگر همچنان فشرده هستند
    Gosub Reset_system_state
    End If
    End If

    ' 
    اگر سیستم مسلح باشد
    If Arm_mode = 1 Then
    ' بررسی شرایط خطا
    If Avg_ldr_value < Threshold Or Pind.2 = 1 Then
    ' 
    خطای تشخیص داده شد
    If Alarm_active = 0 Then ' اگر آلارم قبلا فعال نبوده است
    Alarm_active = 1 ' 
    فعال کردن آلارم
    Start_time 
    = GetTimer ' ثبت زمان شروع آلارم (نیاز به پیاده‌سازی GetTimer با تایمر سخت‌افزاری)
    ' 
    برای سادگی، از Wait استفاده می‌کنیم که دقیق نیست
    ' Start_time = Timer ' استفاده از تایمر داخلی Bascom (اگر فعال باشد)
    ' باید یک روش دقیق برای ثبت زمان داشته باشید
    End If
    End If
    Else
    ' 
    اگر سیستم غیرمسلح است، آلارم نباید فعال شود
    Alarm_active 
    = 0
    End 
    If

    Return

    ' زیربرنامه مدیریت حالت آلارم فعال
    Handle_alarm:
    ' 
    فعال کردن LED چشمک‌زن
    If Led_state = 0 Then
    Set Portb.0 
    = 1
    Led_state 
    = 1
    Waitms 250 
    ' تاخیر برای چشمک زدن
    Set Portb.0 = 0
    Led_state = 0
    Waitms 250
    Else
    ' 
    در حالت عادی چشمک می‌زند
    End 
    If

    ' فعال کردن بازر آژیر
    If Buzzer_state = 0 Then
    Set Portb.1 = 1
    Buzzer_state = 1
    ' 
    الگوی آژیر را اینجا تعریف کنید (مثلا چند ثانیه روشن، چند ثانیه خاموش)
    ' برای سادگی، آن را همیشه روشن نگه می‌داریم تا زمانی که آلارم فعال است
    ' 
    Set Portb.1 = 1
    ' برای ایجاد آژیر واقعی، باید الگو تعریف شود
    Else
    ' 
    Buzzer is already on
    End 
    If

    ' --- مدیریت زمان‌بندی فعال شدن رله‌ها ---
    ' 
    فرض می‌کنیم GetTimer زمان را بر اساس میلی‌ثانیه برمی‌گرداند
    ' برای 1 دقیقه = 60000 میلی‌ثانیه
    ' 
    برای 3 دقیقه = 180000 میلی‌ثانیه

    ' اگر زمان شروع آلارم ثبت شده باشد
    If Start_time > 0 Then
    Current_time = GetTimer ' 
    دریافت زمان فعلی (نیاز به پیاده‌سازی GetTimer)

    ' فعال شدن رله اول پس از 1 دقیقه (60000 میلی‌ثانیه)
    If Timer1_flag = 0 And (Current_time - Start_time) >= 60000 Then
    Set Portc.0 = 1 ' 
    فعال کردن رله اول
    Relay1_state 
    = 1
    Timer1_flag 
    = 1 ' فلگ تایمر اول تنظیم شد
    ' 
    برای سادگی، از LCD برای نمایش وضعیت استفاده می‌کنیم
    ' Lcd "Relay 1 ON "
    End If

    ' 
    فعال شدن رله دوم پس از 3 دقیقه (180000 میلی‌ثانیه)
    If 
    Timer2_flag = 0 And (Current_time - Start_time) >= 180000 Then
    Set Portc.1 
    = 1 ' فعال کردن رله دوم
    Relay2_state = 1
    Timer2_flag = 1 ' 
    فلگ تایمر دوم تنظیم شد
    ' Lcd "Relay 2 ON "
    End If
    End If

    Return

    ' 
    زیربرنامه بازنشانی سیستم به حالت عادی
    Reset_system_state
    :
    Alarm_active = 0
    Arm_mode 
    = 0
    Start_time 
    = 0
    Timer1_flag 
    = 0
    Timer2_flag 
    = 0
    Set Portb.0 
    = 0 ' خاموش کردن LED
    Set Portb.1 = 0 ' 
    خاموش کردن Buzzer
    Set Portc.0 
    = 0 ' خاموش کردن رله 1
    Set Portc.1 = 0 ' 
    خاموش کردن رله 2
    Led_state 
    = 0
    Buzzer_state 
    = 0
    Relay1_state 
    = 0
    Relay2_state 
    = 0
    ' Lcd "System Reset "
    Wait 1 ' 
    صبر کوتاه برای نمایش پیام
    Cls
    Lcd 
    "Alarm System v1.0"
    Lowerline
    Lcd 
    "Standby..."
    Wait 2
    Cls
    Lcd 
    "Standby..."
    Lowerline
    Lcd 
    "Armed: NO" ' نمایش اینکه سیستم مسلح نیست

    Return

    ' 
    --- روتین‌های وقفه ---

    ' وقفه برای سنسور رید (INT0)
    Reed_relay_interrupt:
    ' 
    وقتی سنسور رید قطع می‌شود (از LOW به HIGH می‌رود)
    ' این وقفه برای تشخیص سریع خطا مفید است.
    ' 
    اگر سیستم مسلح باشد، آلارم را فعال کن.
    If 
    Arm_mode = 1 Then
    Alarm_active 
    = 1
    If Start_time = 0 Then ' اگر زمان شروع آلارم هنوز ثبت نشده
    Start_time = GetTimer ' 
    ثبت زمان فعلی
    End 
    If
    End If
    ' برای جلوگیری از خطاهای مکرر، می‌توان اینجا تاخیر کوتاهی ایجاد کرد یا فلگ تنظیم کرد
    Return

    ' 
    وقفه برای کلید ریست (INT1)
    ' این وقفه برای تشخیص همزمانی با کلید قطع استفاده می‌شود
    Reset_button_interrupt:
    ' 
    اگر این وقفه فعال شد، یعنی کلید ریست فشرده شده است.
    ' باید وضعیت کلید قطع (PD4) را نیز بررسی کنیم.
    ' 
    از یک متغیر کمکی برای ثبت اینکه کدام دکمه فشار داده شده استفاده می‌کنیم.
    ' یا مستقیماً در حلقه اصلی وضعیت هر دو را چک کنیم.
    ' 
    این روتین وقفه فقط برای فعال کردن یک فلگ یا ثبت زمان استفاده می‌شود.
    ' برای سادگی، در حلقه اصلی وضعیت هر دو دکمه را بررسی می‌کنیم.
    ' 
    اگر نیاز به واکنش سریع به فشار دکمه ریست بود، منطق آن را اینجا اضافه کنید.
    ' مثلاً اگر دکمه ریست به تنهایی فشار داده شد، سیستم را مسلح کند.
    ' 
    اما طبق درخواست شما، هر دو دکمه باید همزمان فشار داده شوند.

    ' برای اطمینان از اینکه این وقفه به درستی کار می‌کند، می‌توانیم سیستم را مسلح کنیم
    ' 
    این بخش باید با دقت بیشتری پیاده‌سازی شود تا با دکمه قطع تداخل نداشته باشد.
    ' با توجه به اینکه هر دو دکمه باید همزمان فشرده شوند، منطق اصلی در حلقه Do/Loop بهتر است.

    ' 
    اگر هدف این است که با فشار این دکمه، سیستم مسلح شود (و نه قطع)، باید منطق زیر را اضافه کرد:
    ' Arm_mode = 1
    ' 
    Lcd "System Armed"
    ' Wait 1

    Return

    ' 
    --- تابع کمکی برای خواندن زمان (نیاز به پیاده‌سازی دقیق با تایمر سخت‌افزاری) ---
    ' این تابع فقط یک جایگزین ساده است و دقت لازم را ندارد.
    ' 
    برای دقت بالا، باید از تایمرهای سخت‌افزاری ATmega16 استفاده کنید.
    GetTimer:
    ' این تابع باید زمان را بر اساس میلی‌ثانیه یا ثانیه برگرداند.
    ' 
    مثال ساده: استفاده از شمارنده داخلی Bascom (اگر فعال شده باشد)
    ' Return Timer
    ' 
    مثال دیگر: شمارش تیک‌های یک تایمر سخت‌افزاری.

    ' در حال حاضر، یک مقدار ثابت برمی‌گرداند که نشان‌دهنده عدم پیاده‌سازی دقیق است.
    ' 
    باید این بخش را با توجه به نیاز دقیق و تایمرهای سخت‌افزاری ATmega16 تکمیل کنید.
    ' برای تست، یک مقدار ثابت را برمی‌گردانیم.
    ' 
    اگر از تایمر 0 در حالت نرمال با prescaler 1024 استفاده کنیم، هر تیک 0.128ms است.
    ' برای 1 دقیقه، حدود 46875 تیک نیاز داریم.

    ' 
    یک مثال ساده (غیر دقیق):
    Dim Ticks As Long
    Ticks 
    = Ticks + 1 ' هر بار که این تابع فراخوانی می‌شود، یک واحد به شمارنده اضافه می‌شود.
    ' 
    این روش بسیار غیر دقیق است و برای اهداف آموزشی و آزمایشی است.
    Return 
    Ticks * 100 ' ضریب برای شبیه‌سازی زمان (این ضریب باید محاسبه شود)

    ' 
    --- تنظیمات اولیه LCD (اگر از LCD استفاده می‌کنید) ---
    ' Config Lcd = 20 , Lines = 4 ' مثال برای LCD 20x4
    ' Config Lcdpin = Data4lib , E = Portd.5 , Rs = Portd.6 , D4 = Portd.7 , D5 = Portc.2 , D6 = Portc.3 , D7 = Portc.4
    ' 
    Cls
    ' Lcd "Initializing..."
    ' 
    Lowerline
    ' Lcd "Alarm System..."
    ' 
    Wait 2
    ' Cls
    ' 
    Lcd "System Ready"
    ' Lowerline
    ' 
    Lcd "Armed: NO"
    ' Wait 1

    ' 
    --- تنظیمات مربوط به پتانسیومتر برای تنظیم حساسیت ---
    ' این بخش نیاز به یک حلقه یا زیربرنامه جداگانه دارد تا کاربر بتواند حساسیت را تنظیم کند.
    ' 
    برای مثال:
    ' Sub Adjust_sensitivity:
    ' 
    While Pind.3 = 0 ' تا زمانی که کلید ریست فشرده است (برای شروع تنظیم)
    ' 
    Avg_ldr_value = Getadc(0) ' خواندن مقدار فعلی LDR
    ' 
    Threshold = Avg_ldr_value ' تنظیم آستانه بر اساس مقدار فعلی
    ' ' نمایش مقدار آستانه روی LCD (اختیاری)
    ' ' Lcd "Threshold: " & Threshold
    ' 
    Waitms 50
    ' Wend
    ' ' پس از رها کردن دکمه ریست، تنظیمات ذخیره می‌شود
    ' 
    Return

    ' --- تابع برای فعال کردن حالت مسلح شدن سیستم ---
    ' 
    شما می‌توانید این تابع را فراخوانی کنید تا سیستم مسلح شود.
    ' مثلاً با یک دکمه اضافی یا پس از یک دوره زمانی مشخص.
    ' 
    Arm_system:
    ' Arm_mode = 1
    ' ' Lcd "System Armed"
    ' ' Lowerline
    ' ' Lcd "Armed: YES"
    ' ' Wait 1
    ' 
    Return
    ​ 
    این هم یک نمونه دیگر از کد ارسالی توسط هوش مصنوعی

    کد PHP:
    $regfile = "m16def.dat"
    $crystal = 8000000
    $baud 
    = 9600

    '---------------------- تعریف متغیرها ----------------------
    Dim Ldr_value As Word
    Dim Pot_value As Word
    Dim Threshold As Word
    Dim Reed As Bit
    Dim Reset_btn As Bit
    Dim Stop_btn As Bit

    Dim Alarm_active As Bit
    Dim Minute_counter As Byte

    '
    ---------------------- تنظیم ورودی/خروجی -------------------
    Config PortA = Input
    Config PortB 
    = Output
    Config PortD 
    = Input

    PortA 
    = &B00000011                          ' فعالسازی Pull-up برای ورودی‌های آنالوگ
    PortD = &B00011100                          ' 
    فعالسازی pull-up برای کلیدها و reed

    Led Alias Portb.0
    Buzzer Alias Portb.1
    Relay1 Alias Portb.2
    Relay2 Alias Portb.3
    Reed_sw Alias Pind.2
    Btn_reset Alias Pind.3
    Btn_stop Alias Pind.4

    '---------------------- تنظیم ADC --------------------------
    Config Adc = Single , Prescaler = Auto , Reference = Avcc
    Start Adc

    '
    ---------------------- وضعیت اولیه ------------------------
    Led = 0
    Buzzer 
    = 0
    Relay1 
    = 0
    Relay2 
    = 0
    Alarm_active 
    = 0

    '---------------------- برنامه اصلی ------------------------
    Do
        Ldr_value = Getadc(0)
        Pot_value = Getadc(1)
        Threshold = Pot_value

        Reed = Reed_sw

        If (Ldr_value < Threshold) Or (Reed = 0) Then
            Alarm_active = 1
            Minute_counter = 0
        End If

        If Alarm_active = 1 Then
            '
    چشمک‌زدن LED
            Led 
    = 1
            Waitms 200
            Led 
    = 0
            Waitms 200

            
    'آژیر
            Buzzer = 1
            Waitms 100
            Buzzer = 0
            Waitms 100

            '
    افزایش شمارنده زمان در دقیقه
            
    If Minute_counter = 0 Then
                Wait 60
                Incr Minute_counter
            
    Elseif Minute_counter = 1 Then
                Relay1 
    = 1
                Wait 60
                Incr Minute_counter
            
    Elseif Minute_counter = 2 Then
                Relay2 
    = 1
            End 
    If

            
    ' بررسی برای راه‌اندازی مجدد
            If Btn_reset = 0 Then
                If Btn_stop = 0 Then
                    ' 
    همزمان هر دو دکمه فشرده شدند = قطع دزدگیر
                    Alarm_active 
    = 0
                    Relay1 
    = 0
                    Relay2 
    = 0
                    Led 
    = 0
                    Buzzer 
    = 0
                    Waitms 500
                
    Else
                    
    ' فقط دکمه ریست: راه‌اندازی مجدد
                    Minute_counter = 0
                    Relay1 = 0
                    Relay2 = 0
                End If
            End If
        End If
    Loop
    End
    ​ 
    وقتی بشینی کنار جاده‌ی زندگی چیزهای زیاد جالبی جز
    رفت آمد ماشینهای توی جاده نمیتونی ببینی
    باید بلند بشی و جاده زندگیتو خودت
    قدم بزنی آروم قدم بزنی و
    زیباییهاشو کشف کنی
    بعضی چیزها فقط برای تو آماده شده

    دیدگاه


      #3
      از دوستانی که در زمینه avr و کد نویسی بسکام تخصص دارند خواعش میکنم یه وقتی به من بدهند برای عیبیابی این کد و راه اندازیش
      وقتی بشینی کنار جاده‌ی زندگی چیزهای زیاد جالبی جز
      رفت آمد ماشینهای توی جاده نمیتونی ببینی
      باید بلند بشی و جاده زندگیتو خودت
      قدم بزنی آروم قدم بزنی و
      زیباییهاشو کشف کنی
      بعضی چیزها فقط برای تو آماده شده

      دیدگاه

      لطفا صبر کنید...
      X