quinta-feira, 20 de novembro de 2008

Balança implementada

Após a apresentação do ARHTE sem a eletrônica estar pronta, a equipe laranja mecanica não deixa de se empenhar. Na mesma tarde fizemos a parte mecânica e a programação em PIC para um novo componente da esteira, uma balança, onde qnd tiver 200g de brita a esteira irá parar. Agora faltando só mesmo a finalização da eletrônica que está quase pronta.

Amanhã pela manhã haverá notícias da finalização da eletrônica e pela tarde teste de todos os componentes juntos funcionando. Amanhã postamos video da Esteira LM3 finalizada.

Aí segue o código para PIC 16f628a comentado:

#include

__CONFIG _WDT_OFF & _INTRC_OSC_NOCLKOUT & _MCLRE_OFF & _LVP_OFF

CBLOCK 0x20 ;ENDEREÇO INICIAL DA MEMÓRIA DE USUÁRIO
TEMPO
ENDC

#DEFINE BANK0 BCF STATUS,RP0
#DEFINE BANK1 BSF STATUS,RP0
#DEFINE LED PORTA,1
#DEFINE MOTOR PORTA,2
#DEFINE INFRA PORTA,0
#DEFINE LEDV PORTA,3
#DEFINE BALANCA PORTA,4
ORG 0x00
GOTO INICIO

ORG 0x04
GOTO TRATA_TIMER

INICIO

CLRF PORTA
BANK1
MOVLW B'00000111' ; bit do 0 ao 2, configuração de Preescale - 111 = 1:256 Timmer0; bit 8, habilita uso de periféricos.
MOVWF OPTION_REG ; Move o byte de configuração do Work para o registrador OPTION_REG
MOVLW B'11110001'
MOVWF TRISA ; seta as portas de entrada e saida
BANK0
MOVLW b'00000111'
MOVWF CMCON ; Desabilita comparadores
MOVLW .20 ; Atribui 20 para W
MOVWF TEMPO ; Atribui valor de W para TEMPO

MAIN
BTFSS BALANCA ;Checa se o peso exedeu 200g
GOTO EXPESO ;Se execedeu va para expeso
BTFSS INFRA ;Checa se o laser foi interrompido
CALL PARA ;se foi va para subrotina PARA
BTFSC INFRA ;checa se laser nao está interrompido
CALL LIGADO ;se nao estiver va para LIGADO
GOTO MAIN

LIGADO ;Sub-Rotina Ligado
BSF LEDV ;Liga led verde
BCF LED ;Desliga led vermelho
BSF MOTOR ;Liga motor
RETURN

PARA ;Sub-Rotina PARA
BCF LEDV ;desliga led verde
BSF LED ;liga led vermelho
BCF MOTOR ;desliga motor
MOVLW .20
MOVWF TEMPO
MOVLW B'10100000' ; BIT: 7-INTERRUPÇÃO, 5-TIMMER, 2-Flag Timmer
MOVWF INTCON ; Move o byte de configuração do Work para o registrador INTCON
LOOP
GOTO LOOP
RETURN

TRATA_TIMER ; Trata a interrupção gerada pelo Timmer0
BCF INTCON, T0IF ; Desabilita flag de Timmer0
BCF INTCON, GIE ; Habilita Interrupção Geral
BTFSS INFRA
GOTO MAIN
DECFSZ TEMPO ; Decrementa Variavel TEMPO2 e testa se TEMPO2 = 0 pula a proxima linha.
GOTO TESTALED
GOTO MAIN


TESTALED ;Sub-Rotina TESTALED
BTFSC LED ;Checa se led vermelho está apagado
GOTO ASCENDE ;se estiver vai para subrotina ascende
BTFSS LED ;testa se led vermelho está aceso
GOTO APAGA ;se estiver vai para subrotina apaga

ASCENDE ;Sub-Rotina ASCENDE
BCF LED ;Apaga led vermelho
RETFIE

APAGA ;Sub-Rotina APAGA
BSF LED ;Ascende led vermelho
RETFIE

EXPESO ;Sub-Rotina EXPESO
BCF LEDV ;Apaga led verde
BSF LED ;Ascende led vermelho
BCF MOTOR ;Desliga motor
GOTO MAIN

END

segunda-feira, 17 de novembro de 2008

Algorítimo PIC aperfeiçoado

Aproveitando para estudar PIC resolví fazer um algorítimo mais rebuscado. (Código comentado em breve)

Implementações:

-Esperar 5s sempre que o sensor for interrompido para a esteira voltar ao funcionamento.

-LED vermelho piscando enquanto esteira pausa 5s.

Video:



Aí segue o novo código do PIC:

#include

__CONFIG _WDT_OFF & _INTRC_
OSC_NOCLKOUT & _MCLRE_OFF & _LVP_OFF

CBLOCK 0x20 ;ENDEREÇO INICIAL DA MEMÓRIA DE USUÁRIO
TEMPO
ENDC

#DEFINE BANK0 BCF STATUS,RP0
#DEFINE BANK1 BSF STATUS,RP0
#DEFINE LED PORTA,0
#DEFINE MOTOR PORTA,2
#DEFINE INFRA PORTA,1
#DEFINE LEDV PORTA,3
ORG 0x00
GOTO INICIO

ORG 0x04
GOTO TRATA_TIMER

INICIO

CLRF PORTA
BANK1
MOVLW B'00000111'; bit do 0 ao 2, configuração
de Preescale - 111 = 1:256 Timmer0; bit 8, habilita uso de periféricos.
MOVWF OPTION_REG ; Move o byte de configuração do Work para o registrador OPTION_REG
MOVLW B'11110010'
MOVWF TRISA
BANK0
MOVLW b'00001111'
MOVWF CMCON
MOVLW .20 ; Atribui 5 para W
MOVWF TEMPO ; Atribui valor de W
para TEMPO

MAIN
BTFSS INFRA
CALL PARA
BTFSC INFRA
CALL LIGADO
GOTO MAIN

LIGADO
BSF LEDV
BCF LED
BSF MOTOR
RETURN

PARA
BCF LEDV
BSF LED

BCF MOTOR
MOVLW .20
MOVWF TEMPO
MOVLW B'10100000'; BIT: 7-INTERRUPÇÃO, 5-TIMMER, 2-Flag Timmer
MOVWF INTCON ; Move o byte de configuração do Work para o registrador INTCON
LOOP
GOTO LOOP
RETURN

TRATA_TIMER ; Trata a interrupção gerada pelo Timmer0
BCF INTCON, T0IF ; Desabilita flag de Timmer0
BCF INTCON, GIE ; Habilita Interrupção Geral
BTFSS INFRA
GOTO MAIN
DECFSZ TEMPO ; Decrementa Variavel TEMPO2 e testa se TEMPO2 = 0 pula a proxima linha.
GOTO TESTALED
GOTO MAIN


TESTALED
BTFSC LED
GOTO ASCENDE
BTFSS LED
GOTO APAGA

ASCENDE
BCF LED
RETFIE

APAGA
BSF LED
RETFIE

END

domingo, 16 de novembro de 2008


placa de circuito, feita em uma placa padrão, o chip de cima é o PIC16F628A, e o CI uln2803 o de baixo, detalhe para os LEDs que dizem o funcionamento do motor.

sábado, 15 de novembro de 2008

Simulação Esteira - Pic no ISIS



O led azul aceso representa o Motor DC (Led motor DC)
O led vermelho aceso representa interrupção do laser e parada da esteira
O led verde aceso representa a esteira em movimento

O push button representa, quando pressionado, o laser interrompido.

quinta-feira, 13 de novembro de 2008

Programa em PIC

Segue abaixo o algoritimo para pic do sistema demonstrado no vídeo da postagem abaixo:

#include

__CONFIG _WDT_OFF & _INTRC_OSC_NOCLKOUT & _MCLRE_OFF & _LVP_OFF ;Configurações Iniciais


#DEFINE BANK0 BCF STATUS,RP0 ;Facilitando a troca de banco pro banco 0
#DEFINE BANK1 BSF STATUS,RP0 ;e banco 1.
#DEFINE LED PORTA,0
;Dando nome 'LED' ao bit 0 da PORTA.
#DEFINE MOTOR PORTA,2 ;Dando nome 'MOTOR' ao bit 2 da PORTA.
#DEFINE INFRA PORTA,1 ;Dando nome 'INFRA' ao bit 1 da PORTA.
#DEFINE LEDV PORTA,3 ;Dando nome 'LEDV' ao bit 3 da PORTA.

ORG 0x00

GOTO INICIO ;Direciona o ponteiro de execução para a sub-rotina INICIO.

INICIO ;Sub-rotina INICIO.

CLRF PORTA ;Zera todo o byte PORTA.
BANK1 ;Troca do banco atual(banco 0) para o banco 1.
MOVLW B'11110010' ;Move o valor binário 11110010 para o registrador W.
MOVWF TRISA ;Move o byte W para o TRISA(que define os bits de PORTA como entrada=1 ou saída=0).
BANK0 ;Troca do banco atual(banco 1) para o banco 0.
MOVLW b'00001111' ;Move o valor binário 00001111 para o registrador W.
MOVWF CMCON ;Move o byte W para o CMCON.

MAIN ;Sub-rotina Main.
BTFSS INFRA
CALL PARA ;Chama a função PARA.
BTFSC INFRA
CALL LIGADO ;Chama a função LIGADO.
GOTO MAIN ;Direciona o ponteiro de execução para a sub-rotina MAIN.

LIGADO ;Sub-rotina LIGADO.
BSF LEDV ;Seta o bit LEDV '1'.
BCF LED ;Seta o bit LED '0'.
BSF MOTOR ;Seta o bit MOTOR '1'.
RETURN ;Retorna o ponteiro de execução para linha seguinte a chamada da função.

PARA ;Sub-rotina PARA.
BCF LEDV ;Seta o bit LEDV '0'.
BSF LED ;Seta o bit LED '1'.
BCF MOTOR ;Seta o bit MOTOR '0'.
RETURN ;Retorna o ponteiro de execução para linha seguinte a chamada da função.
END

Funcionamento:
Quando o laser for interropido o motor DC pára, e só volta a funcionar quando o laser nao estiver mais interrompido.

Dessa forma podemos simular um ambiente fabril onde quando alguma coisa invade o espaço do processo de produção, nesse caso a esteira, essa pára automaticamente evitando assim um acidente.
teste do circuito com pic na proto board... no video o botão simula um sensor de luz que ira fazer com que o motor pare....

Algorítimo em Delphi 7 para 2 motores (DC e Passo)

Diferente da linguagem C, a qual a maioria de nós estamos ambientados, no delphi o programa é dividido em vários códigos.

Aqui segue a parte do layout do progama, botões, labels etc... (Unit1.dfm):

;------------------------------------Unit1.dfm----------------------------------------

object Form1: TForm1
Left = 189
Top = 119
Width = 352
Height = 317
Caption = 'Controle - Motor de Passo'
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'MS Sans Serif'
Font.Style = []
OldCreateOrder = False
PixelsPerInch = 96
TextHeight = 13
object Label1: TLabel
Left = 24
Top = 24
Width = 71
Height = 22
Caption = 'Motor 1'
Font.Charset = ANSI_CHARSET
Font.Color = clWindowText
Font.Height = -19
Font.Name = 'Arial'
Font.Style = [fsBold]
ParentFont = False
end
object Label2: TLabel
Left = 216
Top = 24
Width = 71
Height = 22
Caption = 'Motor 2'
Font.Charset = ANSI_CHARSET
Font.Color = clWindowText
Font.Height = -19
Font.Name = 'Arial'
Font.Style = [fsBold]
ParentFont = False
end
object Label3: TLabel
Left = 8
Top = 120
Width = 71
Height = 18
Caption = 'Sentido 1:'
Font.Charset = ANSI_CHARSET
Font.Color = clWindowText
Font.Height = -15
Font.Name = 'Arial'
Font.Style = [fsBold]
ParentFont = False
end
object Label4: TLabel
Left = 200
Top = 120
Width = 71
Height = 18
Caption = 'Sentido 2:'
Font.Charset = ANSI_CHARSET
Font.Color = clWindowText
Font.Height = -15
Font.Name = 'Arial'
Font.Style = [fsBold]
ParentFont = False
end
object LaVelocidade2: TLabel
Left = 200
Top = 208
Width = 94
Height = 18
Caption = 'Velocidade 2:'
Font.Charset = ANSI_CHARSET
Font.Color = clWindowText
Font.Height = -15
Font.Name = 'Arial'
Font.Style = [fsBold]
ParentFont = False
end
object LaVelocidade1: TLabel
Left = 8
Top = 208
Width = 94
Height = 18
Caption = 'Velocidade 1:'
Font.Charset = ANSI_CHARSET
Font.Color = clWindowText
Font.Height = -15
Font.Name = 'Arial'
Font.Style = [fsBold]
ParentFont = False
end
object Button1: TButton
Left = 16
Top = 64
Width = 89
Height = 33
Caption = 'DESLIGADO'
TabOrder = 0
OnClick = Button1Click
end
object Button2: TButton
Left = 208
Top = 64
Width = 89
Height = 33
Caption = 'DESLIGADO'
TabOrder = 1
OnClick = Button2Click
end
object Sentido1: TButton
Left = 208
Top = 160
Width = 89
Height = 33
Caption = 'HOR'#193'RIO'
TabOrder = 2
OnClick = Sentido1Click
end
object Sentido: TButton
Left = 16
Top = 160
Width = 89
Height = 33
Caption = 'HOR'#193'RIO'
TabOrder = 3
OnClick = SentidoClick
end
object ScrollBar1: TScrollBar
Left = 16
Top = 240
Width = 89
Height = 17
Max = 225
Min = 1
PageSize = 0
Position = 1
TabOrder = 4
OnScroll = ScrollBar1Scroll
end
object ScrollBar2: TScrollBar
Left = 208
Top = 240
Width = 89
Height = 17
Max = 225
PageSize = 0
TabOrder = 5
OnScroll = ScrollBar2Scroll
end
end


Agora o arquivo principal com o algorítimo (unit1.pas e unit2.pas):


;------------------------------------Unit1.pas---------------------------------------


unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;

type
TForm1 = class(TForm)
Label1: TLabel;
Label2: TLabel;
Button1: TButton;
Button2: TButton;
Sentido1: TButton;
Sentido: TButton;
Label3: TLabel;
Label4: TLabel;
ScrollBar1: TScrollBar;
ScrollBar2: TScrollBar;
LaVelocidade2: TLabel;
LaVelocidade1: TLabel;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure SentidoClick(Sender: TObject);
procedure Sentido1Click(Sender: TObject);
procedure ScrollBar1Scroll(Sender: TObject; ScrollCode: TScrollCode;
var ScrollPos: Integer);
procedure ScrollBar2Scroll(Sender: TObject; ScrollCode: TScrollCode;
var ScrollPos: Integer);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;


implementation

{$R *.dfm}


procedure TForm1.Button1Click(Sender: TObject);
begin
if Button1.Caption='LIGADO' then
begin
Button1.Caption:='DESLIGADO';
end
else
button1.Caption:='LIGADO';
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
if Button2.Caption='LIGADO' then
Button2.Caption:='DESLIGADO'
else
button2.Caption:='LIGADO';
end;

procedure TForm1.SentidoClick(Sender: TObject);
begin
if Sentido.Caption='HORÁRIO' then
Sentido.Caption:='ANTI-HORÁRIO'
else
Sentido.Caption:='HORÁRIO';
end;

procedure TForm1.Sentido1Click(Sender: TObject);
begin
if Sentido1.Caption='HORÁRIO' then
Sentido1.Caption:='ANTI-HORÁRIO'
else
Sentido1.Caption:='HORÁRIO';
end;

procedure TForm1.ScrollBar1Scroll(Sender: TObject; ScrollCode: TScrollCode;
var ScrollPos: Integer);
var
velocidade : Integer;
begin
velocidade := scrollbar1.position;
lavelocidade1.Caption :='Velocidade 1: ' + inttostr(velocidade) + 'ms';
end;
procedure TForm1.ScrollBar2Scroll(Sender: TObject; ScrollCode: TScrollCode;
var ScrollPos: Integer);
var
velocidade1 : Integer;
begin
velocidade1 := scrollbar2.position;
lavelocidade2.Caption :='Velocidade 2: ' + inttostr(velocidade1) + 'ms';
end;

end.


;-----------------------------Unit2.pas--------------------------------------------


unit Unit2;

interface

uses
Classes,unit1,SysUtils, Variants, Graphics, Controls, Forms,
Dialogs, StdCtrls;

type
loop = class(TThread)
private
{ Private declarations }
protected
procedure Execute; override;
procedure Atualiza;
procedure Atualiza1;
end;

implementation
procedure outportb(EndPorta: Integer; Valor:BYTE); stdcall; external 'inpout32.DLL' name 'Out32';
function inportb(EndPorta: Integer): BYTE stdcall; external 'inpout32.DLL' name 'Inp32';

var
contador: integer;
passos2: integer;
procedure loop.Atualiza;
begin
with Form1 do
begin
label5.caption:='Giros = ' + inttostr(contador);
end;
end ;

procedure loop.Atualiza1;
begin
with Form1 do
begin
label6.caption:='Giros = ' + inttostr(passos2);
end;
end ;

procedure loop.Execute;
begin
with Form1 do
begin
while (button1.caption='LIGADO') AND (button2.Caption='DESLIGADO') do
begin
if sentido.Caption='HORÁRIO' then
begin // SENTIDO HORARIO MOTOR DE PASSO
outportb($378,$04);
sleep(scrollbar1.Position);
outportb($378,$08);
sleep(scrollbar1.Position);
outportb($378,$10);
sleep(scrollbar1.Position);
outportb($378,$20);
sleep(scrollbar1.Position);
passos:= passos + 1;
end
else
begin // SENTIDO ANTI HORARIO MOTOR DE PASSO
outportb($378,$20);
sleep(scrollbar1.Position);
outportb($378,$10);
sleep(scrollbar1.Position);
outportb($378,$08);
sleep(scrollbar1.Position);
outportb($378,$04);
sleep(scrollbar1.Position);
passos:= passos - 1;
end;
contador := passos;
synchronize(atualiza);
if(button1.caption='DESLIGADO') OR (button2.Caption='LIGADO')then
begin
exit;
end;
end;
while (button1.caption='LIGADO') AND (button2.Caption='LIGADO') do
begin
if sentido1.Caption='HORÁRIO' then
begin
byt:= $10;
x:=1;
end
else
begin
byt:= $20; x:=-1;
end;
if sentido.Caption='HORÁRIO' then
begin // SENTIDO HORARIO MOTOR DE PASSO
outportb($378,$01 + byt);
sleep(scrollbar1.Position);
outportb($378,$02 + byt);
sleep(scrollbar1.Position);
outportb($378,$04 + byt);
sleep(scrollbar1.Position);
outportb($378,$08 + byt);
sleep(scrollbar1.Position);
passos:= passos + 1;
passos1:= passos1 + 4*x;
end
else
begin // SENTIDO ANTI HORARIO MOTOR DE PASSO
outportb($378,$08 + byt);
sleep(scrollbar1.Position);
outportb($378,$04 + byt);
sleep(scrollbar1.Position);
outportb($378,$02 + byt);
sleep(scrollbar1.Position);
outportb($378,$01 + byt);
sleep(scrollbar1.Position);
passos:= passos - 1;
passos1:= passos1 + 4*x;
end;
contador := passos;
passos2:= passos1;
synchronize(atualiza);
synchronize(atualiza1);
if(button1.caption<>'LIGADO') OR (button2.Caption<>'LIGADO')then
exit;
end;
while (button1.caption='DESLIGADO') AND (button2.Caption='LIGADO') do
begin
if sentido1.Caption='HORÁRIO' then
begin // SENTIDO HORARIO MOTOR DC
outportb($378,$10);
sleep(scrollbar2.Position);
passos1:= passos1 + 1;
end
else
begin // SENTIDO ANTI HORARIO MOTOR DC
outportb($378,$20);
sleep(scrollbar2.Position);
passos1:= passos1 - 1;
end;
if(button1.caption='DESLIGADO') OR (button2.Caption='DESLIGADO')then
begin
sleep(scrollbar1.Position*4);
outportb($378,0);
exit;
end;
passos2:= passos1;
synchronize(atualiza1);
if(button1.caption<>'DESLIGADO') OR (button2.Caption<>'LIGADO')then
exit;
end;
end;
end;
end.

;--------------------------------FIM---------------------------------------------


Sou inesperiente em delphi, e com o pouco que sabia criei esse algorítimo. Estou aberto a ajuda para possíveis melhorias nesse algorítimo, entretanto, dessa forma roda 100%. valeu!

OBS: OS CÓDIGOS NÃO ESTÃO COMENTADOS. QUALQUER DÚVIDA ENTRAR EM CONTATO

e.sampaioo@hotmail.com

Arquivos para download:

http://rapidshare.com/files/163558447/Programa_Projeto_ARHTE_DEFINITIVO.rar.html

bom pessoal.... ai vai um foto dos testes da esteira..... ultimos ajustes
abraços a todos