اطلاعیه

Collapse
No announcement yet.

if(n++>350)X=adc_out

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

    if(n++>350)X=adc_out

    با سلام : مبتدی هستم و شرمنده دوستان و اساتید. لطفا راهنمایی بفرمایید.
    میخوام تا زمانیکه مقدار X متغییر است ( منظورم اینه تا زمانیکه با پتانسومتر بصورت دستی در حال تغییر دادن مقدار X هستیم ) X مساوی adc_out نشه
    مثلا اینجا چه باید اضافه کنم :
    if(n++>350)X=adc_out
    میخوام بعد از زمان 350 تا موقعی که داریم با پتانسومتر مقدار X را دستی تغییر میدیم X=adc_out نشه و اگر مقدارش را با پتانسومتر تغییر ندادیم انوقت مساوی op=adc_out قرار بگیره
    حالا اینجا نمیدانم باید چه اضافه کنم . if(n++>350 && X?????)
    .با تشکر
    جدیدترین ویرایش توسط amiri630; ۱۸:۰۴ ۱۳۹۵/۰۳/۱۴.

    #2
    پاسخ : if(n++>350 && X?????)

    سلام
    دوست عزیز اگه درست متوجه منظور شما شده باشم میخواین به یه متغیر، مقدار خوانده شده از ADC رو نسبت بدین اما میخواین در صورتی این اتفاق بیافته که مقدار خوانده شده از ADC (مقدار کمیت فیزیکی تحت اندازه گیری) پایدار باشد.

    اگه این منظور شماست میتونین بیاین و یک متغیر (Dummy) (منظور متغیری غیر از متغیر اصلی X) در نظر بگیرین و مقدار ADC رو هر چند لحظه یکبار بخونین و تو اون ذخیره کنین حالا بیاین و اختلاف دو مقدار فعلی و قبلی رو بدست بیارین و تو یه شرط مشخص کنین که آیا تغییر کرده یا نه در صورتی که تغییر کرده بود خب کاری نمیکنین ولی اگه تغییر نکرده بود میاین و متغییر X رو برابر مقدار خونده شده قرار میدین.

    حالا این چند لحظه ها رو میتونی با تایمر و وقفه انجام بدین یا به کمک یه wait ساده
    اینش دیگه بستگی به بقیه برنامتون داره.

    در مورد اینکه یه حدی هم براش در نظر بگیرین میتونین بیاین و یه متغیر به عنوان کانتر انتخاب کنین و تو شرط if یه شرط ترکیبی متناسب با لاجیکتون قرار بدین.

    در ضمن لطفا در نگارش دقت کنین که بهم ریخته نشه
    ممنون
    موفق باشید

    دیدگاه


      #3
      پاسخ : if(n++>350)X=adc_out

      خب اینجا شما نیاز به زمان گیری دارید ...به این صورت که وقتی adc_out تغییر کرد زمان گیری شرو بشه(و البته تایمر زمانگیر مقدارش صفر بشه)...وقتی که تغیرات با پتانسیومتر داره انجام میشه مقدار تایمر همیشه در حالت صفر قرار میگیره...وقتی پتانسیومتر ثابت شد مقدار تایمر شروع به افزایش میکنه و تا جایی که خودتون تنطیم کردین زمان گیری انجام میشه...مثلا 500 میلی ثانیه...یعنی تایمر شروع به افزایش میکنه و اگر زمان تونست به مقدار 500 میلی ثانیه برسه اون وقت adc_out رو بریزه داخل x

      یه چیزی شبیه به watchdog timer
      تولید کننده تجهیزات برنامه پذیر اتوماسیون صنعتی

      www.intelart.ir


      ساخت کنترلر دما PID فازي با AVR [آموزشی]

      دیدگاه


        #4
        پاسخ : if(n++>350)X=adc_out

        با سلام و تشکر : با راهنمایی اقای میرزایی عزیز کد ها را اینجوری نوشتم ولی باز هم وقتی با پتانسیومتر مقدار را تغییر میدم Y=adc_in2 میشه !

        کد:
        while(1){ 
        adc_in1=read_adc(0);
        X=adc_in1;
        if(n>=350){
          adc_in2=read_adc(0);
        }
          Diff = adc_in2 - adc_in1;  
          if(n++>=350 && Diff==0){
          Y=adc_in2;//مقدار را با پتانسومتر تغییر میدم ولی باز 
        }
         n++;
        جدیدترین ویرایش توسط amiri630; ۰۲:۲۸ ۱۳۹۵/۰۳/۱۵.

        دیدگاه


          #5
          پاسخ : if(n++>350)X=adc_out

          سلام

          یه تاخیر لازم داره که ننوشتین اینطوری اونقدر سریع حساب میشه که به سرعت اون اختلاف صفر شه.

          لطفا کدی که براتون فرستادم رو هم بذارین

          دیدگاه


            #6
            پاسخ : if(n++>350)X=adc_out

            با تشکر فراوان : کاملا درسته، مشکل من همین تاخیره ، نمیدانم دقیقا کجا تاخیر بگذارم،البته قبل از خواندن adc یک تاخیر 100 میلی ثانیه ای قرار دادم ولی این تاخیر باعث چشمک زدن صفحه نمایش شد. دیلی را کم کردم باز اختلاف صفر میشه. این مشکل را توی میانگین گیری از adc هم دارم نمیدانم تاخیر را چطوری باید بعد از هر بار readadc قرار بدم که باعث چشمک زدن صفحه نمایش نشه. این هم کدهای شما. با تشکر مجدد.

            کد:
            unsigned int X_Dummy;unsigned int X;
            unsigned int n;
            void main (void)
            {
                X_Dummy=ADC_read();
                X=ADC_read();
                while(1)
                {
                  // باعث چشمک زدن صفحه نمایش شد  [COLOR=#FF0000]ms_delay(100);[/COLOR]
                    X_Dummy=ADC_read();
                    Diff=X-X_Dummy;
                    if(Diff==0 || n>=350)
                    {
                        X=X_Dummy;
                    }
                    n++;
                }
            }
            جدیدترین ویرایش توسط amiri630; ۱۳:۱۰ ۱۳۹۵/۰۳/۱۵.

            دیدگاه


              #7
              پاسخ : if(n++>350)X=adc_out

              دو تا مورد به ذهنم میرسه:

              یکی اینکه به جای تاخیر نرم افزاری از تاخیر سخت افزاری استفاده کنی و به کمک فلگ های ADC یه تایمر رو تریگر کنی و به کمک اون تایمر عملیاتت رو انجام بدی (همون روشی که آقای فانی در پست های بالا گفتن)

              ولی مورد دوم که به نظرم میرسه اینکه شما احتمالا برای هر بار نوشتن رو LCD داری محتویات LCD رو پاک میکنی و دوباره مینویسی، اگه اینطوره که محتویات رو پاک نکن و فقط عدد مربوط به محاسبات رو جایگزینش کن (اونم اگه تونستی موقعی که تغییری رخ داد) مثلا اگه 3 خونه رو برای حاصلت در نظر گرفتی بیا و هربار پوینتر LCD رو به اون نقطه ببر و حاصل رو در اونجا بنویس نه اینکه کلش رو پاک کنی و از اول رو نمایشگرت بنویسی.

              این دو مورد فقط به ذهنم رسید
              جدیدترین ویرایش توسط فرید الدین میرزایی; ۱۳:۳۷ ۱۳۹۵/۰۳/۱۵.

              دیدگاه


                #8
                پاسخ : if(n++>350)X=adc_out

                دو تا مورد به ذهنم میرسه:

                یکی اینکه به جای تاخیر نرم افزاری از تاخیر سخت افزاری استفاده کنی و به کمک فلگ های ADC یه تایمر رو تریگر کنی و به کمک اون تایمر عملیاتت رو انجام بدی (همون روشی که آقای فنی در پست های بالا گفتن)
                بله درسته...یا باید مشتق بگیرن و هر وقت مشتق صفر شد متغیر رو تغییر بدن یا اینکه زمان گیری کنند...مشنق گیری محاسبات بیشتری داره و زمان گیری با تایمر منابع سخت افزاری رو به کار میگیره...باید بر حسب نیاز و امکانات دردسترس تصمیم بگیرن!

                راستی فامیلی من فانی هست ...عمدا 2 تا a گذاشتم که آ خونده بشه
                تولید کننده تجهیزات برنامه پذیر اتوماسیون صنعتی

                www.intelart.ir


                ساخت کنترلر دما PID فازي با AVR [آموزشی]

                دیدگاه


                  #9
                  پاسخ : if(n++>350)X=adc_out

                  با تشکر فراوان از اقای میرزایی و اقای فانی :با توجه به راهنمایی های این دو مهندس عزیز مشکل حل شد .سپاسگزارم
                  دعای خیر ما بدرقه راهتان. موفق و موید باشید
                  جدیدترین ویرایش توسط amiri630; ۱۷:۳۱ ۱۳۹۵/۰۳/۱۵.

                  دیدگاه


                    #10
                    پاسخ : if(n++>350)X=adc_out

                    با سلام مجدد : توی پرتیوس چون ریپل خیلی خیلی کمتری نسبت به روی مدار داریم ، دستورات بدرستی عمل می کنه . روی مدار ،ریپل تغذیه adc توی ولتاژ های بالا بیشتر از ولتاژ های کمتر است، بنابراین به علت همین ریپل، در ولتاژ های بالا دستورات بدرستی نمیتوانند اجرا بشوند. اینجوری میانگین گرفته ام ولی انچنان کارساز نیست ، لطفا میشه لطف کنید اشکال این کد های میانگین گیری چیه ؟باتشکر
                    کد:
                    adc_tsum = 0;        
                           for(i=0; i<29; i++)
                            {
                           adc_time[i]=read_adc(2);//chanal 2 (timer)
                           // بیشتر بشه باعث چشمک زدن صفحه نمایش میشهdelay_ms(2);
                           adc_tsum = adc_tsum + adc_time[i];
                           }
                           adc_tim2 = adc_tsum/29;
                    جدیدترین ویرایش توسط amiri630; ۲۲:۰۴ ۱۳۹۵/۰۳/۱۵.

                    دیدگاه


                      #11
                      پاسخ : if(n++&gt;350)X=adc_out

                      سلام

                      پیزی که به ذهن من میرسه اینکه اول از همه از اون فیلتر پایین گذری که تو دیتاشیت اتمل مربوط به میکروتون هست برای تغذیه ADC استفاده کنید و از طرفی هم میتونین به جای در نظر گرفتن صفر به عنوان مقدار اختلاف یه مقدار بزرگتر که در حد مثلا دو یا سه واحد تغییرات ADCشماست استفاده کنید

                      موفق باشید

                      پ.ن: من متوجه کد بالا نشدم ولی برای میانگین گیری باید چند بار بخونید و با هم جمع کنید و سپس به تعداد تقسیم کنید که فکر کنم همین کار رو انجام دادید. ولی متوجه نمیشم چرا یه ارایه تعریف کردین برای میانگین گیری همون جمع کردن و اضافه کردن به حاصل جمع قبلی کافیه.
                      جدیدترین ویرایش توسط فرید الدین میرزایی; ۲۳:۵۲ ۱۳۹۵/۰۳/۱۵.

                      دیدگاه


                        #12
                        پاسخ : if(n++&gt;350)X=adc_out

                        ی پیشنهاد:به جای مقدار گیری از adc با روش polling از اینتراپت اسنفاده کنید...یعنی داخل روتین سرویس اینتراپت یه شمارنده بذارید و با هر بار اینتراپت مقدار رجیستر adcw رو به ی متغیر اضافه کنید...وقتی شمارنده به مقدار مثلا ۵ رسید اون وقت منغیر رو تقسیم بر ۵ کنید....در جای دیگه ای از برنامه میتونید از این منغیر به جای خروجی اینتراپت استفاده کنید... که همون خروجی میانگین شده است...و البته وقت پردازنده هم آزاد تر میشه....
                        تولید کننده تجهیزات برنامه پذیر اتوماسیون صنعتی

                        www.intelart.ir


                        ساخت کنترلر دما PID فازي با AVR [آموزشی]

                        دیدگاه

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