1. Си / Говнокод #13467

    +132

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    10. 10
    11. 11
    12. 12
    13. 13
    14. 14
    15. 15
    16. 16
    17. 17
    18. 18
    19. 19
    20. 20
    21. 21
    22. 22
    23. 23
    24. 24
    25. 25
    26. 26
    27. 27
    28. 28
    29. 29
    30. 30
    31. 31
    32. 32
    33. 33
    34. 34
    35. 35
    36. 36
    37. 37
    38. 38
    39. 39
    40. 40
    41. 41
    42. 42
    43. 43
    44. 44
    45. 45
    46. 46
    47. 47
    48. 48
    49. 49
    #define max    0x08         //Max number of samples to average/filter
    #define byte unsigned char
    #define word unsigned int
    #define dword unsigned long
    
    #define FILTER 0
    #define AVG 1
    
    typedef struct  {
      word  reading[max];
      word  result[max];
    } ResultStct;
    
    
    static ResultStct x;
    static char samp = 0;//filter;
    const byte filter_mode = FILTER;
    
    extern int avg_result;
    
    void MYfilter(word input_sample) 
    {
      byte j;
      dword X;
        
    	x.reading[samp] = input_sample;
      
    	if(samp>0){
    
    		X=0;
    		for (j=0;j<=samp;j++){
    		  X += x.reading[j];
    		}
    		avg_result = (X >> 3) - 0x0200;
    		
    	} 
       
    	// Shift array of results if we hit max
    	if (samp >= max-1) {
    		for (j=0;j<max-1;j++){
    			x.result[j]  = x.result[j+1];
    			x.reading[j] = x.reading[j+1];
    		}
    		samp = max-1;
    	}
    	else 
    	{
    		samp++;
    	} //end if (i => max)

    Такой вот МОЩНЕЙШИЙ фильтр встретился в одном проекте.

    Запостил: _113, 24 Июля 2013

    Комментарии (18) RSS

    • К слову, заменил его так:
      avg_result = (input_sample + avg_result * 7)>>3;
      Ответить
      • Ну скользящее среднее еще примерно так можно считать:
        avg_result = avg_result - samp[current] + input_sample;
        samp[current] = input_sample;
        if (++current >= max)
            current = 0;
        return avg_result >> 3;
        Математически этот вариант точнее, но на практике - всем пофиг, и ваше решение будет быстрее и займет меньше флеша.
        Ответить
        • входные данные - показания акселерометра, приходят с частотой в несколько сот герц, опрос происходит на порядок реже. При таком объеме данных фильтры будут выдавать практически одинаковые значения (хотя высокая точность в данной задаче и не нужна)
          ЗЫ: А вот 2Кб флеша как раз не хватает(((
          Ответить
          • > А вот 2Кб флеша как раз не хватает(((
            Ладно блин на восьминогой-восьмибитной авр тини было 2кб, но для 16-битного контроллера это как-то совсем не айс...
            Ответить
            • Сам удивился, когда к проекту строчку дописал и увидел:
              Error[e104]: Failed to fit all segments into specified ranges. Problem discovered in segment CODE. Unable to place 9 block(s) (0x1c4 byte(s) total) in 0x1ec byte(s) of memory. The problem occurred while processing the segment
              Ответить
              • Эм, так 0х1с4 это даже меньше 512... остальные 1.5кб поди заняты каким-нибудь загрузчиком, чтобы шить без программатора?
                Ответить
                • Видать линкер глючит... вот из рабочего варианта:
                  1 974 bytes in segment CODE
                  49 bytes in segment DATA16_AN
                  18 bytes in segment DATA16_C
                  6 bytes in segment DATA16_I
                  6 bytes in segment DATA16_ID
                  27 bytes in segment DATA16_Z
                  8 bytes in segment INTVEC
                  Ответить
    • #define word unsigned int

      16-битная архитектура?
      Ответить
    • Кто-то прошел и въебал всем по минусу ;)
      Ответить
    • тут гоатсе не хватает
      Ответить

    Добавить комментарий