Емельянов Эдуард Владимирович (eddy_em) wrote,
Емельянов Эдуард Владимирович
eddy_em

Category:

Картинка

Сижу, рисую алгоритм работы чиллера. Для установки значений регуляторов решил не заморачиваться со всякими ПИД/ПИ-регуляторами, а использовать нечеткий бинарный поиск, когда значение искомой величины неизвестно, но известно, с какой стороны ее нужно искать. Для проверки набросал простую программку:

#include <stdio.h>
#include <stdlib.h>
static inline int binsrch(int oldval, int curval, int dir){
    if(dir){ // increase
        if(oldval == 0) oldval = 256;
        else if(oldval < curval){
            oldval = 2*curval - oldval;
        }
    }else{   // decrease
        if(oldval > curval){
            oldval = 2*curval - oldval;
        }
    }
    oldval = (oldval + curval) / 2;
    return oldval;
}

int main(int argc, char **argv){
    int need = atoi(argv[1]);
    int old = 0, current = 0, i = 0;
    while(current != need){
        ++i;
        int n = binsrch(old, current, (need > current) ? 1:0);
        old = current;
        current = n;
    }
    printf("%d\t%i\n", need, i);
    return 0;
}

Заполнение таблички на баше:
for x in $(seq 1 255); do ./a.out $x; done > tst

и результат нарисовал в октаве:
a = dlmread('tst');
plot(a(:,1),a(:,2))
axis([0 256])
print -dpng binsrch.png


Вот что получилось:
binsrch
— классическое дерево бинарного поиска...
P.S. В который раз гребаная ЖЖшка самоуправствует: добавляет в качестве "тегов" всякие инклюды из текста! Идиотизм, блин!!!

Нет, этот алгоритм для моего случая не годится, т.к. как только понадобится изменить температуру (скажем, начала жидкость нагреваться и ее постепенно надо охлаждать, чтобы поддерживать заданную температуру), он будет сидеть на одном и том же месте!
Вот так - правильно:
static inline int binsrch(int oldval, int curval, int dir){
    if(oldval == curval){
        if(dir) oldval = 256;
        else oldval = 0;
    }else{
        if(dir){ // increase
            if(oldval == 0) oldval = 256;
            else if(oldval < curval){
                oldval = 2*curval - oldval;
            }
        }else{   // decrease
            if(curval == 0) oldval = 0;
            else if(oldval > curval){
                oldval = 2*curval - oldval;
            }
        }
    }
    oldval = (oldval + curval) / 2;
    if(oldval > 255) oldval = 0;
    return oldval;
}

Теперь после бинарной установки нужного режима при необходимости значение ШИМ будет изменяться на 1.
Tags: c, всячина
Subscribe
promo eddy_em august 17, 2019 12:33 3
Buy for 10 tokens
Юра намедни напечатал корпус для хронометра. Для первого блина получилось неплохо: И еще немного фотографий:
  • Post a new comment

    Error

    Anonymous comments are disabled in this journal

    default userpic

    Your reply will be screened

  • 2 comments