{"id":1186,"date":"2014-08-26T16:43:46","date_gmt":"2014-08-26T15:43:46","guid":{"rendered":"http:\/\/www.leonardomiliani.com\/?p=1186"},"modified":"2014-08-26T21:50:07","modified_gmt":"2014-08-26T20:50:07","slug":"gestire-3-pulsanti-con-2-soli-pin","status":"publish","type":"post","link":"https:\/\/leonardomiliani.com\/?p=1186","title":{"rendered":"Gestire 3 pulsanti con 2 soli pin"},"content":{"rendered":"<p>Stamani ero al computer senza nulla da fare, e stavo ragionando su un progetto. Facevo la conta dei pin\u00a0che mi servivano, cercando di ottimizzarne l&#8217;uso,\u00a0visto che avevo a che fare con dei pulsanti da far premere all&#8217;utente, e mi \u00e8 sorta la domanda: c&#8217;\u00e8 un modo semplice per risparmiare pin quando si ha a che fare con i pulsanti? Normalmente si usano chip esterni, dei port expander o degli shift register PISO (Parallel In &#8211; Serial Out)\u00a0, per poter gestire pi\u00f9 linee di I\/O. Ma se io volessi fare tutto con poca roba, con quei componenti che normalmente si hanno nel cassetto, senza acquistare chip appositi?\u00a0La soluzione che vi propongo \u00e8 tanto semplice quanto banale: con 2 pin riuscirete a leggere\u00a03 pulsanti.<\/p>\n<p><!--more--><\/p>\n<p>Avete mai sentito parlare di charlieplexing? Si tratta di una tecnica mediante la quale si riescono a pilotare molti LED usando pochi pin e sfruttando la capacit\u00e0 dei LED di condurre in una sola direzione (alla fine, sono dei diodi). Ho rigirato il problema: perch\u00e9 non usare un qualche sistema che mi permette di\u00a0leggere pi\u00f9 ingressi usando pochi pin sfruttando dei componenti che conducono in una sola direzione? Usando quindi dei&#8230; <strong>diodi<\/strong>? Il diodo \u00e8 un semiconduttore\u00a0che permette far scorrere la corrente in un unico verso.\u00a0Se ne accoppio due con i catodi in comune, la corrente scorrer\u00e0 solo verso il nodo, il punto in comune, ma non da uno all&#8217;altro. Quindi se ad esempio\u00a0ho\u00a0due pin impostati in input e connessi da 2 diodi uniti come detto, se collego il primo pin a massa, legger\u00f2 lo stato LOW solo da questo pin perch\u00e9 l&#8217;altro sar\u00e0 isolato dal diodo polarizzato inversamente. Stessa cosa per il secondo pin. E se collego a massa il nodo comune, il punto di giunzione dei 2 diodi? Leggere uno stato LOW su entrambi i pin, perch\u00e9 entrambi i pin saranno collegati a massa dal corrispondente diodo polarizzato. Ecco quindi l&#8217;idea che mi ha portato allo schema seguente:<\/p>\n<p><a href=\"http:\/\/www.leonardomiliani.com\/wp-content\/uploads\/2014\/08\/schema.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-medium wp-image-1187\" src=\"http:\/\/www.leonardomiliani.com\/wp-content\/uploads\/2014\/08\/schema-300x214.png\" alt=\"3 buttons 2 pins\" width=\"300\" height=\"214\" srcset=\"https:\/\/leonardomiliani.com\/wp-content\/uploads\/2014\/08\/schema-300x214.png 300w, https:\/\/leonardomiliani.com\/wp-content\/uploads\/2014\/08\/schema.png 395w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><\/p>\n<p>Proviamo\u00a0il circuito. Avete bisogno di:<\/p>\n<ul>\n<li>una breadboard<\/li>\n<li>2 diodi (vanno benissimo i comuni 1N4007, oppure anche i diodi veloci 1N4148 cos\u00ec come degli Schottky 1N5819)<\/li>\n<li>3 pulsanti di tipo da montaggio superficiale<\/li>\n<li>cavetti<\/li>\n<li>una scheda Arduino (UNO, Leonardo)<\/li>\n<\/ul>\n<p>Realizziamo i collegamenti come nel disegno seguente (realizzato con Fritzing):<\/p>\n<p><a href=\"http:\/\/www.leonardomiliani.com\/wp-content\/uploads\/2014\/08\/3_btns_2_pins.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-medium wp-image-1188\" src=\"http:\/\/www.leonardomiliani.com\/wp-content\/uploads\/2014\/08\/3_btns_2_pins-271x300.jpg\" alt=\"3 buttons 2 pins -circuit\" width=\"271\" height=\"300\" srcset=\"https:\/\/leonardomiliani.com\/wp-content\/uploads\/2014\/08\/3_btns_2_pins-271x300.jpg 271w, https:\/\/leonardomiliani.com\/wp-content\/uploads\/2014\/08\/3_btns_2_pins-925x1024.jpg 925w, https:\/\/leonardomiliani.com\/wp-content\/uploads\/2014\/08\/3_btns_2_pins-900x995.jpg 900w, https:\/\/leonardomiliani.com\/wp-content\/uploads\/2014\/08\/3_btns_2_pins.jpg 1114w\" sizes=\"auto, (max-width: 271px) 100vw, 271px\" \/><\/a><\/p>\n<p>Montate i 3 pulsanti centralmente, poi collegate i loro piedini posti in alto a destra sulla linea di massa superiore. Collegate la linea di massa superiore con quella inferiore. Collegate il piedino in basso a sinistra del pulsante di sinistra con i piedino in basso a sinistra del pulsante centrale usando uno dei due diodi: il catodo (il lato segnato con la linea di colore bianca) va a destra. Adesso collegate il piedino in basso a sinistra del pulsante di destra con il piedino in basso a sinistra del pulsante centrale usando l&#8217;altro diodo, avendo l&#8217;accortezza di rispettare la polarit\u00e0 indicata nel disegno: come nell&#8217;altro diodo, il catodo va posto verso il pulsante centrale, quindi il diodo questa volta deve stare con il corpo che presenta la riga bianca a sinistra.\u00a0Collegate il piedino in basso a sinistra del pulsante di sinistra al pin 7 di Arduino ed il piedino in basso a sinistra del pulsante di destra al pin 6 di Arduino. L&#8217;ultimo collegamento va fatto fra un pin GND di Arduino e la linea inferiore di massa\u00a0della breadboard. Come si vede dallo schema, non usiamo resistenze esterne di pull-up o di pull-down: questa \u00e8 una scelta precisa fatta per risparmiare componenti. Per dare uno stato ben definito ai pulsanti non premuti useremo perci\u00f2 le pull-up interne presente su tutti i pin digitali dell&#8217;Arduino. A causa di questa scelta, dovremo usare nella funzione che legge i pulsanti la logica inversa, dato che uno stato HIGH sul pin corrisponder\u00e0 ad un pulsante non premuto mentre uno stato LOW ad un pulsante premuto. Non preoccupatevi: la funzione esegue la conversione per voi.<\/p>\n<p>Adesso caricate il seguente sketch:<\/p>\n<pre><span style=\"background-color: #00ccff;\">\/* HOW TO READ 3 BUTTONS USING JUST 2 PIN\r\n  Written by Leonardo Miliani\r\n\r\n  Code released under the Creative Commons License\r\n  CC-BY-SA 3.0 or any newer \r\n\r\n  V. 1.0 - 20140826\r\n*\/\r\n\r\n\/\/pins declaration - use any pin you like\r\nconst byte IN1 = 6;\r\nconst byte IN2 = 7;\r\n\r\n\/\/setup function\r\nvoid setup() {\r\n  \/\/setting the mode of the pins\r\n  pinMode(IN1, INPUT_PULLUP);\r\n  pinMode(IN2, INPUT_PULLUP);\r\n\r\n  Serial.begin(19200); \/\/opening the serial\r\n  delay(2000); \/\/a little delay to let the user open the serial monitor\r\n  Serial.println(F(\"Begin\"));\r\n}\r\n\r\n\/\/main loop\r\nvoid loop() {\r\n  byte reading = readButtons(IN1, IN2); \/\/read the buttons\r\n \r\n  if (reading) { \/\/a button has been pressed\r\n    switch(readButtons(IN1, IN2)) {\r\n      case 1: \/\/button 1 pressed\r\n        Serial.println(F(\"Button 1 pressed\"));\r\n        break;\r\n      case 2: \/\/button 2 pressed\r\n        Serial.println(F(\"Button 2 pressed\"));\r\n        break;\r\n      case 3: \/\/button 3 pressed\r\n        Serial.println(F(\"Button 3 pressed\"));\r\n        break;\r\n    }\r\n  }\r\n  delay(100); \/\/a little delay - remove if unnecessary\r\n}\r\n\r\n\/\/read the buttons\r\nbyte readButtons(byte inputPin1, byte inputPin2) {\r\n  byte response = 0;\r\n \r\n  \/\/I'm using the inverted logic so I do a \"not\" (!) to the digital read\r\n  \/\/then I combine the readings in a sngle bit using the 2 binary digits\r\n  response = (((!digitalRead(inputPin1))&lt;&lt;1) | !digitalRead(inputPin2));\r\n  return response;\r\n}<\/span><\/pre>\n<p>Come funziona il sistema? Come detto, il cuore di tutto sono i 2 diodi. In stato di riposo (nessun pulsante premuto), la funzione readButtons che legge i 2 pin a cui \u00e8 connessa la matrice di pulsanti vedr\u00e0 i due ingressi in HIGH (o 1). Ma a noi serve la logica inversa, perch\u00e9 vogliamo che un pulsante non premuto corrisponda ad una lettura LOW (o 0). Per far ci\u00f2 usiamo il segno di negazione del C, il &#8220;<strong>!<\/strong>&#8220;, che restituisce l&#8217;opposto del valore: 0 per 1 e 1 per 0. Uniamo poi le due letture in un&#8217;unica coppia di valori binari usando lo spostamento a sinistra (&lt;&lt;). Il valore che ne esce \u00e8 il valore restituito dalla funzione.\u00a0Quando premiamo il pulsante a sinistra sulla breadboard solo il pin a cui \u00e8 agganciato direttamente (il pin 7 di Arduino) verr\u00e0 collegato a massa, grazie al diodo polarizzato inversamente che lo unisce al pulsante centrale. Stessa cosa per il pulsante a destra. Quindi in entrambi i casi la funzione readButtons, che legge i 2 pin dichiarati nel programma,\u00a0vedr\u00e0 una sola pressione.\u00a0Se premiamo invece il pulsante centrale le cose cambiano: per effetto dei diodi polarizzati direttamente, entrambi i pin verranno collegati a massa.<\/p>\n<p>La tabella della verit\u00e0 della funzione \u00e8 perci\u00f2 la seguente:<\/p>\n<pre>PIN1 \u00a0PIN2  \u00a0LETTURA<\/pre>\n<pre>\u00a01 \u00a0  \u00a00 \u00a0\u00a0  PULSANTE 1<\/pre>\n<pre>\u00a00 \u00a0  \u00a01 \u00a0   PULSANTE 2<\/pre>\n<pre>\u00a01 \u00a0  \u00a01 \u00a0 \u00a0 PULSANTE 3<\/pre>\n<p>&nbsp;<\/p>","protected":false},"excerpt":{"rendered":"<p>Stamani ero al computer senza nulla da fare, e stavo ragionando su un progetto. Facevo la conta dei pin\u00a0che mi&#46;&#46;&#46;<\/p>\n","protected":false},"author":193,"featured_media":1187,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[14],"tags":[],"class_list":["post-1186","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-arduino"],"_links":{"self":[{"href":"https:\/\/leonardomiliani.com\/index.php?rest_route=\/wp\/v2\/posts\/1186","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/leonardomiliani.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/leonardomiliani.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/leonardomiliani.com\/index.php?rest_route=\/wp\/v2\/users\/193"}],"replies":[{"embeddable":true,"href":"https:\/\/leonardomiliani.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1186"}],"version-history":[{"count":5,"href":"https:\/\/leonardomiliani.com\/index.php?rest_route=\/wp\/v2\/posts\/1186\/revisions"}],"predecessor-version":[{"id":1193,"href":"https:\/\/leonardomiliani.com\/index.php?rest_route=\/wp\/v2\/posts\/1186\/revisions\/1193"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/leonardomiliani.com\/index.php?rest_route=\/wp\/v2\/media\/1187"}],"wp:attachment":[{"href":"https:\/\/leonardomiliani.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1186"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/leonardomiliani.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1186"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/leonardomiliani.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1186"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}