Porte logiche: AND, OR, NOT, XOR, tabelle di verità e Arduino
Cosa sono le porte logiche? AND, OR, NOT, NAND, NOR e XOR: simboli, tabelle di verità, integrati 74HC08 e 74HC00, semisommatore e codice Arduino ed ESP32.
Le porte logiche sono i mattoni fondamentali dei circuiti digitali: ognuna osserva uno o più ingressi digitali e produce un'unica uscita digitale secondo una regola fissa. Gli ingressi possono valere solo 0 (LOW) o 1 (HIGH), e lo stesso vale per l'uscita. Le porte di base sono sette: AND, OR, NOT, NAND, NOR, XOR e XNOR. Dal processore del tuo smartphone alla scheda di una lavatrice, dall'ATmega328P di un Arduino a una calcolatrice tascabile, ogni dispositivo digitale funziona combinando milioni di minuscole porte logiche.
In questa guida imparerai il simbolo e la tabella di verità di ogni porta, integrati reali come il 74HC08, il 74HC32 e il 74HC00, un esperimento con due pulsanti sulla breadboard, come costruire tutte le altre porte usando solo NAND e il circuito semisommatore che somma due bit. Nelle ultime sezioni tradurremo la stessa logica in codice su Arduino con gli operatori &&, || e ! e con le operazioni bit a bit, per poi proseguire con esempi per ESP32 e Raspberry Pi Pico (MicroPython).

Cos'è una porta logica e come funziona?
Nell'elettronica digitale ogni segnale si trova in uno di due stati: 1 (HIGH, vero) o 0 (LOW, falso). La matematica che lavora con questi due valori si chiama algebra di Boole; in un libro pubblicato nel 1854, George Boole espresse proprio così il ragionamento logico sotto forma di algebra. Nel 1937 Claude Shannon dimostrò che questa algebra corrisponde esattamente ai circuiti di commutazione a relè, gettando le basi della progettazione dei circuiti digitali. Oggi una porta logica contiene solo pochi transistor: in tecnologia CMOS una porta NOT è formata da 2 MOSFET e una NAND da 4. Spieghiamo come funziona un transistor usato come interruttore in Cos'è un transistor?.
Ma quale tensione il circuito considera 1 e quale 0? Dipende dalla tensione di alimentazione della scheda e dalla famiglia dell'integrato. La tabella qui sotto mostra le soglie oltre le quali un ingresso viene riconosciuto con certezza come 1 o come 0. La zona tra le due soglie è la zona indefinita; se un ingresso resta lì, l'uscita può comportarsi in modo casuale. Un ingresso non collegato a nulla, cioè un ingresso flottante, vaga proprio in questa zona. Per questo ogni ingresso deve essere collegato a un segnale, oppure a GND o VCC tramite una resistenza.
| Scheda / famiglia | Alimentazione | Ingresso riconosciuto come 1 | Ingresso riconosciuto come 0 |
|---|---|---|---|
| Arduino Uno (ATmega328P) | 5 V | ≥ 3,0 V | ≤ 1,5 V |
| ESP32 | 3,3 V | ≥ 2,5 V | ≤ 0,8 V |
| Raspberry Pi Pico (RP2040) | 3,3 V | ≥ 2,0 V | ≤ 0,8 V |
| Integrato 74HC | 5 V | ≥ 3,5 V | ≤ 1,5 V |
| Integrato 74HCT | 5 V | ≥ 2,0 V | ≤ 0,8 V |
| Integrato CD4000 | 5 V | ≥ 3,5 V | ≤ 1,5 V |
Le 7 porte logiche fondamentali e i loro simboli
Negli schemi le porte vengono disegnate secondo due norme diverse. Nella norma americana (ANSI/IEEE) ogni porta ha una forma propria: AND assomiglia a una lettera D, OR a uno scudo appuntito e NOT a un triangolo. Il piccolo cerchio sull'uscita significa "inverti"; una NAND è quindi una AND con un cerchio sulla punta. A distinguere la XOR dalla OR è la seconda linea curva sul lato degli ingressi. Nella norma europea (IEC) tutte le porte sono rettangoli e si riconoscono dal simbolo scritto all'interno: & per AND, ≥1 per OR, =1 per XOR e 1 per NOT. Nei libri di testo troverai anche XOR chiamata OR esclusivo e XNOR chiamata NOR esclusivo.
| Porta | Nome italiano | Simbolo ANSI | Segno IEC | Espressione booleana | Quando l'uscita vale 1? |
|---|---|---|---|---|---|
| AND | E (prodotto logico) | Forma a D | & | Y = A · B | Entrambi gli ingressi valgono 1 |
| OR | O (somma logica) | Scudo appuntito | ≥1 | Y = A + B | Almeno un ingresso vale 1 |
| NOT | Negazione (invertitore) | Triangolo + cerchio | 1 (cerchio in uscita) | Y = A' | L'ingresso vale 0 |
| NAND | AND negata | Forma a D + cerchio | & (cerchio in uscita) | Y = (A · B)' | Almeno un ingresso vale 0 |
| NOR | OR negata | Scudo + cerchio | ≥1 (cerchio in uscita) | Y = (A + B)' | Entrambi gli ingressi valgono 0 |
| XOR | OR esclusivo | Scudo a doppia curva | =1 | Y = A ⊕ B | Gli ingressi sono diversi |
| XNOR | NOR esclusivo | Doppia curva + cerchio | =1 (cerchio in uscita) | Y = (A ⊕ B)' | Gli ingressi sono uguali |
Tabelle di verità delle porte logiche
Una tabella di verità elenca l'uscita di una porta per ogni combinazione dei suoi ingressi. Una porta con n ingressi ha 2ⁿ righe: 4 righe con due ingressi, 8 con tre e 16 con quattro. Se scrivi le righe nell'ordine del conteggio binario (00, 01, 10, 11), non salterai mai una combinazione. Ecco tutte e sei le porte a due ingressi in un'unica tabella:
| A | B | AND | OR | NAND | NOR | XOR | XNOR |
|---|---|---|---|---|---|---|---|
| 0 | 0 | 0 | 0 | 1 | 1 | 0 | 1 |
| 0 | 1 | 0 | 1 | 1 | 0 | 1 | 0 |
| 1 | 0 | 0 | 1 | 1 | 0 | 1 | 0 |
| 1 | 1 | 1 | 1 | 0 | 0 | 0 | 1 |
Poiché la porta NOT ha un solo ingresso, la sua tabella ha due righe: con A = 0 l'uscita è 1, con A = 1 l'uscita è 0. Osservando bene la tabella noterai uno schema: la colonna NAND è esattamente l'opposto di AND, NOR l'opposto di OR e XNOR l'opposto di XOR. Per memorizzarle usa queste regole brevi: AND chiede "sono tutti 1?", OR "ce n'è almeno uno a 1?" e XOR "gli ingressi sono diversi?"; la porta il cui nome inizia con N dà la risposta opposta alla stessa domanda. Per provare le porte da solo e vedere i simboli dal vivo, basta toccare gli ingressi A e B nello strumento Porte logiche.
- AND: Due interruttori in serie. La lampada si accende solo quando entrambi sono chiusi; anche una cassaforte di banca che si apre con due chiavi diverse segue la regola AND.
- OR: Due pulsanti in parallelo. Suona lo stesso campanello sia che si prema il pulsante della porta d'ingresso sia quello della porta sul retro.
- NOT: La luce del frigorifero. Con la porta chiusa l'interruttore è premuto e la luce spenta; quando la porta si apre l'interruttore viene rilasciato e la luce si accende.
- NAND: La regola "avvisa se non è tutto a posto". Se anche solo una delle due protezioni di una macchina è aperta, si accende la spia di allarme.
- NOR: La regola "non è successo niente". Una spia verde di "tutto in ordine" che si accende solo se non viene rilevato né fumo né gas.
- XOR: L'impianto con deviatori di una scala. Azionando il deviatore in basso o quello in alto cambia lo stato della lampada; la lampada è accesa quando i due deviatori sono in posizioni diverse e spenta quando coincidono.
- XNOR: Un controllo di uguaglianza. Dà 1 quando due bit sono uguali; si usa nei comparatori digitali e nei circuiti di rilevamento degli errori.
Integrati di porte logiche: 74HC08, 74HC32, 74HC00
Invece di costruire le porte logiche transistor per transistor, si usano integrati già pronti. La famiglia più diffusa nell'elettronica hobbistica è la serie 74HC: un contenitore DIP a 14 piedini contiene quattro porte a due ingressi, l'alimentazione va sempre al piedino 14 (VCC) e la massa al piedino 7 (GND). I 74HC funzionano da 2 a 6 V, i loro ingressi non assorbono quasi corrente e a 5 V una porta ha un ritardo di circa 10 nanosecondi, centinaia di volte più veloce di una singola chiamata digitalWrite su Arduino. Ogni uscita mantiene i livelli di tensione garantiti con un carico di 4 mA; il limite assoluto è di 25 mA per uscita e 50 mA per l'intero integrato.
| Integrato | Porta | Contenuto | Piedinatura | Equivalente CMOS 4000 |
|---|---|---|---|---|
| 74HC08 | AND | 4 × 2 ingressi | Standard (tabella sotto) | CD4081 |
| 74HC32 | OR | 4 × 2 ingressi | Standard | CD4071 |
| 74HC00 | NAND | 4 × 2 ingressi | Standard | CD4011 |
| 74HC86 | XOR | 4 × 2 ingressi | Standard | CD4070 |
| 74HC02 | NOR | 4 × 2 ingressi | Diversa: uscite su 1, 4, 10, 13 | CD4001 |
| 74HC04 | NOT | 6 × 1 ingresso | Ingressi su 1, 3, 5, 9, 11, 13 | CD4069 |
| 74HC14 | NOT (trigger di Schmitt) | 6 × 1 ingresso | Uguale al 74HC04 | CD40106 |
| CD4077 / 74HCS7266 | XNOR | 4 × 2 ingressi | Raro; di solito 74HC86 + 74HC04 | CD4077 |
74HC08, 74HC32, 74HC00 e 74HC86 hanno esattamente la stessa piedinatura; cambia solo il tipo di porta all'interno. La tacca o il puntino sulla parte superiore indica il piedino 1. Guardando l'integrato dall'alto con la tacca a sinistra, i piedini sono numerati in senso antiorario: la fila inferiore da sinistra a destra da 1 a 7, quella superiore da destra a sinistra da 8 a 14. A e B sono gli ingressi, Y l'uscita, e la cifra davanti indica il numero della porta.
| Piedino | Funzione | Piedino | Funzione |
|---|---|---|---|
| 1 | 1A (ingresso porta 1) | 14 | VCC (+2…6 V) |
| 2 | 1B (ingresso porta 1) | 13 | 4B (ingresso porta 4) |
| 3 | 1Y (uscita porta 1) | 12 | 4A (ingresso porta 4) |
| 4 | 2A (ingresso porta 2) | 11 | 4Y (uscita porta 4) |
| 5 | 2B (ingresso porta 2) | 10 | 3B (ingresso porta 3) |
| 6 | 2Y (uscita porta 2) | 9 | 3A (ingresso porta 3) |
| 7 | GND | 8 | 3Y (uscita porta 3) |
Gli integrati che svolgono la stessa funzione esistono in diverse famiglie. La serie 74LS è la vecchia tecnologia TTL: funziona solo tra 4,75 e 5,25 V, assorbe più corrente e di solito legge come 1 un ingresso flottante. La serie 74HCT è un 74HC con ingressi compatibili TTL; si alimenta a 5 V ma riconosce come 1 sicuro già 2 V, quindi legge senza problemi i segnali a 3,3 V di un ESP32 o di un Pico. La serie CD4000 (CD4081, CD4011 e così via) lavora in un ampio intervallo di 3–18 V, ma è più lenta e ha una piedinatura diversa dai 74HC: un CD4011 non può sostituire direttamente un 74HC00.
Esperimento con pulsanti sulla breadboard: porta AND con il 74HC08
Il modo migliore per capire una porta logica è provarla di persona con due pulsanti. In questo esperimento non c'è nessun microcontrollore; ti servono solo un 74HC08, due pulsanti, due resistenze da 10 kΩ, una da 1 kΩ, un LED e un condensatore da 100 nF. Per l'alimentazione vanno bene i pin 5V e GND di un Arduino, un modulo di alimentazione per breadboard o tre pile AA (4,5 V). Se non sei sicuro dei collegamenti interni della breadboard, leggi prima Cos'è una breadboard?.

- Posiziona il 74HC08 a cavallo del canale centrale della breadboard, con i piedini sui due lati e la tacca rivolta a sinistra.
- Collega il piedino 14 alla linea + (5 V) e il piedino 7 alla linea − (GND), poi metti il condensatore da 100 nF tra questi due piedini.
- Collega un lato del pulsante A alla linea + e l'altro al piedino 1. Aggiungi una resistenza da 10 kΩ dallo stesso piedino verso GND: questa resistenza di pull-down tiene l'ingresso saldamente a 0 finché il pulsante non è premuto.
- Collega il pulsante B al piedino 2 nello stesso modo e dagli la sua resistenza di pull-down da 10 kΩ.
- Dal piedino 3, l'uscita, passa attraverso una resistenza da 1 kΩ fino al piedino lungo del LED (anodo); collega il piedino corto (catodo) a GND.
- Collega a GND gli ingressi inutilizzati, i piedini 4, 5, 9, 10, 12 e 13; lascia libere le uscite 6, 8 e 11.
- Dai alimentazione e prova le quattro combinazioni una dopo l'altra: il LED deve accendersi solo quando premi entrambi i pulsanti insieme. Confronta i risultati con la tabella di verità.
| Collegamento | Piedino del 74HC08 | Da collegare a |
|---|---|---|
| Alimentazione | 14 (VCC) | Linea +, 5 V |
| Massa | 7 (GND) | Linea − |
| Condensatore di disaccoppiamento | Tra 14 e 7 | 100 nF ceramico, vicino all'integrato |
| Ingresso A | 1 | Pulsante A → 5 V, 10 kΩ → GND |
| Ingresso B | 2 | Pulsante B → 5 V, 10 kΩ → GND |
| Uscita | 3 | 1 kΩ → anodo del LED, catodo → GND |
| Ingressi inutilizzati | 4, 5, 9, 10, 12, 13 | GND |
| Uscite inutilizzate | 6, 8, 11 | Libere |
Costruire ogni porta con le NAND: la porta universale
La NAND è chiamata porta universale perché con sole porte NAND puoi costruire qualsiasi altra porta. C'è anche un motivo pratico: in tecnologia CMOS la NAND è una delle porte più semplici, con soli 4 transistor, mentre una AND è in realtà una NAND seguita da una NOT e ne richiede 6. Ecco perché i progettisti di chip amano la NAND. Anche la memoria NAND flash delle chiavette USB deve il suo nome al fatto che le sue celle sono collegate in serie, come i transistor di una porta NAND. Anche la NOR è universale: l'Apollo Guidance Computer che volò verso la Luna fu costruito con circa 2.800 integrati, ognuno con due porte NOR a tre ingressi.
| Porta da ottenere | Come con le NAND? | NAND necessarie |
|---|---|---|
| NOT | A NAND A (unisci i due ingressi) | 1 |
| AND | Fai passare l'uscita di (A NAND B) in una NOT | 2 |
| OR | (A NAND A) NAND (B NAND B) | 3 |
| NOR | OR + NOT | 4 |
| XOR | N1 = A NAND B; (A NAND N1) NAND (B NAND N1) | 4 |
| XNOR | XOR + NOT | 5 |
La riga OR della tabella si basa sulla legge di De Morgan: (A' · B')' = A + B. In altre parole, se prima inverti ciascun ingresso e poi li mandi in una NAND, ottieni una OR. La seconda legge di De Morgan è (A + B)' = A' · B'. Entrambe ti aiutano anche a semplificare le condizioni nel codice: su Arduino, !(a && b) dà sempre lo stesso risultato di (!a || !b), e !(a || b) lo stesso di (!a && !b).
Costruire una XOR con quattro porte NAND è un classico esercizio d'esame e di laboratorio, e le quattro porte di un solo 74HC00 bastano esattamente. Prima si calcola N1 = A NAND B. Poi si ricavano N2 = A NAND N1 e N3 = B NAND N1, e l'uscita dell'ultima porta, Y = N2 NAND N3, dà la XOR. Con il cablaggio qui sotto puoi trasformare l'esperimento sulla breadboard in una XOR a quattro NAND:
| Piedino del 74HC00 | Collegamento | Funzione |
|---|---|---|
| 1 e 4 | Pulsante A | Ingresso A (porte 1 e 2) |
| 2 e 10 | Pulsante B | Ingresso B (porte 1 e 3) |
| 3 → 5 e 9 | Cavetto | N1 = A NAND B |
| 6 → 12 | Cavetto | N2 = A NAND N1 |
| 8 → 13 | Cavetto | N3 = B NAND N1 |
| 11 | 1 kΩ + LED | Y = A XOR B |
| 14 / 7 | 5 V / GND | Alimentazione |
Facciamo un passo in più: se colleghi in modo incrociato le uscite di due porte NAND all'ingresso dell'altra, ottieni una memoria da 1 bit chiamata latch SR. Questo circuito ricorda il suo ultimo stato anche quando rilasci il pulsante. I registri dei processori, i contatori e integrati come lo shift register 74HC595 nascono mettendo in fila celle di memoria di questo tipo, costruite con le porte.
Il semisommatore (half adder): sommare due bit con le porte
La cosa più sorprendente che sanno fare le porte logiche è sommare. In binario 0 + 0 = 0, 0 + 1 = 1, 1 + 0 = 1 e 1 + 1 = 10 (2 in decimale). La cifra destra del risultato si chiama somma e quella che trabocca verso sinistra riporto (carry). Guardando la tabella qui sotto vedrai che la somma è esattamente una XOR e il riporto esattamente una AND. Quindi una porta XOR e una AND affiancate formano un semisommatore che somma due numeri da un bit.
| A | B | Riporto (C = A AND B) | Somma (S = A XOR B) | Risultato decimale |
|---|---|---|---|---|
| 0 | 0 | 0 | 0 | 0 |
| 0 | 1 | 0 | 1 | 1 |
| 1 | 0 | 0 | 1 | 1 |
| 1 | 1 | 1 | 0 | 2 (binario 10) |
Per montarlo sulla breadboard, collega i pulsanti A e B ai piedini 1 e 2 sia di un 74HC86 sia di un 74HC08. Il piedino 3 del 74HC86 pilota il LED della somma, il piedino 3 del 74HC08 quello del riporto. Premendo entrambi i pulsanti, il LED della somma si spegne e quello del riporto si accende: i LED mostrano il binario 10, cioè 2. Se vuoi usare solo un 74HC00, ti servono quattro NAND per la XOR e una quinta NAND che inverta N1 per ottenere il riporto; un semisommatore si costruisce quindi con 5 porte NAND.
Un semisommatore non può tenere conto del riporto proveniente dalla cifra precedente; per questo serve un sommatore completo (full adder). Le sue formule sono S = A ⊕ B ⊕ Cin e Cout = (A · B) + (Cin · (A ⊕ B)), cioè due semisommatori e una porta OR. Collegando in catena quattro sommatori completi, in modo che ognuno passi il riporto al successivo, ottieni un sommatore a 4 bit; l'integrato 74HC283 esegue la stessa somma a 4 bit, ma calcola i riporti con un circuito interno veloce (carry look-ahead) invece di aspettare che si propaghino lungo la catena. L'unità aritmetica del processore del tuo computer è una versione a 64 bit, molto più veloce, della stessa idea.
Porte logiche su Arduino: &&, ||, ! e operazioni bit a bit
Nel codice Arduino ogni porta logica ha due equivalenti. Gli operatori logici (&&, ||, !) combinano le condizioni e restituiscono true o false; li usi nelle istruzioni if e while. Gli operatori bit a bit (&, |, ^, ~), invece, agiscono contemporaneamente su tutti i bit di un numero, colonna per colonna; lavorare su un byte è come far funzionare otto porte insieme. Gli esempi della tabella usano i numeri 0b1100 e 0b1010:
| Porta | Logico (bool) | Bit a bit | Esempio | Risultato |
|---|---|---|---|---|
| AND | a && b | x & y | 0b1100 & 0b1010 | 0b1000 |
| OR | a || b | x | y | 0b1100 | 0b1010 | 0b1110 |
| NOT | !a | ~x | ~0b00001100 (byte) | 0b11110011 |
| NAND | !(a && b) | ~(x & y) | ~(0b1100 & 0b1010) & 0x0F | 0b0111 |
| NOR | !(a || b) | ~(x | y) | ~(0b1100 | 0b1010) & 0x0F | 0b0001 |
| XOR | a != b | x ^ y | 0b1100 ^ 0b1010 | 0b0110 |
| XNOR | a == b | ~(x ^ y) | ~(0b1100 ^ 0b1010) & 0x0F | 0b1001 |
La differenza tra i due tipi sembra piccola ma porta a errori subdoli. && e || usano la valutazione in cortocircuito: in a && b, se a è falso, b non viene nemmeno valutato. & valuta sempre entrambi i lati e guarda i bit dei numeri: 2 && 1 vale true, ma 2 & 1 vale 0, perché 0b10 e 0b01 non hanno bit in comune. Il C++ non ha un operatore XOR logico a sé; per due bool, scrivere a != b è la forma più leggibile. Per approfondire le operazioni bit a bit, gli scorrimenti << e >> e il sistema binario, leggi Sistemi di numerazione e operazioni bit a bit.
Ora portiamo l'esperimento della breadboard su un Arduino Uno. Due pulsanti vanno ai pin 2 e 3, sette LED (ognuno con una resistenza da 330 Ω) ai pin 4–10. Ogni pulsante ha un lato sul pin e l'altro su GND; dato che la resistenza di pull-up interna è attiva, non serve nessuna resistenza aggiuntiva. Un solo sketch dà vita contemporaneamente a tutte e sette le porte:
1// Mantık kapısı simülatörü: 2 buton, 7 LED / Logic gate simulator: 2 buttons, 7 LEDs
2const byte PIN_A = 2; // A butonu, diğer ucu GND / button A, other leg to GND
3const byte PIN_B = 3; // B butonu, diğer ucu GND / button B, other leg to GND
4
5// Sıra: AND, OR, NOT A, NAND, NOR, XOR, XNOR / Order: AND, OR, NOT A, NAND, NOR, XOR, XNOR
6const byte LED_PINS[7] = {4, 5, 6, 7, 8, 9, 10};
7const char* const GATE_NAMES[7] = {"AND", "OR", "NOT A", "NAND", "NOR", "XOR", "XNOR"};
8
9byte lastInputs = 0xFF; // ilk turda yazdırmayı zorlar / forces a print on the first pass
10
11void setup() {
12 pinMode(PIN_A, INPUT_PULLUP);
13 pinMode(PIN_B, INPUT_PULLUP);
14 for (byte i = 0; i < 7; i++) {
15 pinMode(LED_PINS[i], OUTPUT);
16 }
17 Serial.begin(9600);
18}
19
20void loop() {
21 // Basılı buton LOW okunur, ! ile 1 yapılır / A pressed button reads LOW, ! turns it into 1
22 bool a = !digitalRead(PIN_A);
23 bool b = !digitalRead(PIN_B);
24
25 bool out[7];
26 out[0] = a && b; // AND
27 out[1] = a || b; // OR
28 out[2] = !a; // NOT A
29 out[3] = !(a && b); // NAND
30 out[4] = !(a || b); // NOR
31 out[5] = a != b; // XOR: girişler farklı mı? / are the inputs different?
32 out[6] = a == b; // XNOR: girişler aynı mı? / are the inputs equal?
33
34 for (byte i = 0; i < 7; i++) {
35 digitalWrite(LED_PINS[i], out[i] ? HIGH : LOW);
36 }
37
38 // Yalnız girişler değişince yaz / Print only when the inputs change
39 byte inputs = (a << 1) | b;
40 if (inputs != lastInputs) {
41 Serial.print("A=");
42 Serial.print(a);
43 Serial.print(" B=");
44 Serial.print(b);
45 for (byte i = 0; i < 7; i++) {
46 Serial.print(" ");
47 Serial.print(GATE_NAMES[i]);
48 Serial.print('=');
49 Serial.print(out[i]);
50 }
51 Serial.println();
52 lastInputs = inputs;
53 }
54 delay(20); // basit sıçrama önleme / simple debounce
55}Con INPUT_PULLUP un pulsante premuto si legge LOW, quindi il codice inverte la lettura con ! e il pulsante premuto diventa 1. Ogni LED mostra poi il risultato della sua porta: 4 AND, 5 OR, 6 NOT A, 7 NAND, 8 NOR, 9 XOR e 10 XNOR. Se apri il Monitor seriale a 9600 baud, a ogni cambio di pulsante viene stampata l'intera riga; dopo aver provato tutte e quattro le combinazioni avrai ricavato la tabella di verità con le tue mani. I dettagli sulla logica pull-up sono in Come collegare un pulsante ad Arduino.
Per vedere la potenza delle operazioni bit a bit, il secondo esempio calcola tutta la tabella di verità in poche righe. Il trucco: se scrivi la colonna A come il numero 0b1100 e la colonna B come 0b1010, ogni bit corrisponde a una riga della tabella e un solo & ti dà in un colpo le quattro righe della colonna AND. La seconda metà dello sketch somma bit per bit due numeri a 4 bit con le formule del sommatore completo, imitando via software il circuito sommatore di un processore. Questo sketch non richiede hardware; basta aprire il Monitor seriale.
1// Bit işlemleriyle doğruluk tablosu ve 4 bitlik toplayıcı / Truth tables with bitwise ops and a 4-bit adder
2// Her bit bir satırdır: bit 0 = (A=0, B=0) ... bit 3 = (A=1, B=1) / Each bit is one row: bit 0 = (A=0, B=0) ... bit 3 = (A=1, B=1)
3const byte COL_A = 0b1100;
4const byte COL_B = 0b1010;
5const byte MASK = 0b1111; // yalnız 4 satır / only 4 rows
6
7void printRow(const char* name, byte column) {
8 Serial.print(name);
9 Serial.print('\t');
10 for (byte row = 0; row < 4; row++) {
11 Serial.print(bitRead(column, row)); // satır satır yaz / print row by row
12 Serial.print(" ");
13 }
14 Serial.println();
15}
16
17// Tam toplayıcı: iki bit + gelen elde / Full adder: two bits + carry in
18void fullAdder(byte a, byte b, byte carryIn, byte &sum, byte &carryOut) {
19 sum = a ^ b ^ carryIn; // XOR'lar toplamı verir / XORs give the sum
20 carryOut = (a & b) | (carryIn & (a ^ b)); // AND + OR eldeyi verir / AND + OR give the carry
21}
22
23// 4 tam toplayıcı zincirlenir (ripple carry) / 4 full adders chained (ripple carry)
24byte add4(byte x, byte y, byte &carryOut) {
25 byte result = 0;
26 byte carry = 0;
27 for (byte i = 0; i < 4; i++) {
28 byte s, c;
29 fullAdder(bitRead(x, i), bitRead(y, i), carry, s, c);
30 bitWrite(result, i, s);
31 carry = c;
32 }
33 carryOut = carry;
34 return result;
35}
36
37void setup() {
38 Serial.begin(9600);
39 Serial.println(F("AB:\t00 01 10 11"));
40 printRow("AND", COL_A & COL_B);
41 printRow("OR", COL_A | COL_B);
42 printRow("NAND", ~(COL_A & COL_B) & MASK); // ~ sonrası maske şart / mask is required after ~
43 printRow("NOR", ~(COL_A | COL_B) & MASK);
44 printRow("XOR", COL_A ^ COL_B);
45 printRow("XNOR", ~(COL_A ^ COL_B) & MASK);
46
47 byte carry;
48 byte s = add4(9, 12, carry); // 1001 + 1100
49 Serial.print(F("9 + 12 = "));
50 Serial.print(s + carry * 16); // elde 16'lar basamağıdır / the carry is the 16s place
51 Serial.print(F(" (toplam / sum = "));
52 Serial.print(s, BIN);
53 Serial.print(F(", elde / carry = "));
54 Serial.print(carry);
55 Serial.println(')');
56}
57
58void loop() {
59}Un tester per integrati 74HC con Arduino
Se la sigla di un integrato si è cancellata o vuoi sapere se funziona ancora, puoi trasformare Arduino in un tester. Questo sketch applica a turno le quattro combinazioni di ingresso a tutte e quattro le porte di un 74HC00, 74HC08, 74HC32 o 74HC86 (gli integrati con piedinatura standard), legge le uscite e confronta il risultato con schemi noti. Collega il piedino 14 dell'integrato a 5V, il piedino 7 a GND e gli altri ai pin di Arduino indicati nella tabella del codice.
1// 74HC00 / 08 / 32 / 86 tanıyıcı ve test cihazı / 74HC00 / 08 / 32 / 86 identifier and tester
2// Entegre: bacak 14 -> 5V, bacak 7 -> GND / Chip: pin 14 -> 5V, pin 7 -> GND
3// Her kapı: {A, B, Y} Arduino pinleri / Each gate: {A, B, Y} Arduino pins
4const byte GATES[4][3] = {
5 {2, 3, 4}, // kapı 1: entegre 1, 2 -> 3 / gate 1: chip 1, 2 -> 3
6 {5, 6, 7}, // kapı 2: entegre 4, 5 -> 6 / gate 2: chip 4, 5 -> 6
7 {8, 9, 10}, // kapı 3: entegre 9, 10 -> 8 / gate 3: chip 9, 10 -> 8
8 {11, 12, A0} // kapı 4: entegre 12, 13 -> 11 / gate 4: chip 12, 13 -> 11
9};
10
11// Desenin bit sırası: bit 0 = (0,0), bit 3 = (1,1) / Pattern bit order: bit 0 = (0,0), bit 3 = (1,1)
12const char* nameOf(byte pattern) {
13 switch (pattern) {
14 case 0b1000: return "AND (74HC08)";
15 case 0b1110: return "OR (74HC32)";
16 case 0b0111: return "NAND (74HC00)";
17 case 0b0110: return "XOR (74HC86)";
18 default: return "?";
19 }
20}
21
22byte testGate(byte g) {
23 byte pattern = 0;
24 for (byte row = 0; row < 4; row++) {
25 digitalWrite(GATES[g][0], bitRead(row, 1)); // A = satırın üst biti / A = high bit of the row
26 digitalWrite(GATES[g][1], bitRead(row, 0)); // B = satırın alt biti / B = low bit of the row
27 delayMicroseconds(10); // kapı ~10 ns gecikir, bol pay / the gate needs ~10 ns, plenty of margin
28 bitWrite(pattern, row, digitalRead(GATES[g][2]));
29 }
30 return pattern;
31}
32
33void setup() {
34 Serial.begin(9600);
35 for (byte g = 0; g < 4; g++) {
36 pinMode(GATES[g][0], OUTPUT);
37 pinMode(GATES[g][1], OUTPUT);
38 pinMode(GATES[g][2], INPUT);
39 }
40
41 byte first = testGate(0);
42 bool allSame = true;
43 for (byte g = 0; g < 4; g++) {
44 byte p = testGate(g);
45 Serial.print(F("Kapi / Gate "));
46 Serial.print(g + 1);
47 Serial.print(F(": "));
48 Serial.print(nameOf(p));
49 Serial.print(F(" desen / pattern 0b"));
50 Serial.println(p, BIN);
51 if (p != first) allSame = false;
52 }
53
54 if (allSame && nameOf(first)[0] != '?') {
55 Serial.println(F("Sonuc / Result: entegre saglam / chip OK"));
56 } else {
57 Serial.println(F("Sonuc / Result: bozuk kapi ya da baglanti hatasi / faulty gate or wiring error"));
58 }
59}
60
61void loop() {
62}Una porta logica programmabile con l'ESP32
Sull'ESP32 gli stessi operatori funzionano senza modifiche. In questo esempio un terzo pulsante fa scorrere i tipi di porta e un solo LED mostra l'uscita della porta scelta. Così puoi mostrare sei porte con un unico circuito in classe o durante una presentazione. I pulsanti vanno su GPIO 25, 26 e 27 (l'altro lato su GND) e il LED su GPIO 23 tramite una resistenza da 220 Ω; il nome della porta scelta compare nel Monitor seriale a 115200 baud.
1// ESP32 programlanabilir mantık kapısı / ESP32 programmable logic gate
2const int PIN_A = 25; // A butonu, diğer ucu GND / button A, other leg to GND
3const int PIN_B = 26; // B butonu / button B
4const int PIN_MODE = 27; // kapı seçme butonu / gate select button
5const int PIN_LED = 23; // çıkış LED'i (220 ohm) / output LED (220 ohm)
6
7const char* const NAMES[] = {"AND", "OR", "NAND", "NOR", "XOR", "XNOR"};
8const int GATE_COUNT = 6;
9const unsigned long DEBOUNCE_MS = 30; // sıçrama süresi / bounce time
10
11int gate = 0;
12int modeStable = HIGH; // kararlı buton durumu / stable button state
13int modeRaw = HIGH; // son ham okuma / last raw reading
14unsigned long modeChangedAt = 0; // ham değerin son değiştiği an / when the raw value last changed
15
16bool evaluate(int g, bool a, bool b) {
17 switch (g) {
18 case 0: return a && b;
19 case 1: return a || b;
20 case 2: return !(a && b);
21 case 3: return !(a || b);
22 case 4: return a != b; // XOR
23 default: return a == b; // XNOR
24 }
25}
26
27void setup() {
28 Serial.begin(115200);
29 pinMode(PIN_A, INPUT_PULLUP);
30 pinMode(PIN_B, INPUT_PULLUP);
31 pinMode(PIN_MODE, INPUT_PULLUP);
32 pinMode(PIN_LED, OUTPUT);
33 Serial.printf("Kapi / Gate: %s\n", NAMES[gate]);
34}
35
36void loop() {
37 int reading = digitalRead(PIN_MODE);
38 if (reading != modeRaw) { // ham değer değişti, süreyi yeniden başlat / raw value changed, restart the timer
39 modeRaw = reading;
40 modeChangedAt = millis();
41 }
42 // 30 ms boyunca sabit kaldıysa gerçek değişimdir / steady for 30 ms means a real change
43 if (millis() - modeChangedAt > DEBOUNCE_MS && reading != modeStable) {
44 modeStable = reading;
45 if (modeStable == LOW) { // yeni basış (bırakma sayılmaz) / new press (release is ignored)
46 gate = (gate + 1) % GATE_COUNT;
47 Serial.printf("Kapi / Gate: %s\n", NAMES[gate]);
48 }
49 }
50
51 bool a = !digitalRead(PIN_A); // basılı = 1 / pressed = 1
52 bool b = !digitalRead(PIN_B);
53 digitalWrite(PIN_LED, evaluate(gate, a, b) ? HIGH : LOW);
54}Porte logiche con Raspberry Pi Pico e MicroPython
In MicroPython gli operatori logici si scrivono con parole inglesi: and, or, not. Gli operatori bit a bit sono gli stessi del C++: &, |, ^ e ~. Il codice seguente legge due pulsanti su GP14 e GP15 e mostra i risultati di AND, OR, NAND, NOR, XOR e XNOR su sei LED collegati a GP16–GP21. L'altro lato di ogni pulsante va a GND e ogni LED è collegato tramite una resistenza da 220–330 Ω. Se salvi il codice in Thonny come main.py, viene eseguito a ogni accensione del Pico; se sei alle prime armi con il Pico, parti da Cos'è il Raspberry Pi Pico?.
1# Pico ile 6 mantık kapısı / 6 logic gates on the Pico
2from machine import Pin
3import time
4
5btn_a = Pin(14, Pin.IN, Pin.PULL_UP) # A butonu, diğer ucu GND / button A, other leg to GND
6btn_b = Pin(15, Pin.IN, Pin.PULL_UP) # B butonu / button B
7
8# GP16..GP21: AND, OR, NAND, NOR, XOR, XNOR
9leds = [Pin(n, Pin.OUT) for n in range(16, 22)]
10gates = [
11 ("AND", lambda a, b: a and b),
12 ("OR", lambda a, b: a or b),
13 ("NAND", lambda a, b: not (a and b)),
14 ("NOR", lambda a, b: not (a or b)),
15 ("XOR", lambda a, b: a != b),
16 ("XNOR", lambda a, b: a == b),
17]
18
19last = None
20while True:
21 a = int(not btn_a.value()) # basılı = 1 / pressed = 1
22 b = int(not btn_b.value())
23 results = [int(f(a, b)) for _, f in gates]
24 for led, r in zip(leds, results):
25 led.value(r)
26 if (a, b) != last: # yalnız değişince yaz / print only on change
27 line = " ".join("%s=%d" % (g[0], r) for g, r in zip(gates, results))
28 print("A=%d B=%d %s" % (a, b, line))
29 last = (a, b)
30 time.sleep_ms(20)Anche Python ha una trappola simile: ~True dà -2, perché un bool è in realtà un intero. Per invertire un bit usa not x, 1 - x oppure x ^ 1. Inoltre gli operatori and e or di Python non restituiscono sempre True o False, ma l'ultimo valore valutato: 0 or 5 dà 5. Per questo il codice usa le conversioni int(), così i LED ricevono sempre e solo 0 o 1.
Idee di progetti con le porte logiche
- Luce notturna intelligente (AND): Accendi la luce quando è buio E viene rilevato un movimento; combina un LDR e un sensore PIR in un'unica condizione &&.
- Luce delle scale (XOR): Comanda una lampada con due pulsanti in fondo e in cima alla scala; calcola lo stato della lampada con XOR e accendi la lampada a 230 V con un modulo relè.
- Allarme di casa (AND + OR): Con il sistema inserito, fai suonare la sirena se si apre la porta OPPURE la finestra. Rileva porta e finestra con un interruttore reed; trovi i dettagli nella guida sistema di allarme con Arduino.
- Cassaforte a due chiavi (AND): La serratura si apre solo se due persone diverse premono il loro pulsante nello stesso momento, oppure dopo la verifica del codice sul tastierino.
- Calcolatrice a 4 bit: Somma due numeri inseriti con degli interruttori usando la logica del sommatore completo e mostra il risultato su un display a 7 segmenti.
- Pulsante da quiz: Blocca il LED del primo concorrente che preme e impedisci agli altri di farlo; è la versione software di un latch costruito con le NAND.
- Controllo di parità: Applica la XOR a tutti i bit di un byte; se il risultato è 1, il numero di uni è dispari. Il bit di parità della comunicazione seriale si calcola esattamente così.
Errori comuni e soluzioni
| Sintomo | Causa probabile | Soluzione |
|---|---|---|
| Il LED lampeggia da solo e cambia quando avvicini la mano | Ingresso flottante, nessuna resistenza di pull-down | Metti una resistenza di pull-down o pull-up da 10 kΩ su ogni ingresso |
| L'integrato si scalda | VCC e GND invertiti o due uscite collegate tra loro | Il piedino 14 va a VCC e il 7 a GND; non unire mai le uscite |
| Nessuna porta risponde | Manca l'alimentazione o l'integrato non è a cavallo del canale | Misura tra i piedini 14 e 7 con il multimetro e posiziona l'integrato sul canale |
| Risultati sbagliati con un 74HC02 o un CD4011 | Piedinatura diversa dal 74HC08 | Collega secondo la tabella dei piedini del datasheet |
| L'integrato assorbe più corrente del dovuto | Ingressi inutilizzati flottanti | Collega a GND tutti gli ingressi liberi |
| Risultati instabili con ESP32 o Pico | Un segnale a 3,3 V non basta per un 74HC a 5 V | Alimenta il 74HC a 3,3 V o usa un 74HCT |
| if (a & b) è inaspettatamente false | & lavora bit a bit; 2 & 1 = 0 | Usa && nelle condizioni |
| if (x & 1 == 0) non viene mai eseguito | == viene valutato prima di & | Usa le parentesi: (x & 1) == 0 |
| Una pressione cambia la porta più volte | Rimbalzi del pulsante | Attendi 20–50 ms via software o usa un filtro RC + 74HC14 |
Le porte logiche sono l'alfabeto di tutto il mondo digitale, dall'accensione di un LED alla somma eseguita da un processore. Una volta capiti AND, OR e NOT, leggere una condizione if, una regola di allarme o uno shift register diventa molto più semplice. Nell'app BlueGrays trovi progetti per accendere un LED con un pulsante, progetti con pulsanti per ESP32 e Raspberry Pi Pico, un'illuminazione intelligente delle scale e un'illuminazione intelligente che combina PIR e LDR, ognuno con schemi elettrici e codice passo passo, così puoi mettere in pratica in progetti reali la logica delle porte vista in questo articolo.
Domande frequenti
Quali sono le porte logiche e a cosa servono?
Le porte logiche fondamentali sono sette: AND, OR, NOT, NAND, NOR, XOR e XNOR. Ognuna osserva ingressi che valgono 0 o 1 e produce un'unica uscita secondo la propria regola. Tutti i circuiti digitali, come processori, memorie, contatori e calcolatrici, nascono dalla combinazione di queste porte.
Come si costruisce una tabella di verità?
Per prima cosa ricava il numero di righe dal numero di ingressi: n ingressi richiedono 2ⁿ righe. Scrivi gli ingressi nell'ordine del conteggio binario (00, 01, 10, 11), poi applica a ogni riga la regola della porta per riempire la colonna dell'uscita. Nei circuiti con più porte, aggiungere una colonna per ogni uscita intermedia semplifica il calcolo.
Perché la porta NAND è universale?
Perché usando solo porte NAND puoi costruire NOT, AND, OR, NOR, XOR e XNOR. Per esempio, unire i due ingressi di una NAND dà una NOT, due NAND in fila danno una AND e quattro NAND danno una XOR. Anche la porta NOR ha la stessa proprietà, quindi è considerata universale.
Qual è la differenza tra XOR e XNOR?
La XOR dà 1 quando gli ingressi sono diversi, mentre la XNOR dà 1 quando sono uguali. La XNOR è l'inversa della XOR e serve a verificare se due bit sono uguali. La XOR si usa nei circuiti sommatori, nel controllo di parità e per invertire un bit.
Qual è la differenza tra 74HC08 e 74LS08?
Entrambi contengono quattro porte AND a due ingressi e hanno la stessa piedinatura. Il 74HC08 è in tecnologia CMOS, funziona da 2 a 6 V e assorbe pochissima corrente; il 74LS08 è TTL, funziona solo intorno ai 5 V e consuma di più. Per i nuovi progetti scegli il 74HC, e il 74HCT quando colleghi segnali a 3,3 V a un circuito a 5 V.
Qual è la differenza tra && e & in Arduino?
&& è l'operatore AND logico: verifica se entrambe le condizioni sono vere e restituisce true o false. & è l'AND bit a bit e confronta separatamente ogni bit di due numeri. Per questo 2 && 1 vale true, mentre 2 & 1 vale 0; nelle condizioni if devi usare &&.
Progetti da realizzare dopo questo articolo
Vedi tutti i progetti
Accendere un LED con un pulsante (Push)
Come un campanello: la luce resta accesa finché premi e si spegne quando lasci. L'Arduino ascolta il pulsante di continuo; mentre è premuto accende il LED, e appena togli il dito lo spegne. Con questo

Accendere e spegnere un LED con un pulsante
Premi il pulsante una volta e la luce si accende, premilo di nuovo e si spegne, proprio come l'interruttore della tua stanza. L'Arduino si accorge di ogni pressione e porta il LED nello stato opposto,

Controllo LED ESP32 con pulsante (Push)
Il LED si accende quando il pulsante viene premuto e si spegne quando viene rilasciato. Mostra come vengono utilizzati il pin di ingresso digitale dell'ESP32 e la resistenza di pull-up interna. Grazie alla modalità INPUT_PULLUP, non è necessaria alcuna resistenza esterna.

Controllo LED ESP32 con pulsante (Toggle)
Ogni volta che si preme il pulsante, lo stato del LED cambia: se è acceso si spegne, se è spento si accende. Classico schema toggle. Con il debounce puliamo il rumore meccanico del pulsante per garantire una singola commutazione con una sola pressione.

Raspberry Pi Pico LED Controllato da Pulsante (Push, GP14 + GP2)
Primo progetto di **input** con Pico — lettura pulsante! 🔘 LED si accende mentre il pulsante è premuto. Impara `Pin.IN`, `Pin.PULL_UP` e `button.value()`. GP14 LED, GP2 pulsante con PULL_UP interno. Premuto = 0, rilasciato = 1 — standard.

Raspberry Pi Pico: controllo indipendente di 2 LED tramite 2 pulsanti (GP12-13 + GP4-5)
2 pulsanti, 2 LED — completamente indipendenti l'uno dall'altro! 🔴🟢 Ogni pulsante controlla il proprio LED: quando si preme BTN1 si accende il LED rosso, quando si preme BTN2 si accende il LED verde. Se si premono entrambi contemporaneamente, si accendono entrambi i LED (funzionamento in parallelo). Contenuti: **gestione di oggetti con più pin** (più ingressi/uscite contemporanei), **operatore ternario** (`1 if x else 0` — l’if-else compatto di Python), **controllo indipendente di I/O** (logica

Illuminazione intelligente di scale e corridoi
Metti piede sulle scale o nel corridoio e le luci si accendono gradino dopo gradino nella direzione in cui cammini. A ogni estremità c'è un sensore di distanza; davanti a qualunque dei due passi, gli

Illuminazione Intelligente ESP32 (PIR + LDR + Relè + OLED)
Trasforma il tuo corridoio, bagno o dispensa in illuminazione intelligente con ESP32! Utilizzando un sensore di movimento PIR, un sensore di luce LDR e un modulo relè, costruiamo lo scenario classico "la luce si accende quando viene rilevato movimento al buio" — se l'ambiente è già luminoso, il movimento NON attiva la luce, risparmiando energia durante il giorno. La luce rimane accesa per 30 secondi; se il movimento continua, il timer si azzera e la luce rimane accesa più a lungo. Il display OLE
Altri articoli
App BlueGrays
Costruisci questo circuito passo passo sul telefono
Schema, codice ed elenco componenti in un’unica schermata. Oltre 160 progetti Arduino, ESP32 e Pico da realizzare.
Inquadra con il telefono
Punta la fotocamera sul codice: si apre lo store del tuo telefono.
oppure apri lo store

