sábado, 24 de novembro de 2018

Arduino Sonar

Implementação de um Sonar simples. Segundo a Wikipédia, Sonar (do inglês Sound Navigation and Ranging ou “Navegação e Determinação da Distância pelo Som”) é um instrumento inicialmente usado em época de guerra para a localização de submarinos, mas que hoje em dia passou a ter muita utilização na navegação, na pesca, no estudo e pesquisa dos oceanos, estudos atmosféricos.  

Nesse projeto foi utilizado um Arduino, um sensor Ultrassônico (HC-SR04), micro servo motor 9g (SG90). Além disso, foi utilizado uma fonte externa de 5 V para o servo motor e sensor. O servo pode necessitar de muita corrente, então resolvi usar uma fonte externa, caso faça o mesmo, lembre-se de ligar o GND da fonte externa no GND do Arduino. 

O servo motor será utilizado para a movimentação do sensor ultrassônico, em um angulo entre 0-180°. Faça as ligações conforme a Figura 1.

Esquemático Sonar

Após a realização e checagem das ligações, conecte o Arduino ao computador e upload o seguinte código: 


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
#include <Servo.h>

const uint8_t trig_pin = 2;
const uint8_t echo_pin = 3;
const uint8_t servo_pin = 10;

uint8_t angle = 0;
uint16_t dist = 0;

Servo servo;

int calcula_distancia()
{
  long duracao = 0;
  
  digitalWrite(trig_pin, LOW);
  delayMicroseconds(2);

  digitalWrite(trig_pin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trig_pin, LOW);

  duracao = pulseIn(echo_pin, HIGH);
  
  return duracao*0.0343/2;
}

void setup() 
{
  servo.attach(servo_pin, 700, 2300);
  servo.write(angle);
  Serial.begin(9600);
}

void loop() 
{
  for(angle = 0; angle < 180; angle++)
  {
    servo.write(angle);
    dist = calcula_distancia();
    Serial.println(String(angle)+','+String(dist));
    delay(50);
  }

  delay(1000);

  for(angle = 180; angle > 0; angle--)
  {
    servo.write(angle);
    dist = calcula_distancia();
    Serial.println(String(angle)+','+String(dist));
    delay(50);
  }

  delay(1000);
}

Ao abrir o Monitor Serial do IDE do Arduino será possível observar informações sobre o angulo e a distancia até um obstaculo. Agora vem a parte interessante, essas informações foram utilizadas para gerar um gráfico semelhante a um sonar, para isso, foi utilizado o seguinte código em Python:


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
from serial import *
from math import*
from graphics import*

width, height = 500, 500

def limpa_tela(win):
    
    for item in win.items[4:]:
        item.undraw()

def main():
    port = 'COM8'
    baudrate = 9600
    arduino = Serial(port, baudrate)
    
    win = GraphWin("Radar", width, height)
    win.setBackground("green2")
    x_axis = Line(Point(0, height/2), Point(width, height/2))
    y_axis = Line(Point(width/2, 0), Point(width/2, height))
    
    centerPoint = Point(width/2, height/2)

    c125 = Circle(centerPoint, width/4)
    c250 = Circle(centerPoint, width/2)
    
    x_axis.draw(win)
    y_axis.draw(win)
    c125.draw(win)
    c250.draw(win)
    
    while True:
        data = arduino.readline().decode("utf-8")
        angle, dist = data.split(',')
        angle = float(angle)
        dist = float(dist)
        
        x = width/2 - cos(angle*pi/180)*dist
        y = height/2  - sin(angle*pi/180)*dist
        
        obj = Line(Point(250, 250), Point(x, y))
        obj.setFill("red")
        obj.draw(win)
                       
        if angle == 0 or angle == 180:
            limpa_tela(win)
            
if __name__ == "__main__":
    main()

Note que esse programa utiliza algumas bibliotecas, que necessitam seres instaladas anteriormente. Se tudo estiver ok, ao executar o código será gerado algo semelhante ao gráfico da figura 2.


Gráfico Radar
Ok, tenho sou obrigado a concordar, esse gráfico não é dos melhores, mas a ideia era criar algo simples mesmo. O importante é que ele funciona razoavelmente bem. Fique a vontade para modificar e melhorar os códigos dessa página. Enfim, espero que esse projeto tenha sido produtivo e inspirador para você. Até a próxima. 

<< Sumário  

sábado, 15 de setembro de 2018

Transistor de Junção Bipolar (TJB) Introdução

O transistor de Junção Bipolar (ou Transistor Bipolar) é um componente eletrônico que possui três terminais, que são: Coletor, Base e Emissor. Cada um dos terminais é formado por um material semicondutor dopado, para um TJB NPN, temos que o Coletor é formado por um material tipo N, a Base por um material tipo P e o Emissor por um material tipo N. Dessa forma, temos a formação de duas junções PN, Base-Emissor e Base-Coletor. O termo Bipolar refere-se a fato que a corrente no transistor é formada por elétrons livres e lacunas.

Existem dois tipos de TJB, o NPN e o PNP. Para o PNP, temos que o material semicondutor de cada terminal é o inverso do que foi descrito, anteriormente, para o TJB NPN. Assim, para um TJB PNP, temos que o Coletor é formado por um material tipo P, a Base por um material tipo N e o Emissor por um material tipo P. O esquemático de um transistor NPN e um PNP, respectivamente, podem ser vistos na imagem a seguir: 

Figura 1. Esquemático NPN e PNP


Operação


Para um transistor NPN, temos que a Base e o Emissor formam uma junção PN, assim, devemos polarizar essa junção diretamente, como se é feito com um diodo. Entretendo, o Emissor apresenta uma alta densidade de elétrons livres, enquanto que a Base apresenta uma baixa densidade de lacunas. Dessa forma, os elétrons livres do Emissor se recombinam com as lacunas da Base gerando um pequeno fluxo de corrente do Emissor para a Base, assim, gerando um pequeno fluxo de corrente formada por lacunas da Base para o Emissor. 

Como a densidade de lacunas é bem menor que a densidade de elétrons livres, a maior parte dos elétrons livres do Emissor não conseguem se recombinarem com as lacunas da Base e são atraídos pela tensão positiva aplicada no Coletor. Para um transistor PNP, as tensões na Base e Coletor devem ser negativas em relação à Tensão no Emissor.

Como uma pequena parte dos elétrons livres do Emissor flui para a Base. Temos que a corrente do Emissor será maior que corrente do Coletor, assim, tem-se que:

$I_{E}=I_{C}+I_{B}$

Características


A corrente da Base é, em geral, bem menor que a corrente do Coletor, dessa forma, o transistor apresenta um ganho de corrente, que é dado por:

$h_{FE}=\frac{I_{C}}{I_{B}}$

O ganho típico de um transistor é de 20 a 200 ou até bem mais. A relação entre a corrente do Coletor e do Emissor é dada por:

$\alpha=\frac{I_{C}}{I_{E}}$

Essa relação apresentará um valor sempre menor que 1, tipicamente entre 0.95 e 0.99. Um TJB é dito como uma fonte de corrente controlada por corrente, podendo ser representado pelo modelo da figura a seguir: 

Figura 2. Modelo ideal de um TBJ NPN

Pelo modelo apresentado, nota-se que a tensão entre a Base e o Emissor deve ser próxima ou maior que 0.7 V para que ocorra condução de corrente elétrica. 


Região de Operação


O TBJ apresenta três regiões de operação, que são: região de Corte, Saturação e Ativa. Assim, temos valores limites de corrente e tensão para cada região de operação.

Na região de Corte, o corrente da Base é igual a 0, com isso, impossibilitando a presença de corrente no Coletor e no Emissor.

Região de saturação, a corrente no Coletor é limitada pela carga ligada entre a fonte e o Coletor, dessa forma, a corrente do Coletor independe da corrente da Base.

Região Ativa, temos que a corrente no Coletor é diretamente proporcional a corrente da Base. As regiões de operação do TJB podem ser resumidas pelo gráfico a seguir:

Figura 3. Curva característica 

Nota-se que para cada corrente de Base existe uma corrente de Coletor máxima, além disso, é apresentada a região de ruptura que representa a tensão máxima entre Coletor e Emissor suportada pelo TJB. A partir desse gráfico, é possível ainda, traçar a curva de carga do TJB.

Além da tensão máxima entre Coletor e Emissor, outra limitação de operação do TJB, como todo componente eletrônico, é a sua potência, dada por:

$P=V_{CE}\times I_{C}$

Assim, para uma tensão máxima entre Coletor e Emissor, pode-se calcular a corrente máxima do Coletor por:

$I_{C}=\frac{P_{MAX}}{V_{CE}}$

Com isso, encerra-se a primeira parte do conteúdo sobre Transistor Bipolar nesta página, a segunda parte abordará suas aplicações. Até lá e parabéns por ter chegado até aqui.

<< Diodo Aplicações                                                                                                  TJB Aplicações >>

quinta-feira, 6 de setembro de 2018

Arduino Controlador PI de Luminosidade

Implementação de um controlador PI para o controle da luminosidade do ambiente. O valor da luminosidade desejada será ajustado pelo uso das teclas “+” e “-”, onde para “+” seu valor será incrementado em 50 e para “-” seu valor será decrementado em 50.

Um controlador PI ou controlador proporcional-integral é utilizado em sistemas de controle para controlar a estabilidade de um sistema. Funcionando da seguinte forma, o controlador utiliza um sensor para as leituras do sinal na saída no sistema, esse valor é então comparado com o sinal desejado (setpoint), resultando em um erro. O esse é utilizado para o controle do sinal, onde o sinal será proporcional à integral do erro. Dessa forma, o sinal do sistema será dado pela seguinte equação (lei de controle PI):

$Sinal(t)=KP \times Erro(t)+KI \times \int_{0}^{t}Erro(t)dt $

Onde:

$Erro(t)=setpoint-leitura$

$KP$ e $KI$ são constantes de ganho

A teoria de controle é um assunto bastante extenso, a intenção aqui é apenas dá uma pequena ideia do que é possível ser realizado. Faça as ligações como na imagem a seguir: 

Figura 1. Controlador PI de luminosidade
O sensor do sistema é um divisor de tensão formado por um LDR (Light Dependent Resistor) e um resistor de 4.7 kΩ, a resistência do LDR é proporcional à luminosidade que incide sobre ele, assim, quanto maior a luminosidade, menor será sua resistência. Dessa forma, temos um sensor de luminosidade simples.

O LED branco (de preferência de alto brilho) é o atuador do sistema, seu brilho será controlador por um sinal PWM, que será calculado de acordo com a lei de controle PI. Dessa forma, o LDR deve ser colocado próximo do LED, para que sua luz incida sobre o LDR (caso necessário, encurte os terminais do LDR).

Com o circuito montado, procure um ambiente com pouca luminosidade, conecte o Arduino ao computador e upload o seguinte código:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
uint8_t pinLDR = 0;    // LDR no pino analógico A0
uint8_t pinLed = 10;   // LED no pino 10

char setSerial = 0;    // Valor enviado pelo monitor
uint16_t lum = 0;      // Luminosidade lida
uint16_t setLum = 550; // Luminosidade desejada
int16_t erro = 0;      // Erro entre as luminosidades
int16_t somaErro = 0;  // Soma os erros
int16_t duty = 0;      // Duty para luminosidade do LED

float KP = 1.25; // Constante de ganho da lei de controle
float KI = 0.75; // Constante de ganho da lei de controle

void setup()
{
  Serial.begin(9600); // Configura comunicação serial, baudrate = 9600
}

void loop()
{
  lum = analogRead(pinLDR); // Lê e armazena o valor do LDR (Luminosidade)
  erro = setLum - lum;      // Calcula o erro
  somaErro+= erro;          // Acumula o erro

  duty = KP*erro + KI*somaErro; // Calcula o duty ideal

  if(duty > 1023)  // Limita o valor máximo de duty em 1023
  {
    duty = 1023;
  }

  if(duty < 0)  // Limita o valor mínimo de duty em 0
  {
    duty = 0;
  }
  
  duty = map(duty, 0, 1023, 0, 255); // Muda a escala do duty

  analogWrite(pinLed, duty); // Ativa o PWM no LED 

  if(Serial.available()) // Espera o recebimento de dados pelo monitor
  {
    setSerial = Serial.read(); // setSerial recebe o char enviado

    switch(setSerial) 
    {
      case 43: // caso setSerial = "+" -> setLum = setLum + 50
        setLum+=50;
        break;

      case 45: // caso setSerial = "-" -> setLum = setLum - 50
        setLum-=50;
        break;
    }

    if(setLum > 1000)  // Limita o valor máximo de setLum em 1000
    {
      setLum = 1000;
    }
  
    if(setLum < 0)  // Limita o valor mínimo de setLum em 0
    {
      setLum = 0;
    }
  }
  
  Serial.print("lum = ");    // Envia os dados para o monitor
  Serial.println(lum);
  Serial.print("setLum = ");
  Serial.println(setLum);
  Serial.print("Duty = ");
  Serial.println(duty);
  delay(1000);
}

Abra o Monitor Serial do IDE do Arduino para observar a atuação do controlador PI. O valor do setpoint (setLum) foi inicializado com um valor de 550, assim, o valor do sinal PWM será gradativamente ajustado para que o valor do sensor de luminosidade estabilize próximo de 550.

Caso ocorra um aumento na luminosidade (janela ou porta seja aberta, luz externa seja acessa) o sinal PWM se ajustará a nova luminosidade do ambiente. Então, bastante impressionante, concorda?

Fique à vontade para modificar o código, por exemplo, modifique os valores de KP e KI e observe como o sistema se comporta. Enfim, espero que tenha achado interessante esse assunto, pesquise mais sobre a teoria de controle. 

<< Sumário