Kapcsoló érzékelése GPIO-n keresztül megbízhatóan (Láma)

Egy hobbi projektemben van 4 kapcsoló (végállás kapcsolók), amik állapotát szeretném megbízhatóan kiolvasni egy ESP32-vel. A kapcsolók távolsága 50cm is lehet az ESP-től, így viszonylag hosszúak a vezetékek, és nem árnyékoltak. (Ez van itthon.)

Azt hittem, mi sem egyszerűbb ennél, de csalódnom kellett. Jelenleg azt csinálom, hogy a kapcsolóból jövő egyik vezetéket a +5V-ra kötöm (ilyen tápom van), a másik vezetéket meg egy ellenállás lábára, és ide kötöm a GPIO-t is. Az ellenállás másik lába a testen van. Az ellenállás értéke R=500k.

     /
 ---/  ----
 |        |
 |        +---------> ESP 32 GPIO (3.3V)
 |        |
 |       ---
 |      |   |
 |      | R | = 500k
 |      |   |  
 |       ---
 |        |
 |        |
+5V       0V

A 4 kapcsolóból 3-nál teljesen stabilan tudom így olvasni az állapotot, de a 4. kapcsoló mágikusan működik. Amennyiben tesztelem egy programkóddal, jól működik, amint azonban az éles alkalmazásban kezdem el olvasni, false kapcsolásokat jelez, azaz gyakran úgy is HIGH értéket olvasok, hogy nincs bekapcsolva a kapcsoló.

Gondolom, rossz a kapcsolás, amit használok.

Mivel a kapcsolók már be vannak építve, mindenképpen a beérkezett jelet kellene megbízhatóbban olvasnom.

Hogyan javítsam ki (bővítsem?) egyszerűen a kapcsolásom, hogy megbízhatóan tudjam olvasni a kapcsolók állapotát?

Kérem, aki válaszolt, tartsa szem előtt, hogy ezt teljesen hobbi, és nincs nagy jártasságom a hardver oldalon.

Hozzászólások

ESP32 GPIO nem 5V tolerant. Neked egy feszültségosztó kellene (vagy level shifter), ha még él a pin egyáltalán!

Ez a Heltec Wifi Kit 32, ami meghajtható 5V-ról, és úgy tűnik, a GPIO pineket is ellátták valami védelemmel, mert stabilan fogadja az 5V-os jeleket. De a gond nem is azzal van, hogy ha be van kapcsolva a kapcsoló, akkor HIGH legyen a bemeneten, hanem azzal, hogy ha nincs bekapcsolva, akkor még véletlenül se legyen HIGH. Ami ugye pont független attól, hogy 5V vagy 3.3V az, ami épp nem jut rá.

Szoktak még kondenzátort is párhuzamosan kötni a kapcsolóval, nem jut eszembe a jelenség magyar neve, de lehet egy kisebb értékű kerámiakondenzátor már pont segítene és nagyon bontani se kellene semmit.

http://www.labbookpages.co.uk/electronics/debounce.html

PS: Ha nem nyomógomb, akkor vágd ki a fenébe a kapcsolót, vagy csekkold a kábelezést, meg amit még írtak a többiek a feszültségosztásról.

Az ESP32 NEM 5V tolerant. Ha tiszteleted teszed a gyártó oldalán, ő mutatja a leírást.

Az 500 kilós ellenállás valószínűleg túl nagy, hogy a lábat megbízhatóan lehúzza.

 

"meghajtható 5V-ról,"

NEM. Nem az ESP-t hajtod 5V-tal, hanem a nyákon előtte elhelyezett LDO-t. Az ESP 3.3-at kap.

Ez a 3.3V biztosan ott van a panelon, csak rá kéne csattanni, és nem 5V-tal stresszelni szerencsétlen input lábakat.

(Ha a nyákon lenne MINDEN GPIO-hoz 3.3V-os védelem, az látható. Lenne, ha lenne. Nem szoktak csinálni, mert minek.)

"Normális ember már nem kommentel sehol." (c) Poli

Bármelyik tápfeszültsége az ESP32-nek legfeljebb 3,6 V lehet. Bármelyik I/O lábán a feszültség legfeljebb 0,3 V-tal lehet magasabb a tápfeszültségnél, így ez messze van az 5 V-tól. Az én olvasatomban maximum 3,9 V-ot lehet kötni az I/O lábakra, de azt is csak akkor, ha 3,6 V-tal megy a táplálás.

forrás: https://www.espressif.com/sites/default/files/documentation/esp32_datas…

Eddig még nem hajtottam 5 V-tal az ESP32 bemeneteit, de nem is akarom kipróbálni. (Nem azt mondom, hogy nem bírja ki, csak azt, hogy az adatlap szerint nem szabad ekkora feszültséget rákötni.)

Bármelyik tápfeszültsége az ESP32-nek legfeljebb 3,6 V lehet. Bármelyik I/O lábán a feszültség legfeljebb 0,3 V-tal lehet magasabb a tápfeszültségnél, így ez messze van az 5 V-tól. Az én olvasatomban maximum 3,9 V-ot lehet kötni az I/O lábakra, de azt is csak akkor, ha 3,6 V-tal megy a táplálás.

Igen, tudom, hogy mi van a dokumentációban, az a hivatalos, régebben benne volt, hogy 5 volt toleráns. Viszont ezeregy példát találni arra, hogy 5v tolerant, többek között én is évek óta így használok több ESP eszközt is, 5 voltos perifériákkal, valahol az Expressif CTO/CEO amúgy kis is mondta, hogy minden GPIO védett és 5 volt toleráns, de nem írják bele a doksiba, mert nem akarnak belőle pereket, ha mégsem.

So Is ESP8266 5V Tolerant?
Well, this is a difficult question to answer because it means different things to different people, and it can be confusing for those who are not into circuits. So what could the possible interpretations of the question be?

  1. the chip runs off only 5V supply
  2. the chip runs off a combination fo 5V and 3.3V supplies; 5V for those supplies connected to IOs that connect 5V interfaces
  3. the chip runs off only 3.3V supply, but the IO connects to 5V interface.
    For ESP8266, case 3 is what we mean when we say that the GPIO pads are 5V tolerant.
    [I was utterly mortified when users read "5V tolerant output" in an early version of our specifications to mean that the chip's power supply should connect to 5V. Well, it wasn't designed to be powered from 5V, although some users have reported success, which makes the problem somewhat worse. Thereafter, we banned any mentions of 5V.]
    (for those who still aren't clear.) So what is the point of the pad being 5V tolerant if the chip is to be powered from 3.3V? Yes, there is a way to do voltage translation by setting the ESP8266 pads to the open drain mode, and adding a pull up resistor connected to 5V supply. voila. The input and output can now interface with 5V systems.
    And then, some sharp eye engineers noticed that the chip also supports CMOS output asked if it would sink current when a 5V signal connects to the pad. What these engineers are asking is if the diode between the PMOS drain and Nwell would be forward biased sink current from the 5V supply to the 3.3V supply.
    For ESP8266, it would not in the open drain mode: the diodes are disconnected in the open drain mode.
    ∆! So, do not use CMOS interfaces with 5V signals in ESP8266. Please use the open drain configuration.
    [If you are still confused, beep me right here, right now!]

Ha nem űrtechnika, amit építesz és nincs jogi következménye annak, hogy megáll (de ugye ekkor miért használnál ESP-ket), akkor nyugodtan engedj rá 5 voltot, menni fog. Sokat lehet spórolni a dologgal, hogy nem kell szintillesztő, se ellenállásosztó.

A 2013-as doksiban amúgy benne volt még (utána szedték ki):

All digital IO pins are protected from over-voltage with a snap-back circuit connected between the pad and ground. The snap back voltage is typically about 6V, and the holding voltage is 5.8V. This provides protection from over-voltages and ESD. The output devices are also protected from reversed voltages with diodes.

Még megvan a verzió nálam, amiben ez volt: https://drive.google.com/file/d/1MXqpKVWYBwvfnmgW4bX-CSoFMbSWW5_d/view

Csodálkoznék, ha kivették volna ezeket a védelmeket. És a gyakorlat azt mutatja, hogy nem vették ki, ott vannak.

az Expressif CTO/CEO amúgy kis is mondta, hogy minden GPIO védett és 5 volt toleráns, de nem írják bele a doksiba, mert nem akarnak belőle pereket, ha mégsem.

Szerintem (illetve én így értelmezem a fentieket) inkább azért vették ki az 5 V emlegetését, mert csak egy esetben, csak open drain módban tűri az ESP8266EX, ha 5 V kerül egy GPIO lábra, sok felhasználó meg nagyon kevés elektronikai ismerettel rendelkezik, így sokan rosszul használták volna, aminek következtében sok eszköz hibásodott volna meg.

Amúgy meg az ESP8266 és az ESP32 között lehet különbség, szóval nem biztos, hogy az újabb chip is ugyanazt tudja ebből a szempontból, mint a régi. Nem mondom, hogy lehetetlen, hogy ugyanolyan legyen, csak azt, hogy nem írják sehol, hogy ugyanolyan, és ennek az okáról meg nincs értelme vitatkozni. Ha a gyakorlatban bevált ez a megoldás, akkor jó, viszont lehet úgy is tervezni áramköröket, hogy betartjuk az eszközök specifikációit, és az meg még jobb :)

Ha a gyakorlatban bevált ez a megoldás, akkor jó, viszont lehet úgy is tervezni áramköröket, hogy betartjuk az eszközök specifikációit, és az meg még jobb :)

A kérdezőnek egy hobbi projektje van, persze, lehet építeni Halálcsillagot is, de minek. Megosztottam az információt, a tapasztalataimat, aztán mindenki úgy használja, ahogy gondolja.

Megosztottam az információt, a tapasztalataimat, aztán mindenki úgy használja, ahogy gondolja.

Igen, ezt értem is, csak az az információ, amit egy sorban, tömören odaböktél, szöges ellentétben van azzal, amit az EP32 adatlapja mond.

 

A kérdezőnek egy hobbi projektje van

Az én értelmezésem szerint pont az ilyen hobbisták miatt vették ki az ESP8266 leírásából azt az ominózus részt, ahogy már ezt korábban is írtam. Lehet, hogy nem a megfelelő embernek adtad ezt a tanácsot. (lásd: "Láma" - nem én írtam, hanem a kérdező)

Igen, ezt értem is, csak az az információ, amit egy sorban, tömören odaböktél, szöges ellentétben van azzal, amit az EP32 adatlapja mond.

A gyakorlattal viszont nincs szöges ellentétben.

Az én értelmezésem szerint pont az ilyen hobbisták miatt vették ki az ESP8266 leírásából azt az ominózus részt, ahogy már ezt korábban is írtam.

Mert 5 volttal próbálták megtápolni. Hozzátenném, hogy ESP-IDF kell ahhoz, hogy ne open drain legyen a GPIO, aki meg ESP-IDF programozik, az vélhetően nem hobbista.

De tényleg azt tudom mondani zárszóként, hogy mindenki azt csinál amit akar, én nem költök feleslegesen szintillesztőre.

Keress rá az ellenállásosztó varázsszóra, és ne köss 5 V-ot a 3.3V-os bemenetre. (Csak ha az adatlap esküszik, hogy 5V toleráns. Az ESP-ről nekem az rémlik, hogy nem az.)

Én mindenesetre a fogadó oldalon húznám fel a lábakat, és a kapcsoló húzná le földre. Ekkor nem kell külső, idegen, független táppal szórakozni.

És 500k az durván nagy, inkább 10k nagyságrendben válogatnék.

"Normális ember már nem kommentel sehol." (c) Poli

Szakiknak leginkabb egy olyan oldal lenne jo hogy megadod a Vin-t, a Vout-ot es megmondja hogy milyen letezo R1/(R1+R2) osztobol tudod ezt a legpontosabban megepiteni ;) Mert ugye hiaba mondjak azt hogy (pl) az E24-es sorozat 5%-os turesu, manapsag mar ugyis az is 1% alatti pontossagu lesz... meg valogatni se tudunk. 

Gondolod, nem volt erre szükségem? Megírtam (ap)calc scriptben. Ez nem a LibreOffice. Részlet a .calcrc file-omból:

define pair(x) {
    if (x<=0) {
	printf("Invalid parameter: zero or negative\n");
	return;
    }
    local mode2save, m, len, i, j, idx, y, err, sc, mi, mj, n, full, min;
    sc=ilog10(x);
    if (abs(sc)>4) {
	printf("Invalid parameter: too large rate\n");
	return;
    }
    mode2save=config("mode2", "off");
    m=list(10, 11, 12, 15, 16, 18, 20, 22, 24, 27, 30, 33, 39, 47, 51, 56, 68, 75, 82, 91);
    full=list();
    len=size(m);
    for (i=0; i<len; i++) {
	for (j=0; j<len; j++) {
	    mi=m[[i]];
	    mj=m[[j]];
	    if (sc<0) {
		mi*=10^-sc;
	    }
	    if (j<i) {
		if (sc<0) {
		    mi/=10;
		} else {
		    mj*=10;
		}
	    }
	    if (sc>0) {
		mj*=10^sc;
	    }
	    y=mj/mi;
	    err=(y-x)/x;
	    n=list(mi, mj, err);
	    append(full, n);
	}
    }
    for (j=0; j<4; j++) {
	len=size(full);
	min=10;
	for (i=0; i<len; i++) {
	    n=full[[i]];
	    err=abs(n[[2]]);
	    if (err<min) {
		min=err;
		idx=i;
	    }
	}
	for (i=idx; i<size(full); i++) {
	    n=full[[i]];
	    err=n[[2]];
	    if (abs(err)==min) {
		delete(full, i--);
		mi=n[[0]];
		mj=n[[1]];
		printf("%d %d\terr=%7.2f %%\n", mi, mj, 100*err);
	    }
	}
    }
    null(config("mode2", mode2save));
}

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Nagyon fasza, koszi ;) Annyi "bug" mintha lenne benne hogy a list()-ed nem teljes: a 13, 36, 43 es 62 hianyzik belole. Ha beleteszem, akkor szepen megtalalja azt amit a minap kerestunk: 0.8V <=> 5V-re oszto: 82/(82+430). A javitas nelkul egyebkent meg nem talal ennyire jot...!

Szerk: ket modon lehetne kenyelmesebbe tenni ezt: egyreszt hogy lenne pl egy pair24() es egy pair12() is, masreszt meg hogy ket parameteres is lehetne... hogy (0.8, 5)-ot adok meg es kiadja hogy 82 430 ;]

Fejből írtam azokat az értékeket, amelyekkel gyakrabban találkozom, s nem néztem meg, mi van benne az E24-ben. Ízlés szerint bővíthető. :)

A két paraméteren én is gondolkodtam, de valahogy feleslegesen soknak éreztem. Úgy voltam vele, akárhogyan nézzük, ez egy hányados, ami egyetlen szám. Amiatt van még lelkiismeret-furdalásom, hogy nem olvashatóan, szellősen írtam, hanem szemkifolyatósan ömlesztve az egészet. Mindegy, így sikerült, viszont jól működik, használom a mindennapjaimban. Ha jól emlékszem, növekvő hibaráta szerint írja ki az első néhány találatot.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

5v-tal siman mehet, inkabb a zizeges lesz a baj. Nezz utana a debounce algoritmusnak/lib-nek.

Amikor ervenytelen erteket mutat, akkor a feszultsegmero mennyit mutat a bemeneten? Nem zarlatos/megtort a vezetek?

50cm nem palya, 5m-nel kezdenek aggodni. 

amit felettem is írtak, azt lehet hardveresen, illetve szoftveresen is lehet rajta segíteni: mivel egy mérés nem mérés, ezért érdemes többször vizsgálni a kapcsoló állapotát a programban:

- ha pollingolsz akkor egyszerűen nem az első HIGH értékre csinálsz valamit, hanem megnézed még egyszer, meg még egyszer és azt nézed, hogy a 3 mérésből a LOW vagy a HIGH van többségben.

- ha interrupt handlered van szintváltozásra, akkor pedig a handler elején meg lehet nézni még egyszer az állapotot, hogy biztosan volt-e szintváltozás.

a keresőszavak a szoftveres megoldásokhoz: debounce, prell

Szerkesztve: 2021. 03. 10., sze – 12:05

A kapcsolót a GPIO és GND közé kösd, az ellenállást pedig a kártya saját +3.3 V-jára. Aztán az az 500 kΩ sok lesz. Legyen pl. 3.3 kΩ, akkor nem lesz zavarérzékeny. Ezen felül illik software-esen is szűrni egyrészt azért, mert a kapcsoló pereg, prellezik, tehát átkapcsoláskor impulzus sorozat keletkezik, másrészt azért, mert beeshet egy-egy rövid, kósza tranziens, amiről nem szeretnél tudni.

Egy lehetséges algoritmus, hogy időalap IT-ből, pl. 2 ms-onként olvasod a GPIO-t. Ha 1-et olvasol, növelsz egy számlálót, de telítődően, ha 0-t olvasol, csökkented, de azt is úgy, hogy telít, ha elér a legkisebb értékig. Ha a számlálód a maximumon van, 0-ba billented a kimenetet tároló flag-et, ha minimumon, akkor 1-be, közte pedig változatlanul hagyod. Fejből írtam gyorsan, nem biztos, hogy jó.

A key az globális volatile bool változó.

void IT_callback(void) {
#define COUNTER_LENGTH 6
  static uint8_t key_cnt = 0;

  if (Get_GPIO()) {
    if (++key_cnt & ((1 << COUNTER_LENGTH) - 1) == 0) {
      key_cnt--;
      key = false;
    }
  } else {
    if (--key_cnt & ((1 << COUNTER_LENGTH) - 1) == ((1 << COUNTER_LENGTH) - 1)) {
      key_cnt++;
      key = true;
    }
  }
}

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Semmi. Így jutott eszembe épp, amikor írtam. Nyilván lehet úgy vizsgálni, hogy ha már a tetején vagyunk, nem piszkáljuk, egyébként inkrementálunk, illetve, ha már alul vagyunk, nem piszkáljuk, különben csökkentjük. Amúgy manapság szinte mindegy mit írsz, a compiler úgyis a felismerhetetlenségig optimalizálja majd, és a végeredmény kb. ugyanaz lesz. Ha assemblyben írod, akkor lehet érdekes, hogyan csinálja az ember.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

bool pinSWLast == true
int swVal;

void stup(){
  pinMode(pinSW, INPUT_PULLUP);
}

void loop(){
    sensSW();
}

int sensSW() {
  swVal = !digitalRead(pinSW);
    if (pinSWLast == true ) {
       if (swVal == LOW){
         Itt csinálsz valamit
         
         pinSWLast = false;
       }
    }
  if (swVal == HIGH) {
    pinSWLast = true;
  }

Én ezt használom Arduino-nál. Nekem bevált. Az INPUT_PULLUP felhúzza a bemenetet 5V-ra belső ellenállással, nem kell külső szerelgetés.

Szerkesztve: 2021. 03. 06., szo – 11:52

Egyébként, ha az kell, hogy statikusan nyomnak valamit, vagy le- illetve felfutó él volt-e, így egyszerűbb:

static uint8_t key = 0;

key = (key << 1 | (Get_GPIO() ? 1 : 0)) & 3;
switch (key) {
  case 0:
    /* nyugalom van */
    break;

  case 1:
    /* a megnyomás pillanata */
    break;

  case 2:
    /* az elengedés pillanata */
    break;

  case 3:
    /* nyomják, mintha muszáj lenne */
    break;
}

Get_GPIO() 0-val tér vissza, ha nem nyomják a billentyűt, nem 0-val, ha igen. Persze a pergésmentesítéshez még kellene az az IT rutin, amit írtam fentebb.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Az 500k rettentően sok, nyitot állapotban ez egy jó kis antenna, bármilyen zavart összeszedhet. <50k kellene használnod, és akár tűri az 5V -ot akár nem mindenképpen kell áramkorlátozás, min. 1K sorban a GIO bemenettel (ez akár lehet az osztó felső tagja, az alsó a bemeneti impedancia), 50cm -nél még talán nem, de érdemes ESD diódákat betenni.
Meg kell nézni a GPIO bemenetek védelmét, illetve van e előtte/benne schmit trigger (hiszterézis).
A prell mentesítésre rengeteg mindent találsz a neten. A lényeg, hogy a kapcsoló ki/be kapcsolása után egy lecsengő rezgést kapsz, így többszöri beolvasás után akkor fogadd el az értéket/állapotot ha az már "beállt", mivel ez a mechanika rezgése miatt jön létre arra is gondolj, hogy ez idővel változik (hónapok, évek, de eleinte radikálisan, bejáratós :) .

A neten található ilyen-olyan receptek általában mellőznek minden védelmet amit ha tényleg használni akarsz muszáj betenni, nem csak az olcsó kis eszközöd miatt, de benne van a munkád is, illetve lehet tényleg fontos a feladat amit ellát.

* Én egy indián vagyok. Minden indián hazudik.

Szerkesztve: 2021. 03. 06., szo – 11:27

Érdemes itt is körül nézni:
https://www.adafruit.com/product/4431

Ha jól megnézed, minden gombhoz tartozik 2 db ellenállás.

A gyors rákereséssel találtam egy ilyet (igazán kimerítő):

https://www.electronics-tutorials.ws/io/input-interfacing-circuits.html

Egyébként sokkal jobb felállás, ha a panelnél közvetlenül felhúzod tápra és a kapcsoló lehúz a földre. Tényleg nem lehet a szoftverben megfordítani?

* Én egy indián vagyok. Minden indián hazudik.

"Mivel a kapcsolók már be vannak építve, "

Az én olvasatomban ez azt jelenti, hogy a kapcsolók fixen hozzák az 5V-ot, azokhoz nem tud (nem akar!) nyúlni. Tipikus szoftveres rendszertervezés. Egy elcseszett hardvert szeretne szoftveresen korrigálni.

 

"sokkal jobb felállás, ha a panelnél közvetlenül felhúzod tápra és a kapcsoló lehúz a földre."

Mindenki ezt írja neki, de ő elment. Remélem, olvasni ment.

"Normális ember már nem kommentel sehol." (c) Poli

Ahogy a tobbiek is irjak:

 - 3.3V-rol huzd fel azt az ellenallast: alapszabaly hogyha egy adott IC tapfeszultsege annyi amennyi, akkor az I/O labai is maxmium annyit birnak. Ha ennel tobbet (pl 3V3-as tappal birja az 5V-ot) akkor azt nagyon-nagyon hangsulyosan, mar az adatlap legtetejen irjak hogy vannak ilyen labai, melyik labak azok es hogy miert. Pelda: sok mikrokontroller tud CAN interface-t kezelni, viszont a CAN fizikai illesztok by def 5V-osak. Igy a mikrokontroller azon labai ahova a CAN RX/TX-et illeszted (leginkabb az RX-et), azok sok esetben 5V-toleransak. De altalaban nem azok, nem szabad ebbol kiindulni.

 - az 500k nagyon sok. Alapszabaly lehet itt is hogy 1mA-t folyass at legalabb, azaz 3.3k-s ellenallassal huzd le. 

 - Ha tudsz, hasznalj Schmidt triggeres bemenetet vagy szurot vagy ilyesmit. Utolag is betehetsz ilyet, vannak pl 6 csatornas schmidt-triggerek a klasszikus 74xx-es sorozatban is. Pl a 7414-es. Ez ugyan meg is forditja a logikai szintet, de nem problema ha a kontrollerben kezeled a foritott logikai szintet. Egyszeru, olcso, ezer eves technologia, sot, meg akar az 5V->3V3 illesztest is megoldhatod vele! 

 - A szoftveres szures is sokat segit. Peldaul csinalhatsz olyat hogy folyamatosan olvasod es shifteled a bemenetet egy (pl.) 8 bites regiszterbe:

uint8_t curr,prev;
...
while ( 1 )
 {  curr = (prev<<1) | (INPUT?1:0);
    if ( curr==0xFF && prev != curr )
     {   do_something_if_button_is_pressed();
         ...
     }
    else if ( curr==0x00 && prev != curr )
     {   do_something_if_button_is_released();
         ...
     }
    prev=curr;
    ...
 }

Ez ilyen kicsit "szegeny ember schmidt-triggere" jellegu megoldas, de utolagos, tisztan szoftveres javitasra egesz jo lehet. Hasznaltam mar ilyet, volt hogy ez mentette meg a dolgokat. Az INPUT mintavetelezesenek idoskalajaval tudsz jatszani, ha fizikai bemenetet erzekelsz akkor nem kell tul gyakran (pl masodpercenkent 1000x eleg).

Alapvetően egyetértek, bár a Schmitt-triggert feleslegesnek érzem. Az a bit vagy 1, vagy 0 lesz már az adatbuszon. A pergésre meg remek firmware-es lehetőségek vannak, csak a fantázia szab határt. Te is írtál egy példát, én is, de írtak itt mások is lehetőséget.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Hat, jo kerdes, de az ilyen schmidt-triggeres inputot kvazi kotelezonek vennem egy digitalis inputnal. Oke, lehet szoftverbol is szurni, vagy pl FPGA-kba is relative egyszeru betenni egy digital filter-t, de... de ne azon a ket-harom tranzisztoron muljon a boldogsag. A topiknyito kollega altal felvetett problema is mar inkabb mixed-signal kategoria - pont azert mert a vezetekhossz mar kezd osszemerhetove valni a mikrokontroller orajel-periodusaval (marmint fenysebesseg=1 mertekegysegrendeszerben :p) es/vagy a kapcsolo-kapcsolas RC idoallandoja a mikrokontroller orajel-periodusaval (barmilyen mertekegysegrendszerben). Impedancia-illesztesekrol meg mar ne is beszeljunk :)

A vázolt kapcsolással sok baj van, többen írtuk is már ezt. Amikor bekapcsolod a kapcsolót, az a bemenet kis impedancián +5 V-ra lesz húzva. A mikrokontroller bemenetén jó eséllyel van két clamp dióda. Ezek közül a felső kinyit, s megemeli az egész MCU tápfeszültségét nagyjából 4.3 V-ra, csak hát szegény nem erre van méretezve, így tönkre mehet. Nyilván, ha A/D konverter referenciája a tápfeszültség, az is érdekes ilyenkor.

További probléma, hogy a nyitott clamp dióda jellemzően 2 mA fölött - amúgy katalógus adat, lehet több is jobb esetben - elárasztja töltéshordozókkal a chip egymásra halmozott p-n átmeneteit, s így a nem szándékosan kialakított parazita tirisztor begyújt, rövidre zárja a tápfeszültséget a chip, majd a disszipációba illetve a lokálisan nagy áramsűrűségbe bele is pusztul.

Aztán ott van az 500 k problémája. Azon túl, hogy nem tudom, hol adnak ilyet - 470k, 499k, 510k hihetőbb nekem - nagyobb gond, hogy nagyon gyengén húz lefelé, a bemeneten lifegő fél méter madzag kapacitív úton összeszedi az 50 Hz-et, meg persze a rádióhullámok egy részét is, így a kapcsoló kikapcsolt állapotában itt nem mindig lesz alacsony szint, hiszen a bemenet CMOS. És akkor nem beszéltem a kapcsoló esetleges szivárgási áramáról, illetve a bemenet maradékáramáról.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Köszönöm, a sok hozzászólást.

Összefoglalva a leírtakat, tehát a következő kapcsolásra lenne szükségem:

     /
 ---/  ----
 |        |
 |        |
 |       ---
 |      |   |
 |      | R | = 24k
 |      |   |  
 |       ---
 |        |
 |        |
 |        +----------------------------> ESP 32 GPIO (3.3V)
 |        |                   |
 |       ---                  | 100n
 |      |   |            _____________
 |      | R | = 50k      _____________
 |      |   |                 |
 |       ---                  |
 |        |-------------------
 |        |
+5V       0V

Remélem, jól számoltam az értékeket.

Kérem, valami hozzábbértő hagyja jóvá, és akkor megoldottá teszem a threadet, későbbi lámák számára.

Amúgy közben megtaláltam a hiba forrását. Az egész áramkör egyelőre próbapanelen van összedugdosva. A hibásan olvasó GPIO melletti GPIO vezérelt, és HIGH értékre állítva bezavart. Átraktam ezt a vezérlő jelet egy távolabbi GPIO-ra, azóta stabil, és nincs fals érzékelés. De a végső változatban, - jóváhagyás esetén - a végállás kapcsolók detektálásához már a fenti kapcsolást fogom megépíteni.

Elvileg ha 3.3 V a VDD, akkor 2.475V-tól 3.6V-ig rendben van:
High-level input voltage max - VDD+0.3 V
High-level input voltage min - 0.75×VDD
https://www.espressif.com/sites/default/files/documentation/esp32_datas…

Azonban én is olyan ~3V-ra lőném be (ki tudja mennyire stabil az az 5V).

Persze, amíg a felső clamp-dióda nem nyit ki, nincs baj. De én is abból indultam ki, hogy ha a VDD lefelé, a külső táp felfelé szór - vagy tűr? :) -, akkor valahogy nyugodtabb vagyok, ha +3.3 V alá van ez belőve. Ugye, ott is van statikus zajtartalék, tehát VDD alatt egy jó darabig még stabil magas szint van.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Én nem tenném bele a kondenzátort, firmware-ben szűrnék, de az is igaz, ha beleteszed, abból baj nem lesz. A másik, hogy kisebb ellenállást javasolnánk itt jó sokan, ráadásul még mindig 3.3 V fölé lőtted be. Azért kisebb ellenállás, hogy ne legyen minden zavarra meg minimális maradékáramra érzékeny.

Az én javaslatom az 50k helyett 3.3k, a 24k helyett 1.8k.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Hát, pár megjegyzés:

- az ilyen direktbe kötött kapcsolónál általában nem pozitív tápról adjuk a kapcsolóval a jelet, és húzzuk nullára alapból a bemenetet, hanem fordítva, így ugyanis rögtön elmúlik az a probléma, hogy honnan adunk olyan tápot a kapcsolónak, ami pont megegyezik az áramkör tápjával, meg nem fordulhat elő, hogy a kapcsolóhoz kivezetett táp kap egy ordas nagy rövidzárt egy rossz mozdulat miatt mondjuk,

- ha a kapcsoló messzebb van (vagy dobozon kívülre megy a vezeték), akkor én inkább beraknék egy NPN BJT-t is az áramkörbe - ebben az esetben ismét tápot kell a kapcsolóhoz vinni, viszont cserébe az bármilyen lehet, és nem lesz baj belőle, ha a báziskör ellenállásának egyik része már a táp és a kapcsoló közé bekerül (ezzel az ordas nagy rövidzár esetét ki is védtük),

- a leghatékonyabb megoldás nálam ezekre az esetekre az optocsatoló, ott még galvanikus leválasztást is kapunk, ami nagyságrendileg jobb védelmet ad pl. sztatikus eseményekkel szemben,

Bármelyik megoldás kerül szóba, valami védődióda fog kelleni (optiocsatolónál a diódával ellentétes irányba, BJT-nél a B-E átmenettel ellentétes irányba, direkt esetnél meg a plusz és a mínusz táp felé, szintén ellentétes irányokba).

Egyelőre próbapanelen raktam össze, és egy-egy kapcsoló GPIO-ra kötéséhez alig van hely, emiatt minimalizálnám az alkatrészek számát. De ha már opto, akkor inkább egy optikai végállásérzékelőt néztem. Ha jól látom, abba 3 vezeték megy, és közvetlenül ráköthetem a tápra meg a GPIO-ra, nem kell semmilyen további alkatrész. Ez szimpatikus, de a jelenlegi kapcsolóim meg már be vannak építve fizikailag, így nem bontanám meg. Vagyis egyelőre maradok a minél kevesebb alkatrésszel, de stabilan irányban.

Ha nem akkurol/elemrol megy, akkor nyugodtan lehetnek kisebbek az ellenallasok ahogy mar a tobbiek irtak. Ha akkurol megy, akkor is, felteve, hogy a vegallaskapcsolorol leszallsz a vegen, es nem folyik folyamatosan aram. Gondolom valami motort forgat, szoval a tap meg van oldva, es a fogyasztasa a motorehoz kepest elhanyagolhato. (no meg az ESP is imadja a villanyt zabalni)

Ja, es a hosszu drotszakasz ugye a felso ellenallas es a kapcsolod kozott lenne?

A strange game. The only winning move is not to play. How about a nice game of chess?

Te, figyelj már, arra a GPIO-ra nem lehet a mikrokontrolleren belül felhúzást - weak pullup - programozni? Mert akkor semmilyen alkatrész sem kell, csak a kapcsoló a GPIO input pin és a GND közé.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Ez jogos. Viszont software-esen ez is kezelhető. Jól definiált sebességgel - pl. 1 ms-onként - mintát veszünk, telítődő számlálót inkrementálunk, ha 1 jön be, dekrementálunk, ha 0, s amikor a számláló valamelyik irányban telít, akkor állítjuk a kimeneti bitet a neki megfelelő irányba, ellenkező esetben emlékezünk a legutóbbi értékre.

Ugye a megoldás lényege az, hogy a zaj - pl. 50 Hz - DC komponens nélküli, így nagyjából 50 % kitöltésű. Ha az egyik irányba elhúzzuk a bemenetet, még ha ott is lesz a zaj, a kitöltési tényezője vagy jelentősen 100 % felé tolódik el, vagy 0 % közelébe. Ez viszont már jól processzálható.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Ugye a megoldás lényege az, hogy a zaj - pl. 50 Hz - DC komponens nélküli, így nagyjából 50 % kitöltésű. Ha az egyik irányba elhúzzuk a bemenetet, még ha ott is lesz a zaj, a kitöltési tényezője vagy jelentősen 100 % felé tolódik el, vagy 0 % közelébe. Ez viszont már jól processzálható.

Nem az 50 Hz brumm az igazi baj, hanem bármi más: fázishasítós nagyobb gép indítása, konyhai gépek, szikrázó szénkefés munkagépek, satöbbi, meg tudja szórni a hosszabb vezetékeket, ha nincs kellő árammal előfeszítve, akkor könnyen jelként érzékeli a uC.

Ugyanugy, mint prellezesnel: nem hiszi el rogton az uj erteket. Ha sok egymas utani ertek alapjan atbillent, akkor mar igen. A "rogton", "sok", es a konkret algoritmus persze alkalmazasfuggo. Kezi nyomogombnal viszonylag ritkan valtozhat az erteke tenylegesen. Egy mechanikai rendszer vegallaskapcsolojakent szinten mondhato ra ertelmes limit.

A strange game. The only winning move is not to play. How about a nice game of chess?

Értem, de egy szarabb botmixer (konkrét tapasztalat) úgy megszórja RF a környezetét, hogy nem tudod eldönteni, hogy ami másodperceken át jön, az most jel vagy zaj, főleg, ha digitális a GPIO és nem látod a bejövő analóg jelet. Nyilván megoldható, hogy akár egy másodpercig nyomni kelljen a biztos reakcióhoz, de a legtöbb esetben az irreálisan sok. De felőlem mindenki úgy szopik, ahogy szeretne.

Jo, nyilvan adott jel-zaj viszonyig mukodik. Ha ez nem eleg, akkor azon kell javitani (12V/24V-os jellel, vagy differencialtan csavart erparon kell kuldeni). Ha az sem eleg (vagy draga), akkor johet a logika mindket oldalra, es hibajavito kodolassal kell kuldeni-fogadni (ld. NASA urszondait). Egy kapcsolonal remelhetoleg nem kell odaig elmenni, az tenyleg urtechnika.

A strange game. The only winning move is not to play. How about a nice game of chess?

Hát, nézd, nekem erre volt a közelmúltban első kézből tapasztalatom, hogy egy RF zajt szóró kézimixer úgy átmegy az ilyen prell-védelmen az ESP32 saját pull-up ellenállásával, mint meleg kés a vajon, de nem volt kedvem tovább "kötözködni", szóval igazad van neked is és neki is.

Kérdés, milyen algoritmussal, annak milyen paraméterezésével. De egyébként mindketten azt hangoztattuk, hogy kisebb, pl. 3.3k-s felhúzás volna jó. Pusztán azt mondtam, hogy ha nincs, még akkor is van a firmware-ben mozgástér erre a problémára.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Analóg példa. Végy egy integrátort, s a bejövő jelet integráld. Ha az integrátorod kiült az egyik tápfeszre, az az egyik állapotba billentsen egy flip-flop-ot, ha kiül a másik tápfeszre, az a másik állapotba tegye a flip-flop-ot, ha pedig valami nem telített állapotban kóricál az integrátor kimenete, a flip-flop emlékezik a legutóbbi állapotra. Más megközelítésben az integrátor kimenetére kössünk egy marha nagy hiszterézisű Schmitt-triggert, az épp a kívánt eredményt adja.

Na, most ezt csináld meg digitálisan az MCU-val. Faék egyszerűségű, telítődő számlálót kell implementálni.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Mert amikor azt a hozzászólást eredetileg írtam, akkor arról volt szó. Mivel senki sem szólt hozzá, tudtam javítani a kedvedért a kódon általánosabb számláló hosszt beleírva. Eredetileg 3 bites volt. De a módszer lényege ennyi, s ez elég jól menne belső felhúzással is. Nem 5 m kábellel, de 50 cm-rel még igen.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Inkább egy raspály relével! ;)

Mindkét megoldásból kifelejtetted a frekvencia domaint. Vajon milyen időállandó kell az integrátorhoz? A számláló 10MHz tartományban menjen, vagy elég 10Hz is?

A gyakorlatban rigorózus prellmetesítésre egy rc tagot (integrátor) és egy flip-flop-ot (rs tároló) lehet használni. De vajon érdekes-e a végálláskapcsoló állapotának nagyon pontos meghatározása?

Vagyis el kell-e bonyolítani ennyire?

A kapcsoló kapcsolási és lengési ideje (ha van olyan) megmérhető és ekkor máris többet tudnunk. Mérés helyett jó közelítés a >10ms, vagy a >>10ms. Vagyis hiába rakod oda akár a mobilodat, mint zavaró frekvenciát, a kapcsoló nem fog gyorsabban kapcsolni.

Így aztán egy >>10ms időállandójú rc tag meg is oldotta a valós és vélt problémák java részét.

A hardver-szoftver feldolgozást sem kell elbonyolítani. A fenti időállandó miatt elég >10ms gyakorisággal olvasni a portot. Ha 2-3 egymás után következő olvasás állapotváltozást jelez, akkor működött a kapcsoló. Ezzel az a probléma is kiküszöbölódött, ha a nem st bemenetű port a határozott kapcsolás helyett kicsit billeg.

Ha megfigyeled, itt már az integrátor és a számláló (hossza és frekvenciája is) defined állapotú.

Az rc tag méretezésénél arra kell törekedni, hogy a fellépő zavarfrekvenciáknál minél kisebb impedanciát képviseljen. Ez a gyakorlatban <10kOhm - ezen az alacsony frekvencián. Ilyen esetekben a wpu alkalmazása általában nem célszerű.

Igen, azt többen javasoltuk itt, hogy 3.3k körül volna az ideális. Én pusztán azt írtam, hogy jó eséllyel ezt még meg lehet stabilra csinálni az MCU weak pullup-jával is, ha nem kell túl gyorsan reagálni a kapcsolóra. Ha az egyik legdominánsabb és egyben legalacsonyabb frekvenciájú zavar forrásának az 50 Hz-et tekintem, akkor 1 ms-os mintavételezés kellő túlmintavételezést fog adni, a számláló hossza ebből becslésem szerint 5 vagy 6 bit, azaz  31 vagy 63 ms alatt ténferegnénk el zavarmentes állapotban a másik állapotba. Nyilván zavarjel esetén nagyjából a kettőt előre, egyet hátra fontolva haladás miatt lassabbak lennénk, tehát az egész csodának bizony lenne egy kb. 100 ms-os késése. Kérdés, ez belefér-e. Ha precíziós vezérlés kell, akkor nem, de oda inkrementális jeladót használunk, és nem rendszergazdák fórumán kérdezzük egy hibás kapcsolásról, hogy jó-e. Ha belefér a 100 ms, mert mondjuk lámpát kapcsolunk vele, akkor nem rugóznék ezen, akkor nem kell külső alkatrész, csak a kapcsoló, meg persze be kell kapcsolni a weak pullup-ot.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

A wpu >100k ellenállásnak felel meg, ezért nem jó.

Ez nem egy ADC, nem "túlmintavételezni kell", hanem "alul". Illetve a >10ms időállandó esetén is a 10ms minavétel 2-3x-os túlmintavételezést jelent, de erre sincs szükség. Ha elegendően nagy az rc tag, akkor 1-2 bit bőven elég. (A leírt algoritmus.) Eközben a hiba maximum 1-2 mintavételezésnyi lesz. Ez a hibát le lehet fordítani centiméterre. ;) Ha nagyobb pontosságra van szükség, akkor más megoldást kell alkalmazni. Itt azért elmondható, hogy az rc tag + mintavételezés késleltetése elég stabil.

Vajon az 50cm dróton 3,3k terhelés mellett mekkora feszültség keletkezik az 50Hz-ből? ;) Ha tényleg van 50Hz vagy egyéb zavar, akkor elsősorban a bemeneten kell szűrni, hogy kisebb legyen a zaj, mint  a jel. A hálózati 100Hz-es zavarból eredő jitter kiküszöbölésére legegyszerűbb módszer a hálózati szinkronizálás, amihez egy ellenállás és két dióda elegendő. Sőt, ez a megoldás jó pl. triac vagy ssr szinkron vezérléséhez is.

A precíziós érzékelővel meg jártam úgy...

Egy fékpadi terhelés forgását mértem előfeszített Hall érzékelővel. (néhány us pontossággal) Kiderült, hogy rossz a programom, mert dupla fordulatszámot mér. Miután minden hibalehetőséget kizártam, kinyomoztam mi is történt: Józsi bácsi felfogta a tárcsát a mágnesasztalra... :-D

A programodban , ami az ESP32 fut a GPIO -kat hogy inicializálod ??  Szerintem  INPUT_PULLUP  -pal kéne. Így a feszültség esést fogja szépen érzékelni.

A hozzászólásokat olvasva a probéma megoldhatatlannak tűnik.

Alkalmazz inkább tárcsás jelzőőrt!

Is. ;)

Arra még senki nem gondolt, hogy az 5V vagy a 3,3V jelenik meg előbb. Hiába, bonyolult ez az áramkör! ;)

Mindig mondom, az áramkörök java részének méretezéséhez elegendő az Ohm törvény. A zemberek java része meg ezt nem érti, nem hiszi el, esetleg nem tanulta. Ebből aztán keletkeznek az ilyen topicok, mikor már a hozzáértő is elbizonytalanodik. ;) Az 500k-ról eszembe jut az autóriasztók hajnala, amikor a gagyi áramkörök a hajnali harmat hatására dudáltak. ;) Nem kellett 10 év, és az olaszoknál kimondták: A dilettáns áramkör nem mentesít a felelősség alól - akkor is fizetned kell a csendháborításért. :-D