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


  }

Exibições: 1644

Responder esta

Respostas a este tópico

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.

RSS

© 2024   Criado por Marcelo Rodrigues.   Ativado por

Badges  |  Relatar um incidente  |  Termos de serviço