Arduino – Função map() – Mapeando intervalos de valores numéricos
Função map() no Arduino
A função map() permite efetuar o mapeamento de um intervalo numérico em outro intervalo numérico desejado. Isso significa que em um intervalo numérico que vai de um valor mínimo até um valor máximo, o valor mínimo será mapeado em um novo_mínimo, e o valor máximo será mapeado em um novo_máximo, e os valores intermediários serão remapeados em novos valores intermediários, de forma correspondente.
Sintaxe:
map(valor,Mínimo_Atual,Máximo_Atual,Novo_Mínimo,Novo_Máximo);
Onde:
- valor: Número a ser mapeado, geralmente contido em uma variável.
- Mínimo_Atual: Limite inferior do intervalo de valores atual
- Máximo_Atual: Limite superior do intervalo de valores atual
- Novo_Mínimo: Limite inferior do novo intervalo de valores mapeados
- Novo_Máximo: Limite superior do novo intervalo de valores mapeados
Exemplo: Queremos mapear os valores em um intervalo que vai de 0 a 1023 para um novo intervalo entre 0 e 200. Os valores atuais serão lidos a partir de uma variável chamada valor, e os novos valores mapeados serão gravados em uma variável de nome novo_valor:
novo_valor = map(valor,0,1023,0,200);
Desta forma, toda vez que um valor entre 0 e 1023 for gravado na variável valor, ele será mapeado para seu correspondente no intervalo entre 0 e 200, e esse novo valor será atribuído à variável novo_valor.
A função também pode mapear valores de forma inversa, bastando para isso trocar a posição dos valores mínimo e máximo novos:
novo_valor = map(valor,0,1023,200,0);
A função map() opera somente com números inteiros, não retornando valores de ponto flutuante (fracionários). Se um número fracionário for gerado, ele será truncado antes de ser retornado. A função não arredonda os valores mapeados.
Funcionamento interno
Internamente, a função map() é codificada da seguinte forma:
long map(long x, long in_min, long in_max, long out_min, long out_max) { return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min; }
Na prática
Vamos aplicar a função map() em um projeto simples. Vamos usar o mesmo circuito que foi utilizado anteriormente quando mostramos como ler um valor de tensão aplicado a um pino analógico. Os valores retornados, que por padrão estão no intervalo entre 0 e 1023 (resolução de 10 bits dos pinos analógicos), serão remapeados para um outro intervalo, de 8 bits (valores entre 0 e 255). Os valores lidos serão exibidos no monitor serial.
Abaixo temos o diagrama esquemático a ser utilizado:
Usaremos um potenciômetro de 10 kΩ (outros valores próximos também servirão), e um resistor de baixo valor (47 Ω são suficientes) para evitar que uma corrente em excesso possa danificar o Arduino.
Vamos começar conectando o potenciômetro entre os pinos 5V e GND, e seu terminal central (divisor de tensão) será conectado ao pino analógico A0, a partir de onde será feita a leitura do valor da tensão elétrica. Para maiores informações sobre o funcionamento do circuito utilizado, consulte o projeto “Lendo valores analógicos a partir de um potenciômetro“.
Código do sketch
Abaixo temos o código utilizado no projeto:
const int potenciometro = 0; int valor = 0.0; int valor_mapeado; void setup() { Serial.begin(9600); } void loop() { valor = analogRead(potenciometro); valor_mapeado = map(valor,0,1023,0,255); Serial.println(valor_mapeado); delay(200); } |
Testando a função map()
Após compilar e carregar o código no Arduino, abra o monitor serial clicando em Ferramentas -> Monitor serial no Arduino IDE (ou pressione a combinação de teclas Ctrl + Shift + M), e observe que os valores capturados na entrada analógica aparecerão. Movimente o eixo do potenciômetro e você verá os valores sendo alterados de acordo com a rotação aplicada, como podemos ver na captura de tela abaixo:
Na figura podemos ver que eu variei a rotação do potenciômetro de um valor próximo ao máximo até zero, e depois de volta ao valor máximo, ou seja, no terminal central do potenciômetro fomos da tensão máxima até 0V, e de volta à tensão máxima (aproximadamente 5V, fora a queda no resistor de 47Ω). Os valores mostrados estão no intervalo entre 0 e 255, e não entre 0 e 1023, como seria o normal, pois estão senado remapeados pela função.
É isso aí! Vamos utilizar essa função nos próximos projetos, a fim de efetuarmos a leitura de sinais de sensores e o controle de cargas a partir dos valores lidos.
Até mais!
muito obrigado pela aula…esse valor de 1023 é fixo??? eu preciso pegar um angulo de 10 Cº em 10Cº… porem a leitura dele começa só a partir dos 30Cº
tem alguma configuração para eu deixar esse sistema mais sensivel?
obrigado!
Olá amigo!
A resolução de 10 bits (de 0 a 1023) é fixa.
Você pode mapear os valores que necessita, a partir dos 30º, fazendo algo como map(variável, 0, 1023, 30, valor_máximo), onde variável contém o valor a ser mapeado, e valor_máximo é o valor limite superior a ser lido (e mapeado)
Olá, Fábio
Tem como simular o potenciômetro através do código tipo,
estou testando o potênciometro com um piezo-buzzer
ex:
frec = map(tono,0,1023,10000,12000); // colocando 440,440) emite a nota musical LA
caso eu queira imitar uma melodia
delay(2000);
tone(10,262,200); //DO
delay(200);
tone(10,294,300); //RE
delay(200);
tone(10,330,300); //MI
delay(200);
tone(10,349,300); //FA
delay(300);
tone(10,349,300); //FA
delay(300);
tone(10,349,300); //FA
agora tem como fazer um loop do som que é emitido no buzzer numa frequencia de por exemplo
de 100 a 200 sem precisar estar girando o potenciometro e sem escrever varias linhas de código
Obrigado e até
Parabéns pelo canal, explicação muito eficaz
Olá, adorei a explicação e caiu como uma luva para o que preciso.
Entretanto, tenho mais uma dúvida. Em um projeto de controlador de simulador de voo, usarei este potenciometro como controlador dos motores da aeronave. Entretanto, supondo que ele atuará com aceleração entre 0 e 45º, gostaria de saber se é possível fazer com que ele atuasse o “reversor” com o valor inferior a 0. Mais ou menos assim…entre -20 e 0, reversor(“Marcha ré). entre 0 e 10, neutro. E entre 10 e 45 aceleração.
Boa tarde
Estou tentando usar um sensor mpx5050dp
Tenho uma curva padrão e quero aumentar e diminuir de acordo com a variação de leitura do sensor
Float valorSensor=(analogRead(A0)-offset )/1.748;
ValorSensor=map(ValorSensor,0,1023,1,0);
Lcm.writeTrendCurve0(1+curvaA/ValorSensor));
As curvas são plotadas mas não consigo aumentar ou diminuir sua amplitude de acordo com a leitura do sensor ????
A Impedância de entrada do arduino é 100 Mega ohms, completamente desnecessário o resistor de 47 ohms.
O resistor de 47 ohns é para proteção do microcontrolador. Este artigo da documentação do Arduino explica bem o porquê da necessidade de tal resistor:
https://docs.arduino.cc/learn/microcontrollers/digital-pins
Boa tarde meu amigo gostaria de saber se é possível eu utilizar o map dentro de um If que testa um porta digital através de um botão se verdadeiro o map() retornaria um grau tipo 20 senão 0 grau é possível?