اطلاعیه

Collapse
No announcement yet.

مشکل با صفحه کلید ماتریسی

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

    مشکل با صفحه کلید ماتریسی

    با سلام و آرزوی قبولی طاعات و عبادات در این ماه عزیز ، یه سئوال دوستان : در یه صفحه کلید ماتریسی اگه سه تا کلید رو همزمان فشار بدیم که دوتای اونا روی یک ستون و دوتا روی یک سطر باشن یعنی کلیدای فشرده شده حرف L انگلیسی رو تداعی کنن ، نتیجه اسکن صفحه کلید به اشتباه چهار تا کلید رو شناسایی می کنه . به نظرتون میشه الگوریتمی نرم افزاری برای حل این مشکل پیدا کرد؟ ظاهر قضیه میگه نمیشه و این جزء ذات صفحه کلید ماتریسیه. ممنون میشم نظراتتون رو بدونم.

    #2
    پاسخ : مشکل با صفحه کلید ماتریسی

    سلام
    متشکرم...
    این به الگوریتم خواندن کیپد برمیگرده...یک الگوریتم این هست که شما مثلا برای کیپد 4*4 ستون ها رو به نیبل بالا و سطرها رو به نیبل پایین متصل کنید و نیبل بالا رو خروجی کنید و در چهار مرحله مقدار 0 برای هر ستون قرار بدید و نیبل پایین رو ورودی و پول اپ کنید.سپس مقدار سطرها رو بخونید.به صورت زیر:
    char keypad()
    {
    unsigned char i, j, row_detect;
    DDRA = 0x0f; //Keypad is Connected To PORTA

    for (i = 0; i < 4; i++)
    {
    PORTA = row_out[i];
    for (j = 0; j < 4; j++)
    {
    row_detect = 4;
    if (c0 == 0)
    row_detect = 0;
    if (c1 == 0)
    row_detect = 1;
    if (c2 == 0)
    row_detect = 2;
    if (c3 == 0)
    row_detect = 3;
    if (row_detect != 4)
    return keys[i][row_detect];
    while (c0 == 0);
    while (c1 == 0);
    while (c2 == 0);
    while (c3 == 0);
    }

    }
    return 0;
    }



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

    char keypad()
    {
    unsigned char i, j;
    unsigned char row_detect[16];
    DDRA = 0x0f; //Keypad is Connected To PORTA


    for (i = 0; i < 4; i++)
    {

    PORTA = row_out[i];
    for (j = 0; j < 4; j++)
    {
    row_detect[i + j] = 4;
    row_detect[i + j + 1] = 4;
    row_detect[i + j + 2] = 4;
    row_detect[i + j + 3] = 4;
    if (c0 == 0)
    row_detect[i + j] = 0;
    if (c1 == 0)
    row_detect[i + j + 1] = 1;
    if (c2 == 0)
    row_detect[i + j + 2] = 2;
    if (c3 == 0)
    row_detect[i + j + 3] = 3;

    while (c0 == 0);
    while (c1 == 0);
    while (c2 == 0);
    while (c3 == 0);
    }

    }
    return 0;
    }


    خب حالا یک آرایه داریم که مقادیر اون رو میتونیم بخونیم و تشخیص بدیم که کدوم کلید(ها) فشرده شده...

    راه دیگه اینه که ابتدا نیبل پایین رو خروجی کنیم و مقدار صفر رو واسش در نظر بگیریم و نیبل بالا رو ورودی و پول اپ کنیم و سپس نیبل بالا رو بخونیم و در ادامه نیبل بالا رو خروجی کنیم و مقدار صفر بدین و نیبل پایین رو ورودی کنیم و پول اپ و مقدارشو بخونیم...خب حالا دو مجوعه عدد 8 بیتی بدست آوردیم که در هر کدام نیبل بالا یا پایین اونها صفر شده...کافیه که این دو عدد 8 بیتی رو با هم or کنیم و یک عدد 8 بیتی بدست بیاریم...خب چه اتفاقی میفته؟
    اگر هیچی کلیدید فشرده نشه خروجی یکی عدد 8 بیتی با مقدار 0xff میشه و به ازای فشرده شدن هر کلید مقدار این عدد تغییر میکنه...با این روش شما میتونید تمام 256 حالات فشرده شدن صفحه کلید رو شناسایی کنید...به ازای اینکه چند کلید و کدام کلید ها فشرده شدند میتونید کد مربوطه به اون رو تعریف کنید...
    پبسنهاد من استفاده از الگوریتم دوم هست...هم پردازش کمتری داره و هم استفاده ازش ساده تره...

    برای اطلاعات بیشتر میتونید فایل زیر رو مطالعه کنید:

    DOWNLOAD
    جدیدترین ویرایش توسط Mahdi.Faani; ۲۰:۳۵ ۱۳۹۵/۰۴/۱۵.
    تولید کننده تجهیزات برنامه پذیر اتوماسیون صنعتی

    www.intelart.ir


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

    دیدگاه


      #3
      پاسخ : مشکل با صفحه کلید ماتریسی

      نوشته اصلی توسط Mahdi.Faani نمایش پست ها
      سلام
      متشکرم...
      این به الگوریتم خواندن کیپد برمیگرده...یک الگوریتم این هست که شما مثلا برای کیپد 4*4 ستون ها رو به نیبل بالا و سطرها رو به نیبل پایین متصل کنید و نیبل بالا رو خروجی کنید و در چهار مرحله مقدار 0 برای هر ستون قرار بدید و نیبل پایین رو ورودی و پول اپ کنید.سپس مقدار سطرها رو بخونید.به صورت زیر:
      char keypad()
      {
      unsigned char i, j, row_detect;
      DDRA = 0x0f; //Keypad is Connected To PORTA

      for (i = 0; i < 4; i++)
      {
      PORTA = row_out[i];
      for (j = 0; j < 4; j++)
      {
      row_detect = 4;
      if (c0 == 0)
      row_detect = 0;
      if (c1 == 0)
      row_detect = 1;
      if (c2 == 0)
      row_detect = 2;
      if (c3 == 0)
      row_detect = 3;
      if (row_detect != 4)
      return keys[i][row_detect];
      while (c0 == 0);
      while (c1 == 0);
      while (c2 == 0);
      while (c3 == 0);
      }

      }
      return 0;
      }



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

      char keypad()
      {
      unsigned char i, j;
      unsigned char row_detect[16];
      DDRA = 0x0f; //Keypad is Connected To PORTA


      for (i = 0; i < 4; i++)
      {

      PORTA = row_out[i];
      for (j = 0; j < 4; j++)
      {
      row_detect[i + j] = 4;
      row_detect[i + j + 1] = 4;
      row_detect[i + j + 2] = 4;
      row_detect[i + j + 3] = 4;
      if (c0 == 0)
      row_detect[i + j] = 0;
      if (c1 == 0)
      row_detect[i + j + 1] = 1;
      if (c2 == 0)
      row_detect[i + j + 2] = 2;
      if (c3 == 0)
      row_detect[i + j + 3] = 3;

      while (c0 == 0);
      while (c1 == 0);
      while (c2 == 0);
      while (c3 == 0);
      }

      }
      return 0;
      }


      خب حالا یک آرایه داریم که مقادیر اون رو میتونیم بخونیم و تشخیص بدیم که کدوم کلید(ها) فشرده شده...

      راه دیگه اینه که ابتدا نیبل پایین رو خروجی کنیم و مقدار صفر رو واسش در نظر بگیریم و نیبل بالا رو ورودی و پول اپ کنیم و سپس نیبل بالا رو بخونیم و در ادامه نیبل بالا رو خروجی کنیم و مقدار صفر بدین و نیبل پایین رو ورودی کنیم و پول اپ و مقدارشو بخونیم...خب حالا دو مجوعه عدد 8 بیتی بدست آوردیم که در هر کدام نیبل بالا یا پایین اونها صفر شده...کافیه که این دو عدد 8 بیتی رو با هم or کنیم و یک عدد 8 بیتی بدست بیاریم...خب چه اتفاقی میفته؟
      اگر هیچی کلیدید فشرده نشه خروجی یکی عدد 8 بیتی با مقدار 0xff میشه و به ازای فشرده شدن هر کلید مقدار این عدد تغییر میکنه...با این روش شما میتونید تمام 256 حالات فشرده شدن صفحه کلید رو شناسایی کنید...به ازای اینکه چند کلید و کدام کلید ها فشرده شدند میتونید کد مربوطه به اون رو تعریف کنید...
      پبسنهاد من استفاده از الگوریتم دوم هست...هم پردازش کمتری داره و هم استفاده ازش ساده تره...

      برای اطلاعات بیشتر میتونید فایل زیر رو مطالعه کنید:

      DOWNLOAD
      سلام دوست عزیز عیدتون مبارک، از اینکه اینقدر خوب وقت گذاشتین و راهنمایی کردین بسیار متشکرم . ببینید اگه فرض کنیم سطرها خروجی باشن و ستونها ورودی ، با اسکن متوالی سطرها اگه دو یا چند کلید روی یک ستون با هم اتصال کوتاه شده باشن هر کلیدی (هایی) که در هر سطر فشرده بشه بدلیل اتصال کوتاه موجود در یک ستون برای سایر سطرها هم به حساب میاد و این مشکل با هیچ کدوم از روشهایی که گفتین قابل حل نیست ( تازه مساله اتصال کوتاه شدن سطر صفر با سطرهای یک بماند) چون اطلاعات خوانده شده از ستونها نمی تونه مشخص کنه که صفر شدن یه ستون اثر فشرده شدن کلید در کدوم سطر بوده . ضمناً برای اینکه تمام حالات ممکن برای فشرده شدن کلیدای یه صفحه کلید ماتریسی مثلاً 4x4 رو در نطر بگیرم باید مجموع حالات زیر رو در نظر بگیریم:
      1- کل حالاتی که فقط یک کلید از 16 کلید فشرده شده باشه
      2- کل حالتی که دو کلید از 16 کلید فشرده شده باشه
      3- کل حالاتی که سه کلید از 16 کلید فشرده شده باشه
      ........
      16- کل حالاتی که 16 کلید از 16 کلید فشرده شده باشه
      که این مجموع از لحاظ ریاضی برابر 2 به توان 16 یعنی 65536 حالت میشه در حالی با 8 بیت نمیشه بیش از 256 حالت رو تشخیص داد. فکر می کنم باید ساختار صفحه کلید ماتریسی اصلاح بشه تا بتونیم هر تعداد کلید رو که بصورت همزمان فشرده بشن شناسایی کنیم. اما آیا در صفحه کلید کامپیوتر هم این مشکل وجود داره ؟

      دیدگاه


        #4
        پاسخ : مشکل با صفحه کلید ماتریسی

        نوشته اصلی توسط mhmdabi نمایش پست ها
        سلام دوست عزیز عیدتون مبارک، از اینکه اینقدر خوب وقت گذاشتین و راهنمایی کردین بسیار متشکرم . ببینید اگه فرض کنیم سطرها خروجی باشن و ستونها ورودی ، با اسکن متوالی سطرها اگه دو یا چند کلید روی یک ستون با هم اتصال کوتاه شده باشن هر کلیدی (هایی) که در هر سطر فشرده بشه بدلیل اتصال کوتاه موجود در یک ستون برای سایر سطرها هم به حساب میاد و این مشکل با هیچ کدوم از روشهایی که گفتین قابل حل نیست ( تازه مساله اتصال کوتاه شدن سطر صفر با سطرهای یک بماند) چون اطلاعات خوانده شده از ستونها نمی تونه مشخص کنه که صفر شدن یه ستون اثر فشرده شدن کلید در کدوم سطر بوده . ضمناً برای اینکه تمام حالات ممکن برای فشرده شدن کلیدای یه صفحه کلید ماتریسی مثلاً 4x4 رو در نطر بگیرم باید مجموع حالات زیر رو در نظر بگیریم:
        1- کل حالاتی که فقط یک کلید از 16 کلید فشرده شده باشه
        2- کل حالتی که دو کلید از 16 کلید فشرده شده باشه
        3- کل حالاتی که سه کلید از 16 کلید فشرده شده باشه
        ........
        16- کل حالاتی که 16 کلید از 16 کلید فشرده شده باشه
        که این مجموع از لحاظ ریاضی برابر 2 به توان 16 یعنی 65536 حالت میشه در حالی با 8 بیت نمیشه بیش از 256 حالت رو تشخیص داد. فکر می کنم باید ساختار صفحه کلید ماتریسی اصلاح بشه تا بتونیم هر تعداد کلید رو که بصورت همزمان فشرده بشن شناسایی کنیم. اما آیا در صفحه کلید کامپیوتر هم این مشکل وجود داره ؟
        سلام مجدد
        عید شما هم مبارک باشه
        خواهش مکینم

        ببینید تمام حالات شناسایی میشه...
        به طور کامل توضیح میدم تا آیندگان هم دچار ابهام نشن...

        ببینید وقتی در حالت ساده یک کلید از یک صفحه کلید ماتریسی فشرده میشه اتفاق زیر میفته:



        خب تا اینجا که پیدا کردن کلید فشرده شده مشکلی نداره و با توجه به روش های گفته شده در بالا میشه پیداش کرد.
        به این صورت:



        خب حالا تصور کنید سه کلید به صورت زیر با هم فشرده بشن:


        در این حالت هم میشه برنامه رو طوری نوشت که فشردن شدن همزمان این چند کلید تشخیص داده بشه.(چحوری؟در بالا توضیح دادم)

        حالت بعدی اینه که چند کلید به صورت سطری فشرده بشن:


        در این حالت هم با توجه به اینکه در هر مرحله از 1 بودن ستون ها اطلاع داریم میتوانیم از فشرده شدن کلید مربوطه اطمینان پیدا کنیم...

        حالت بدی که ممکنه رخ بده در این شکل دیده میشه:



        در این حالت فشرده شدن یا فشرده نشدن کلید C3 هیچ تاثیری نداره...در هر صورت میکروکنترلر فکر میکنه که C3 فشرده شده...
        ببینید هر سه حالت زیر یک خروجی دارند:



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



        با قرار دادن دیود مناسب (مناسب از این جهت که باید به تناسب سرعت نمونه برداری دیود سریع یا معمولی انتخاب کنید) میشه از برگشت جریان جلوگیری کرد و این مشکل رو برطرف کرد.
        نتیجه رو ببینید:




        تمام این حالات رو میشه با اون متد اول که کدش رو گذاشتم نشخیص داد ولی مشکلی که داره اینه که باید دو تا حلقه تو در تو دائما چک بشه و این یعنی افزایش پردازش تحمیل شده به CPU

        در مورد کد دوم که جای ورودی و خروجی شدن سطرها رو تغییر میداد نمیشه تمام حالات رو بررسی کرد و استفاده از اون متد در صورتی مشکل زا نیست که از کیپد برای کارهای معمول استفاده بشه..مزیت اون روش این هست که هیچ حلقه ای در کار نیست و با 4 بار تغییر رجیستر ها و OR کردن دو بایت با هم میشه کد کلید فشرده شده رو تشخیص داد.

        به هر حال به تناسب کاری که قراره انجام بدید میتونید یکی از این دو متد رو انتخاب کنید...
        اگر سوال دیگه ای بود در خدمتم...
        تولید کننده تجهیزات برنامه پذیر اتوماسیون صنعتی

        www.intelart.ir


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

        دیدگاه


          #5
          پاسخ : مشکل با صفحه کلید ماتریسی

          سلام دوست عزیز جناب فانی بازم ممنونم از اینکه بسیار شفاف و واضح جواب میدید. ببینید منظور منم همین بود یعنی برای تشخیص درست تمام حالات ممکن ،روشهای نرم افزاری جوابگو نیست و نیاز به اصلاح سخت افزاریه و صفحه کلید ماتریسی معمولی فاقد چنین قابلیتی هست . اتفاقاً با یکی دیگه از دوستان هم که سر این مشکل صحبت داشتیم اونم یه کامنت از یه سایت خارجی گذاشت که دقیقاً با همین روشی که شما گفتین یعنی افزودن دیود برای هر کلید مشکل رو حل کرده بود. البته در حالتی که دو کلید یا بیشتر روی یک سطر بصورت همزمان فشرده بشن اتصال کوتاه بین ستونهای صفر و یک رخ میده که میتونه به پورت های میکرو در دراز مدت آسیب بزنه که استفاده از دیود سری با هر کلید و یا حتی قرار دادن چهار دیود در مسیر اتصال پورتهای میکرو به ستونها ، این مشکل رو هم مرتفع می کنه اما اگه کسی بخواد بدون استفاده از دیود این مشکل رو حل بکنه فکر می کنم باید از حالت مدار باز یا همون Hi impedance پورتها به همراه مقاومت Pullup یا Pulldown برای ستون های غیر فعال استفاده کنه . اما من هنوز در مورد صفحه کلید کامپیوتر جوابم رو نگرفتم و برام مشخص نیست که آیا این مشکل در اونجا هم وجود داره یا به طریقی حل شده؟
          ضمناً من با بسکام کار می کنم و در مورد کدویژن و c اطلاعات بسیار اندکی دارم. در هر صورت از اینکه وقت گذاشتین بسیار متشکرم. خدا خیرتون بده.
          جدیدترین ویرایش توسط mhmdabi; ۲۱:۱۷ ۱۳۹۵/۰۴/۱۸.

          دیدگاه


            #6
            پاسخ : مشکل با صفحه کلید ماتریسی

            خواهش میکنم دوست من
            بله دقیقا با فرمایش شما یکیست...باید اصلاحات سخت افزاری انجام بشه تا بدون مشکل کار کنه...به این مشکل Ghosting یا سایه اندازی گفته میشه.
            در مورد کیبورد کامپیوتر داستان همینه...یه لینک خیلی جالب پیدا کردم حتما ببینید...میتونید تست کنید ببینید کدوم کلیدهای کیبورد رو میتونید همزمان فشار بدید:


            راه حل هایی که ارائه کرده:
            اولی همون گذاشتن دیود هست که گفته هزینه رو بالا میبره...
            دوم گذاشتن دو تا صفحه ماتریسی هست که بشه کلید ها رو تشخیص داد که اونم هزینه رو بالا میبره

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

            چیزی که در مورد کیبورد لپ تاپم جالبه اینه که توی این برنامه مایکروسافت اگه اول کلید A رو فشار بدم میتونه کلیدهای کناریش که Q و W هستند رو هم همزمان تشخیص بده...ولی اگه بعد از A کلید S رو فشار بدم دیگه نه Q و نه W رو نمیشناسه!
            شما هم تست کنید ببینید همیطوره یا نه!

            تکنولوژی های دیگه ساخت کیبورد مثل خازنی و موارد دیگه رو هم میتونید در لینک زیر ببینید:
            تولید کننده تجهیزات برنامه پذیر اتوماسیون صنعتی

            www.intelart.ir


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

            دیدگاه


              #7
              پاسخ : مشکل با صفحه کلید ماتریسی

              جناب فانی بسیار ممنون از راهنمایی هایی که کردین. الحمدالله مشکلم حل شد. سرفراز و پیروز باشید.

              دیدگاه

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