| Linha 257: | Linha 257: | ||
* Abaixo se encontra o esquema das ligações utilizadas no projeto, o cuidado e a atenção foram essenciais nesta etapa, visto que o risco de choques elétricos é grande. | * Abaixo se encontra o esquema das ligações utilizadas no projeto, o cuidado e a atenção foram essenciais nesta etapa, visto que o risco de choques elétricos é grande. | ||
[[Arquivo:ControlMachine Circuit.jpg]] | [[Arquivo:ControlMachine Circuit.jpg]] | ||
==Código utilizado no Arduino== | |||
<nowiki>#include <LiquidCrystal.h> // Biblioteca LCD | |||
#include <stdlib.h> | |||
#define sensor1 A0 //Define A0 como "sensor" | |||
#define sensorPin A1 | |||
LiquidCrystal lcd (38, 40, 42, 39, 41, 43);// Define os pinos utilizados pelo lcd. | |||
int rele = 8; // Define a saida digital como sendo a 8 | |||
int j=0; // contador | |||
int k=0; | |||
int y=0; | |||
int sensorValue_aux = 0; | |||
float sensorValue = 0; | |||
float currentValue = 0; | |||
float voltsporUnidade = 0.004887586;// 5%1023 | |||
int valor=0; // Variavel auxiliar para receber o valor da string ( do PC ) | |||
int tempsis=100; //Armazena a temperatura recebida do usuario (PC) | |||
float media=0; // Grava 1000 vezes a temperatura e posteriormente tira a média | |||
float Vsensor1; // Le tensão do LM35 | |||
float temp1; // Armazena a temperatura | |||
char temp[10]; | |||
char current[10]; | |||
void setup() | |||
{ | |||
lcd.begin(20,4); // LCD 20x4 | |||
lcd.print(" ControlMachine "); | |||
Serial.begin(9600); // Configuração da porta serial para comunicação à taxa de 9600 bps | |||
pinMode(Vsensor1,INPUT); | |||
pinMode(rele,OUTPUT); | |||
pinMode(sensorPin,INPUT); | |||
} | |||
void loop() | |||
{ | |||
if (Serial.available() > 0) | |||
{ | |||
valor=Serial.parseInt(); // lê valor do motor ( PC ) | |||
} | |||
if(Serial.available()!=0){ | |||
tempsis=valor; // armazena valor recebido pelo usuario para evitar o acionamento repetido do rele | |||
} | |||
for(j=0;j<1000;j++) | |||
{ | |||
Vsensor1=0; | |||
temp1=0; | |||
Vsensor1=analogRead(sensor1); | |||
temp1=(512*Vsensor1)/1023; | |||
media=media+temp1; | |||
} | |||
media=media/1000; | |||
if ( k != 0 ) | |||
{ | |||
media = media - 0.6; | |||
} | |||
lcd.setCursor(0,3); | |||
lcd.print("Temp.:"); | |||
lcd.print(media); | |||
lcd.print(" C"); | |||
for(int i=1000; i>0; i--){ | |||
sensorValue_aux = (analogRead(sensorPin) -512); // le o sensor na pino analogico A0 e ajusta o valor lido ja que a saída do sensor é (1023)vcc/2 para corrente =0 | |||
sensorValue += pow(sensorValue_aux,2); // somam os quadrados das leituras. | |||
} | |||
sensorValue = (sqrt(sensorValue/ 1000)) * voltsporUnidade; // finaliza o calculo da méida quadratica e ajusta o valor lido para volts | |||
currentValue = (sensorValue/0.066); // calcula a corrente considerando a sensibilidade do sernsor (185 mV por amper) | |||
sensorValue =0; | |||
lcd.setCursor(0,2); | |||
lcd.print("Corrente.:"); | |||
lcd.print(currentValue); | |||
lcd.print(" A"); | |||
if ( tempsis == 6000 ) | |||
{ | |||
dtostrf(media,4,2,temp); | |||
Serial.println(temp); | |||
dtostrf(currentValue,4,2,current); | |||
Serial.println(current); | |||
} | |||
if(media > tempsis) | |||
{ | |||
digitalWrite(rele,LOW); | |||
lcd.setCursor(0,1); | |||
lcd.print("Motor ligado "); | |||
k = 1; | |||
}else | |||
{ | |||
digitalWrite(rele,HIGH); | |||
lcd.setCursor(0,1); | |||
lcd.print("Motor desligado"); | |||
k = 0; | |||
}lcd.setCursor(0,1); | |||
if (tempsis==-100 || tempsis == 100 || tempsis == 6000) | |||
{ | |||
if (tempsis == -100) | |||
lcd.print("MOTOR: OFF "); | |||
else | |||
lcd.print("MOTOR: ON "); | |||
} | |||
else | |||
{ | |||
lcd.print("Temp MAX: "); | |||
lcd.print(tempsis); | |||
lcd.print(" C"); | |||
} | |||
delay (500); | |||
}</nowiki> | |||
==Código do Visual C++== | |||
<nowiki>#include <windows.h> | |||
#include <stdio.h> | |||
#include <dos.h> | |||
#include <conio.h> | |||
#include <stdlib.h> | |||
#include <string.h> | |||
typedef struct | |||
{ | |||
float temp; | |||
char nome[20]; | |||
struct elemento *prox; | |||
}elemento; | |||
elemento *F=NULL; | |||
elemento *atual=NULL; | |||
elemento *anterior=NULL; | |||
elemento *alocarno() | |||
{ | |||
elemento *novo; | |||
novo=(elemento*)malloc(sizeof(elemento)); | |||
novo->prox=NULL; | |||
return novo; | |||
} | |||
void cadastro() | |||
{ | |||
float temp; | |||
char nome[20]; | |||
printf("\n\nCADASTRAR MOTOR\n NOME:"); | |||
scanf("%s", &nome); | |||
printf(" TEMPERATURA MAXIMA DE OPERACAO:"); | |||
scanf("%f", &temp); | |||
if(F==NULL) | |||
{ | |||
F=alocarno(); | |||
strcpy(F->nome,nome); | |||
F->temp=temp; | |||
} | |||
else | |||
{ | |||
atual=F; | |||
while(atual->prox!=NULL) | |||
{ | |||
atual=(elemento*)atual->prox; | |||
} | |||
atual->prox=(struct elemento*)alocarno(); | |||
atual=(elemento*)atual->prox; | |||
strcpy(atual->nome,nome); | |||
atual->temp=temp; | |||
} | |||
system("PAUSE"); | |||
} | |||
int imprimir() | |||
{ | |||
int count = 0; | |||
if(F==NULL) | |||
{ | |||
printf("Lista vazia"); | |||
printf("\n"); | |||
} | |||
else | |||
{ | |||
count=1; | |||
atual=F; | |||
while(atual!=NULL) | |||
{ | |||
printf("\n MOTOR %d\n Motor: %s \n",count, atual->nome); | |||
printf("Temperatura MAX OP: %f \n",atual->temp); | |||
atual=(elemento*)atual->prox; | |||
count++; | |||
} | |||
} | |||
return count; | |||
} | |||
float EscolherTemperatura() | |||
{ | |||
elemento *paux; | |||
int count=1, j=0, i=1; | |||
count = imprimir(); | |||
if(count==0) | |||
{ | |||
return 0; | |||
} | |||
else | |||
{ | |||
printf("\nEscolha entre os motores cadastrados:"); | |||
scanf("%d", &j); | |||
if(j>(count-1) || j<1) | |||
{ | |||
printf("\n Numero invalido!!\n"); | |||
return 0; | |||
} | |||
else | |||
{ | |||
paux=F; | |||
while(paux->prox!=NULL) | |||
{ | |||
if(j==i) | |||
break; | |||
else | |||
i++; | |||
paux=(elemento*)paux->prox; | |||
} | |||
return paux->temp; | |||
} | |||
} | |||
} | |||
void limparlista() | |||
{ | |||
atual=F; | |||
while(atual!=NULL) | |||
{ | |||
F=(elemento*)atual->prox; | |||
free(atual); | |||
atual=F; | |||
} | |||
} | |||
void excluir() | |||
{ | |||
int count = 1, i = 1, j = 0; | |||
count = imprimir(); | |||
printf("\n Escolha motor para ser excluido: \n"); | |||
scanf("%d", &j); | |||
if(j>(count-1) || j<1) | |||
printf("\n Numero invalido!!\n"); | |||
else | |||
{ | |||
anterior = NULL; | |||
atual = F; | |||
while(atual!=NULL) | |||
{ | |||
if(i==j) | |||
{ | |||
if(anterior==NULL) | |||
{ | |||
F=(elemento*)atual->prox; | |||
free(atual); | |||
break; | |||
} | |||
else | |||
{ | |||
anterior->prox=atual->prox; | |||
free(atual); | |||
} | |||
anterior->prox = atual->prox; | |||
free(atual); | |||
break; | |||
} | |||
else | |||
{ | |||
i++; | |||
anterior = atual; | |||
atual = (elemento *) atual->prox; | |||
} | |||
} | |||
} | |||
} | |||
// Ler caractere | |||
char SerialGetc(HANDLE *hCom) | |||
{ | |||
char rxchar; | |||
BOOL bReadRC; | |||
static DWORD iBytesRead; | |||
bReadRC = ReadFile(*hCom, &rxchar, 1, &iBytesRead, NULL); | |||
return rxchar; | |||
} | |||
// Escrever caractere | |||
void SerialPutc(HANDLE hCom, char txchar) | |||
{ | |||
BOOL bWriteRC; | |||
static DWORD iBytesWritten; | |||
bWriteRC = WriteFile(hCom, &txchar, 1, &iBytesWritten,NULL); | |||
return; | |||
} | |||
// Ler string | |||
char* SerialGets(HANDLE *hCom) | |||
{ | |||
static char rxstring[256]; | |||
char c; | |||
int pos = 0; | |||
while(pos <= 255) | |||
{ | |||
c = SerialGetc(hCom); | |||
if (c==13) break; | |||
if(c == '\r') continue; // discard carriage return | |||
rxstring[pos++] = c; | |||
if(c == '\n') break; | |||
} | |||
rxstring[pos] = 0; | |||
return rxstring; | |||
} | |||
// Escrever string | |||
void SerialPuts(HANDLE *hCom, char *txstring) | |||
{ | |||
BOOL bWriteRC; | |||
static DWORD iBytesWritten; | |||
bWriteRC = WriteFile(*hCom, txstring, strlen(txstring), &iBytesWritten,NULL); | |||
} | |||
int main(int argc, char *argv[]) | |||
{ | |||
FILE *p; | |||
DCB dcb; | |||
HANDLE hCom; | |||
BOOL fSuccess; | |||
LPCWSTR LpcCommPort = L"COM4"; | |||
int i=0, opc,on=0; | |||
char t='1'; | |||
float *vet; | |||
float *vet2; | |||
int tempo = 0; | |||
float temp; | |||
char temperatura[4],sensor[20]; | |||
int loop = 0; | |||
int c; | |||
int cr; | |||
int vetor; | |||
hCom = CreateFile( LpcCommPort, | |||
GENERIC_READ | GENERIC_WRITE, | |||
0, // must be opened with exclusive-access | |||
NULL, // no security attributes | |||
OPEN_EXISTING, // must use OPEN_EXISTING | |||
0, // not overlapped I/O | |||
NULL // hTemplate must be NULL for comm devices | |||
); | |||
if (hCom == INVALID_HANDLE_VALUE) | |||
{ | |||
// Handle the error. | |||
printf ("CreateFile failed with error %d.\n", GetLastError()); | |||
return (1); | |||
} | |||
// Build on the current configuration, and skip setting the size | |||
// of the input and output buffers with SetupComm. | |||
fSuccess = GetCommState(hCom, &dcb); | |||
if (!fSuccess) | |||
{ | |||
// Handle the error. | |||
printf ("GetCommState failed with error %d.\n", GetLastError()); | |||
return (2); | |||
} | |||
// Fill in DCB: 57,600 bps, 8 data bits, no parity, and 1 stop bit. | |||
dcb.BaudRate = CBR_9600; // set the baud rate | |||
dcb.ByteSize = 8; // data size, xmit, and rcv | |||
dcb.Parity = NOPARITY; // no parity bit | |||
dcb.StopBits = ONESTOPBIT; // one stop bit | |||
fSuccess = SetCommState(hCom, &dcb); | |||
// | |||
if (!fSuccess) | |||
{ | |||
// Handle the error. | |||
printf ("SetCommState failed with error %d.\n", GetLastError()); | |||
return (3); | |||
} | |||
printf ("Serial port %s successfully reconfigured.\n", LpcCommPort); | |||
//SerialPuts(&hCom, "This is a text\n\nAnother line!\n"); | |||
Sleep(2000); | |||
while(1) | |||
{ | |||
system("cls"); | |||
printf("OPCOES\n 1-CADASTRAR MOTOR\n 2-MOSTRAR SENSORES MOTOR\n 3-EXCLUIR MOTOR\n 4-LIGAR MANUALMENTE(ON/OFF)\n 5-ESCOLHER MOTOR\n 6-SAIR\n "); | |||
scanf("%d", &opc); | |||
switch(opc) | |||
{ | |||
case 1: | |||
cadastro(); | |||
break; | |||
case 2: | |||
{ | |||
vet=(float*)malloc(tempo*sizeof(float)); | |||
vet2=(float*)malloc(tempo*sizeof(float)); | |||
p=fopen("DadosMotor.txt","a"); | |||
while(!loop) | |||
{ | |||
printf("\MONITOR TEMPO REAL\n Aperte E para sair.\n"); | |||
tempo=1; | |||
temp=6000; | |||
sprintf(temperatura,"%.2f",temp); | |||
SerialPuts(&hCom, temperatura); | |||
Sleep(1000); | |||
while( i < tempo ) | |||
{ | |||
if ( atof(SerialGets(&hCom)) == 0) // alterna entre 0 e o valor, se esse é 0, o próximo nao é; | |||
{ | |||
vet[i]=atof(SerialGets(&hCom)); | |||
fprintf(p,"Temperatura: %f \n",vet[i]); | |||
} | |||
Sleep(500); | |||
if ( atof(SerialGets(&hCom)) == 0) // alterna entre 0 e o valor, se esse é 0, o próximo nao é; | |||
{ | |||
vet2[i]=atof(SerialGets(&hCom)); | |||
fprintf(p,"Corrente: %f\n",vet2[i]); | |||
fprintf(p,"=====================================================\n",vet2[i]); | |||
i++; | |||
} | |||
} | |||
for ( i = 0; i < tempo; i++ ) | |||
{ | |||
printf("\n Temperatura %f ", vet[i]); | |||
printf("\n Corrente %f ", vet2[i]); | |||
} | |||
i=0; | |||
Sleep(500); | |||
system("cls"); | |||
if ( kbhit()) | |||
{ | |||
c = getch(); | |||
if ( c == 'E' || c=='e') | |||
{ | |||
fclose(p); | |||
loop = 1; | |||
} | |||
} | |||
} | |||
break; | |||
} | |||
case 3: | |||
excluir(); | |||
break; | |||
case 4: | |||
printf("\n Digite '1' para ON e '0' para OFF: \n"); | |||
scanf("%i",&on); | |||
if(on==0) | |||
{ | |||
temp=-100; | |||
sprintf(temperatura,"%.2f",temp); | |||
SerialPuts(&hCom, temperatura); | |||
}else | |||
if(on==1) | |||
{ | |||
temp=100; | |||
sprintf(temperatura,"%.2f",temp); | |||
SerialPuts(&hCom, temperatura); | |||
} | |||
break; | |||
case 5: | |||
{ | |||
temp = EscolherTemperatura(); | |||
if ( temp!= 0 ) | |||
{ | |||
printf("\n Temperatura escolhida : %f\n",temp); | |||
sprintf(temperatura,"%.2f",temp); | |||
SerialPuts(&hCom, temperatura); | |||
} | |||
} | |||
break; | |||
case 6: | |||
limparlista(); | |||
exit(0); | |||
break; | |||
default: | |||
printf("Opcao nao existente"); | |||
break; | |||
} | |||
Sleep(1000); | |||
} | |||
SerialPuts(&hCom, "Fim!!\n\nMaravilha!!\n"); | |||
SerialPutc(hCom,'1'); | |||
printf ("Read value: %c\n", SerialGetc(&hCom)); | |||
CloseHandle(hCom); | |||
system("PAUSE"); | |||
return (0); | |||
} | |||
</nowiki> | |||
Edição das 19h32min de 14 de fevereiro de 2015
5W2H
What
- 1. Qual o nome do seu projeto?
- O nome escolhido para o projeto foi ControlMachine
- 2. Qual o objetivo deste projeto?
- O projeto consiste em criar um sistema de monitoramento e controle para motores industriais, visando preservar os equipamentos com a sua utilização correta.
- 3. Quais os maiores desafios, na sua opinião, para se realizar este trabalho?
- Obtenção de dados através de sensores que utilizam em sua grande maioria sinais analógicos, a interface de comunicação entre os motores e as máquinas que os utilizam. Tanto a interface lógica como a gráfica de controle vão requerer um alto processamento de dados em tempo real. A malha de comunicação entre as máquinas, motores e sistemas está entre um dos maiores desafios encontrados.
- 4. Quais os conhecimentos básicos que devemos ter para se implementar este projeto?
- Para o desenvolvimento do projeto, será necessário o conhecimento de motores elétricos e controle e acionamento do mesmo. Para a criação dos algoritmos utilizaremos a linguagem C; para a construção da rede de comunicação utilizaremos a interface USB (Universal Serial Bus) que permite uma rápida transferência de dados e uma comunicação independente entre periféricos.
- 5. Quais soluções similares existem no mercado?
- Na parte de interface lógica e gráfica conhecemos um software supervisório que é capaz de realizar um serviço similar chamado Elipse-Scada, que proporciona uma interface de controle limpa e fluida, necessitando de um sistema que faça o controle direto das minhas variáveis, como um CLP.
Existe também equipamentos de controle de motores que possuem sofisticados artifícios para a preservação do motor, como inversores de frequência modernos e soft-starter.
Why
- 1. Porque é interessante desenvolver este projeto?
- Com o uso do software que pretendemos desenvolver poderemos monitorar e através de relatórios prevenir futuros erros. Poderemos também realizar manutenções preventivas através dos dados que forem processados pelo software
- 2. Porque deve usar a tecnologia escolhida?
- A utilização do software se deve a facilidade de manuseio.
- 3. Porque usar o hardware específico?
- Utilizaremos a plataforma open source Arduíno que permite uma ampla variedade de implementos como flexibilidade na linguagem utilizada para sua programação assim como uma variada gama de sensores e dispositivos já desenvolvidos para tal plataforma, podendo ainda ser utilizado interfaces físicas desenvolvidas por nós mesmos.
- 4. Porque usar o sistema específico?
- Devemos utilizar esse sistema em especial pois não encontramos no mercado um sistema que une todos os dispositivos disponíveis.
Who
- 1. Quem pode se beneficiar deste projeto?
- O engenheiro, o técnico, o gerente e toda a linha de produção.Todos do meio industrial se beneficiarão de um controle mais eficiente, pois com ele pode-se previnir falhas ou até mesmo antecipa-las, fazendo com que cada vez menos a linha de produção pare devido a falhas técnicas.
- 2. Quem poderá operar o sistema?
- O engenheiro responsável e os técnicos.
- 3. Quem deverá participar do desenvolvimento do sistema?
- Os engenheiros e técnicos responsáveis,assim como os programadores, que serão os responsáveis por codificar o sistema.
Where
- 1. Onde os dados serão inseridos?
- No banco de dados como por exemplo o Oracle ou o mySQL.
- 2. Onde os dados serão externalizados, publicados?
- Os dados serão externalizados na interface gráfica em tempo real e em relatórios periódicos.
- 3. Onde esta aplicação poderá ser usada?
- Empresas em geral que utilizam motores elétricos de grande ou médio porte,que necessitem de um controle mais eficaz.
- 4. Onde os dados serão armazenados?
- Devemos armazenar os dados em um computador local.
- 5. Onde o software deverá ser hospedado?
- O software será armazenado juntamente com os dados.
When
- 1. Em quanto tempo pretende desenvolver o sistema?
- O tempo de desenvolvimento do sistema pode variar de acordo com as necessidades e o porte da empresa, mas a base do sistema devera ser desenvolvida em aproximadamente 90 dias.
- 2. Quais serão as fases e em quanto tempo cada uma?
- Primeira fase, estudo de campo: coletar informações do ambiente de implementação; coletar dados das máquinas; tempo: uma semana
- Segunda fase, projeto: consiste em dimensionar os componentes a serem utilizados, ou seja, a escolha dos hardware; tempo: duas semanas
- Terceira fase: codificação; tempo: um mês
- Quarta fase: implementação; tempo: um mês
- 3. Qual o tempo de resposta do dispositivo ou do sistema?
- O sistema devera operar em tempo real.
- 4. Quanto tempo para responder a uma entrada?
- O tempo de resposta varia de acordo com os equipamentos utilizados, mas está na casa dos mili-segundos.
- 5. Quanto tempo para gerar a saída?
- O tempo de uma saída depende da aplicação.
How
- 1. Como será dividido o desenvolvimento do sistema?
- O sistema sera dividido em três etapas as quais certos integrantes do grupo tomarão a frente do projeto, sendo que o desenvolvimento dos elemento do software ficara responsável aos programadores da equipe. A escolha de hardware necessária para o projeto, que é individual para cada fábrica, será determinada em conjunto com o desenvolvedor de software e o responsável por indicar quantos motores e máquinas existem em tal empresa.
- 2. Como será feita a entrada de dados?
- A entrada de dados no sistema terá inicio nos sensores utilizados, os quais estão ligados a microcontroladores em rede. Há um servidor responsável por receber os dados dessa rede, processá-los e armazena-los em um banco de dados.
- 3. Como será feita a saída de dados?
- Depois de tratados os dados de entrada podemos criar gráficos e tabelas para analisar o funcionamento de cada equipamento em especifico e em conjunto, sendo assim, podemos indicar a melhor forma de gerenciar os equipamentos.
- 4. Descreva a 1a. funcionalidade?
- Ler dados dos sensores em tempo real e externalizar esses dados.
- 5. Descreva a 2a. funcionalidade?
- Criar rotinas para processamento dos dados para proteção contra falhas. Ex: desligar um motor se a corrente de trabalho for superior durante um tempo estipulado.
- 6. Descreva a 3a. funcionalidade?
- Desligar o sistema caso ele seja codependente. Ex: um sistema que utiliza quatro motores para o perfeito funcionamento, caso um desses venha a sofrer alguma anomalia deve-se parar os outros motores instantaneamente para evitar danos e preservar o sistema.
- 7. Descreva a 4a. funcionalidade?
- Criar um banco de dados contendo a marca, o modelo, e demais informações especificas dos motores. Armazenaremos dados como: rotação, tempo de uso, ultima verificação, corrente de trabalho, e afins.
- 8. Descreva a 5a. funcionalidade?
- Criar uma rotina de manutenção com base nos dados e falhas anteriormente registrados, como uma manutenção preditiva.
- 9. Descreva a 6a. funcionalidade?
- Os sensores utilizados serão:
- Sensor de corrente
- Sensor de tensão
- Sensor de frequência
- Sensor de RPM
- Sensor de temperatura
- Os sensores utilizados serão:
How much
- 1. Quanto custa cada parte do sistema?
- O custo do hardware sera em torno de 200 reais por motor.
- O custo de implementação do software base, que será usado no servidor, será em torno de 3.500 reais
- Desenvolvimento de banco de dados será em torno de 500 reais.
- Desenvolvimento do software do microcontrolador 400 reais.
- 2. Quanto deverá custar todo o sistema?
- O custo total sera dado pela função: y(x)=5000 + 5x , onde x representa o número de motores.
- 3. Quantas pessoas deverão ser usadas (Equipe) ?
- 10 pessoas
- 4. Quanto custa cada profissional?
- 5. Qual deverá ser o preço de aquisição do seu software para o usuário final (Valor de mercado)?
- R$15.000 reais fora a aquisição dos hardwares independentes além da taxa de instalação.
- A taxa de instalação será dada pela função: y(x)= 3500 +100x, onde x é a quantidade de motores.
- O custo total será dado por: y(x)=18.500 + 300x, onde x é a quantidade de motores.
DER
DFD
DD
OBS.: As interfaces gráficas utilizadas para cada entrada estão disponíveis no final da página.
Sensor Temperatura: Utiliza um sinal digital, gerado um por um circuito integrado do próprio sensor, no caso o DS18B20. Ele trabalha na faixa de -55ºC a 125ºC, com precisão de +/-0,5ºC. A interface de comunicação é lógica, utilizando uma entrada digital do Arduino.
Vide Datasheet: datasheets.maximintegrated.com/en/ds/DS18B20.pdf
Sensor de Corrente: Tem sua comunicação feita através de sinal digital, tem um conversor A/D no próprio módulo. A corrente máxima de leitura varia conforme o modelo, mas para efeito de projeto utilizaremos um de 20A.
Vide Datasheet: http://pdf1.alldatasheet.com/datasheet-pdf/view/168326/ALLEGRO/ACS712.html
Sensor Tensão: Não existe um sensor comercial para leitura de tensões, sendo assim devemos confecciona-lo, para isso utilizamos um acoplador óptico ligado a um resistor, do outro lado temos um sinal máximo de 5v (analógico) que varia conforme a tensão de entrada. Neste ponto precisamos utilizar o conversor A/D interno do arduino, além de calibrar os valores lidos e equaciona-los.
Sugestão de modelo: http://www.cuin.com.br/2013/06/sensor-de-tensao-eletrica-versao-2/
Sensor RPM: O sensor utiliza o efeito hall para medir as rotações do eixo do motor, porém deve ser colocado neste eixo um pequeno imã. Há um módulo pronto para uso, o mesmo utiliza um sinal analógico, sendo necessária a utilização do conversor A/D interno do arduino.
Vide módulo: http://www.usinainfo.com.br/sensores-e-modulos/sensor-de-efeito-hall-com-modulo-para-arduino--2633.html
Sensor Frequência: O sensor devera ser desenvolvido, ele usará uma porta digital do arduino, o mesmo receberá uma tensão de no máximo 5V, logo é necessário atenuar a tensão da fonte com um circuito.
Ideia Inicial: http://microcontrolandos.blogspot.com.br/2013/01/frquencimetro-com-arduino.html
Coletar Dados: Para gerenciar e ler os sensores utilizaremos um Arduino Mega 2560, nele devemos tratar os dados e envia-los por um módulo Ethernet para um servidor onde os dados serão externalizados, guardados e comparados com valores estabelecidos. Tratar Dados: Não podemos utilizar valores “simples” de um sensor, devemos ler o mesmo um certo numero de vezes em um curto intervalo de tempo e fazer a sua média, só assim conseguiremos uma boa precisão. Esse processo é estabelecido pelo Administrador do sistema.
Cadastrar Sensores: O administrador deve indicar quais sensores serão utilizados, ou seja, quão estarão cadastrados no sistema. Administrador: Entidade externa responsável pela manutenção do sistema.
Comparar Dados: Compara os valores ideais de trabalho dos motores com os valores fornecidos pelos sensores. Proteger equipamentos: Função responsável por desligar os motores e afins ligados ao mesmo processo, caso os valores comparados na função anterior estejam discrepantes.
Chave Motor: São relés destinados a ligar e desligar os motores ou equipamentos.
Alarme Falha: Caso os parâmetros de operação não estejam de acordo, será soado um sinal.
Armazenar Dados: Os dados serão armazenados a cada hora, sendo que guardaremos os valores de máximo, mínimos e a média.
Mostrar Sensores em Tempo real: Tem a função de reunir os dados que estão sendo obtidos pelos sensores em tempo real.
Monitor: Entidade externa responsável por externalizar os dados da função acima através de uma interface gráfica.
Realizar manutenção: Deve indicar o momento correto para a manutenção preditiva, sendo assim devemos estipular um numero de valores discrepantes máximo, após esse valor, o equipamento deve receber a manutenção.
Gerar relatório: Teremos dois tipos, o primeiro é para o gerente, o qual está contido dados relacionados a tempo de trabalho e tempo de parada de cada equipamento. Já o engenheiro e o técnico recebem o mesmo relatório, indicando os números de falhas e quais peças foram trocadas, caso tenha a necessidade.
Tempo de trabalho: Essa função deve realizar o tempo de uso do motor desde a data de compra. Além de determinar os horários de funcionamento dos mesmos.
CRUD Máquinas: Nesta função podemos cadastrar os equipamentos que o sistema irá monitorar.
CRUD Funcionários: O cadastro dos operadores do sistema é realizado pelo gerente.
Diagrama de Classes
Diagrama de Casos de Uso
Detalhamento dos Casos de Uso
Protótipo
Dificuldades encontradas
- Durante a montagem do projeto ocorreram vários imprevistos, dentre eles um que mudou drasticamente a dinâmica de comunicação entre o arduino e o servidor. Passamos de uma interface Ethernet para USB, isso ocorreu pelo tempo que tivemos para implementar o projeto, visto que a programação é muito sofisticada e requer muito tempo e dedicação.
Outro ponto foi o alto custo dos sensores, sendo assim tivemos que utilizar apenas o de corrente e o de temperatura. E também nem todos os sensores que precisávamos para o projeto existe em módulos para o arduino, por isso é preciso desenvolver um módulo, o que também requer muito tempo e vários testes. A saga do motor também surpreendeu, o motor utilizado veio da cidade de Franca-SP, onde um dos integrantes do grupo encontrou o motor para o projeto.
Maiores desafios
- Um dos maiores desafios encontrados foi durante a programação, mesmo o projeto sendo simples tivemos muitas dificuldades, para sincronizar o arduino com o Visual C++ pois foi na tentativa e erro, por muitas vezes o arduino não enviava dados concretos para o Visual e com isso tinhamos apenas lixo de memoria nas variáveis.
Componentes utilizados
- Arduino Mega 2560
- Módulo relé
- Sensor de corrente acs712
- Módulo Lcd 20x4
- Sonda de temperatura - LM35
- Motor WEG 1/4HP - 127V
- Cabo UBS - Utilizado para a comunicação.
- Fios para as ligações
- Bancada para testes
- Fita isolante - Para fixação da sonda no motor.
Esquema de montagem
- Abaixo se encontra o esquema das ligações utilizadas no projeto, o cuidado e a atenção foram essenciais nesta etapa, visto que o risco de choques elétricos é grande.
Código utilizado no Arduino
#include <LiquidCrystal.h> // Biblioteca LCD #include <stdlib.h> #define sensor1 A0 //Define A0 como "sensor" #define sensorPin A1 LiquidCrystal lcd (38, 40, 42, 39, 41, 43);// Define os pinos utilizados pelo lcd. int rele = 8; // Define a saida digital como sendo a 8 int j=0; // contador int k=0; int y=0; int sensorValue_aux = 0; float sensorValue = 0; float currentValue = 0; float voltsporUnidade = 0.004887586;// 5%1023 int valor=0; // Variavel auxiliar para receber o valor da string ( do PC ) int tempsis=100; //Armazena a temperatura recebida do usuario (PC) float media=0; // Grava 1000 vezes a temperatura e posteriormente tira a média float Vsensor1; // Le tensão do LM35 float temp1; // Armazena a temperatura char temp[10]; char current[10]; void setup() { lcd.begin(20,4); // LCD 20x4 lcd.print(" ControlMachine "); Serial.begin(9600); // Configuração da porta serial para comunicação à taxa de 9600 bps pinMode(Vsensor1,INPUT); pinMode(rele,OUTPUT); pinMode(sensorPin,INPUT); } void loop() { if (Serial.available() > 0) { valor=Serial.parseInt(); // lê valor do motor ( PC ) } if(Serial.available()!=0){ tempsis=valor; // armazena valor recebido pelo usuario para evitar o acionamento repetido do rele } for(j=0;j<1000;j++) { Vsensor1=0; temp1=0; Vsensor1=analogRead(sensor1); temp1=(512*Vsensor1)/1023; media=media+temp1; } media=media/1000; if ( k != 0 ) { media = media - 0.6; } lcd.setCursor(0,3); lcd.print("Temp.:"); lcd.print(media); lcd.print(" C"); for(int i=1000; i>0; i--){ sensorValue_aux = (analogRead(sensorPin) -512); // le o sensor na pino analogico A0 e ajusta o valor lido ja que a saída do sensor é (1023)vcc/2 para corrente =0 sensorValue += pow(sensorValue_aux,2); // somam os quadrados das leituras. } sensorValue = (sqrt(sensorValue/ 1000)) * voltsporUnidade; // finaliza o calculo da méida quadratica e ajusta o valor lido para volts currentValue = (sensorValue/0.066); // calcula a corrente considerando a sensibilidade do sernsor (185 mV por amper) sensorValue =0; lcd.setCursor(0,2); lcd.print("Corrente.:"); lcd.print(currentValue); lcd.print(" A"); if ( tempsis == 6000 ) { dtostrf(media,4,2,temp); Serial.println(temp); dtostrf(currentValue,4,2,current); Serial.println(current); } if(media > tempsis) { digitalWrite(rele,LOW); lcd.setCursor(0,1); lcd.print("Motor ligado "); k = 1; }else { digitalWrite(rele,HIGH); lcd.setCursor(0,1); lcd.print("Motor desligado"); k = 0; }lcd.setCursor(0,1); if (tempsis==-100 || tempsis == 100 || tempsis == 6000) { if (tempsis == -100) lcd.print("MOTOR: OFF "); else lcd.print("MOTOR: ON "); } else { lcd.print("Temp MAX: "); lcd.print(tempsis); lcd.print(" C"); } delay (500); }
Código do Visual C++
#include <windows.h> #include <stdio.h> #include <dos.h> #include <conio.h> #include <stdlib.h> #include <string.h> typedef struct { float temp; char nome[20]; struct elemento *prox; }elemento; elemento *F=NULL; elemento *atual=NULL; elemento *anterior=NULL; elemento *alocarno() { elemento *novo; novo=(elemento*)malloc(sizeof(elemento)); novo->prox=NULL; return novo; } void cadastro() { float temp; char nome[20]; printf("\n\nCADASTRAR MOTOR\n NOME:"); scanf("%s", &nome); printf(" TEMPERATURA MAXIMA DE OPERACAO:"); scanf("%f", &temp); if(F==NULL) { F=alocarno(); strcpy(F->nome,nome); F->temp=temp; } else { atual=F; while(atual->prox!=NULL) { atual=(elemento*)atual->prox; } atual->prox=(struct elemento*)alocarno(); atual=(elemento*)atual->prox; strcpy(atual->nome,nome); atual->temp=temp; } system("PAUSE"); } int imprimir() { int count = 0; if(F==NULL) { printf("Lista vazia"); printf("\n"); } else { count=1; atual=F; while(atual!=NULL) { printf("\n MOTOR %d\n Motor: %s \n",count, atual->nome); printf("Temperatura MAX OP: %f \n",atual->temp); atual=(elemento*)atual->prox; count++; } } return count; } float EscolherTemperatura() { elemento *paux; int count=1, j=0, i=1; count = imprimir(); if(count==0) { return 0; } else { printf("\nEscolha entre os motores cadastrados:"); scanf("%d", &j); if(j>(count-1) || j<1) { printf("\n Numero invalido!!\n"); return 0; } else { paux=F; while(paux->prox!=NULL) { if(j==i) break; else i++; paux=(elemento*)paux->prox; } return paux->temp; } } } void limparlista() { atual=F; while(atual!=NULL) { F=(elemento*)atual->prox; free(atual); atual=F; } } void excluir() { int count = 1, i = 1, j = 0; count = imprimir(); printf("\n Escolha motor para ser excluido: \n"); scanf("%d", &j); if(j>(count-1) || j<1) printf("\n Numero invalido!!\n"); else { anterior = NULL; atual = F; while(atual!=NULL) { if(i==j) { if(anterior==NULL) { F=(elemento*)atual->prox; free(atual); break; } else { anterior->prox=atual->prox; free(atual); } anterior->prox = atual->prox; free(atual); break; } else { i++; anterior = atual; atual = (elemento *) atual->prox; } } } } // Ler caractere char SerialGetc(HANDLE *hCom) { char rxchar; BOOL bReadRC; static DWORD iBytesRead; bReadRC = ReadFile(*hCom, &rxchar, 1, &iBytesRead, NULL); return rxchar; } // Escrever caractere void SerialPutc(HANDLE hCom, char txchar) { BOOL bWriteRC; static DWORD iBytesWritten; bWriteRC = WriteFile(hCom, &txchar, 1, &iBytesWritten,NULL); return; } // Ler string char* SerialGets(HANDLE *hCom) { static char rxstring[256]; char c; int pos = 0; while(pos <= 255) { c = SerialGetc(hCom); if (c==13) break; if(c == '\r') continue; // discard carriage return rxstring[pos++] = c; if(c == '\n') break; } rxstring[pos] = 0; return rxstring; } // Escrever string void SerialPuts(HANDLE *hCom, char *txstring) { BOOL bWriteRC; static DWORD iBytesWritten; bWriteRC = WriteFile(*hCom, txstring, strlen(txstring), &iBytesWritten,NULL); } int main(int argc, char *argv[]) { FILE *p; DCB dcb; HANDLE hCom; BOOL fSuccess; LPCWSTR LpcCommPort = L"COM4"; int i=0, opc,on=0; char t='1'; float *vet; float *vet2; int tempo = 0; float temp; char temperatura[4],sensor[20]; int loop = 0; int c; int cr; int vetor; hCom = CreateFile( LpcCommPort, GENERIC_READ | GENERIC_WRITE, 0, // must be opened with exclusive-access NULL, // no security attributes OPEN_EXISTING, // must use OPEN_EXISTING 0, // not overlapped I/O NULL // hTemplate must be NULL for comm devices ); if (hCom == INVALID_HANDLE_VALUE) { // Handle the error. printf ("CreateFile failed with error %d.\n", GetLastError()); return (1); } // Build on the current configuration, and skip setting the size // of the input and output buffers with SetupComm. fSuccess = GetCommState(hCom, &dcb); if (!fSuccess) { // Handle the error. printf ("GetCommState failed with error %d.\n", GetLastError()); return (2); } // Fill in DCB: 57,600 bps, 8 data bits, no parity, and 1 stop bit. dcb.BaudRate = CBR_9600; // set the baud rate dcb.ByteSize = 8; // data size, xmit, and rcv dcb.Parity = NOPARITY; // no parity bit dcb.StopBits = ONESTOPBIT; // one stop bit fSuccess = SetCommState(hCom, &dcb); // if (!fSuccess) { // Handle the error. printf ("SetCommState failed with error %d.\n", GetLastError()); return (3); } printf ("Serial port %s successfully reconfigured.\n", LpcCommPort); //SerialPuts(&hCom, "This is a text\n\nAnother line!\n"); Sleep(2000); while(1) { system("cls"); printf("OPCOES\n 1-CADASTRAR MOTOR\n 2-MOSTRAR SENSORES MOTOR\n 3-EXCLUIR MOTOR\n 4-LIGAR MANUALMENTE(ON/OFF)\n 5-ESCOLHER MOTOR\n 6-SAIR\n "); scanf("%d", &opc); switch(opc) { case 1: cadastro(); break; case 2: { vet=(float*)malloc(tempo*sizeof(float)); vet2=(float*)malloc(tempo*sizeof(float)); p=fopen("DadosMotor.txt","a"); while(!loop) { printf("\MONITOR TEMPO REAL\n Aperte E para sair.\n"); tempo=1; temp=6000; sprintf(temperatura,"%.2f",temp); SerialPuts(&hCom, temperatura); Sleep(1000); while( i < tempo ) { if ( atof(SerialGets(&hCom)) == 0) // alterna entre 0 e o valor, se esse é 0, o próximo nao é; { vet[i]=atof(SerialGets(&hCom)); fprintf(p,"Temperatura: %f \n",vet[i]); } Sleep(500); if ( atof(SerialGets(&hCom)) == 0) // alterna entre 0 e o valor, se esse é 0, o próximo nao é; { vet2[i]=atof(SerialGets(&hCom)); fprintf(p,"Corrente: %f\n",vet2[i]); fprintf(p,"=====================================================\n",vet2[i]); i++; } } for ( i = 0; i < tempo; i++ ) { printf("\n Temperatura %f ", vet[i]); printf("\n Corrente %f ", vet2[i]); } i=0; Sleep(500); system("cls"); if ( kbhit()) { c = getch(); if ( c == 'E' || c=='e') { fclose(p); loop = 1; } } } break; } case 3: excluir(); break; case 4: printf("\n Digite '1' para ON e '0' para OFF: \n"); scanf("%i",&on); if(on==0) { temp=-100; sprintf(temperatura,"%.2f",temp); SerialPuts(&hCom, temperatura); }else if(on==1) { temp=100; sprintf(temperatura,"%.2f",temp); SerialPuts(&hCom, temperatura); } break; case 5: { temp = EscolherTemperatura(); if ( temp!= 0 ) { printf("\n Temperatura escolhida : %f\n",temp); sprintf(temperatura,"%.2f",temp); SerialPuts(&hCom, temperatura); } } break; case 6: limparlista(); exit(0); break; default: printf("Opcao nao existente"); break; } Sleep(1000); } SerialPuts(&hCom, "Fim!!\n\nMaravilha!!\n"); SerialPutc(hCom,'1'); printf ("Read value: %c\n", SerialGetc(&hCom)); CloseHandle(hCom); system("PAUSE"); return (0); }







