C > 連続的条件成立検知 > v0.1..v0.3

```txt:動作環境
C
```

### リンク

- [連続的条件成立検知](https://qiita.com/SaitoAtsushi/items/d26a5cfa5453d8d91b63)
- [c++ builder > 複数回条件が成立したかどうかの実装 > double型の範囲内/範囲外チェック](https://qiita.com/7of9/items/b38d74707a18263a10b4)

### 概要

- ON,OFFを返す仕組みがある
- 連続(N回)状態が続いた時にON, OFFを判断する
    - delayがあるようなもの
    - 下図参照

![qiita.png](https://qiita-image-store.s3.amazonaws.com/0/32870/4a1ae112-3693-29d5-41b8-1e8c98bd6ac0.png)

### code 手抜き版 v0.1

```checkContinuousCondition_180207.c
#include <stdio.h>
#include <stdlib.h>


#define NUM_CHECK (3)

static const int in_data[] = {
	0, 1, 1, 1, 1, // 0..4 
	1, 1, 1, 1, 1, // 5..9
	1, 0, 0, 0, 0, // 10..14
	0, 0, 0, 0, 0, // 15..19
};

int main(void)
{
	int contOn = 0;
	int contOff = 0;
	int pre = 0;
	int cur;
	int num_data = sizeof(in_data)/sizeof(in_data[0]);

	for(int idx=0; idx<num_data; idx++) {
		cur = in_data[idx];
		if (pre != cur) {
			if (cur) {
				contOn = 0;
			} else {
				contOff = 0;
			}
		} else {
			if (cur) {
				if (contOn <= NUM_CHECK) {
					contOn++;
					if (contOn == NUM_CHECK) {
						printf("%d: ON\n", idx);
					}
				}
			} else {
				if (contOff <= NUM_CHECK) {
					contOff++;
					if (contOff == NUM_CHECK) {
						printf("%d: OFF\n", idx);
					}
				}
			}
		}
		pre = cur;
		//printf("%d\n", in_data[idx]);
	}
}
```

```txt:comiple
$ gcc checkContinuousCondition_180207.c 
```

```txt:run
$ ./a.out 
4: ON
14: OFF
```

### 備考

じっくり見る時間が取れないので、手抜き版です。


### code v0.2

```checkContinuousCondition_180207.c
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

#define NUM_CHECK (3)

static const int in_data[] = {
	0, 1, 1, 1, 1, // 0..4 
	1, 1, 1, 1, 1, // 5..9
	1, 0, 0, 0, 0, // 10..14
	0, 0, 0, 0, 0, // 15..19
};

enum { STS_STABLE = 0, STS_ON, STS_OFF };

int checkStatus(bool cur)
{
	static int contOn = 0;
	static int contOff = 0;
	static bool pre = 0;

	int ret = STS_STABLE;

	if (pre != cur) {
		if (cur) {
			contOn = 0;
		} else {
			contOff = 0;
		}
	} else {
		if (cur) {
			if (contOn <= NUM_CHECK) {
				contOn++;
				if (contOn == NUM_CHECK) {
					ret = STS_ON;					
				}
			}
		} else {
			if (contOff <= NUM_CHECK) {
				contOff++;
				if (contOff == NUM_CHECK) {
					ret = STS_OFF;
				}
			}
		}
	}
	pre = cur;
	return ret;
}

int main(void)
{
	int num_data = sizeof(in_data)/sizeof(in_data[0]);

	int ret;
	for(int idx=0; idx < num_data; idx++) {
		ret = checkStatus(in_data[idx]);
		switch(ret){
		case STS_STABLE:
			printf(".");
			break;
		case STS_ON:
			printf("A");
			break;
		case STS_OFF:
			printf("V");
			break;
		}
	}
	printf("\n");
}
```

```txt:run
$ ./a.out 
....A.........V.....
```

### code v0.3

`OFF, OFF, ..., OFF, ON, OFF, OFF, OFF`があると、後者のON+3回目に`V`が入る不具合があった。

下記のように変更した。

- [last_sts]追加
- checkStatus()の処理変更

```checkContinuousCondition_180207.c
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

#define NUM_CHECK (3)

static const bool in_data[] = {
    false,  true,  true,  true,  true, // 0..4 
     true,  true,  true,  true,  true, // 5..9
     true, false, false, false, false, // 10..14
    false, false, false, false, false, // 15..19
     true, false,  true, false, false, // 20..24
    false, false, false, false, false, // 25..29
     true,  true,  true,  true, false, // 30..34
    false,  true, false,  true, false, // 35..39
    false, false, false, false, false, // 40..44
};

enum { STS_STABLE = 0, STS_ON, STS_OFF };

int checkStatus(bool cur_in)
{
    static int contOn = 0;
    static int contOff = 0;
    static bool pre_in = false; // previous input
    static bool last_sts = false; // false: at boot

    int ret = STS_STABLE;

    if (cur_in != pre_in || (cur_in == last_sts) ) {
        if (cur_in) {
            contOn = 0;
        } else {
            contOff = 0;
        }
        pre_in = cur_in;
        return STS_STABLE;
    }

    if (cur_in) {
        if (contOn <= NUM_CHECK) {
            contOn++;
            if (contOn == NUM_CHECK) {
                last_sts = true;
                ret = STS_ON;
            }
        }
    } else {
        if (contOff <= NUM_CHECK) {
            contOff++;
            if (contOff == NUM_CHECK) {
                last_sts = false;
                ret = STS_OFF;
            }
        }
    }
    pre_in = cur_in;
    return ret;
}

int main(void)
{
    int num_data = sizeof(in_data)/sizeof(in_data[0]);

    int ret;
    for(int idx=0; idx < num_data; idx++) {
        ret = checkStatus(in_data[idx]);
        switch(ret){
        case STS_STABLE:
            printf(".");
            break;
        case STS_ON:
            printf("A");
            break;
        case STS_OFF:
            printf("V");
            break;
        }
    }
    printf("\n");
}
```

```txt:run
$ ./a.out 
....A.........V..................A........V..
```

last_stsの初期値をfalseにするかtrueにするかは要検討。
(起動数秒後にSTS_ONを検知したいかによる)。