Changes between Initial Version and Version 1 of ReverseEngineering/Encoders


Ignore:
Timestamp:
07/06/10 08:03:08 (14 years ago)
Author:
art
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • ReverseEngineering/Encoders

    v1 v1  
     1= Encoders = 
     2 
     3On the [http://www.e39-forum.de E39-forum.de] somebody found out the manufacturer of compatible rotating knobs for the 4:3 monitor. I think for the 16:9 it could be the same. The original knobs where a special development for Alpina. The compatible one is that one: Grayhill 61C22-01-04-02, [http://datasheet.octopart.com/61C22-01-04-02-Grayhill-datasheet-67218.pdf data sheet]. 
     4 
     5== Two types == 
     6In the original bord monitor there are two types of rotary knobs. The left one, is responsible for volume setting, which is also called RADIO knob. The right one, responsible for menu navigation, which is also called BMBT knob. The interesting part about both of them, they are of different hardware types. 
     7 
     8The right one, is mainly hall-effect based type, which gives a grey code sequence on its both ends: 00-01-11-10-00. The sequence depends on the direction of the rotation. The output is changed step-by-step.  
     9The left one, is optically based and gives a sequence: 00-11-00 on each rotation step. However, inbetween this output the bits 01 or 11 are also triggered, to indicate the direction. In the internet there is tons of codes which show how to interface such encoders. Here is a simplified example of how I am interfacing these both encoders: 
     10 
     11{{{ 
     12#!div style="font-size: 0.75em;" 
     13 
     14{{{ 
     15#!c 
     16        // definitions 
     17        #define ENC_BMBT_OUT1 (1 << 1) 
     18        #define ENC_BMBT_OUT2 (1 << 2) 
     19        #define ENC_BMBT 0 
     20        #define ENC_RADIO_OUT1 (1 << 6) 
     21        #define ENC_RADIO_OUT2 (1 << 5) 
     22        #define ENC_RADIO 1 
     23 
     24        // global variables to remember current states 
     25        uint8_t g_enc_last[2]; 
     26        uint8_t g_enc_delta[2]; 
     27 
     28        // special tracking of radio encoders, since they have intermediate states 
     29        int8_t g_enc_last_radioRotaryStateCW; 
     30        int8_t g_enc_last_radioRotaryStateCCW; 
     31 
     32... 
     33void check_encoders() 
     34{ 
     35        // poll current state of both encoders 
     36        uint8_t state = get_encoder_state(); 
     37 
     38        // get value for BMBT encoder 
     39        int8_t new = 0; 
     40        if( (state & ENC_BMBT_OUT1) ) new  = 0b11; 
     41        if( (state & ENC_BMBT_OUT2) ) new ^= 0b01; 
     42        int8_t diff = g_enc_last[ENC_BMBT] - new; 
     43        if( diff & 1 ) 
     44        { 
     45            g_enc_last[ENC_BMBT] = new; 
     46            g_enc_delta[ENC_BMBT] += (diff & 2) - 1;            // bit 1 = direction (+/-) 
     47        } 
     48        if (g_enc_delta[ENC_BMBT] < 0) 
     49        { 
     50            set_active(BMBT_CCW); 
     51            set_not_active(BMBT_CW); 
     52        }else if (g_enc_delta[ENC_BMBT] > 0) 
     53        { 
     54            set_active(BMBT_CW); 
     55            set_not_active(BMBT_CCW); 
     56        } 
     57        g_enc_delta[ENC_BMBT] = 0; 
     58 
     59 
     60        // check state of RADIO encoder 
     61        new = 0; 
     62        if( (state & ENC_RADIO_OUT1) ) new  = 0b11; 
     63        if( (state & ENC_RADIO_OUT2) ) new ^= 0b01; 
     64        diff = g_enc_last[ENC_RADIO] - new; 
     65        if( diff & 1 ) 
     66        { 
     67            g_enc_last[ENC_RADIO] = new; 
     68            g_enc_delta[ENC_RADIO] += (diff & 2) - 1;           // bit 1 = direction (+/-) 
     69        } 
     70        if (g_enc_delta[ENC_RADIO] < 0 && !g_enc_last_radioRotaryStateCCW) 
     71        { 
     72            set_active(RADIO_CCW); 
     73            set_not_active(RADIO_CW); 
     74        }else if (g_enc_delta[ENC_RADIO] > 0 && !g_enc_last_radioRotaryStateCW) 
     75        { 
     76            set_active(RADIO_CW); 
     77            set_not_active(RADIO_CCW); 
     78        } 
     79        g_enc_delta[ENC_RADIO] = 0; 
     80} 
     81 
     82}}} 
     83 
     84}}}