Boa tarde pessoal,

Gostaria de pedir a ajuda de vcs com um programa que fiz no arduino para medir o nível de um tanque usando sensor ultrassônico HC-SR04 para controlá-lo suando algoritmo PID e integrar esse sistema a um supervisorio com o LabVIEW.

o programa (abaixo) está compilando mas, o arduino não está medindo o nível com o sensor.

#include <LiquidCrystal.h> // Biblioteca de funções do LCD
#include <PID_v1.h> // Biblioteca do PID

// VARIÁVEIS DO ULTRASSOM
#define echoPin 13 //Pino 13 recebe o pulso do echo
#define trigPin 8 //Pino 8 envia o pulso para gerar o echo
#define Intertravamento 1 // pino de saída para o intertravamento
// LCD
LiquidCrystal lcd(12, 11, 5, 4, 3, 2); // Pinos que serão utilizados para conectar o LCD
#define Luz_Fundo 7

// PID
double Setpoint, Input, Output;//Define Variables we'll be connecting to
float kp,ki,kd;
PID myPID(&Input, &Output, &Setpoint, kp, ki, kd, DIRECT);//Specify the links and initial tuning parameters
char LabVIEW_data[3] = "";
float Numero = 0;
int i;
float nivel_percentual, nivel, distancia;

void setup()
{
Serial.begin(115200); //inicia a porta serial

//INTERTRAVAMENTO

pinMode(Intertravamento,OUTPUT);

// ULTRASSOM
pinMode(echoPin, INPUT); // define o pino 13 como entrada (recebe)
pinMode(trigPin, OUTPUT); // define o pino 8 como saida (envia)

// LCD
lcd.begin(16, 2); // declara a dimenção do LCD
pinMode(Luz_Fundo,OUTPUT); //define o pino como saída
digitalWrite(Luz_Fundo,HIGH); // Liga a luz do display.

// PID
myPID.SetMode(AUTOMATIC); //turn the PID on
int i; // Variável auxiliar
}

void loop()
{

// Recebendo dados do LabView
//Recebe uma string de caracteres pela serial
if (Serial.available() > 0) {
for (int i=0;i<3;i++){
//Armazena na string (array de char)
LabVIEW_data[i] = Serial.read();
delay(10);
}
// OBTENÇÃO DO SINAL DO SENSOR ULTRASSONICO
//seta o pino 8 com um pulso baixo "LOW" ou desligado ou ainda 0
digitalWrite(trigPin, LOW);
// delay de 2 microssegundos
delayMicroseconds(2);
//seta o pino 8 com pulso alto "HIGH" ou ligado ou ainda 1
digitalWrite(trigPin, HIGH);
//delay de 10 microssegundos
delayMicroseconds(10);
//seta o pino 8 com pulso baixo novamente
digitalWrite(trigPin, LOW);
//pulseInt lê o tempo entre a chamada e o pino entrar em high
float duration = pulseIn(echoPin,HIGH);
//Esse calculo é baseado em s = v . t, lembrando que o tempo vem dobrado
//porque é o tempo de ida e volta do ultrassom
distancia = duration /29 / 2 ;
// Esse eh o cálculo no nível que é representado pela altura do recipiente
// subitraida da distância lida pelo sensor
nivel = 30.3 - distancia;
// Converte nivel numerico para %
nivel_percentual = (nivel*100)/30.3;

// APLICAÇÃO DO PI


//Converte a string em inteiro
Numero = atoi(LabVIEW_data);

if (100 <= Numero && Numero<200)
{
Setpoint=(Numero-100);
}
if (200 <= Numero && Numero<300)
{
kp=(Numero-200);
}
if (300 <= Numero && Numero< 400)
{
ki=(Numero-300);
}
if (400 <= Numero && Numero< 500)
{
kd=(Numero-400);
}
}


Input = nivel_percentual;
myPID.Compute();
analogWrite(6,Output);

// TRNASMISSÃO DE DADOS VIA PORTA SERIAL
Serial.print("m");
Serial.print(Output);
Serial.print("p");
Serial.print(nivel);
Serial.print("s");
Serial.print(Setpoint);

// INDICAÇÃO DE NÍVEL DO LCD
// seta o cursor para: (coluna = 0, linha = 0)
lcd.setCursor(0,0);

if(nivel>0){
// imprime nível do tanque no LCD
lcd.print(nivel);
lcd.print("CM");
}
// seta para linha 1, ou seja, a linha de baixo
lcd.setCursor(0,1);
// limpa tela lcd
lcd.print("");

// sinaliza conexão perdida com o sensor
if(distancia == 0){
lcd.print("Lost Connection");
}

// sinaliza nível mínimo
if(nivel==0){
digitalWrite(Intertravamento,HIGH);
lcd.print("Minimum Level");
}

// sinaliza nível máximo
if(nivel==30.8){
digitalWrite(Intertravamento,LOW);
lcd.print("Maximum Level");
}

}

EU já testei so a parte do programa do sensor ultrassônico e funcionou normalmente...

 se alguem souber o que esta ocorrndo fico grato desde já pela ajuda!!

Exibições: 4097

Responder esta

Respostas a este tópico

Nunca mexi com Arduíno, mas trabalho com programação... dá para melhorar esse seus IFs.

if (Numero>=100 && Numero<200) {
   Setpoint=(Numero-100); 
}

elseif (Numero<300) {

    kp=(Numero-200); 
}
elseif (Numero< 400) {
    ki=(Numero-300); 
}
elseif (Numero< 500) {
    kd=(Numero-400); 
}

Numero NUNCA será >= 500 ou menor do que 100?

_________________

LabVIEW_data é um array, e depois você usa uma função que "converte string para inteiro" - essa função executa direto em todos elementos do array?

E depois como que você atribui um array de char (a serial retorna mesmo char?) em uma variável numérica para o IF acima?!

_________________

Você usa onde essa variável Input? (Input = nivel_percentual;)

Aliás nivel_percentual também.. parece que não tem uso...

_________________

Como falei, não programo arduíno, só avaliei lógica de programação....

Natascha

Obrigado pela melhoria dos ifs, melhorou meu código... e as conversões: instring-int, array-numero, apesar de estranhas estão funcionando... eu criei a variável nível percentual pois a entrada de função PID q uso é em porcentagem por isso o programa calcula quantos% do valor total o nivel medido representa.. mas, VLW...

Tempestade em copo de dagua, desta maneira que organizam e fazem a logica de programação nunca vai sair nada que presta, programação regra numero 1ºobjetivo, 2º organização,3º dividir por  Etapas.

qual a duvida? ler a distancia, ou fazer o controle PID?

se ja sabem o valor do nivel 100% correto, postem só o PID, isso cria menos poluição visual, outro detalhe, controle PID nao precisa de nenhum IF muito menos essa gambiarrada que fizeram, Antonio entra a noite na net que vou te encinar como se faz um PID descente, ja peguei programas aonde o cara tava usando 95% da memoria do CLP, eu refiz o programa e usei 15% de memoria, somente trabalhando organizado, o codigo ficou muito melhor e mais legivel, antonio programar é uma arte lembre´-se disso.

eu to usando uma biblioteca do arduino da função PID e o problema eh que o programa acima está executando mas eu não consigo ajustar os ganhos do controle no arduino via o sistema supervisório que eu criei no LabVIEW... e eu ainda não achei nada que solucionasse isso...a "gambiarra" de if foi uma forma que achei de o arduino diferenciar a que variavel deve ser atribuido o valor que ele estiver recebendo via porta serial... 

se você tiver algum código melhor por favor posta aki...eh q eu so entro de noite quando eu não tenho aula no IFBA... pq meu no curso lá eu normalmente tenho aula até as 22h.. VLW!!

amigo, tu sabe fazer comunicacao serial com arduino?

cria tres variaveis do tipo int chamadas P , I , D , e substitui coloca essas variaveis no lugar da configuracao PID logo no comeco, tens o ganho P, o tempo I e o tempo D configurados diratamente com valores, colocar tuas variaveis ali no lugar, quando tu declarar a tua variavel tu ja coloca um valor inicial nela pro teu PID nao comecar louco. se tiver duvidas posta ai que eu te ajudo.

Amigo deixa eu te perguntar uma coisa, voce sabe como funciona um controle PID? 

PID é para quando voce tem condiçoes variaveis em busca de um determinado valor, ou seja, algo que tu desconhece e que o controle PID atraves de ganho proporcional, tempo integral e tempo derivativo, ele acha para voce, exemplo, tens uma bonmba de oleo acionada por um inversor de frequencia onde tu seta um fluxo de vazao, o PID recebe a informacao da tua vazao e aumenta ou diminui a frequencia do teu inversor para a vazao aumentar ou diminuir, ate ate o setpoint seja igual ao feedback, na grande maioria se usa controle PI, nesta tua aplicacao nao vejo motivo para controle PI muito menos PID, pega a altura da água com teu sensor ultrasonico e se ele for menor que um valor liga, se for maior que outro valor desliga, se tu tens um motor que tu so liga on off, vejo menos ainda aplicacao PID para ele, PID em 99% dos casos são para situações em que voce tem controle variavel sobre os perifericos, obtendo assim um valor linear na tua aplicação., sabe a unica aplicacao que conheco que usa controle on off utilizando PID, rele´de estado solido acionando resistencia de aquecimento, aonde o PID acha o PWM (lento) para a resistencia de forma que a temperatura nao aumente e nem diminua. espero ter ajudado

Complementando o post do Alex:

Eu trabalho na ICOS, fabricante de Sensor de Nível On/Off. Se intuito for controle on/off, nem de instrumento por ultrassom você precisa - é muito caro e na maioria das vezes uma chave de nível tipo bóia com um contator atende perfeitamente por menos de R$100,00.

Se for um medidor, a saída dele deve ser 4 a 20mA, maioria pelo menos é. É só você converter, exemplo: 20mA = XX Litros,  10mA = X Litros. Deve ser mais simples do que você imagina.

Natascha

@nshgeek

OK VLW pela disponibilidade... se precisar entro em contato com vc para ver os sensores... VLW

Entendi o q vc disse a cerca do PID e necessidade de controle PI realmente não tem... eh que eu não expliquei que o tanque pertence a uma planta didática que simula processos de 1ª e 2ª ordem do âmbito industrial... e na industria, quando o controle do nivel de um reservatorio é importante a melhor estratégia é a PI.. meu professor pediu para usar essa ação somente pela didática mesmo... VLW a ajuda e a dica do sistema de temperatura, isso me vai ser útil em outro trabalho tb... VLW2!

RSS

© 2024   Criado por Marcelo Rodrigues.   Ativado por

Badges  |  Relatar um incidente  |  Termos de serviço