Postagem em destaque

Controle PID de Potência em Corrente Alternada - Arduino e TRIAC - Parte I

Este post é o primeiro de uma série de seis que escrevi tratando de controle de potência e PID (controle proporcional, integral e derivativo...

domingo, 23 de março de 2014

Fotografia/fimagem time-lapse com Raspberry Pi

Ano passado comprei um Raspberry Pi e comecei a me divertir com ele. Tenho arduinado já há alguns anos, e foi uma ótima ter incorporado o Pi aos meus brinquedinhos.
Junto com ele comprei uma câmera, desenvolvida para o Pi. A bichinha é valente, full HD. Fotografa e filma, mas não tem microfone para as filmagens. O ponto negativo é que ela é conectada ao Pi com um flat muito delicado, que eu acho que nem vai durar muito na minha mão. Aliás ela é toda muito delicada, como vc pode ver abaixo:

 

Eu comprei um suporte que protege-a um pouco, mas mesmo assim...



















Ontem resolvi estudar o comando da câmera pelo Pi, e como a melhor linguagem de programação do mundo da última semana é o Python, tomei logo esse rumo.

Pesquisa dali e daqui, achei essa lib, que prometia comandar as muitas features da camerazinha. Fiz então uma aplicação chamada piCamExplorer.py, que roda no Pi e faz as seguintes coisas:

python piCamExplorer.py -mp: tira uma foto e armazena no arquivo pict1.jpg.

python piCamExplorer.py -mm -i10: entra no modo filme, exibindo o que a câmera "vê" durante o intervalo especificado em -i, em segundos.

python piCamExplorer.py -mt -i10 -mt -n1000 -i5 -d3600: entra no modo timelapse, tirando -n fotos em sequencia, a um intervalo de -i segundos, depois de um delay de -d segundos (serve por exemplo prá vc fotografar o nascer do sol sem ter que ficar acordado até de madrugada). As fotos são numeradas como pic00000.jpg, pic00001.jpg e assim por diante.
Depois fica fácil de vc, com um programa tipo mencoder, transformar as imagens no filme como esse abaixo. Os fontes do programa python estão aqui. Nesse outro post vc vê o resultado. Posicionei a câmera junto à janela, de modo a "passar" pelas grades do ap, assim:





No meu "modo de vista"...

Um domingão assim...


Fica mais divertido se visto... assim:



PS: Para um "making of", clique cá.


Aqui, o dispositivo responsável pela mágica:























Para um "making of", clique .

sábado, 22 de março de 2014

Código fonte do arquivo piCamExplorer.py.

O código fonte aplicação piCamExplorer.py segue abaixo.
# programa piCamExplorer.py
# Copywright by Mauro Assis (assismauro@hotmail.com)
import time
import picamera
import sys
import cv2
import getopt

camera = picamera.PiCamera()

def header():
    print
    print 'piCamExplorer v0.9'
    print

def usage():
    print
    print 'Usage: pyhton piCamExplorer -m(mode m,p or t) -d(secs delay) -n(numbers of pics) -i(secs interval) -h(help)'
    print
    
def main():
    nPic = 10
    interval = 10
    delay = 0
# processa linha de comando
    try:    
        opts, args = getopt.getopt(sys.argv[1:],'m:d:n:i:h')
    except getopt.GetoptError:
        usage()
        sys.exit(2)
    camera.resolution = (1024, 768)
    camera.vflip = True
    mode = ''
    for opt, arg in opts:
        if opt == '-h':
            usage()
        elif opt == '-m':
            mode = arg;
        elif opt == '-n':
            nPic = int(arg)
        elif opt == '-i':
            interval = int(arg)
        elif opt == '-d':
            delay = int(arg)
# funções            
# filme
    if mode == 'm':
        print 'Movie mode'
        camera.start_preview()
        time.sleep(interval)
        camera.stop_preview()
    elif mode == 'p':
# foto 
        print 'Picture mode'
        camera.capture('pict.jpg')
        time.sleep(2);
        img = cv2.imread('pict.jpg')
        cv2.imshow('pict',img)
        cv2.waitKey(0)
        cv2.destroyAllWindows()
# timeslice
  elif mode == 't':
        print 'Time-lapse mode'
        print 'Delay (h): ', float(delay)/3600.0
        print 'Now: ',time.ctime()
        time.sleep(delay)
        print 'Start time: ',time.ctime()
        for i in range(0,nPic):
            fName='pict'+str(i).rjust(5,'0')+'.jpg'
            camera.capture(fName)
            print fName
            time.sleep(interval)
    
header()
try:
    main()
except:
    print 'Error: ',sys.exc_info()[0]
    usage()
    


domingo, 9 de março de 2014

Controlando o acionamento e velocidade de um motor CC com Arduino e transistor

Ontem, no Automação no Parque, contrariando as minhas expectativas, o movimento foi muito bom. Alguns trainees, o Euclas trabalhando em um projeto dele próprio, e outros.

Choveu bastante, e como o telhado do quiosque não tá lá essas coisas, deu o que fazer para a gente conseguir posicionar as mesas de maneira a escaparmos das goteiras. É que eletrônicos e água geralmente não se dão bem, como vcs sabem...





Achada uma posição como poucas e fracas goteiras, volta ao trabalho.

Apareceu por lá um ex-aluno com um projeto de um mecanismo de ajuste de pH de soluções. Consiste em um pHgâmetro que captará o pH da solução, enviando ao Arduino. Este fará o ajuste do circuito acionando uma de duas bombas ligadas respectivamente a soluções ácida e básica.

Ele trouxe o sensor, testamos, funcionou. Trouxe tb as bombas, mas não tínhamos fonte capaz de acioná-las. Como elas são tocadas por motores CC, resolvemos montar o circuito de controle do motor, para adiantar.

Apesar de não precisarmos controlar o sentido de rotação do motor (já que isso não faz sentido para uma bomba), primeiro tentamos usar uma plaquinha driver que o camarada tinha, essa aqui à esquerda, código ZC-A0591.

Ela é usada para se controlar motores de passo, e na minha cabeça deveria funcionar para motores CC. Não foi o que aconteceu, testamos num motor CC de 5V e nada de acionar.

Como a gente não tinha que mudar de direção, mas só acionar e controlar a velocidade, resolvemos fazer uma outra implementação, mais simples, usando transistor. O transistor é necessário porque o Arduino não aguenta mais do que uns 40, 50 mA de corrente em suas portas, e a gente mediu no motor uma corrente de 250 mA.




Abaixo, esquema do circuito que usamos:

Bem simples e barato, o circuito usa um TIP120, transistor tipo Darlington que consegue "administrar" 5A, muito mais  do que o que o motor precisa.

O resistor de 220 mA serve para limitar a corrente de base em 22 mA, bem menos que os 120 mA que o TIP120 "guenta".

O diodo 1N4001 serve para evitar que a corrente gerada pelo motor quando ele é desligado atinja o transistor e o resto do circuito.



Montado o "circuitim", toca a fazer o programa, também bem simples:


#define pinControl 10

void setup()
{
  Serial.begin(9600);
  pinMode(pinControl,OUTPUT);
}

void runAndWait(int speed, int interval)
{
  analogWrite(pinControl,speed);
  delay(interval);
}

void loop()
{
  runAndWait(100,2000);
  runAndWait(150,2000);
  runAndWait(200,2000);
  runAndWait(250,2000);
}

O pino 10 (pode ser qualquer outro, desde que seja PWM) controla o motor. A função runAndWait aciona o motor com a velocidade speed, durante o intervalo de tempo interval, em milissegundos.

No loop o programa aciona o motor em quatro velocidades distintas (abaixo de 100 ele não gira, a corrente fica muito baixa).

Observe que, se fôssemos apenas ligar e desligar o motor, poderíamos utilizar um relé. Ocorre que, para controlar a velocidade, precisamos passar a "variação de tensão" (entre aspas porque é PWM), só podemos usar um transistor, já que o relé tem partes mecânicas e não pode portanto ser chaveado com a rapidez necessária para o PWM.

Agora, mesmo que só precisássemos ligar e desligar o motor, o uso do TIP120 é bastante interessante, já que ele é barato, possivelmente mais do que o relé, é absolutamente silencioso e, por não ter partes móveis, deve durar mais.

Observação: depois que terminei esse post descobri um jeito de ligar a plaquinha lá em cima de maneira a que ela ela controle motores CC. O texto do cara pode ser visto aqui. Vou ligá-la na próxima semana e testar prá ver se rola.

Abaixo vídeo da bagaça funcionando:


Dividindo um programa (sketch) do Arduino em mais de um arquivo

Impressionante, vira e mexe eu aprendo um troço útil sobre a plataforma Arduino!

Quando uma aplicação do Arduino começa a crescer muito, ou seja, os fontes passam das dezenas de linhas, começa a ficar incômodo lidar com aquele monte de instruções no mesmo texto. No Pascal, e depois no Delphi da Borland a gente tinha o recurso de dividir o fonte em diferentes arquivos e depois incluí-los em um deles usando-se o comando INCLUDE, dessa forma:

{$INCLUDE interface.pas}
{$INCLUDE calculos.pas}

Quando o compilador, ao compilar o fonte "principal" topava com um include desses, ele achava o arquivo e o incluía naquela posição, montando um arquivão contendo todos os includes.

Obs: não é um include como no C/C++, onde o include é só uma referência a um outro arquivo compilado que vai ser linkado pelo linker.

Procurei esse troço várias vezes no mundo Arduino, sem sucesso. Assim, quando queria dividir os fontes em mais de um arquivo, eu criava uma lib do arquivo e usava o include estilo C. Funcionar funciona, mas...
tem o inconveniente de que muitos projetos do Arduino podem muito bem ser organizados "proceduralmente", ou seja, criando-se simples procedures e não classes. Aí eu tinha que juntar numa classe métodos que não precisavam estar agrupados em uma para poder dividir os fontes.

Hoje no Automação no Parque o amigo Carlos, a.k.a. kbça me mostrou um projeto que baixou da net que parecia ser estruturado em vários arquivos sem a criação de libs/classes. Fomos destrinchando a coisa até que descobrimos o que segue abaixo. O exemplo que eu uso é de um arquivo pequeno, para facilitar a visualização. Na prática normalmente eu não dividiria um arquivo tão pequeno, mas sim arquivos maiores, com vários procedimentos e funções dentro.

- Se vc cria um arquivo .ino, como normalmente se faz com projetos Arduino, o editor do Arduino cria um diretório com o mesmo nome do seu projeto e coloca o arquivo .ino lá, como vc pode ver abaixo:


Aqui a gente tem o programa ControleMotorTransistor.ino no diretório D:\Atrium\Projects\Arduino\ControleMotorTransistor.

Abaixo, o programa, ainda "inteiro":

#define pinControl 10

void setup()
{
  Serial.begin(9600);
  pinMode(pinControl,OUTPUT);
}

void runAndWait(int pin, int speed, int interval)
{
  analogWrite(pin,speed);
  delay(interval);
}

void loop()
{
  runAndWait(pinControl,100,2000);
  runAndWait(pinControl,150,2000);
  runAndWait(pinControl,200,2000);
  runAndWait(pinControl,250,2000);
}

O programa roda um motor CC em quatro velocidades diferentes, usando PWM e um circuito com transistor TIP120 (mais sobre isso em outro post), cada velocidade sendo usada durante 2 segundos.

Para isso foi criada a rotina runAndWait que aciona o motor com os parâmetros pino, velocidade e intervalo de tempo.

Agora, vamos dizer que eu quisesse que o arquivo principal (o ControleMotorTransistor.ino)   contivesse somente o setup e o loop, sem o "miolo", no caso a rotina runAndWait. Para que isso funcione, eu tenho que criar um outro arquivo extensão ino, colocar a rotina dentro e salvar no mesmo diretório onde está o "programa principal" com extensão .ino. Aí os arquivos ficam assim, primeiro o arquivo ControleMotorTransistor.ino.

#define pinControl 10

void setup()
{
  Serial.begin(9600);
  pinMode(pinControl,OUTPUT);
}

void loop()
{
  runAndWait(pinControl,100,2000);
  runAndWait(pinControl,150,2000);
  runAndWait(pinControl,200,2000);
  runAndWait(pinControl,250,2000);
}
Observe que a rotina runAndWait sumiu, ficando só o setup e o loop. Abaixo segue o arquivo procs.ino, que contém a rotina "sumida" do arquivo acima:

void runAndWait(int pin, int speed, int interval)
{
  analogWrite(pin,speed);
  delay(interval);
}

Importante: como já foi dito, o arquivo procs.ino foi salvo no mesmo diretório da aplicação, como dá prá ver abaixo:

Ao abrir o arquivo .ino na IDE do Arduino, vemos:





































Observe que o aplicativo já abriu os dois arquivos .ino, cada um em uma "aba" conforme circulado em vermelho. Isso já indica que já foi identificada uma relação entre os dois arquivos.

Agora, é só compilar e enviar para o Arduino que funcionará.

Vc pode ter vários arquivos contendo rotinas no mesmo diretório. O "programa principal" será aquele que tem o mesmo nome do diretório.

Bom... é isso. Abracadabraço!