Contatos

e-mail: daniloxc@msn.com

Skype: Daniloxc1

Pages

segunda-feira, 10 de agosto de 2015

Programação em PHP

Brevemente farei uma postagem de como desenvolver um website e uma webapp utilizando a linguagem PHP e utilizando o Framework Yii.

terça-feira, 1 de outubro de 2013

Projeto de Controlador para um Sistema de Nível

Os sistemas de controle de nível são um dos mais utilizados nas industrias, laboratórios, ambiente acadêmico etc. De modo a internalizar conceitos relativos a física, controle de processos, projeto de microcontroladores, eletrônica etc, este tipo de sistema é inter e multidisciplinar. Pois, além de necessitar de conhecimentos físicos dos processos, os profissionais da área de automação e controle precisará de conhecimentos na área de eletrônica e programação e terá de saber como linkar tais conceitos. Nesta postagem, utilizando o software Simulink-Matlab, irei elaborar uma modelagem de um sistema de controle de nível simples e projetar um controlador PID para este sistema. Primeiramente, iremos fazer a modelagem matemática do sistema de nível.

Percebemos então que o sistema é composto de um reservatório de água (Tanque) e uma bomba. 
O reservatório tem uma entrada (através da bomba) e uma saída (através de um orifício no fundo do tanque). Note que, podemos controlar o nível do tanque, e consequentemente, a vazão de saída através da vazão de entrada que será fornecida pela bomba dágua. 
Então teremos:
  1. Vazão de Entrada - Variável manipulada
  2. Nível do tanque - Variável controlada
Abaixo, temos uma forma mais simples para chegarmos até a equação diferencial que representará este sistema:
Onde:
qi1 - Vazão de entrada
q1 - Vazão de saída
R1 - Resistência à vazão de entrada (Onde a bomba atuará)
R2 - Resistência à vazao de saída
A1 - Área do tanque - Como a área não varia de acordo a altura, A1 será a capacitância
h1 - Nível do tanque

Resistência será a relação entre Variação na diferença de nível sobre a variação do fluxo de líquido. A resistência nos dará a relação de quanto de líquido que teremos que acumular para que a vazão de saída aumente em uma unidade.

Capacitância nos dará a relação de quanto o tanque é capaz de armazenar.

A equação ficará da seguinte maneira:

A1.h1'(t) = (dH - h1)/R1 - h1/R2

Ou seja, a variação do nível do recipiente será dado pela vazão de entrada menos a vazão de saída.
Perceba que o primeiro termo da equação é qi1 e o segundo é q1.

Modelando no simulink teremos:

Perceba que temos 1 integrador no sistema, devido a este ser caracterizado como sistema de primeira ordem.
Agora aplicarei algumas entradas através do bloco step, apenas modificando a amplitude para observamos como se comporta a saída (scope). Não podemos esquecer de atribuir valores para as variáveis Rin, Rout e At.

Ao aplicarmos uma entrada em degrau com amplitude 1, temos este resultado:
Percebemos então que a saída não consegue acompanhar a entrada.
Apliquemos agora um degrau com amplitude 8.
Perceba que ele se estabiliza, porém não no valor desejado que seria 8.
Notamos que o sistema necessita de um controlador.
Introduzirmos o controlador PID no sistema:

E agora vamos sintonizá-lo com sistema de nível:

Agora, nós poderemos utilizar os parâmetros do controlador PID para satisfazer nossa necessidade. Um controlador P.I.D. é constituído de:
P - Proporcional: Quanto maior for a diferença entre o Setpoint e o que o sistema estará retornando, maior será a resposta para a correção deste erro, ou seja é uma resposta proporcional.
I - Integral: Existem erros que permanecem no estado estacionário de sistemas, estes são chamados de erros estáticos. A parcela integral do controlador serve para sanar tal problema, eliminando assim o erro no estado estacionário. 
D - Derivativo: Esta parcela consegue prever o comportamento da resposta do controlador, fazendo com que ele tome ações prevendo o que irá acontecer posteriormente, esta parcela trabalha com a derivada, ou seja, saberemos qual será o coeficiente angular da reta tangente à todos pontos da curva de resposta ao erro e assim, poderemos predizer comportamentos.

Nota: É importante salientar que as parcelas I e D, puramente não conseguem realizar o controle de um sistema, sendo assim, sempre necessária a parcela P.

Após pressionarmos o botão tune, aparecerá esta tela interativa, você poderá escolher o tempo de resposta para o sistema. Note que, sempre que ganhamos em uma característica perderemos em outra, portanto é de suma importância sabermos qual as necessidades reais do sistema, para projetarmos corretamente o controlador.



Após tudo configurado, a resposta do sistema será a seguinte:


O sistema responde satisfatoriamente.








sexta-feira, 6 de setembro de 2013

Python + Simulino (Simulador do Arduino) no ISIS Proteus



Olá, hoje nós iremos fazer uma comunicação entre o IDLE do Python 2.7.
Para comunicarmos com a porta serial através do Python, é preciso baixar a biblioteca serial.py, segue o link:
https://pypi.python.org/pypi/pyserial
Descompacte na pasta do python, localize a pasta através do prompt de comando e digite:
python setup.py install

Para testar se foi instalado corretamente basta abrirmos a o python no prompt do DOS, digitando python e depois import serial. (Veja abaixo)
Se não apresentar nenhuma mensagem de erro, a instalação foi feita corretamente.

Segue abaixo o circuito feito no proteus:
O Simulino do Arduino Uno você encontrará em: http://blogembarcado.blogspot.com.br
Temos que fazer algumas configurações no componente COMPIM, utilizar largura de banda:9600 e a porta COM1 (estou usando a COM 1 aqui para o Simulino e COM 2 para o objeto Serial do Python)
Para fazer esta ligação entre Python e Simulino, precisamos de um software que gere portas COM virtuais.
Utilizaremos o Virtual Serial Port Emulator (link: http://www.baixaki.com.br/download/free-virtual-serial-ports-emulator.htm)

Após instalá-lo, geramos as portas virtuais:

Escolha 'pair' para fazer com que tudo que aconteça numa porta ocorra na outra, aqui estou a utilizar COM1 e COM2.
Vídeo:


Código feito para o Arduino:
 int led_biby = 13;  
 int led_blue = 12;  
 int led_yellow = 11;  
 int led_red = 10;  
 char var;  
 void setup(){  
  pinMode(led_biby, OUTPUT);  
  pinMode(led_blue, OUTPUT);  
  pinMode(led_yellow, OUTPUT);  
  pinMode(led_red, OUTPUT);  
  Serial.begin(9600);  
 }  
 void loop(){  
  digitalWrite(led_biby, LOW);  
  digitalWrite(led_blue, LOW);  
  digitalWrite(led_yellow, LOW);  
  digitalWrite(led_red, LOW);  
  if(Serial.available()>0){  
   var = Serial.read();  
   switch (var){  
   case 'a':  
    digitalWrite(led_biby, HIGH);  
    Serial.print("Led Biby is on");  
    delay(300);  
    break;  
   case 'b':  
    digitalWrite(led_blue, HIGH);  
    Serial.print("Led Blue is on");  
    delay(300);  
    break;  
   case 'y':  
    digitalWrite(led_yellow, HIGH);  
    Serial.print("Led Yellow is on");  
    delay(300);  
    break;  
   case 'r':  
    digitalWrite(led_red, HIGH);  
    Serial.print("Led Red is on");  
    delay(300);  
    break;  
   default:  
    break;  
   }  
  }  
 }  
Código feito no Python:
 #importa a biblioteca serial encontrada no endereço: https://pypi.python.org/pypi/pyserial  
 import serial  
 #cria-se um objeto com o nome arduino que se comunicará com o proteus  
 arduino_uno = serial.Serial()  
 #define qual porta COM arduino será conectado (Estou utilizando windows)  
 arduino_uno.port = 1  
 #define qual o timeout para comunicação entre o idle do python e o simulino  
 arduino_uno.timeout = 2  
 #começa a comunicação  
 arduino_uno.open()  
 ligar_led='e'  
 #loop para comunicação  
 while(ligar_led!='s'):  
   ligar_led = raw_input('Informe qual led queres ligar (a, b, y ou r) para sair informe s: ')  
   arduino_uno.write(ligar_led)  
   print(arduino_uno.readall()+'\n\n')  
 #fecha comunicaçao  
 arduino_uno.close()  

segunda-feira, 15 de julho de 2013

Modelagem de Churrasqueira - Sketchup

SketchUp é um software proprietário para a criação de modelos em 3D no computador. Foi originalmente desenvolvido pela At Last Software(@last software), uma empresa estadunidense com sede em BoulderColorado, a qual foi adquirida pela Google, como anunciado a 14 de Março de 2006. Em 2012 Trimble Navigation adquiriu o programa. O SketchUp está disponível em duas versões: a versão profissional, Pro, e a versão gratuita, Make, (para uso privado, não comercial). No site em inglês do SketchUp, você encontra para download a versão 2013 em inglês do software.
(Wikipédia)

O Sketchup é um software de fácil manuseio para se fazer modelagens 3D dos mais diversos tipos.

Muito útil quando se tem que fazer apresentações
Utilizando deste software fiz a modelagem de uma churrasqueira, seguem as imagens:



Gastando pouco tempo (Menos de 30 mins), modelei esta churrasqueira.


sexta-feira, 12 de julho de 2013

Programa de geração de quadrados mágicos com função recursiva

Anteriormente postei um programa feito em C, em que gerava quadrados mágicos de ordem [3x3].
Utilizando a linguagem de programação Python, através de uma função recursiva para geração de todas as combinações possíveis de números, consegui fazer um programa onde é possível a geração de quaisquer quadrado mágico. Porém, requer mais tempo. Segue o código
 from math import sqrt  
 """Esta função verifica se todos os termos do vetor são únicos"""  
 def unico(vet):  
      cont=0  
      uni=True  
      for each_term in vet:  
           for this_term in vet:  
                if each_term==this_term:  
                     cont+=1  
                     if(cont>1):  
                          uni=False  
           cont=0  
      return uni  
 """Esta é a função para comparar linhas, colunas e diagonais do quadrado mágico  
 Ela exige a passagem de um vetor como parâmetro. Obs.: 'Esta função somente funciona com vetores os quais sua ordem tenham raizes quadradas exatas"""  
 def compare(vet):  
      ordem=int(sqrt(len(vet)))  
      somas=[]  
      somas2=[]  
      somas3=[0]  
      somas4=[0]  
      magicSquare=False  
      acm=0  
      i=0  
      for each_term in vet:  
           acm+=each_term  
           if ((vet.index(each_term)+1)%ordem==0):  
                somas.append(acm)  
                acm=0  
      acm=0  
      for each_index in range(0,ordem):  
           somas2.append(0)  
      for each_term in vet:  
           somas2[i]+=each_term  
           i+=1  
           if i==ordem:  
                i=0  
      for inx in range(0,ordem):  
           somas3[0]+=vet[inx*(ordem+1)]  
           somas4[0]+=vet[(len(vet)-1)-(1+inx)*(ordem-1)]  
      somas=set(somas)  
      somas2=set(somas2)  
      somas3=set(somas3)  
      somas4=set(somas4)  
      if (somas==somas2==somas3==somas4):  
           magicSquare=True  
      return magicSquare  
 """Esta função gera todas as combinações possíveis de acordo a ordem passada do vetor  
 Exemplo merge(vet, len(vet), len(vet)-1)"""  
 def merge (vet, tam, it):  
   quad=[]  
   if it>0:  
     for each_term in vet:  
       merge(vet, tam, it-1)  
       vet[it]+=1  
     vet[it]=1  
   else:  
     for each_term in vet:  
       if(unico(vet)):  
         if compare(vet):  
           quad.append(vet)     
       print(vet)  
       vet[it]+=1  
     vet[it]=1  
   return quad  
 vet=[1 for each_term in range(1,10)]  
 print(merge(vet, len(vet), len(vet)-1))  
ShotScreen do programa em funcionamento

segunda-feira, 20 de maio de 2013

Programa de Controle - Sumô de Robô | Medusa Software

Segue explicações e regras para a confecção de um robô de sumô
http://www.area1.edu.br/_media/textos/2832013164658.pdf

Para a construção da parte física do Robô Medusa utilizamos placas de zinco, a estrutura física foi concebida por meu colega Leandro Leal.
* Motores de vidro elétrico da Bosch.
* Baterias de lítio de 12V, 2200mAH.
* Placa microcontroladora Arduino Uno, baseada no Microcontrolador ATmega328

http://arduino.cc/en/Main/arduinoBoardUno
* Sensores Infravermelhos (Utilizados para 'enxergar' a borda)
* Sensor Ultrassônico para enxergar o oponente.




Segue o programa de controle do robô.
Note que, quando o programa está em funcionamento, só utilizamos a função delay() quando ele encontra a borda. Isto é feito como medida de sobrevivência.

Porém, não é recomendável utilizar a função de delay() quando necessitamos que um equipamento realize diversas tarefas simultaneamente. Desta forma, utilizamos um conceito conhecido como Multitarefa (Multithread) para que fosse possível que 'ao mesmo tempo' o robô procurasse o oponente e verificasse se teria encontrado a borda.





 /*Este programa foi elaborado para controlar um robô de sumô*/  
 #define borda 2 //definimos que no pino 2 será conectado o sensor de borda  
 #define trigger 13 //definimos que o pino 13 funcionará como trigger do sensor ultrasônico  
 #define echo 7 //definimos o pino 7 como echo do sensor ultrasônico  
 #define motorDir01 6 //definimos que a porta 5 será o bit 1 da ponte H do motor direito (0x)  
 #define motorDir02 5 //definimos que a porta 6 será o bit 2 da ponte H do motor direito (x0)  
 #define motorEsq01 4 //definimos que a porta 3 será o bit 1 da ponte H do motor esquerdo(0x)  
 #define motorEsq02 3 //definimos que a porta 4 será o bit 1 da ponte H do motor esquerdo(x0)  
 //a ponte H funciona da seguinte maneira: (motorDir01,motorDir02,motorEsq01,motorEsq02)  
 // (0,1,0,1) Anda pra frente  
 // (1,0,1,0) Anda pra trás  
 // (0,0,0,0) Parado  
 // (1,1,1,1) Parado, condição não recomendada  
 /*********************Estrutura utilizada para realizar multitarefa ***************************/  
 typedef struct Timer  
 {  
   unsigned long start;//Armazena o tempo de quando foi iniciado o timer  
   unsigned long timeout;//Tempo após o start para o estouro  
 };  
 unsigned long Now ( void )  
 {  
   return millis ( );//Retorna os milisegundos depois do reset  
 }  
 boolean TimerEstorou (struct Timer * timer)  
 {  
   //Verifica se o timer estourou  
   if ( Now () > timer->start + timer->timeout) {  
     return true;  
   }  
   return false;   
 }  
 //após o tempo estourar temos que iniciar o timer com o tempo atual  
 void timerStart(struct Timer * timer){  
   timer->start = Now();  
 }  
 void timerDesloc(struct Timer * timer, unsigned long tempo){  
  timer->start = Now()+tempo;  
 }  
 Timer timerBorda = {0, 10}; //Verifica se achou a borda a cada 10 milisegundos  
 Timer timerAchou = {0, 100}; //verifica se achou o oponente a cada 100 milisegundos  
 Timer timerFrente = {0, 800}; //tempo que o robô passa indo pra frente  
 Timer timerGira = {0, 3243}; //tempo que o robô passa girando  
 Timer timerfinal = {0, 85000};// tempo de 1:30 minutos, final do round  
 boolean sentidoGiro=true; //variável criada para o robô girar hora pra direita, hora pra esquerda  
 /********** Função preparatória ****************/  
 void setup(){  
  // pinos definidos como saída  
  pinMode(motorDir01, OUTPUT);  
  pinMode(motorDir02, OUTPUT);  
  pinMode(motorEsq01, OUTPUT);  
  pinMode(motorEsq02, OUTPUT);  
  pinMode(trigger, OUTPUT);  
  // pinos definidos como entrada  
  pinMode(borda, INPUT);  
  pinMode(echo, INPUT);  
  //chama a função parado e espera 3 segundos antes de começar a luta.  
  parado();  
  delay(5000); //espera de 5 segundos antes do início da partida. Este parâmetro foi alterado para 3000 pois //quando testamos com o delay(5000) o robô ficava 7 segundos parado.  
  timerFrente.start= Now() - timerFrente.timeout; // atrasamos o Start do tempo de ir pra frente de modo ao robô começar a luta indo pra frente.  
  timerGira.start= Now();  
  timerAchou.start= Now();  
 }  
 int i=0;  
 void loop(){  
 if(TimerEstorou(&timerfinal)){  
  while(1)  
   parado();// função a ser chamada no final de cada round. Se o robô continuar andando isso caracteriza punição  
 }  
 if(i=0)  
 {  
  timerStart(&timerBorda);  
  timerStart(&timerGira);  
  timerStart(&timerAchou);  
  i+=1;  
 }  
 if(TimerEstorou(& timerFrente)){  
  andaFrente();  
  timerStart(& timerFrente);  
  //timerStart(& timerGira);  
 }  
 if(TimerEstorou(& timerBorda)){  
  if(!digitalRead(borda)){// verifica se achou a borda -- ver pino nomeado como borda  
   andaTras();  
   delay(1000);//delay de sobrevivência  
   timerStart(& timerFrente);//colocar o timer frente no início de seu ciclo  
   timerDesloc(& timerGira, -timerGira.timeout);// faz com que o robô gire  
   timerStart(& timerAchou);  
  }  
  timerStart(& timerBorda);  
 }  
 //dentro da função achou tem um delay,porém é na casa dos Microssegundos e isso o torna desprezível  
 if(TimerEstorou(& timerAchou)){  
  if(achou()){  
   andaFrente();  
   timerStart(& timerGira);  
  }  
  timerStart(& timerAchou);  
 }  
 if(TimerEstorou(& timerGira)){  
  if(sentidoGiro){  
   giraDireita();  
   sentidoGiro=!sentidoGiro;  
  }  
  else  
  {  
   giraEsquerda();  
   sentidoGiro=!sentidoGiro;  
  }  
  timerStart(& timerGira);  
 }  
 }  
 /********** Funções de movimento ****************/  
 void andaFrente(){  
  digitalWrite(motorDir01, HIGH);  
  digitalWrite(motorDir02, LOW);  
  digitalWrite(motorEsq01, HIGH);  
  digitalWrite(motorEsq02, LOW);  
 }  
 void andaTras(){  
  digitalWrite(motorDir01, LOW);  
  digitalWrite(motorDir02, HIGH);  
  digitalWrite(motorEsq01, LOW);  
  digitalWrite(motorEsq02, HIGH);  
 }  
 void parado(){  
  digitalWrite(motorDir01, LOW);  
  digitalWrite(motorDir02, LOW);  
  digitalWrite(motorEsq01, LOW);  
  digitalWrite(motorEsq02, LOW);  
 }  
 void giraDireita(){  
  digitalWrite(motorDir01, HIGH);  
  digitalWrite(motorDir02, LOW);  
  digitalWrite(motorEsq01, LOW);  
  digitalWrite(motorEsq02, HIGH);  
 }  
 void giraEsquerda(){  
  digitalWrite(motorDir01, LOW);  
  digitalWrite(motorDir02, HIGH);  
  digitalWrite(motorEsq01, HIGH);  
  digitalWrite(motorEsq02, LOW);  
 }  
 /********** Função de busca ****************/  
 float distancia() {  
  float tempo, dist;  
  digitalWrite(trigger, LOW);  
  delayMicroseconds(2);  
  digitalWrite(trigger, HIGH);  
  delayMicroseconds(10);  
  tempo = pulseIn(echo, HIGH);  
  dist = (((tempo/2) * 350)/1000000);  
  dist *= 100;  
  return dist;  
 }  
 boolean achou(){  
  /*if(giro)  
   giraHorario();  
  else  
   giraAnti();*/  
  if (distancia()<55)  
   return true;  
  else  
   return false;  
 }  
Fotos do robô





quinta-feira, 16 de maio de 2013

Autocad - Perspectiva Isométrica

Algumas vezes é necessário fazer desenhos em perspectivas para a melhor implementação de um projeto.
No AutoCAD temos um recurso que facilita o desenho em perspectiva isométrica.
Segue vídeo explicando como utilizar tal recurso.


http://www.youtube.com/watch?v=ODXyYdokdfE