Fundamentos · 16 min de leitura

Lista de comandos do Arduino: sintaxe, exemplos e erros comuns

Comandos do Arduino explicados: pinMode, digitalWrite, analogRead, analogWrite, millis, Serial, map, tone, pulseIn e attachInterrupt, com exemplos e armadilhas.

Os comandos do Arduino são funções prontas que dizem à placa o que fazer: pinMode() transforma um pino em saída, digitalWrite() acende um LED, analogRead() lê um sensor e Serial.println() envia uma mensagem ao seu computador. A maioria dos sketches de Arduino é, na verdade, só uns vinte comandos básicos combinados de jeitos diferentes. Quando você entende esses comandos e o que significam, consegue ler qualquer código que encontrar, de um LED piscando a um carrinho robô, e escrever o seu próprio projeto do zero.

Neste guia, agrupamos os comandos do Arduino mais usados em quatro categorias: entrada/saída, tempo, matemática e comunicação. Para cada comando você encontra a sintaxe, o significado dos parâmetros, um exemplo curto que compila e roda em um Arduino Uno e o erro que os iniciantes mais cometem. Nas últimas seções, também vemos como os mesmos comandos se comportam de forma diferente no ESP32 e quais são os equivalentes em MicroPython no Raspberry Pi Pico.

Placa Arduino Uno com seus pinos digitais e analógicos
Arduino Uno: os pinos digitais 0–13, as entradas analógicas A0–A5 e os pinos PWM marcados com ~ são tudo o que você precisa para testar cada comando deste artigo.

O que é um comando do Arduino e como um sketch é executado?

O código do Arduino é construído sobre C/C++; a maior parte do que chamamos de “comandos” são, na verdade, funções que o core do Arduino oferece a você. Uma função recebe parâmetros entre parênteses (por exemplo, um número de pino e um valor), e algumas retornam um resultado: digitalRead() dá o estado de um pino, millis(), o tempo decorrido. Todo sketch de Arduino tem duas funções obrigatórias: setup() roda uma única vez quando a placa liga ou é reiniciada, e loop() se repete para sempre depois disso. Preparativos como a configuração dos pinos e Serial.begin() vão no setup(), e o trabalho que precisa acontecer continuamente vai no loop().

C++ (Arduino IDE)
1// Her Arduino programı bu iki fonksiyondan oluşur / Every Arduino sketch has these two functions
2void setup() {
3  // Açılışta ya da resetten sonra bir kez çalışır / Runs once at power-up or after reset
4  pinMode(13, OUTPUT);      // dahili LED pini çıkış / built-in LED pin as output
5}
6
7void loop() {
8  // Sonsuza kadar tekrar eder / Repeats forever
9  digitalWrite(13, HIGH);   // LED'i yak / turn the LED on
10  delay(500);               // 500 ms bekle / wait 500 ms
11  digitalWrite(13, LOW);    // LED'i söndür / turn the LED off
12  delay(500);
13}

Guardar três regras desde o início poupa você de muitos erros de compilação: os comandos diferenciam maiúsculas de minúsculas (se digitar digitalwrite, você recebe o erro “'digitalwrite' was not declared in this scope”), toda instrução termina com ponto e vírgula, e texto vai entre aspas duplas, enquanto caracteres isolados vão entre aspas simples. Para tipos de variáveis e estruturas como if e for, dê uma olhada em Fundamentos de programação do Arduino.

Lista de comandos do Arduino: tabelas por categoria

As quatro tabelas abaixo resumem quase todos os comandos que você vai usar nos projetos do dia a dia. O primeiro grupo é o dos comandos de entrada/saída; eles definem o papel de um pino, colocam uma tensão nele ou leem um valor dele. Você pode ver os números dos pinos da sua placa na ferramenta Pinagem.

ComandoSintaxeO que fazExemplo
pinModepinMode(pino, modo)Transforma um pino em entrada ou saídapinMode(13, OUTPUT);
digitalWritedigitalWrite(pino, valor)Coloca um pino em HIGH (5 V) ou LOW (0 V)digitalWrite(13, HIGH);
digitalReaddigitalRead(pino)Lê se um pino está em HIGH ou LOWint b = digitalRead(2);
analogReadanalogRead(pino)Transforma uma tensão de 0–5 V em um número de 0 a 1023int v = analogRead(A0);
analogWriteanalogWrite(pino, valor)Gera um sinal PWM de 0 a 255analogWrite(9, 128);
analogReferenceanalogReference(tipo)Escolhe a tensão de referência do analogReadanalogReference(INTERNAL);
tone / noTonetone(pino, frequência, duração)Gera som com uma onda quadrada; noTone o interrompetone(8, 440, 500);
pulseInpulseIn(pino, valor, timeout)Mede a duração de um pulso em µspulseIn(10, HIGH, 30000);
shiftOutshiftOut(pinoDados, pinoClock, ordem, byte)Envia um byte bit a bit (ex.: para um 74HC595)shiftOut(11, 12, MSBFIRST, 255);
attachInterruptattachInterrupt(interrupção, função, modo)Chama uma função no instante em que um pino mudaattachInterrupt(digitalPinToInterrupt(2), say, FALLING);

O segundo grupo é o dos comandos de tempo. Entender a diferença entre delay(), que espera, e millis() e micros(), que medem o tempo, é a chave para escrever um sketch que roda sem engasgos.

ComandoSintaxeO que fazAtenção
delaydelay(ms)Espera o número de milissegundos informadoO programa para durante esse tempo
delayMicrosecondsdelayMicroseconds(us)Espera um número de microssegundosPreciso entre 3 e 16383 µs
millismillis()Retorna os milissegundos desde a inicializaçãounsigned long; dá a volta depois de cerca de 49,7 dias
microsmicros()Retorna os microssegundos desde a inicializaçãoPassos de 4 µs no Uno, dá a volta depois de cerca de 70 minutos

O terceiro grupo é o dos comandos de matemática; você os usa para converter uma leitura de sensor para outra faixa, limitá-la ou gerar um número aleatório. O quarto grupo, o dos comandos de comunicação, permite que a placa troque dados com o seu computador e com outros dispositivos.

ComandoSintaxeO que fazExemplo de resultado
mapmap(x, deMin, deMax, paraMin, paraMax)Reescala uma faixa para outramap(512, 0, 1023, 0, 255) → 127
constrainconstrain(x, minimo, maximo)Mantém um valor entre dois limitesconstrain(300, 0, 255) → 255
min / maxmin(a, b) / max(a, b)Retorna o menor ou o maior valormin(7, 3) → 3
absabs(x)Valor absolutoabs(-12) → 12
pow / sqrt / sqpow(base, expoente), sqrt(x), sq(x)Potência, raiz quadrada, quadradopow(2, 10) → 1024.0
randomrandom(minimo, maximo)Inteiro aleatório (o máximo não entra)random(1, 7) → de 1 a 6
randomSeedrandomSeed(semente)Muda o ponto de partida da sequência aleatóriarandomSeed(analogRead(A3));
ComandoO que fazExemplo
Serial.begin(velocidade)Abre a porta serial no baud rate informadoSerial.begin(9600);
Serial.print(dado)Mostra o dado e fica na mesma linhaSerial.print(temperatura);
Serial.println(dado)Mostra o dado e passa para uma nova linhaSerial.println("Olá");
Serial.available()Retorna o número de bytes esperando para ser lidosif (Serial.available() > 0)
Serial.read()Lê um byte; retorna -1 se não houver dadoschar c = Serial.read();
Serial.readStringUntil(c)Lê texto até um caractere definidoString s = Serial.readStringUntil('\n');
Serial.parseInt()Extrai um número inteiro do texto recebidoint n = Serial.parseInt();
Serial.write(byte)Envia um byte brutoSerial.write(65); // 'A'
Wire.begin()Inicia o barramento I2C (Wire.h)Wire.begin();
SPI.begin()Inicia o barramento SPI (SPI.h)SPI.begin();

pinMode(): definindo o papel de um pino

pinMode(pino, modo) diz à placa se um pino digital é entrada ou saída, e normalmente você o escreve uma vez no setup(). Há três modos: OUTPUT transforma o pino em saída (para acionar um LED, um buzzer ou um relé), INPUT o transforma em uma entrada de alta impedância (para circuitos com resistor de pull-up ou pull-down externo), e INPUT_PULLUP o transforma em entrada e liga um resistor interno de cerca de 20–50 kΩ ao 5 V. Os pinos analógicos (A0–A5) também podem ser usados como pinos digitais com pinMode; por exemplo, pinMode(A0, OUTPUT) é um comando válido.

Se você esquecer pinMode(pino, OUTPUT) e usar digitalWrite(pino, HIGH), o pino não vira saída; no Uno, o comando só liga o resistor de pull-up interno. O LED acende, mas fica muito fraco, porque a corrente precisa passar por um resistor de 20–50 kΩ. Se o seu LED estiver fraco, o primeiro lugar para conferir é a linha do pinMode no setup().

digitalWrite() e digitalRead(): saída e entrada digitais

digitalWrite(pino, HIGH) leva um pino de saída a 5 V no Uno, e digitalWrite(pino, LOW) o leva a 0 V. Tirar até 20 mA de um pino é seguro (o máximo absoluto é 40 mA); ligue sempre um LED com resistor, e você encontra o valor certo com a calculadora de resistor para LED. digitalRead(pino) olha a tensão no pino e retorna HIGH ou LOW; no Uno, mais ou menos qualquer valor acima de 3 V conta como HIGH, e abaixo de 1,5 V, como LOW. No exemplo abaixo, o LED embutido acende quando você aperta o botão ligado ao D2:

C++ (Arduino IDE)
1const int BUTON_PIN = 2;   // buton: bir ucu D2, diğer ucu GND / button: one leg to D2, the other to GND
2const int LED_PIN = 13;    // dahili LED / built-in LED
3
4void setup() {
5  pinMode(BUTON_PIN, INPUT_PULLUP);   // dahili pull-up direnci açık / internal pull-up resistor enabled
6  pinMode(LED_PIN, OUTPUT);
7}
8
9void loop() {
10  int durum = digitalRead(BUTON_PIN); // HIGH ya da LOW döner / returns HIGH or LOW
11  if (durum == LOW) {                 // pull-up ile basılı = LOW / with pull-up, pressed = LOW
12    digitalWrite(LED_PIN, HIGH);
13  } else {
14    digitalWrite(LED_PIN, LOW);
15  }
16}

Com INPUT_PULLUP a lógica se inverte: com o botão solto, o pino lê HIGH graças ao resistor interno, e apertado ele lê LOW porque fica ligado ao GND. Se você ligar o botão sem resistor no modo INPUT, o pino fica flutuando e digitalRead() retorna valores aleatórios; até aproximar a mão pode mudar o resultado. Para o repique de botões e as formas corretas de ligar um botão, veja Como ligar um botão ao Arduino.

analogRead() e analogWrite(): entrada analógica e PWM

analogRead(pino) usa um conversor de 10 bits (ADC) para transformar uma tensão entre 0 e 5 V nos pinos A0–A5 em um número de 0 a 1023. Uma leitura leva cerca de 100 µs, então você consegue fazer mais ou menos 10.000 leituras por segundo. Para converter o número em tensão, use valor × 5.0 / 1023; uma leitura de 512, por exemplo, significa cerca de 2,5 V. A tensão de referência pode ser mudada com analogReference(): a opção INTERNAL usa a referência interna de 1,1 V do Uno e melhora a resolução para tensões pequenas. Você encontra os detalhes de resolução e referência em ADC e conversão analógico-digital.

Apesar do nome, analogWrite(pino, valor) não gera uma tensão analógica de verdade. Ele liga e desliga o pino muito rápido para criar um sinal PWM: 0 significa sempre desligado, 255 sempre ligado e 127 mais ou menos metade do tempo ligado. É essa média que faz um LED parecer com meio brilho aos nossos olhos e um motor girar devagar. No Uno, só os pinos 3, 5, 6, 9, 10 e 11, marcados com ~ na placa, fornecem PWM; a frequência é de 490 Hz na maioria dos pinos e de 980 Hz nos pinos 5 e 6. analogWrite() já define o pino como saída, então o pinMode não é obrigatório. O código abaixo ajusta o brilho de um LED com um potenciômetro e mostra a leitura junto com a tensão no Monitor Serial; para os detalhes de ciclo de trabalho e frequência, veja O que é PWM?.

C++ (Arduino IDE)
1const int POT_PIN = A0;   // potansiyometrenin orta bacağı / potentiometer wiper
2const int LED_PIN = 9;    // ~9 PWM pini + 220 ohm direnç / ~9 PWM pin + 220 ohm resistor
3
4void setup() {
5  Serial.begin(9600);
6}
7
8void loop() {
9  int ham = analogRead(POT_PIN);         // 0-1023 arası / between 0 and 1023
10  float volt = ham * (5.0 / 1023.0);     // sayıyı gerilime çevir / convert the reading to volts
11  analogWrite(LED_PIN, ham / 4);         // 0-1023 -> 0-255 PWM parlaklığı / 0-1023 -> 0-255 PWM brightness
12
13  Serial.print(F("Ham / raw: "));
14  Serial.print(ham);
15  Serial.print(F("  Gerilim / voltage: "));
16  Serial.print(volt, 2);                 // 2 ondalık basamak / 2 decimal places
17  Serial.println(F(" V"));
18  delay(200);
19}
Em um pino sem PWM, analogWrite() não consegue gerar valores intermediários: ele coloca o pino em LOW para valores abaixo de 128 e em HIGH para 128 ou mais. Os pinos A0–A5 do Uno também não fornecem PWM, e o Uno R3 clássico não tem saída analógica de verdade (DAC); escrever analogWrite(A0, 100) não vai dar 2 V. Se você precisa de uma tensão analógica de verdade, use uma placa com DAC (como o Uno R4, que tem DAC no A0) ou acrescente um filtro RC a uma saída PWM.

delay(), millis() e micros(): comandos de tempo

delay(ms) espera o número de milissegundos informado, e durante esse tempo nenhuma outra linha do loop() é executada; delay(1000) é uma pausa de um segundo inteiro. Para esperas curtas, na faixa dos microssegundos, existe o delayMicroseconds(), que é preciso entre 3 e 16383 µs. millis(), por outro lado, não espera; ele retorna o tempo desde que a placa ligou, em milissegundos. Guarde sempre o resultado em uma variável unsigned long: se você usar int, no Uno o valor estoura assim que passa de 32.767, depois de cerca de 33 segundos, e a sua temporização quebra. millis() volta a zero mais ou menos a cada 49,7 dias; o método da subtração abaixo continua funcionando certo mesmo nessa volta.

C++ (Arduino IDE)
1const int LED_PIN = 13;
2const unsigned long ARALIK = 500;   // yanıp sönme aralığı (ms) / blink interval (ms)
3unsigned long oncekiZaman = 0;      // son değişim anı / time of the last toggle
4
5void setup() {
6  pinMode(LED_PIN, OUTPUT);
7}
8
9void loop() {
10  unsigned long simdi = millis();
11  if (simdi - oncekiZaman >= ARALIK) {               // taşmada da doğru çalışır / safe across overflow
12    oncekiZaman = simdi;
13    digitalWrite(LED_PIN, !digitalRead(LED_PIN));    // LED'i tersine çevir / toggle the LED
14  }
15  // Burada buton, sensör ve ekran işleri de yapılabilir / button, sensor and display tasks can run here
16}

Com esse padrão o loop() nunca para; enquanto o LED continua piscando, você pode ler um botão, medir um sensor e atualizar um display no mesmo laço. micros() funciona do mesmo jeito em microssegundos; no Uno ele avança em passos de 4 µs e dá a volta depois de cerca de 70 minutos. Explicamos em detalhes como rodar várias tarefas ao mesmo tempo em millis() vs delay() no Arduino.

Serial.begin(), Serial.print() e Serial.read(): comunicação serial

Os comandos Serial permitem que o Arduino converse com o seu computador pelo cabo USB, e eles são a sua ferramenta de depuração mais importante. Serial.begin(9600) abre a porta serial a 9600 bits por segundo; se a velocidade no Monitor Serial não for a mesma, você vai ver caracteres estranhos na tela. Serial.print() mostra os dados e fica na mesma linha, enquanto Serial.println() passa para uma nova linha depois de mostrar. Um segundo parâmetro permite escolher o formato: Serial.print(78, HEX) mostra “4E”, Serial.print(78, BIN) mostra “1001110”, e Serial.print(3.14159, 3) mostra “3.142” (números de ponto flutuante saem por padrão com 2 casas decimais). Colocar texto fixo dentro de F("...") economiza espaço nos 2 KB de RAM do Uno.

Para ler dados, primeiro você confere com Serial.available() se há bytes esperando no buffer; o buffer de recepção do Uno tem 64 bytes. Serial.read() tira um único byte desse buffer e retorna -1 se não houver nada para ler. O código abaixo liga e desliga o LED com os caracteres 1 e 0 que você envia pelo Monitor Serial:

C++ (Arduino IDE)
1const int LED_PIN = 13;
2
3void setup() {
4  Serial.begin(9600);                    // Seri Monitör de 9600 olmalı / Serial Monitor must be 9600 too
5  pinMode(LED_PIN, OUTPUT);
6  Serial.println(F("1: LED açık / on, 0: LED kapalı / off"));
7}
8
9void loop() {
10  if (Serial.available() > 0) {          // tamponda bayt var mı? / any bytes waiting?
11    char c = Serial.read();              // ilk baytı al / read the first byte
12    if (c == '1') {                      // '1' karakteri, 1 sayısı değil / the character '1', not the number 1
13      digitalWrite(LED_PIN, HIGH);
14      Serial.println(F("LED açık / on"));
15    } else if (c == '0') {
16      digitalWrite(LED_PIN, LOW);
17      Serial.println(F("LED kapalı / off"));
18    }
19    // '\n' ve '\r' gibi diğer karakterler atlanır / other characters such as '\n' and '\r' are ignored
20  }
21}

Repare que a comparação é feita com '1' (aspas simples, ou seja, um caractere): o 1 que você digita no teclado corresponde ao número 49 na tabela ASCII, então a condição c == 1 nunca é verdadeira. Para números com vários dígitos você pode usar Serial.parseInt() e, para pegar uma linha inteira, Serial.readStringUntil('\n'). Para as configurações de final de linha, baud rate e plotter do Monitor Serial, veja Como usar o Monitor Serial do Arduino.

map() e constrain(): escalando e limitando valores

map(valor, deMin, deMax, paraMin, paraMax) leva um número proporcionalmente de uma faixa para outra. A fórmula por trás é: (x − deMin) × (paraMax − paraMin) / (deMax − deMin) + paraMin. Por exemplo, map(512, 0, 1023, 0, 255) retorna 127 e não 127,6, porque map() trabalha só com inteiros e descarta a fração. Você pode criar uma relação inversa trocando a faixa de destino: map(x, 0, 1023, 255, 0). map() não limita o resultado; se a entrada sair da faixa que você informou, a saída também sai. Por isso ele costuma ser combinado com constrain(x, minimo, maximo).

C++ (Arduino IDE)
1const int LDR_PIN = A0;   // LDR + 10k gerilim bölücü / LDR + 10k voltage divider
2const int LED_PIN = 9;    // ~9 PWM pini / ~9 PWM pin
3
4void setup() {
5  pinMode(LED_PIN, OUTPUT);
6}
7
8void loop() {
9  int isik = analogRead(LDR_PIN);           // odada ölçülen aralık ~200-800 / measured range in the room ~200-800
10  int pwm = map(isik, 200, 800, 255, 0);    // karanlıkta parlak, aydınlıkta sönük / bright in the dark, dim in the light
11  pwm = constrain(pwm, 0, 255);             // aralık dışı değerleri kes / clip out-of-range values
12  analogWrite(LED_PIN, pwm);
13  delay(20);
14}

Neste exemplo, o LDR dá valores entre 200 e 800 no cômodo. Se a leitura cair para 100 à noite, map() calcula 297; sem constrain(), analogWrite() receberia esse valor fora da faixa de 0–255. No Uno, esse valor dá resultados diferentes e inesperados conforme o pino: nos pinos 3, 5, 6 e 11, que usam timers de 8 bits, 297 estoura e se comporta como 41, então o LED quase apaga na escuridão total em vez de brilhar forte. Como constrain(), min(), max() e abs() são definidos como macros no Uno, não coloque x++ nem outra chamada de função dentro dos parênteses; a expressão pode ser avaliada mais de uma vez e dar resultados inesperados. Para a ligação do LDR, veja Sensor de luz LDR.

tone() e noTone(): fazendo som com um buzzer

tone(pino, frequência, duração) gera uma onda quadrada com ciclo de trabalho de 50% em um pino e faz um buzzer passivo ou um pequeno alto-falante soar nessa frequência. A duração é em milissegundos e opcional; sem ela, o som continua até você chamar noTone(pino). Um detalhe importante: tone() não espera; ele começa o som e passa direto para a próxima linha. Então, quando você toca notas uma atrás da outra, precisa de um delay() pelo menos tão longo quanto a nota depois de cada chamada de tone(), senão só ouve a última nota.

C++ (Arduino IDE)
1const int BUZZER_PIN = 8;   // pasif buzzer'ın + ucu / passive buzzer + leg
2
3void setup() {
4  int notalar[] = {262, 294, 330, 349, 392};   // Do Re Mi Fa Sol (Hz) / C D E F G (Hz)
5  for (int i = 0; i < 5; i++) {
6    tone(BUZZER_PIN, notalar[i], 200);         // 200 ms çal / play for 200 ms
7    delay(250);                                // tone() beklemez, sen bekle / tone() does not wait, so you do
8  }
9  noTone(BUZZER_PIN);                          // sesi kapat / stop the sound
10}
11
12void loop() {
13}
  • Limites de frequência: no Uno, tons abaixo de 31 Hz não podem ser gerados e o limite superior é 65.535 Hz; a faixa útil com um buzzer é de mais ou menos 100–5000 Hz.
  • Um som por vez: só um pino pode tocar um tom de cada vez; para fazer som em outro pino, você precisa primeiro parar o anterior com noTone().
  • Conflito com PWM: no Uno, tone() usa o Timer2, então analogWrite() nos pinos 3 e 11 fica prejudicado enquanto um som está tocando.
  • Buzzer ativo: como ele tem o seu próprio oscilador, a frequência não pode ser mudada com tone(); basta ligar e desligar um buzzer ativo com digitalWrite(). Para as diferenças, veja O que é um buzzer?.

pulseIn(): medindo a duração de pulsos

pulseIn(pino, HIGH) espera o pino ir a HIGH, mede quanto tempo ele fica em HIGH e retorna o resultado em microssegundos; ele mede pulsos de 10 µs a 3 minutos. O uso mais conhecido é o sensor ultrassônico de distância HC-SR04: o sensor fornece um pulso tão longo quanto o tempo que o som leva para ir e voltar. O som viaja no ar a cerca de 343 m/s, ou 0,0343 cm/µs; como o caminho é de ida e volta, distância = duração × 0,0343 / 2.

C++ (Arduino IDE)
1const int TRIG_PIN = 9;
2const int ECHO_PIN = 10;
3
4void setup() {
5  Serial.begin(9600);
6  pinMode(TRIG_PIN, OUTPUT);
7  pinMode(ECHO_PIN, INPUT);
8}
9
10void loop() {
11  digitalWrite(TRIG_PIN, LOW);
12  delayMicroseconds(2);
13  digitalWrite(TRIG_PIN, HIGH);            // 10 µs tetik darbesi / 10 µs trigger pulse
14  delayMicroseconds(10);
15  digitalWrite(TRIG_PIN, LOW);
16
17  unsigned long sure = pulseIn(ECHO_PIN, HIGH, 30000UL);   // en fazla 30 ms bekle / wait at most 30 ms
18  if (sure == 0) {
19    Serial.println(F("Menzil dışı / out of range"));
20  } else {
21    float mesafe = sure * 0.0343 / 2.0;    // ses hızı 343 m/s, gidiş-dönüş / speed of sound 343 m/s, round trip
22    Serial.print(mesafe, 1);
23    Serial.println(F(" cm"));
24  }
25  delay(100);
26}

O terceiro parâmetro, o timeout, é muito importante. Sem ele, pulseIn() espera 1 segundo quando nenhum pulso chega e retorna 0; se o fio do sensor se soltar, o programa inteiro trava por um segundo a cada volta do laço. Um timeout de 30000 µs corresponde a cerca de 5 metros, o que basta para o alcance de 4 metros do HC-SR04. Para a ligação e a precisão do sensor, veja Sensor de distância HC-SR04.

attachInterrupt(): reagindo na hora com interrupções

attachInterrupt(digitalPinToInterrupt(pino), função, modo) executa a função que você informa no instante em que um pino muda, não importa o que o loop() esteja fazendo naquele momento. Essa função se chama rotina de serviço de interrupção (ISR). O modo pode ter quatro valores: RISING dispara em uma transição de LOW para HIGH, FALLING em uma transição de HIGH para LOW, CHANGE a cada mudança e LOW enquanto o pino ficar em LOW. No Uno e no Nano, só os pinos D2 e D3 podem disparar interrupções desse jeito; no Mega, você pode usar os pinos 2, 3, 18, 19, 20 e 21. É ideal para não perder um encoder girando rápido, os pulsos de um anemômetro ou um toque muito curto em um botão.

C++ (Arduino IDE)
1const int BUTON_PIN = 2;            // Uno'da kesme pinleri: 2 ve 3 / interrupt pins on the Uno: 2 and 3
2volatile unsigned long sayac = 0;   // ISR'de değişen değişken volatile olmalı / variables changed in an ISR must be volatile
3
4void say() {                        // kesme fonksiyonu (ISR): kısa tut / interrupt service routine: keep it short
5  sayac++;
6}
7
8void setup() {
9  Serial.begin(9600);
10  pinMode(BUTON_PIN, INPUT_PULLUP);
11  attachInterrupt(digitalPinToInterrupt(BUTON_PIN), say, FALLING);   // HIGH'dan LOW'a geçişte / on a HIGH-to-LOW edge
12}
13
14void loop() {
15  noInterrupts();                   // 4 baytlık değeri güvenle kopyala / copy the 4-byte value safely
16  unsigned long kopya = sayac;
17  interrupts();
18
19  Serial.print(F("Basma sayısı / presses: "));
20  Serial.println(kopya);
21  delay(500);
22}
Declare como volatile toda variável que você muda dentro de uma ISR e mantenha a função o mais curta possível. Dentro de uma ISR, delay() não funciona, millis() não avança e Serial.print() pode travar o programa; só atualize uma flag ou um contador e faça o trabalho de verdade no loop(). Botões mecânicos têm repique, então o contador pode subir várias vezes com um único toque; a solução para o repique e todos os detalhes sobre interrupções estão em Interrupções no Arduino.

random() e randomSeed(): gerando números aleatórios

random(max) retorna um inteiro aleatório entre 0 e max−1, e random(min, max), um entre min e max−1; o limite superior não entra no resultado. Por isso você escreve random(1, 7) para um dado de 1 a 6. O Arduino não gera aleatoriedade de verdade; ele calcula uma sequência de números com uma fórmula fixa, então, se você não chamar randomSeed(), vai ver os mesmos números na mesma ordem toda vez que a placa ligar. Usar o ruído de um pino analógico desconectado como semente resolve isso na prática:

C++ (Arduino IDE)
1void setup() {
2  Serial.begin(9600);
3  randomSeed(analogRead(A3));     // boştaki A3 pininin gürültüsü / noise from the unconnected A3 pin
4}
5
6void loop() {
7  int zar = random(1, 7);         // 1-6 arası; üst sınır dahil değil / 1 to 6; the upper bound is exclusive
8  Serial.print(F("Zar / dice: "));
9  Serial.println(zar);
10  delay(1000);
11}

Comandos do Arduino no ESP32: o que observar

O ESP32 é programado na Arduino IDE com os mesmos comandos, e a maior parte do código deste artigo roda direto depois que você muda os números dos pinos. Como o hardware é diferente, porém, alguns comandos se comportam de outro jeito. A diferença mais importante é a tensão: os pinos do ESP32 trabalham em 3,3 V, digitalWrite(pino, HIGH) fornece 3,3 V e sinais de 5 V não podem ser ligados direto nos pinos. Para conhecer melhor a placa, veja O que é o ESP32?.

ComandoArduino UnoESP32
digitalWrite(pino, HIGH)5 V3,3 V
analogRead()10 bits, 0–1023, A0–A512 bits, 0–4095; com o Wi-Fi ligado, só os pinos do ADC1 (GPIO 32–39)
analogWrite()Só os pinos ~ (3, 5, 6, 9, 10, 11), 490/980 HzQuase todo GPIO com capacidade de saída; defina a frequência com ledcAttach(pin, freq, resolution)
attachInterrupt()Só D2 e D3Todos os GPIOs; acrescente IRAM_ATTR à ISR
tone()Usa o Timer2, atrapalha o PWM no 3 e no 11Funciona no hardware LEDC
Serial.begin()Normalmente 9600Normalmente 115200 (as mensagens de boot também usam essa velocidade)
delay()Mantém o processador totalmente ocupado esperandoPassa o tempo ao FreeRTOS; o Wi-Fi continua funcionando em segundo plano
C++ (Arduino IDE)
1const int POT_PIN = 34;     // ADC1 pini, Wi-Fi açıkken de okur / ADC1 pin, works with Wi-Fi on
2const int LED_PIN = 2;      // çoğu DevKit'te dahili LED / onboard LED on most DevKits
3const int BUTON_PIN = 4;    // butonun diğer ucu GND / other button leg to GND
4
5volatile bool basildi = false;
6
7void IRAM_ATTR butonISR() { // ESP32'de ISR IRAM'e yerleşmeli / on the ESP32 the ISR should live in IRAM
8  basildi = true;
9}
10
11void setup() {
12  Serial.begin(115200);
13  pinMode(BUTON_PIN, INPUT_PULLUP);
14  attachInterrupt(digitalPinToInterrupt(BUTON_PIN), butonISR, FALLING);   // her GPIO kesme destekler / every GPIO supports interrupts
15}
16
17void loop() {
18  int ham = analogRead(POT_PIN);                     // 0-4095 (12 bit)
19  analogWrite(LED_PIN, map(ham, 0, 4095, 0, 255));   // 8 bit PWM / 8-bit PWM
20  if (basildi) {
21    basildi = false;
22    Serial.println("Butona basıldı / button pressed");
23  }
24  Serial.println(ham);
25  delay(200);
26}

Como analogRead() retorna 0–4095 no ESP32, a faixa do map() muda de acordo. O IRAM_ATTR na frente da ISR coloca o código na memória interna rápida; sem ele, a placa pode, em algumas situações, reiniciar com um “Guru Meditation Error”. As leituras analógicas do ESP32 não são lineares perto das pontas da faixa (em torno de 0 V e de 3,3 V); se você precisa de uma medição mais precisa, a função analogReadMilliVolts() retorna um valor calibrado em milivolts.

Raspberry Pi Pico: equivalentes em MicroPython dos comandos do Arduino

Se você programa o Raspberry Pi Pico com a Arduino IDE (o core arduino-pico), todos os comandos deste artigo funcionam com o mesmo nome; analogRead() retorna 10 bits por padrão e analogWrite() gera PWM de 1 kHz. A maioria das pessoas, porém, usa o Pico com MicroPython. Lá os comandos são escritos com objetos dos módulos machine e time; a lógica é a mesma, só a sintaxe muda. Os pinos do Pico também são de 3,3 V, e as entradas analógicas dele são os pinos GP26, GP27 e GP28. Para começar, veja O que é o Raspberry Pi Pico?.

Comando do ArduinoEquivalente em MicroPythonObservação
pinMode(15, OUTPUT)led = Pin(15, Pin.OUT)O objeto Pin é criado uma vez
pinMode(14, INPUT_PULLUP)btn = Pin(14, Pin.IN, Pin.PULL_UP)Resistor de pull-up interno
digitalWrite(15, HIGH)led.value(1)led.on() também funciona
digitalRead(14)btn.value()Retorna 0 ou 1
analogRead(A0)ADC(26).read_u16()Retorna 0–65535
analogWrite(15, 128)PWM(Pin(15)).duty_u16(32768)Ciclo de trabalho de 0 a 65535
delay(500)time.sleep_ms(500)time.sleep(0.5) também funciona
millis()time.ticks_ms()Use time.ticks_diff() para diferenças
Serial.println(x)print(x)Aparece no shell do Thonny
tone(pin, 440)pwm.freq(440) e pwm.duty_u16(32768)Silencie com duty_u16(0)
pulseIn(pin, HIGH, 30000)machine.time_pulse_us(pin, 1, 30000)Retorna um valor negativo no timeout
attachInterrupt(...)btn.irq(trigger=Pin.IRQ_FALLING, handler=f) (borda de descida)f recebe o objeto do pino como parâmetro
random(1, 7)random.randint(1, 6)O limite superior entra
map() / constrain()Não vêm prontos, você mesmo os escrevePara constrain: min(max(x, 0), 255)
MicroPython
1from machine import Pin, ADC, PWM
2import time
3
4led = PWM(Pin(15))                       # pinMode + analogWrite karşılığı / pinMode + analogWrite equivalent
5led.freq(1000)                           # 1 kHz PWM
6buton = Pin(14, Pin.IN, Pin.PULL_UP)     # INPUT_PULLUP karşılığı / INPUT_PULLUP equivalent
7pot = ADC(26)                            # GP26 = ADC0
8
9def map_deger(x, giris_min, giris_max, cikis_min, cikis_max):   # Arduino map() karşılığı / Arduino map() equivalent
10    return (x - giris_min) * (cikis_max - cikis_min) // (giris_max - giris_min) + cikis_min
11
12onceki = time.ticks_ms()                 # millis() karşılığı / millis() equivalent
13while True:
14    ham = pot.read_u16()                 # 0-65535 (analogRead)
15    led.duty_u16(ham)                    # parlaklık / brightness (analogWrite)
16    if buton.value() == 0:               # digitalRead; basılı = 0 / pressed = 0
17        print("Butona basıldı / button pressed")
18    if time.ticks_diff(time.ticks_ms(), onceki) >= 1000:   # saniyede bir / once a second
19        onceki = time.ticks_ms()
20        print("Yüzde / percent:", map_deger(ham, 0, 65535, 0, 100))
21    time.sleep_ms(50)                    # delay(50)

Como a tabela mostra, random.randint(1, 6) no MicroPython inclui o limite superior e dá o mesmo resultado que random(1, 7) no Arduino; time.ticks_diff() oferece a mesma segurança contra a volta do contador que a subtração com millis(). São essas pequenas diferenças que mais confundem quem alterna entre as duas plataformas. Para os outros comandos básicos do MicroPython, dê uma olhada em Fundamentos de MicroPython.

Ideias de projetos que você pode montar com esses comandos

  • Semáforo: acenda três LEDs em sequência com pinMode(), digitalWrite() e delay(); explicamos passo a passo em Semáforo com Arduino.
  • Dado digital: gere um número de 1 a 6 com random() e, quando o botão for apertado, mostre o resultado com LEDs ou em um display de 7 segmentos.
  • Sensor de estacionamento: meça a distância com pulseIn(), transforme-a em um intervalo de bipes com map() e soe um aviso com tone().
  • Luz noturna automática: leia o nível de luz com analogRead() e ajuste o brilho do analogWrite() com map() e constrain().
  • Controle pela porta serial: controle um LED, um relé ou um servo motor com comandos do computador usando Serial.read().
  • Teste de reação: acenda um LED em um momento aleatório com random() e meça o seu tempo de reação no botão, ao milissegundo, com attachInterrupt() e millis().

Erros comuns e como corrigi-los

ErroSintomaSolução
pinMode() esquecidoO LED fica muito fraco ou não acendeEscreva pinMode(pino, OUTPUT) no setup()
Botão sem resistor no modo INPUTdigitalRead() retorna 0s e 1s aleatóriosUse INPUT_PULLUP; pressionado, lê LOW
Erro de digitação no nome de um comando'digitalwrite' was not declared in this scope (erro de compilação)Atenção às maiúsculas e minúsculas: digitalWrite
Baud rate diferenteCaracteres estranhos no Monitor SerialIguale a velocidade do Monitor Serial à do Serial.begin()
analogWrite() em um pino sem PWMO LED só fica totalmente aceso ou totalmente apagadoUse um pino marcado com ~ (3, 5, 6, 9, 10, 11)
millis() guardado em um intA temporização quebra depois de cerca de 33 segundosUse unsigned long
Dado com random(1, 6)Nunca sai 6Escreva random(1, 7); o limite superior não entra
Esperar casas decimais do map()O resultado é sempre inteiro, mudanças pequenas se perdemEscreva a sua própria fórmula com float, se precisar
pulseIn() sem timeoutCada volta do laço trava por 1 segundo quando o sensor faltaPasse 30000 como terceiro parâmetro
delay() ou Serial dentro de uma ISRO programa trava ou se comporta de forma estranhaNa ISR, só mude uma flag volatile
Se não tiver certeza do que um comando faz exatamente, escreva um pequeno sketch de teste e mostre o resultado com Serial.println(); na Arduino IDE 2 você também pode clicar com o botão direito no nome do comando e escolher “Ir para definição” para ver o código-fonte dele. Se o seu código não compilar, a primeira linha da mensagem de erro costuma apontar o problema; as mensagens mais comuns e as soluções estão em Erros de compilação do Arduino.

Os comandos deste artigo são os blocos de construção da maioria dos projetos que você vai fazer com um Arduino; o resto são, em geral, funções extras oferecidas por bibliotecas. Testar cada comando uma vez em um pequeno circuito próprio e ver o resultado no Monitor Serial fixa o aprendizado muito melhor do que decorar. No app BlueGrays você encontra projetos que usam esses comandos, como acender um LED, controlar um LED com botão, medir luz com LDR, ajustar a frequência de um buzzer, medir distância com HC-SR04 e um projeto de dado, passo a passo, com esquemas do circuito e código comentado.

Perguntas frequentes

Quais são os comandos do Arduino mais usados?

Os mais usados são pinMode(), digitalWrite(), digitalRead(), analogRead(), analogWrite(), delay(), millis(), Serial.begin() e Serial.println(). Acrescente map() para escalar valores, tone() para som, pulseIn() para sensores de distância e attachInterrupt() para interrupções, e você consegue escrever quase todos os seus projetos de iniciante.

Em que linguagem os comandos do Arduino são escritos?

O código do Arduino é construído sobre C e C++; o core do Arduino acrescenta à linguagem funções prontas como pinMode() e digitalWrite(). Os comandos são em inglês, diferenciam maiúsculas de minúsculas e toda instrução termina com ponto e vírgula. O ESP32 e o Raspberry Pi Pico também podem ser programados em MicroPython, se você preferir.

Qual é a diferença entre digitalWrite e analogWrite?

digitalWrite() coloca um pino em um de apenas dois estados: HIGH (5 V no Uno) ou LOW (0 V). analogWrite() liga e desliga o pino muito rápido para criar um sinal PWM de 0 a 255, assim você pode ajustar o brilho de um LED ou a velocidade de um motor. No Uno, analogWrite() só funciona nos pinos marcados com ~.

O que significam void setup e void loop?

setup() é a função que roda uma vez quando a placa liga ou é reiniciada; preparativos como pinMode() e Serial.begin() vão aqui. loop() é a função que se repete para sempre depois que o setup() termina. O void na frente delas significa que essas funções não retornam valor.

Qual é a diferença entre Serial.print e Serial.println?

Serial.print() mostra os dados e deixa o cursor na mesma linha, então o próximo dado vem logo em seguida. Serial.println() envia os caracteres de final de linha (\r\n) depois de mostrar, então o próximo dado começa em uma nova linha. Para mostrar vários valores lado a lado em uma linha, use print() primeiro e println() no final.

O que faz a função map do Arduino?

map() converte proporcionalmente um número de uma faixa para outra; por exemplo, transforma o valor de 0–1023 do analogRead() na faixa de 0–255 do analogWrite() ou em 0–180 graus para um servo. Ela trabalha só com inteiros e não limita o resultado, então é recomendado combiná-la com constrain() para lidar com entradas fora da faixa.

Ver todos os projetos
LED piscante
#1Iniciante

LED piscante

O primeiro contato com a eletrônica: acender e apagar um único LED. O Arduino acende e apaga o LED em intervalos curtos, fazendo a luz piscar rapidamente. Você vê da forma mais simples como a placa co

4.6(188)
1127
Controle de LED com botão (momentâneo)
#9Iniciante

Controle de LED com botão (momentâneo)

É como uma campainha: a luz fica acesa enquanto você pressiona o botão e apaga quando você solta. O Arduino monitora o botão continuamente; enquanto ele está pressionado, o LED fica aceso e apaga assi

4.8(113)
229
Medição da intensidade da luz com LDR
#11Iniciante

Medição da intensidade da luz com LDR

Quer ver a luminosidade do seu quarto em números? O LDR, um pequeno componente sensível à luz, mede a luz ambiente, e o Arduino exibe o valor na tela do computador a cada meio segundo. Cubra o sensor

4.6(81)
139
Ajuste de frequência com buzzer
#14Intermediário

Ajuste de frequência com buzzer

Você controla o som de um buzzer com quatro botões: um inicia o som, outro o interrompe e os outros dois o deixam mais agudo ou mais grave. Mantenha pressionado o botão de aumentar ou diminuir, e o to

4.6(69)
118
Medição de distância com HC-SR04 (Monitor Serial)
#27Iniciante

Medição de distância com HC-SR04 (Monitor Serial)

O sensor HC-SR04 funciona como um morcego que se orienta no escuro: emite um som que você não consegue ouvir, escuta o eco e mede a distância até o objeto à sua frente. O Arduino escreve essa distânci

4.6(46)
71
Efeito Knight Rider com LEDs e velocidade ajustável
#8Intermediário

Efeito Knight Rider com LEDs e velocidade ajustável

Uma luz percorre seis LEDs de uma ponta à outra, muda de direção e volta. Ao girar o botão do potenciômetro, você ajusta a velocidade na hora: em uma extremidade, a luz quase voa; na outra, avança dev

4.5(60)
120
Uso de servo motor com potenciômetro
#36Iniciante
Premium

Uso de servo motor com potenciômetro

Conforme você gira o botão do potenciômetro, o braço do servo motor gira junto: uma extremidade do botão corresponde a zero grau, e a outra, a meia volta. O Arduino lê continuamente a posição do botão

4.6(37)
52
Projeto de dado
#79Intermediário
Premium

Projeto de dado

Chega de perder o dado durante os jogos de tabuleiro: a cada toque no botão, um número aleatório de 1 a 6 aparece no display de 7 segmentos. Cada toque gera exatamente um resultado, que também aparece

5.0(48)
67