سؤال

أواجه مشكلة في جعل برنامج التشفير الدوار يعمل بشكل صحيح مع وحدات التحكم الدقيقة AVR.التشفير ميكانيكي التشفير ALPS, ، وأنا أستخدم اتميجا168.

إيضاح

لقد حاولت استخدام مقاطعة خارجية للاستماع إلى الدبابيس، ولكن يبدو أنها بطيئة جدًا.عندما يرتفع مستوى Pin A، يبدأ إجراء المقاطعة ثم يتحقق مما إذا كان Pin B مرتفعًا.الفكرة هي أنه إذا كان الدبوس B مرتفعًا في اللحظة التي ارتفع فيها الدبوس A، فإنه يدور عكس اتجاه عقارب الساعة.إذا كان الدبوس B منخفضًا، فهو يدور في اتجاه عقارب الساعة.ولكن يبدو أن AVR يستغرق وقتًا طويلاً جدًا للتحقق من Pin B، لذلك يتم قراءته دائمًا على أنه مرتفع.

لقد حاولت أيضًا إنشاء برنامج يقوم ببساطة بالحظر حتى يتغير Pin B أو Pin A.ولكن قد يكون هناك الكثير من الضوضاء عند تدوير جهاز التشفير، لأن هذا لا يعمل أيضًا.كانت محاولتي الأخيرة هي الحصول على مؤقت يقوم بتخزين آخر 8 قيم في مخزن مؤقت والتحقق مما إذا كانت تنتقل من الأقل إلى الأعلى.هذا لم ينجح أيضا.

لقد حاولت تحديد نطاق برنامج التشفير، ويبدو أنه يستخدم ما بين 2 و4 مللي ثانية من تغيير الدبوس الأول حتى يتغير الدبوس الآخر.

هل كانت مفيدة؟

المحلول

لدي صفحة ويب حول التشفيرات الدوارة وكيفية استخدامها, ، والتي قد تجدها مفيدة.

لسوء الحظ، بدون مزيد من المعلومات، لا يمكنني استكشاف مشكلتك الخاصة وإصلاحها.

ما هي أطراف المتحكم الدقيق المتصلة بجهاز التشفير، وما هو الرمز الذي تستخدمه حاليًا لفك تشفير النبضات؟

حسنًا، أنت تتعامل مع بعض المشكلات المختلفة، المشكلة الأولى هي أن هذا جهاز تشفير ميكانيكي، لذلك يتعين عليك التعامل مع ضوضاء التبديل (الارتداد والثرثرة).ال ورقة البيانات يشير إلى أن الأمر قد يستغرق ما يصل إلى 3 مللي ثانية حتى تتوقف الأجزاء عن الارتداد وإنشاء مخرجات خاطئة.

تحتاج إلى إنشاء روتين debounce.أبسطها هو التحقق المستمر لمعرفة ما إذا كان A سيرتفع أم لا.إذا حدث ذلك، فابدأ مؤقتًا وتحقق منه مرة أخرى خلال 3 مللي ثانية.إذا كان لا يزال مرتفعًا، فيمكنك التحقق من B - إذا لم يكن مرتفعًا، فسوف تتجاهل النبض الزائف وتستمر في البحث عن المستوى A.عندما تحدد B، تنظر إليه، وتبدأ مؤقتًا لمدة 3 مللي ثانية، ثم تنظر إلى B مرة أخرى.إذا كانت هي نفسها في المرتين، فيمكنك استخدام هذه القيمة - إذا تغيرت خلال 3 مللي ثانية، فسيتعين عليك القيام بذلك مرة أخرى (اقرأ B، وانتظر 3 مللي ثانية، ثم اقرأها مرة أخرى ومعرفة ما إذا كانت متطابقة).

إن atmega سريع بما يكفي بحيث لا داعي للقلق بشأن بطء عمليات التحقق هذه، إلا إذا كنت تقوم أيضًا بتشغيل سرعة ساعة بطيئة.

بمجرد التعامل مع الضوضاء الميكانيكية، فأنت تريد إلقاء نظرة على روتين الكود الرمادي المناسب - لن تعمل الخوارزمية التي تتبعها إلا إذا قمت أيضًا بإنقاص ما إذا كانت A مرتفعة عندما تنخفض B.بشكل عام، يقوم الأشخاص بتخزين القيمة الأخيرة للمدخلين، ثم مقارنتها بالقيمة الجديدة للمدخلين واستخدام دالة صغيرة للزيادة أو النقصان بناءً على ذلك.(راجع عنوان "القراءة عالية الدقة" على الموقع الإلكتروني الذي ذكرته أعلاه للحصول على الجدول).أقوم بدمج القراءتين في رقم مكون من أربعة بتات واستخدم مصفوفة بسيطة لإخباري ما إذا كنت أقوم بزيادة العداد أو إنقاصه، ولكن هناك حلول أكثر تقدمًا، وتعمل على تحسين حجم الكود أو السرعة أو سهولة صيانة الكود.

نصائح أخرى

تؤدي إضافة مرشح تمرير منخفض تناظري إلى تحسين الإشارة بشكل كبير.مع مرشح التردد المنخفض، كان الكود الموجود على AVR بسيطًا حقًا.

       _________
        |         |
        | Encoder |
        |_________|
          |  |  |
          |  |  |
     100n |  O  | 100n  
 GND O-||-+ GND +-||-O GND
          |     | 
          \     /
      3K3 /     \ 3K3
          \     /
          |     |    
VCC O-/\/-+     +-\/\-O VCC
     15K  |     |  15K
          |     |
          O     O
          A     B

آه، عجائب فن ASCII :p

وهنا البرنامج على AVR.قم بتوصيل A وB لإدخال PORTB على avr:

#include <avr/io.h>

#define PIN_A (PINB&1)
#define PIN_B ((PINB>>1)&1)

int main(void){
    uint8_t st0 = 0;
    uint8_t st1 = 0;
    uint8_t dir = 0;
    uint8_t temp = 0;
    uint8_t counter = 0;
    DDRD = 0xFF;
    DDRB = 0;
    while(1){   
    if(dir == 0){
        if(PIN_A & (!PIN_B)){
            dir = 2;
        }else if(PIN_B & (!PIN_A)){
            dir = 4;
        }else{
            dir = 0;
        }
    }else if(dir == 2){
        if(PIN_A & (!PIN_B)){
            dir = 2;
        }else if((!PIN_A) & (!PIN_B)){
            counter--;
            dir = 0;
        }else{
            dir = 0;
        }
    }else if(dir == 4){
        if(PIN_B & (!PIN_A)){
            dir = 4;
        }else if((!PIN_A) & (!PIN_B)){
            counter++;
            dir = 0;
        }else{
            dir = 0;
        }
    }else if(PIN_B & PIN_A){
        dir = 0;
    }
        PORTD = ~counter;
    }
    return 0;
}

يعمل هذا الرمز إلا إذا قمت بتدوير برنامج التشفير بسرعة كبيرة.ومن ثم قد يخطئ خطوة أو خطوتين، لكن هذا ليس مهمًا، لأن الشخص الذي يستخدم جهاز التشفير لن يعرف عدد الخطوات التي قام بتدويرها.

لا ينبغي أن تكون السرعة مشكلة.في الغالب تحتاج جميع المفاتيح الميكانيكية إلى إجراءات الارتداد.إذا كنت تريد القيام بذلك باستخدام المقاطعات، فأوقف تشغيل المقاطعة عند تشغيلها، وابدأ مؤقتًا سيعيد تشغيلها بعد بضع مللي ثانية.سيبقي برنامجك خاليًا من الاقتراع > :)

ما الذي تواجه مشاكل معه بالضبط؟أفترض أنك تمكنت من ربط دبابيس جهاز التشفير بالموافقة المسبقة عن علم (PIC) الخاصة بك وفقًا للمواصفات الفنية المرتبطة بصفحة Farnell التي قدمتها، فهل المشكلة في قراءة البيانات؟هل لا تحصل على أي بيانات من التشفير؟هل لا تعرف كيفية تفسير البيانات التي تحصل عليها؟

/* into 0 service rutine */
if(CHB)
{
  if(flagB)
   Count++;
  FlagB=0;
}
else
{
  if(FlagB)
   count--:
  FlagB=0:
}

/* into 1 service rutine */
FlagB=1;

/* make this give to you a windows time of 1/4 of T of the encoder resolution
   that is in angle term: 360/ (4*resolution)
 */
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top