Stisk více tlačítek

Uživatelský avatar
gilhad
Příspěvky: 779
Registrován: 07 bře 2018, 11:22
Reputation: 0

Re: Stisk více tlačítek

Příspěvek od gilhad » 07 kvě 2021, 05:47

Neni mi to moc jasne, o co presne jde, ale asi bych to zkusil takhle:

Kazde kolo ma nekde ulozen cas posledniho pootoceni (teda prichodu signalu od jeho cidla).
Dale ma nejake pole kam se ukladaji doby mezi signaly (a ukazatel do toho pole a pri dosazeni delky toho pole (treba 3) se ten ukazatel uz nezvysuje, ale pole se posune a nejstarsi hodnota vypadne)

Kdyz prijde signal od kola, tak se od akualnich millis() odecte ten ulozeny cas, doba se vlozi do toho pole, aktualni cas se ulozi jako posledni cas

Nasledne (pokud je pole delsi nez LEN treba 5 - nebo jeste lepe, pokud se pole prave posouvalo) se sectou vsechny doby v tom poli cimz vznikne delka historie za poslednich LEN-1 kroku.

Pak se projdou ostatni kola a pokud ma nejake posledni cas zpatky vic, nez je historie, tak se LEN-krat nepootocilo a to je moc a tak teda asi stoji a je spusten poplach. (Proste se nemuze jedno kolo tocit LENkrat (treba 5x) rychleji nez jine - zalezi na aplikaci, kolik to LEN bude, pokud se hlasi pootoceni jednou dokola, je 5 asi dost, pokud se hlasi pootoceni o 1 stupen, tak mozna dat vetsi rezervu, treba LEN 20)

Tim se zajisti, ze na rychlosti otaceni v podstate nesejde, jen na vzajemnem pomeru rychlosti tech kol.

Pokud se pri pruchodu loop() zjisti, ze posledni cas u kazdeho z kol je starsi, nez nejake OLD (treba 10 sec), (a aspon jedno kolo ma plne pole) tak vsechna kola stoji, tudiz je bazmek ve vzduchu, vypnuty, startuje ci co a vsechna pole a casy se vynuluji.

Asi by LEN melo byt minimalne 3, aby nedoslo k problemu, kdyz se jedno kolo bude tocit o fous pomaleji a druhe ho jednou tesne dozene (jdou skoro naraz) a pak ho predbehne, tak bude mit "o otacku vic" i kdyz slo jen o zlomek casu, proto je to potreba brat za trochu delsi dobu nez jen jeden usek.

Predpokladam, ze celkova aktualni historie neprekroci 50 dni (pokud se to nejak toci a vejde do pameti, tak snad ne).

Pokud by kola mela hodne udaju na jednu otocku a zaroven se nesmela otacet "vyrazneji jinak" tak se to da udelat tak, ze bude delsi historie a bude se u ostatnich k tomu aktualnimu zmeskani pricitat jeste nekolik dalsich hodnot - takhle by slo nastavit treba rozdil 5/7 otacky, nebo tak.

Nastin kodu

Kód: Vybrat vše

#define KOL 6
#define LEN 5
#define OLD 10000

//	pokud bychom chteli pocitat prokluz v mensim rozsahu, nez 1:LEN, tak to nesmi proklouznout vic nez o OUR_LEN:LEN (plus minus nejake cislo, ted to pocitat nechci)
//	#define OUR_LEN 3

unsigned long last_time[KOL]; // millis() posledniho signalu u kazdeho z kol
unsigned long history[KOL][LEN]; // doby mezi jednotlivymi signaly u kazdeho z kol
int max_history[KOL]; // ukazatel do tech historii pro jednotliva kola vlastne to neni int, ale jen -1..LEN (-1 bez zaznamu, LEN preteceni)

void reset(){
	unsigned int now=millis();
	for (int k=0; k<KOL; k++) {
		last_time[k]=now;
		history[k][0]=0;
		max_history[k]=-1;
	}
}

bool all_is_old(unsigned long now){ // pokud se dlouho nic netoci, vrati true
	for (int k=0; k<KOL; k++) {
		if ( (now - last_time[k]) <= OLD ) return false;
	};
	return true;
}

bool all_is_new(){ // pokud nemame nikde historii, vrati true
	for (int k=0; k<KOL; k++) {
		if ( max_history[k] >= 0 ) return false;
	};
	return true;
}

bool add_time(int k, unsigned long now){ // prida cas now do historie kola k, vrati true, pokud je pole plne
	unsigned long delta= (now-last_time[k]); // doba od posledniho mereni
	last_time[k]=now;
	max_history[k]++; // zvedneme max_history
	if (max_history[k] >=LEN ) { // pole je plne ci preteklo
		for (int i =1; i<LEN; i++) {
			history[k][i-1] = history[k][i]; // i zacina od jedne, takze i-1 >=0 ukazuje do pole
		};
		max_history[k]=LEN-1; // kdyz je plne, tak max_history ukazuje na posledni polozku
	}; // ted uz vime, ze max_history ukazuje do pole a v poli je misto pro novou hodnotu
	history[k][max_history[k]] = delta; // pridame tu dobu
	return (k == LEN-1); // pravda, pokud pole je plne
}

bool is_locked(int k, unsigned long now, unsigned long max_delta ){ // vrati, zda je kolo zablokovane
	if (all_is_old(now)) return false;
	if (all_is_new()) return false;
	// tady je to na tenkem lede, pokud by historie byla neco prez 50 dni
	return (now - last_time[k]) > max_delta;
	/* tady jsme na tenkem lede uz za 25 dni, ale muzeme pocitat i mensi rozdily
		unsigned int our_delta=0; // soucet nasich historickych zaznamu
		int low_hist = ( max_history[k] < OUR_LEN ) ? 0 : ( max_history[k] - OUR_LEN ); // OUR_LEN zaznamu zpet, ale ne vic, nez opravdu mame
		for ( int i = max_history[low_hist]; i<= max_history[k]; i++ ) {
			our_delta += history[k][i];
		};
		return (now - last_time[k]) > (max_delta+our_delta);
	*/
}

void have_problem(int k) {} // nejake varovani, pipani zobrazovani a tak
bool got_signal_from(int k) { return true;} // zjisti, zda prave prisel signal od daneho kola. Signal pripadne nejak zpracuje

void setup(){
	reset();
}

void loop(){
	unsigned int now=millis();
	unsigned int max_delta=0; // jak dlouho se neco smi netocit
	if ( all_is_old(now) ) { // kdyz se to dlouho netoci, tak se nepipa
		reset();
	};
	for (int k=0; k<KOL; k++) {
		if (got_signal_from(k)){
			if (all_is_new()) reset(); // prave nas nekdo polozil na zem, jeste nemame data, tak nastavime casy od ted - add_time nasledne zacina od nuly a pote uz neplati all_is_new()
			if (add_time(k,now)){ // mame plnou frontu u tohoto kola, bude se testovat blokovani
				unsigned long delta=0;
				for (int i =1; i<LEN; i++) {
					delta += history[k][i];
				};
				if (max_delta == 0) max_delta = delta; // nemame-li max_delta, tak ho nastavime
				if ((delta > 0) && (max_delta > delta)) max_delta = delta; // na nejkratsi z pricetnych historii
			};
		};
	};
	if (max_delta >0){
		for (int k=0; k<KOL; k++) {
			if (is_locked(k,now,max_delta) ) {
				have_problem(k);
			}
		};
	};
}


void have_problem(int k) je potreba naprogramovat - kolo k ma problem

bool got_signal_from(int k) je potreba naprogramovat - od minule prisel signal od kola k (nastavit si debounce, pripadne zpracovani, ...)

Vencir86
Příspěvky: 3
Registrován: 06 kvě 2021, 22:42
Reputation: 0

Re: Stisk více tlačítek

Příspěvek od Vencir86 » 07 kvě 2021, 17:18

Dekuju za nástin kódu. Kéž bych to takhle uměl z hlavy taky skládat. :| Jde o 6 kol na secí masine na kukurici. Toceji se stejnou rychlosti a impuls to sepne 1x za otacku. Potrebuju hlídat, když by na některým kole prasknul pohaneci řetěz dávkovače zrna, tak aby mě to zvukove a na LCD upozornilo, že neseje konkrétní řádek a mohlo se hned zastavit a problém odstranit. Dost špatně se to hledá, jelikož je to schovaný pod krytama.

Uživatelský avatar
pavel1tu
Příspěvky: 2054
Registrován: 26 říj 2017, 08:28
Reputation: 0
Bydliště: Trutnov
Kontaktovat uživatele:

Re: Stisk více tlačítek

Příspěvek od pavel1tu » 07 kvě 2021, 18:43

Vencir86 píše:
07 kvě 2021, 17:18
Dekuju za nástin kódu. Kéž bych to takhle uměl z hlavy taky skládat. :| Jde o 6 kol na secí masine na kukurici. Toceji se stejnou rychlosti a impuls to sepne 1x za otacku. Potrebuju hlídat, když by na některým kole prasknul pohaneci řetěz dávkovače zrna, tak aby mě to zvukove a na LCD upozornilo, že neseje konkrétní řádek a mohlo se hned zastavit a problém odstranit. Dost špatně se to hledá, jelikož je to schovaný pod krytama.
Udělal bych to stylem "jak funguje detekce prokluzu u auta" ;)

- porovnávat počty pulzů mezi sebou - mezi jednotlivými koly
- pokud všechny třeba udělají 5 pulzů a jedno žádný, nebo méně (to asi nejlépe definuješ ty) tak to vyhlásí alarm a zobrazí vadné kolo
UNO, NANO, Mikro, PRO mini, DUE, ESP32S2, RPi PICO
Pavel1TU
"Správně napsaný kod lze číst jako knihu"

Vencir86
Příspěvky: 3
Registrován: 06 kvě 2021, 22:42
Reputation: 0

Re: Stisk více tlačítek

Příspěvek od Vencir86 » 07 kvě 2021, 20:48

Dobrej nápad. Tohle mě vůbec nenapadlo. Jdu to zkusit nějak spleskat a pak dám vědět. Jinak vřele díky za suprovy rady. Díky moc.

Uživatelský avatar
gilhad
Příspěvky: 779
Registrován: 07 bře 2018, 11:22
Reputation: 0

Re: Stisk více tlačítek

Příspěvek od gilhad » 08 kvě 2021, 01:35

pavel1tu píše:
07 kvě 2021, 18:43
- porovnávat počty pulzů mezi sebou - mezi jednotlivými koly
- pokud všechny třeba udělají 5 pulzů a jedno žádný, nebo méně (to asi nejlépe definuješ ty) tak to vyhlásí alarm a zobrazí vadné kolo
Tohle ten muj kod prave dela :)
Plus resi i problemy s tim, ze kdyz se zataci, tak se kola toci ruzne (a rozfazujou) a ze se to musi vyporadat s tim zvedanim a s ruznou rychlosti jizdy :)

Odpovědět

Kdo je online

Uživatelé prohlížející si toto fórum: Žádní registrovaní uživatelé a 11 hostů