Boa tarde,
Preciso de uma ajuda que para mim se tornou uma dor de cabeça mas acredito que não deve ser algo muito complicado, eu é que não sou do ramo.
No código abaixo é lido o valor da porta 0 e dependendo da resistência será impresso um valor na serial entre 0 - 1023, creio que todos que começaram no arduino já fizerem este teste.
Meu problema é o seguinte, eu quero que ele envie para serial o valor da variável "valor" somente uma vez e só envie novamente se houver uma alteração no potenciômetro que altera o valor da variável.
Exemplo: o primeiro valora atribuído a variável é 10.
Ele irá enviar 10 e verificar novamente o valor da variável, se houve alteração ele imprime, se não houve não imprime na serial.
Eu já testei várias condições, o problema é que a variável nunca tem o mesmo valor e pode variar, mesmo que não tenha mexido no potenciômetro uma pouco acima ou abaixo do valor inicial, creio que devido a instabilidade de corrente que circula entre o positivo e negativo.
Agradeço se alguém me der uma luz.
int potenciometro = 0; // Define o pino do Arduino que o potenciômetro está conectado
int valor = 0; //Variável que irá receber o valor do potenciômetro
void setup() {
Serial.begin(9600);
}
void loop() {
valor = analogRead(potenciometro); //Recebe o valor do potenciômetro
Serial.println(valor); //Mostra no Serial Monitor o valor obtido do potenciômetro
}
Tags:
basta guardar o valor lido numa variável e, antes de imprimir na serial, checar se o novo valor é igual ou não ao último valor guardado.
Boa tarde,
O problema é que existe uma pequena variação neste valor, nunca é igual.
Obrigado.
afinal de contas, vc quer que seja exibido o valor lido, correto? Se for igual, despreza-se. Se for diferente, exibe-se. Então, não tem do que reclamar... é assim mesmo. O sketch fará o que vc mandar, não importa se o valor muda pouco ou muda muito.
Já se vc quer aplicar um filtro, aí a história muda. Suponhamos que vc queira que seja exibido na serial apenas valores que mudem 5% para cima ou 5% para baixo do valor anterior. Dessa forma, pequenas variações (menores que 5% de variação para cima ou para baixo) não serão exibidas. Pra fazer dessa forma, basta colocar na sua condicional algo como:
if (novoValor > 1.05 * ValorAntigo || novoValor < 0.95 * ValorAntigo)
{
// exibe na serial
}
Obrigado,
Acho que pode funcionar sim, vou fazer uns teste hoje.
valeu pela ajuda.
Agora deu certo:
int potenciometro = 0; // Define o pino do Arduino que o potenciômetro está conectado
int valor; //Variável que irá receber o valor do potenciômetro
int val;
int vold;
int dif ;
void setup() {
Serial.begin(115200);
}
void loop() {
valor = analogRead(potenciometro); //Recebe o valor do potenciômetro
val = map(valor, 0, 1023, 0, 100);
pot();
}
void pot(){
if (val != vold) {
dif = val - vold;
if (dif != 0 && dif > 2) {
//Serial.print("C56");
Serial.print("VAL ");
Serial.println(val); //Mostra no Serial Monitor o valor obtido do potenciômetro
vold = val;
Serial.print("dif ");
Serial.println(dif);
Serial.print("vold ");
Serial.println(vold);
delay(1000);
}
}
}
Caro Durval,
Se considera que seu tópico esta solucionado, por favor, coloque antes do titulo atual a palavra RESOLVIDO, isso ajuda a todos a pesquisar casos similares sabendo que foi solucionado.
Obrigado.
Um abraço.
Boa Noite,
Minha alegria durou pouco. Na verdade funcionou em partes.
quando a variável cresce ele funciona, pois atende a condição e imprime na saída serial, o problema continua no memento em que ele tem que decrescer a variável.
ou seja: de 0 a 1023 ele faz o que eu quero, mas o contrário ele não imprime.
Continuo precisando de uma luz.
Agora sim deu certo, abaixo o código.
Tem um macete, como não conheço muito eletrônica demorei para perceber que o potenciômetro tem que estar isolado.
int potenciometro = 0; // Define o pino do Arduino que o potenciômetro está conectado
int val;
int vold;
byte dif;
void setup() {
Serial.begin(115200);
}
void loop() {
val = (analogRead(potenciometro)/10); //Recebe o valor do potenciômetro
{pot();}
}
void pot(){
dif = val - vold;
if (dif !=0 && dif > 1) {
Serial.print("C56");
Serial.println(val); //Mostra no Serial Monitor o valor obtido do potenciômetro
Serial.print("C57");
Serial.println(val); //Mostra no Serial Monitor o valor obtido do potenciômetro
vold = val;
}
}
amigo, vc está escrevendo uma condicional redundante. Veja:
if (dif !=0 && dif > 1)
Pra que checar se "dif != 0" ???? Não precisa, pois se "dif" for maior que 1 ele automaticamente já é diferente de zero!
Outra coisa: essa sua condicional apenas prevê a situação onde "dif" é maior que 1. Mas deveria também imprimir na serial quando "dif" fosse menor que 1, correto?
Então sugiro que vc corrija aquela linha da condicional para ficar assim:
if (dif < -1 && dif > 1)
Bom dia,
Obrigado pela sugestão, vou verificar.
Bom dia. Permita-me dar um pitaco.
O valor lido na analógica fica instável por dois motivos.
Primeiro - Ripple da fonte. A tensão da fonte oscila dentro de certo limite, essa variação é normal em qualquer tipo de fonte. O capacitor de filtro tem por finalidade amenizar, porém ele sempre existirá em maior ou menor grau, dependendo da qualidade da fonte.
Segundo - Indução da rede. Repare que ao tocar no potenciômetro ou mesmo chegar com a mào perto a oscilação aumenta, pois seu corpo e a fiação funcionam como uma antena e recebe indução da rede de 60Hz.
Para melhorar coloque um capacitor de 100nF em paralelo com a entrada analógica, o mais proximo do pino que puder.
Outra forma muito interessante é um filtro por software. Existem vários algorítimos para esse fim. Eu particularmente gosto do sistema de média, por ser simples e eficaz.
Experimente esta lógica que lhe envio já com a detecção de variação para envio pela serial como você deseja.
Você pode usar esse filtro sempre que for utilizar uma entrada analógica. O valor 50 no número de interações determina quantas leituras serão feitas para se tirar uma média dos valores lidos.
Se aumentar fica mais estável, porém o tempo de convergência fica maior.(Demora mais para estabilizar o valor quando você muda o potenciômetro).
Se diminuir fica menos estável, porem o tempo de convergência diminui.
O valor ideal dependerá da estabilidade que você quer ter e do tempo que leva para que o sistema varie.
Ex. Se estiver medindo temperatura, que normalmente tem inércia alta, pode ter um número de interações alta, pois o sistema é mais lento.
Se tiver medindo posição ou algo assim que necessite uma resposta rápida, o número de interações deverá ser mais baixo para que a resposta de um eventual contrôle seja mais rápido.
Como oscilações normalmente são de fontes alternadas que variam com um semiciclo positivo e outro negativo, se tirarmos a média a tendência será que o semiciclo positivo e negativo se anulem.
Matematicamente essa proeza é realizada somando-se várias leituras consecutivas e tirando a média. O algorítimo abaixo permite coletar uma número de leituras e tirar essa média. Depois da matriz estar carregada a próxima leitura substitui um valor lido e tira uma nova média a cada varredura do programa, desta forma sempre teremos como no exemplo abaixo, a média das últimas 50 leituras ou qualquer valor que você experimente colocar no Filtro.
Espero que lhe tenha ajudado.
// --------------------------------------------------------------- FILTRO analógico
const int Filtro = 50; // Número de interações
int Leituras[Filtro]; // Matriz que armazenará as Leituras
int Ind = 0; // Indice de leitura
long Acc = 0; // Acumulador para a somatória dos valores
int Entrada_analogica; // Receberá o valor da entrada analógica
int Entrada_filtrada; // Receberá o valor da entrada já filtrada
int Memo;
void setup() {
Serial.begin(9600); // Inicializa a comunicação serial
}
void loop() {
// ------------------------------------------------------------- LEITURA DOS CANAIS ANALÓGICOS
Entrada_analogica = analogRead(A0); // Lê o valor da entrada analógica
FILTRO(); // Chama a rotina do filto da entrada analógica
if (Entrada_filtrada != Memo) { // Se a entrada modificou o valor
Serial.print ("Valor: "); // então imprime na serial
Serial.println (Entrada_filtrada);
}
Memo = Entrada_filtrada; // Atualiza o valor na memória que detecta a alteração de valor
}
// ROTINAS A SEREM CHAMADAS
void FILTRO() {
Acc = Acc - Leituras[Ind]; // Subtrai a última leitura
Leituras[Ind] = Entrada_analogica; // Lê a entrada analógica
Acc = Acc + Leituras[Ind]; // Acumula
Ind ++; // Incrementa índice
if (Ind >= Filtro) Ind = 0; // Se chegou ao final da matriz retorna ao início
Entrada_filtrada = (Acc / Filtro); // Calcula o valor médio
}
Bom dia,
Muito obrigado Luiz, suas explicações esclarecem algumas das minhas dúvidas.
Estou montando um simulador e isto irá enviar o sinal para o throttle do simulador acelerar e desacelerar.
Bem-vindo a
Laboratorio de Garagem (arduino, eletrônica, robotica, hacking)
© 2024 Criado por Marcelo Rodrigues. Ativado por