Olá pessoal,
Neste post veremos a implementação dos comandos do trocador de fitas. Através de comandos recebidos pela serial o Arduino aciona os motores e o servo para fazer os movimentos.
// Programa : Tape changer - garra e motores de passo
// Autor : Fernando Asashi Nitatori
#include <Servo.h> // Biblioteca para acionamento do servo
#include <AccelStepper.h> //Biblioteca para os motores de passo
Servo myservo; // Cria um objeto do tipo Servo para controlar um servo chamado myservo
int pos = 0; // variavel para armazenar a posicao do servo
int position;
int positioncenter = 84; // variavel para setar a posicao central do servo
int velocidade_motor_1 = 600; //velocidade do motor de passo 1
int velocidade_motor_2 = 600; //velocidade do motor de passo 1
int aceleracao_motor_1 = 80; //aceleracao do motor de passo 1
int aceleracao_motor_2 = 80; //aceleracao do motor de passo 1
int sentido_horario_motor_1 = 0;
int sentido_antihorario_motor_1 = 0;
int sentido_horario_motor_2 = 0;
int sentido_antihorario_motor_2 = 0;
int chave1;
int chave2;
int chave3;
int pino_endstop1 = 9;
int pino_endstop2 = 10;
int pino_endstop3 = 11;
int posicao = 0;
int posicao2 = 0;
int posicao1_motor1 = 8000;
int posicao2_motor1 = 16000;
int posicao3_motor1 = 24000;
int posicao1_motor2 = 2500;
int posicao2_motor2 = 10000;
int posicao3_motor2 = 22000;
char ultcmdservo = 'm';
char comando;
// Definicao pino ENABLE
int pino_enable = 8;
// Definicao pinos STEP e DIR
AccelStepper motor1(1,2,5);
AccelStepper motor2(1,4,7);
void setup()
{
Serial.begin(9600);
pinMode(pino_enable, OUTPUT);
pinMode(pino_endstop1, INPUT);
pinMode(pino_endstop2, INPUT);
pinMode(pino_endstop3, INPUT);
digitalWrite(pino_endstop1, HIGH);
digitalWrite(pino_endstop2, HIGH);
digitalWrite(pino_endstop3, HIGH);
// Configuracoes iniciais motor de passo
motor1.setEnablePin(pino_enable);
motor1.setMaxSpeed(velocidade_motor_1);
motor1.setSpeed(velocidade_motor_1);
motor1.setAcceleration(aceleracao_motor_1);
// Configuracoes iniciais motor de passo
motor2.setEnablePin(pino_enable);
motor2.setMaxSpeed(velocidade_motor_2);
motor2.setSpeed(velocidade_motor_2);
motor2.setAcceleration(aceleracao_motor_2);
sentido_horario_motor_1 = 0;
sentido_antihorario_motor_1 = 0;
sentido_horario_motor_2 = 0;
sentido_antihorario_motor_2 = 0;
ligaservo();
myservo.write(positioncenter);
Serial.println("Digite l, m ou r para movimentar o servo e clique em ENVIAR...");
Serial.println("Digite c para parar o motor 1...");
Serial.println("Digite f para parar o motor 2...");
Serial.println("Digite 0 para girar o motor 1 para esquerda.");
Serial.println("Digite 1 para girar o motor 1 para a posicao 1.");
Serial.println("Digite 2 para girar o motor 1 para a posicao 2.");
Serial.println("Digite 3 para girar o motor 1 para a posicao 3.");
Serial.println("Digite 5 para girar o motor 2 para esquerda.");
Serial.println("Digite 6 para girar o motor 2 para a posicao 6.");
Serial.println("Digite 7 para girar o motor 2 para a posicao 7.");
//Serial.println("Digite 8 para girar o motor 2 para a posicao 8.");
}
void ligaservo() {
myservo.attach(19,500,2700); // attaches the servo on pin 19 to the servo object
}
void desligaservo() {
myservo.detach(); //desliga o servo
}
/*
void movezero() {
posicao = 0;
moveposicao0motor1();
}
*/
void moveposicao0motor1() {
digitalWrite(pino_enable, LOW);
sentido_horario_motor_1 = 0;
sentido_antihorario_motor_1 = 1;
}
void moveposicao0motor2() {
digitalWrite(pino_enable, LOW);
sentido_horario_motor_2 = 1;
sentido_antihorario_motor_2 = 0;
}
void moveposicao1motor2() {
digitalWrite(pino_enable, LOW);
sentido_horario_motor_2 = 0;
sentido_antihorario_motor_2 = 1;
posicao2 = 1;
}
void moveposicao2motor2() {
digitalWrite(pino_enable, LOW);
sentido_horario_motor_2 = 0;
sentido_antihorario_motor_2 = 1;
posicao2 = 2;
}
void moveposicao3motor2() {
digitalWrite(pino_enable, LOW);
sentido_horario_motor_2 = 0;
sentido_antihorario_motor_2 = 1;
posicao2 = 3;
}
void moveposicao1motor1() {
digitalWrite(pino_enable, LOW);
sentido_horario_motor_1 = 1;
sentido_antihorario_motor_1 = 0;
posicao = 1;
}
void moveposicao2motor1() {
digitalWrite(pino_enable, LOW);
sentido_horario_motor_1 = 1;
sentido_antihorario_motor_1 = 0;
posicao = 2;
}
void moveposicao3motor1() {
digitalWrite(pino_enable, LOW);
sentido_horario_motor_1 = 1;
sentido_antihorario_motor_1 = 0;
posicao = 3;
}
void ligamotor1horario() {
digitalWrite(pino_enable, LOW);
sentido_horario_motor_1 = 1;
sentido_antihorario_motor_1 = 0;
}
void ligamotor1antihorario() {
digitalWrite(pino_enable, LOW);
sentido_horario_motor_1 = 0;
sentido_antihorario_motor_1 = 1;
}
void ligamotor2horario () {
digitalWrite(pino_enable, LOW);
sentido_horario_motor_2 = 1;
sentido_antihorario_motor_2 = 0;
}
void ligamotor2antihorario() {
digitalWrite(pino_enable, LOW);
sentido_horario_motor_2 = 0;
sentido_antihorario_motor_2 = 1;
// puxa_horario_motor_2 = 0;
// puxa_antihorario_motor_2 = 0;
}
void loop()
{
// Aguarda os caracteres na serial
if (Serial.available() > 0)
{
comando = (char) Serial.read();
if (comando == 'c')
{
Serial.println("Letra c recebido - Parando motor 1...");
sentido_horario_motor_1 = 0;
sentido_antihorario_motor_1 = 0;
motor1.stop();
motor1.runToPosition();
motor1.setCurrentPosition(0);
digitalWrite(pino_enable, HIGH);
}
if (comando == 'f')
{
Serial.println("Letra f recebido - Parando motor 2...");
sentido_horario_motor_2 = 0;
sentido_antihorario_motor_2 = 0;
motor2.stop();
motor2.runToPosition();
motor2.setCurrentPosition(0);
digitalWrite(pino_enable, HIGH);
}
if (comando == 'l') {
ligaservo();
if (ultcmdservo == 'r') {
Serial.println("Nao digitar comando r aqui. Va para o centro com m e depois va para direita com r");
}
else
{
for(pos = positioncenter; pos<=162; pos += 1)
{
myservo.write(pos); // tell servo to go to position in variable 'pos'
delay(50);
}
}
ultcmdservo = 'l';
desligaservo();
}
if (comando == 'm') {
ligaservo();
position = myservo.read();
//Serial.println(position);
if (position >= positioncenter) {
for(pos = position; pos>=positioncenter; pos -= 1) // goes from 0 degrees to 180 degrees
{
myservo.write(pos); // tell servo to go to position in variable 'pos'
delay(50); // waits 15ms for the servo to reach the position
}
}
else
{
for(pos = position; pos<=positioncenter; pos += 1) // goes from 0 degrees to 180 degrees
{ // in steps of 1 degree
myservo.write(pos); // tell servo to go to position in variable 'pos'
delay(50); // waits 15ms for the servo to reach the position
}
}
ultcmdservo = 'm';
desligaservo();
}
if (comando == 'r') {
ligaservo();
if (ultcmdservo == 'l') {
Serial.println("Nao digitar comando l aqui. Va para o centro com m e depois va para direita com l");
}
else
{
for(pos = positioncenter; pos>=5; pos-=1) {
myservo.write(pos); // movimenta o servo ate a posicao
delay(50); // espera 50ms para o servo atingir a posicao
}
}
ultcmdservo = 'r';
desligaservo();
}
if (comando == '0') {
moveposicao0motor1();
}
if (comando == '1') {
moveposicao1motor1();
}
if (comando == '2') {
moveposicao2motor1();
}
if (comando == '3') {
moveposicao3motor1();
}
if (comando == '5') {
moveposicao0motor2();
}
if (comando == '6') {
moveposicao1motor2();
}
if (comando == '7') {
moveposicao2motor2();
}
if (comando == '8') {
moveposicao3motor2();
}
}
chave1 = digitalRead(pino_endstop1);
chave2 = digitalRead(pino_endstop2);
chave3 = digitalRead(pino_endstop3);
// Move o motor1 no sentido horario ate a posicao desejada
if (sentido_horario_motor_1 == 1){
if (posicao == 1) {
motor1.moveTo(posicao1_motor1);
motor1.run();
}
if (posicao == 2) {
motor1.moveTo(posicao2_motor1);
motor1.run();
}
if (posicao == 3) {
motor1.moveTo(posicao3_motor1);
motor1.run();
}
}
// Move o motor1 no sentido anti-horario ate a posicao desejada
if (sentido_antihorario_motor_1 == 1){
if (posicao == 0) {// se posicao for 0 move ate encontrar chave fim de curso
if (chave1 == 0) {
Serial.println("Fim de curso - Parando motor 1...");
sentido_horario_motor_1 = 0;
sentido_antihorario_motor_1 = 0;
motor1.stop();
motor1.runToPosition();
// motor1.setCurrentPosition(0);
digitalWrite(pino_enable, HIGH);
}
else
{
motor1.move(-20000);
motor1.run();
}
}
motor1.moveTo(0);
motor1.run();
}
// Move o motor2 no sentido horario ate a posicao desejada
if (sentido_horario_motor_2 == 1){
if (posicao2 == 0) {
if (chave2 == 0) {
Serial.println("Fim de curso 2 - Parando motor 2...");
sentido_horario_motor_2 = 0;
sentido_antihorario_motor_2 = 0;
motor2.stop();
motor2.runToPosition();
digitalWrite(pino_enable, HIGH);
}
else
{
motor2.move(-19000);
motor2.run();
}
}
motor2.moveTo(0);
motor2.run();
}
// Move o motor2 no sentido anti-horario ate a posicao desejada
if (sentido_antihorario_motor_2 == 1) {
if (posicao2 == 1) {
motor2.moveTo(posicao1_motor2);
motor2.run();
}
if (posicao2 == 2) {
motor2.moveTo(posicao2_motor2);
motor2.run();
}
if (posicao2 == 3) {
motor2.moveTo(posicao3_motor2);
motor2.run();
}
}
}
O código acima é para a implementação do movimento da garra e servo. Segue abaixo código para o motor DC:
//Programa: Tape changer - abre e fecha a garra
#include <AFMotor.h>
AF_DCMotor motor(1);
char comando;
void abregarra() {
uint8_t i;
motor.run(BACKWARD);
for (i=0; i<128; i++) {
motor.setSpeed(i);
delay(10);
}
delay(3000);
motor.run(RELEASE);
}
void fechagarra() {
uint8_t i;
motor.run(FORWARD);
for (i=0; i<255; i++) {
motor.setSpeed(i);
delay(10);
}
delay(2000);
}
void setup () {
Serial.begin(9600);
}
void loop () {
if (Serial.available() > 0)
{
comando = (char) Serial.read();
if (comando == 'g')
{
Serial.println("Abrindo garra");
abregarra();
}
if (comando == 'h')
{
Serial.println("Fechando garra");
fechagarra();
}
}
}
O script retirafita.sh é um script que roda em shell Linux ou FreeBSD. Segue abaixo script completo com os comandos para retirar a fita do drive e colocá-la no compartimento:
#Script retira.sh
echo "Abre a garra..."
echo 'g' > /dev/tty.usbmodem1421
sleep 5s
echo "Fecha a garra..."
echo 'h' > /dev/tty.usbmodem1421
sleep 5s
echo "Movimenta a garra ate a posicao 8..."
echo '8' > /dev/tty.usbmodem1411
sleep 45s
echo "Vira para a direita..."
echo 'r' > /dev/tty.usbmodem1411
sleep 5s
echo "Movimenta a garra ate a posicao 5..."
echo '5' > /dev/tty.usbmodem1411
sleep 45s
echo "Abre a garra..."
echo 'g' > /dev/tty.usbmodem1421
sleep 5s
echo "Movimenta a garra ate a posicao 7..."
echo '7' > /dev/tty.usbmodem1411
sleep 22s
echo "Fecha a garra..."
echo 'h' > /dev/tty.usbmodem1421
sleep 5s
echo "Movimenta a garra ate a posicao 5..."
echo '5' > /dev/tty.usbmodem1411
sleep 27s
echo "Movimenta a garra ate a posicao 6..."
echo '6' > /dev/tty.usbmodem1411
sleep 10s
echo "Vai para o centro..."
echo 'm' > /dev/tty.usbmodem1411
sleep 5s
echo "Abre a garra..."
echo 'g' > /dev/tty.usbmodem1421
sleep 5s
echo "Movimenta a garra ate a posicao 5..."
echo '5' > /dev/tty.usbmodem1411
sleep 5s
Quaisquer dúvidas sobre os códigos entrem em contato,
Até mais pessoal,
Blog voltado para compartihamento de experiências e projetos utilizando a plataforma Arduino.
sexta-feira, 5 de agosto de 2016
quarta-feira, 13 de julho de 2016
Tape changer - acionamento do motor de passo com CNC shield
Olá pessoal,
Dando continuidade ao detalhamento do projeto de tape changer vamos mostrar como se dá o acionamento do motor de passo NEMA 17 na mesa linear. Afinal de contas, como ligar um motor de passo?
Segue vídeo explicativo da ligação com CNC shield e o acionamento:
Uma das coisas que já podemos concluir é que este motor de passo exigindo pelo menos 12V de tensão e fornecer uma corrente de até 1A (está nas especificações do motor) é necessário um circuito extra que permita o Arduino interagir nestes patamares de tensão e corrente. Aí que entram em ação os drivers que terão como função acionar as bobinas do motor através de transistores de potência e ficando o Arduino somente com a função de controlar o acionamento. O driver que utilizaremos é o A4988. Segue abaixo o esquema de ligação se for usar protoboard:
Segue abaixo a pinagem utilizada pelo shield:
Para testar o motor de passo implementamos o seguinte código abaixo:
Créditos: Blog Arduino e Cia:
Link: http://www.arduinoecia.com.br/2015/03/controle-motor-de-passo-bipolar-driver-A4988.html
// Programa : Driver motor de passo A4988
// Autor : Arduino e Cia
#include <AccelStepper.h>
int velocidade_motor_1 = 700;
int aceleracao_motor_1 = 80;
int sentido_horario_motor_1 = 0;
int sentido_antihorario_motor_1 = 0;
char comando;
// Definicao pino ENABLE
int pino_enable = 8;
// Definicao pinos STEP e DIR
AccelStepper motor1(1,2,5);
void setup()
{
Serial.begin(9600);
pinMode(pino_enable, OUTPUT);
// Configuracoes iniciais motor de passo
motor1.setEnablePin(pino_enable);
motor1.setMaxSpeed(velocidade_motor_1);
motor1.setSpeed(velocidade_motor_1);
motor1.setAcceleration(aceleracao_motor_1);
sentido_horario_motor_1 = 0;
sentido_antihorario_motor_1 = 0;
Serial.println("Digite a, b ou c e clique em ENVIAR...");
}
void ligamotor1horario() {
digitalWrite(pino_enable, LOW);
sentido_horario_motor_1 = 1;
sentido_antihorario_motor_1 = 0;
}
void ligamotor1antihorario() {
digitalWrite(pino_enable, LOW);
sentido_horario_motor_1 = 0;
sentido_antihorario_motor_1 = 1;
}
void loop()
{
// Aguarda os caracteres no serial monitor
if (Serial.available() > 0)
{
comando = (char) Serial.read();
if (comando == 'a')
{
Serial.println("Letra a recebido - Girando motor1 sentido horario ate chave2 acionar.");
ligamotor1horario();
}
if (comando == 'b')
{
Serial.println("Letra b recebido - Girando motor1 sentido anti-horario ate chave1 acionar.");
ligamotor1antihorario();
}
if (comando == 'c')
{
Serial.println("Letra c recebido - Parando motor...");
sentido_horario_motor_1 = 0;
sentido_antihorario_motor_1 = 0;
motor1.moveTo(0);
digitalWrite(pino_enable, HIGH);
}
}
if (sentido_horario_motor_1 == 1)
{
motor1.moveTo(20000);
motor1.run();
}
if (sentido_antihorario_motor_1 == 1)
{
motor1.moveTo(-20000);
motor1.run();
}
}
É isso aí pessoal! Espero que tenham gostado! Até a próxima!
Dando continuidade ao detalhamento do projeto de tape changer vamos mostrar como se dá o acionamento do motor de passo NEMA 17 na mesa linear. Afinal de contas, como ligar um motor de passo?
Segue vídeo explicativo da ligação com CNC shield e o acionamento:
Uma das coisas que já podemos concluir é que este motor de passo exigindo pelo menos 12V de tensão e fornecer uma corrente de até 1A (está nas especificações do motor) é necessário um circuito extra que permita o Arduino interagir nestes patamares de tensão e corrente. Aí que entram em ação os drivers que terão como função acionar as bobinas do motor através de transistores de potência e ficando o Arduino somente com a função de controlar o acionamento. O driver que utilizaremos é o A4988. Segue abaixo o esquema de ligação se for usar protoboard:
Há uma outra maneira de se ligar esse motor de passo utilizando o CNC Shield.
Note que o driver A4988 é encaixado em dos compartimentos do shield CNC para cada motor/eixo:
Segue abaixo a pinagem utilizada pelo shield:
Para testar o motor de passo implementamos o seguinte código abaixo:
Créditos: Blog Arduino e Cia:
Link: http://www.arduinoecia.com.br/2015/03/controle-motor-de-passo-bipolar-driver-A4988.html
// Programa : Driver motor de passo A4988
// Autor : Arduino e Cia
#include <AccelStepper.h>
int velocidade_motor_1 = 700;
int aceleracao_motor_1 = 80;
int sentido_horario_motor_1 = 0;
int sentido_antihorario_motor_1 = 0;
char comando;
// Definicao pino ENABLE
int pino_enable = 8;
// Definicao pinos STEP e DIR
AccelStepper motor1(1,2,5);
void setup()
{
Serial.begin(9600);
pinMode(pino_enable, OUTPUT);
// Configuracoes iniciais motor de passo
motor1.setEnablePin(pino_enable);
motor1.setMaxSpeed(velocidade_motor_1);
motor1.setSpeed(velocidade_motor_1);
motor1.setAcceleration(aceleracao_motor_1);
sentido_horario_motor_1 = 0;
sentido_antihorario_motor_1 = 0;
Serial.println("Digite a, b ou c e clique em ENVIAR...");
}
void ligamotor1horario() {
digitalWrite(pino_enable, LOW);
sentido_horario_motor_1 = 1;
sentido_antihorario_motor_1 = 0;
}
void ligamotor1antihorario() {
digitalWrite(pino_enable, LOW);
sentido_horario_motor_1 = 0;
sentido_antihorario_motor_1 = 1;
}
void loop()
{
// Aguarda os caracteres no serial monitor
if (Serial.available() > 0)
{
comando = (char) Serial.read();
if (comando == 'a')
{
Serial.println("Letra a recebido - Girando motor1 sentido horario ate chave2 acionar.");
ligamotor1horario();
}
if (comando == 'b')
{
Serial.println("Letra b recebido - Girando motor1 sentido anti-horario ate chave1 acionar.");
ligamotor1antihorario();
}
if (comando == 'c')
{
Serial.println("Letra c recebido - Parando motor...");
sentido_horario_motor_1 = 0;
sentido_antihorario_motor_1 = 0;
motor1.moveTo(0);
digitalWrite(pino_enable, HIGH);
}
}
if (sentido_horario_motor_1 == 1)
{
motor1.moveTo(20000);
motor1.run();
}
if (sentido_antihorario_motor_1 == 1)
{
motor1.moveTo(-20000);
motor1.run();
}
}
É isso aí pessoal! Espero que tenham gostado! Até a próxima!
sábado, 9 de julho de 2016
Tape changer - motor de passo, acoplamento e fuso
Neste post vou detalhar como implementei o movimento retilíneo da garra usando motor de passo, acoplamento e fuso com barra roscada.
Detalhes de como implementei no vídeo abaixo:
Usei os seguintes componentes:
1) Motor de passo Nema 17 (descrito no post anterior).
2) Barra roscada 8mm:
Barra roscada de 8mm |
3) Acoplamento flexível 5mm x 8mm:
4) Porca sextavada 8mm:
5) Corrediça telescópica:
6) Chapas em MDF:
É isso aí pessoal!
Até a próxima!
quinta-feira, 23 de junho de 2016
Tape changer - mudança no projeto
Bom dia pessoal,
Vamos lá para mais um post sobre e o projeto do tape changer e no último post descrevi as dificuldades de se implementar um braço robótico. Neste post vou descrever a mudança radical que tive de implementar para resolver as dificuldades. Vamos lá:
1) Mudança: utilização de motores de passo ao invés de servos para movimentação retilínea da garra.
Uma decisão que tive tomar foi a de utilizar motor de passo ao invés de servos. Agora qual motor de passo utilizar? Em um primeiro momento resolvi começar a fazer testes com motores de passo para drives de CD/DVD.
Pensei: "Poxa que legal... funciona...e com Arduino ainda". Uma dificuldade que encontrei para utilizar estes motores de passo foi a dificuldade de implementar um fuso mais comprido a ponto de conseguir mover a fita ou colocá-la no drive LTO. Também pensei em utilizar dois motores de passo e dois fusos para fazer a abertura e fechamento da garra porém sem sucesso.
De repente tive um insight: esse movimento retilíneo está bastante presente em projetos de CNC!!! Comecei a pesquisar as implementações de fusos e motores de passo para movimentar em eixos nos projetos de CNC e encontrei um canal excelente no Youtube - o canal Eletrônica Hoje:
Agradeço a ajuda!!!
2) Implementação do movimento retilíneo:
O motor de passo que escolhi foi esse:
Motor de passo Nema 17 |
Para acionamento e controle do motor de passo escolhi o driver A4988:
Driver A4988 |
Segue abaixo esquema de ligação do driver ao motor de passo:
Atente para o esquema onde é realizada a ligação de alimentação externa (pinos VMOT e GND) que exige a conexão de um capacitor de 100 microFarad para dar maior estabilidade no fornecimento de tensão. Os enrolamentos do motor de passo devem ser ligados nos pinos 2B,2A,1A e 1B.
Maiores detalhes de ligação estão em alguns vídeos do canal Eletrônica Hoje:
a) Ligação dos motores de passo de 4 ou 6 fios:
b) Ajuste de corrente dos drivers A4988 - Parte 1:
c) Ajuste de corrente dos drivers A4988 - Parte 2:
A ligação com o Arduino e o código para testes são estes:
http://www.arduinoecia.com.br/2015/03/controle-motor-de-passo-bipolar-driver-A4988.html
É importante fazermos um teste do motor de passo sem carga para verificar o comportamento do motor para depois fazermos a conexão do fuso.
No próximo post vamos ver como fazer o acoplamento do motor de passo ao fuso que transmitirá o movimento para o conjunto a ser movimentado.
Até mais!
Agradecimentos ao Canal Eletrônica Hoje e ao site Arduino e Cia.
quarta-feira, 22 de junho de 2016
Tape changer com braço robótico - parte 2
Olá pessoal! Neste post vou contar para vocês um pouco da experiência que tive para implementar o projeto de tape changer (trocador de fita) utilizando braço robótico. Bom, vamos lá!
Como não tenho noção nenhuma a ponto de construir a estrutura do braço robótico resolvi comprar uma em alumínio...
Comprei este no Aliexpress:
Não veio com instruções de montagem porém o vendedor me enviou por e-mail as instruções (em chinês) mas muito bem detalhado e não foi difícil a montagem.
Depois de montado comprei os servos (6 servos) MG995 e os montei na estrutura. A partir daí fomos aos testes.
Realizadas as ligações dos servos atentamos para a corrente exigida pelos servos e tensão de alimentação e precisamos de alimentação externa. Deve-se prestar atenção na interligação do terra do Arduino com o terra da alimentação externa dos servos.
Fizemos o controle da movimentação dos servos através de potenciômetros e notamos que determinados servos eram mais exigidos que outros em termos de corrente e também que o movimento necessário do braço e da garra para remover a fita ou colocar tem que ser retilíneo (por conta da fita), o que dificultou bastante o teste pois teríamos que acionar vários servos ao mesmo tempo para reproduzir este movimento retilíneo. Somada a esta dificuldade temos também tivemos que recorrer a uma fonte de alimentação com maior capacidade de fornecimento de corrente.
Devido às dificuldades de implementação chegamos a conclusão que era necessário rever o projeto e pensar na possibilidade de se usar motores de passo para realizar o movimento retilíneo da garra. É que fizemos e veremos no próximo post como foi essa mudança na implementação.
Até a próxima!
Como não tenho noção nenhuma a ponto de construir a estrutura do braço robótico resolvi comprar uma em alumínio...
Comprei este no Aliexpress:
Não veio com instruções de montagem porém o vendedor me enviou por e-mail as instruções (em chinês) mas muito bem detalhado e não foi difícil a montagem.
Depois de montado comprei os servos (6 servos) MG995 e os montei na estrutura. A partir daí fomos aos testes.
Realizadas as ligações dos servos atentamos para a corrente exigida pelos servos e tensão de alimentação e precisamos de alimentação externa. Deve-se prestar atenção na interligação do terra do Arduino com o terra da alimentação externa dos servos.
Fizemos o controle da movimentação dos servos através de potenciômetros e notamos que determinados servos eram mais exigidos que outros em termos de corrente e também que o movimento necessário do braço e da garra para remover a fita ou colocar tem que ser retilíneo (por conta da fita), o que dificultou bastante o teste pois teríamos que acionar vários servos ao mesmo tempo para reproduzir este movimento retilíneo. Somada a esta dificuldade temos também tivemos que recorrer a uma fonte de alimentação com maior capacidade de fornecimento de corrente.
Devido às dificuldades de implementação chegamos a conclusão que era necessário rever o projeto e pensar na possibilidade de se usar motores de passo para realizar o movimento retilíneo da garra. É que fizemos e veremos no próximo post como foi essa mudança na implementação.
Até a próxima!
terça-feira, 15 de março de 2016
Novo projeto: tape changer com Arduino
Olá pessoal,
Depois de um bom tempo sem postar hoje coloco um novo projeto com Arduino: um tape changer com drive de fita LTO. Até agora é o projeto mais complexo que estou implementando e ainda não está terminado. Trocadores de fita (ou biblioteca de fitas) são equipamentos que armazenam fitas magnéticas para fins de backup e trocam a fita automaticamente no drive quando finalizam uma gravação. Vocês podem dar uma olhada no funcionamento de um desses:
Uma biblioteca de fitas não é barata...
Vamos lá então pessoal... a idéia inicial era de usar um braço robótico para puxar e trazer a fita do drive e para o drive. Nos próximos posts vou relatar como foi a experiência disso. Depois de várias tentativas mal sucedidas de se utilizar braço robótico acabei por modificar totalmente o projeto.
Abraços,
Depois de um bom tempo sem postar hoje coloco um novo projeto com Arduino: um tape changer com drive de fita LTO. Até agora é o projeto mais complexo que estou implementando e ainda não está terminado. Trocadores de fita (ou biblioteca de fitas) são equipamentos que armazenam fitas magnéticas para fins de backup e trocam a fita automaticamente no drive quando finalizam uma gravação. Vocês podem dar uma olhada no funcionamento de um desses:
Uma biblioteca de fitas não é barata...
Vamos lá então pessoal... a idéia inicial era de usar um braço robótico para puxar e trazer a fita do drive e para o drive. Nos próximos posts vou relatar como foi a experiência disso. Depois de várias tentativas mal sucedidas de se utilizar braço robótico acabei por modificar totalmente o projeto.
Abraços,
sábado, 21 de novembro de 2015
Alarme anti-furto para projetores multimídia - parte 2
Olá pessoal,
Continuando com o projeto segue abaixo vídeo do alarme e do código implementado:
O código:
#include <Wire.h>
#include <SPI.h>
#include <Ethernet.h>
#include <Agentuino.h>
//#include "RTClib.h"
// this must be unique
static byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xF0, 0xDA };
// change network settings to yours
// change server to your email server ip or domain
// IPAddress server( 1, 2, 3, 4 );
//char server[] = "mail.sorocaba.unesp.br";
//char server[15] = "200.145.27.7";
EthernetClient client;
// RFC1213-MIB OIDs
// .iso (.1)
// .iso.org (.1.3)
// .iso.org.dod (.1.3.6)
// .iso.org.dod.internet (.1.3.6.1)
// .iso.org.dod.internet.mgmt (.1.3.6.1.2)
// .iso.org.dod.internet.mgmt.mib-2 (.1.3.6.1.2.1)
// .iso.org.dod.internet.mgmt.mib-2.system (.1.3.6.1.2.1.1)
// .iso.org.dod.internet.mgmt.mib-2.system.sysDescr (.1.3.6.1.2.1.1.1)
static char sysDescr[20] PROGMEM = "1.3.6.1.2.1.1.1.0"; // read-only (DisplayString)
// .iso.org.dod.internet.mgmt.mib-2.system.sysObjectID (.1.3.6.1.2.1.1.2)
static char sysObjectID[20] PROGMEM = "1.3.6.1.2.1.1.2.0"; // read-only (ObjectIdentifier)
// .iso.org.dod.internet.mgmt.mib-2.system.sysUpTime (.1.3.6.1.2.1.1.3)
static char sysUpTime[20] PROGMEM = "1.3.6.1.2.1.1.3.0"; // read-only (TimeTicks)
// .iso.org.dod.internet.mgmt.mib-2.system.sysContact (.1.3.6.1.2.1.1.4)
static char sysContact[20] PROGMEM = "1.3.6.1.2.1.1.4.0"; // read-write (DisplayString)
// .iso.org.dod.internet.mgmt.mib-2.system.sysName (.1.3.6.1.2.1.1.5)
static char sysName[20] PROGMEM = "1.3.6.1.2.1.1.5.0"; // read-write (DisplayString)
// .iso.org.dod.internet.mgmt.mib-2.system.sysLocation (.1.3.6.1.2.1.1.6)
static char sysLocation[20] PROGMEM = "1.3.6.1.2.1.1.6.0"; // read-write (DisplayString)
// .iso.org.dod.internet.mgmt.mib-2.system.sysServices (.1.3.6.1.2.1.1.7)
static char sysServices[20] PROGMEM = "1.3.6.1.2.1.1.7.0"; // read-only (Integer)
// Arduino defined OIDs
// .iso.org.dod.internet.private (.1.3.6.1.4)
// .iso.org.dod.internet.private.enterprises (.1.3.6.1.4.1)
// .iso.org.dod.internet.private.enterprises.arduino (.1.3.6.1.4.1.36582)
// .iso.org.dod.internet.private.enterprises.arduino.value.valA0-A5 (.1.3.6.1.4.1.36582.3.1-6)
/*
static char valA0[] PROGMEM = "1.3.6.1.4.1.36582.3.1.0"; // read-only (Integer)
static char valA1[] PROGMEM = "1.3.6.1.4.1.36582.3.2.0"; // read-only (Integer)
// .iso.org.dod.internet.private.enterprises.arduino.value.valD0-D13 (.1.3.6.1.4.1.36582.3.7-20)
static char valD0[] PROGMEM = "1.3.6.1.4.1.36582.3.7.0"; // read-only (Integer)
static char valD1[] PROGMEM = "1.3.6.1.4.1.36582.3.8.0"; // read-only (Integer)
*/
static char alarme1[24] PROGMEM = "1.3.6.1.4.1.36582.3.1.0"; // read-only (Integer)
static char alarme2[24] PROGMEM = "1.3.6.1.4.1.36582.3.2.0"; // read-only (Integer)
static char alarme3[24] PROGMEM = "1.3.6.1.4.1.36582.3.3.0"; // read-only (Integer)
static char relay[24] PROGMEM = "1.3.6.1.4.1.36582.3.7.0"; // read-only (Integer)
static char locDescr[20] = "Agentuino";
static char locObjectID[20] = "1.3.6.1.4.1.36582";
static uint32_t locUpTime = 0;
static char locContact[20] = "Eric Gionet";
static char locName[20] = "Agentuino";
static char locLocation[20] = "Nova Scotia, CA";
static int32_t locServices = 7;
boolean localarme1 = 0;
boolean localarme2 = 0;
boolean localarme3 = 0;
boolean locrele = 0;
boolean statusalarme1 = 0;
boolean statusalarme2 = 0;
boolean statusalarme3 = 0;
boolean statusrele = 0;
//uint32_t prevMillis = millis();
uint32_t dispMillis = 0;
char oid[SNMP_MAX_OID_LEN];
SNMP_API_STAT_CODES api_status;
SNMP_ERR_CODES status;
const int switchPin1 = 2; // Reed switch to digital pin 2
const int switchPin2 = 3; // Reed switch to digital pin 3
const int switchPin3 = 4; // Reed switch to digital pin 3
const int rele = 7;
boolean disparou;
boolean disptempo;
long lastDebounceTime = 0;
long debounceDelay = 1500;
int lastswitch1State = HIGH;
int lastswitch2State = HIGH;
int lastswitch3State = HIGH;
int staterelay = HIGH;
void pduReceived()
{
SNMP_PDU pdu;
Serial.println("UDP Packet Received...");
api_status = Agentuino.requestPdu(&pdu);
if ( (pdu.type == SNMP_PDU_GET || pdu.type == SNMP_PDU_GET_NEXT || pdu.type == SNMP_PDU_SET)
&& pdu.error == SNMP_ERR_NO_ERROR && api_status == SNMP_API_STAT_SUCCESS ) {
pdu.OID.toString(oid);
Serial.print("OID = ");
Serial.println(oid);
if ( pdu.type == SNMP_PDU_SET ) {
status = SNMP_ERR_READ_ONLY;
} else if ( strcmp_P(oid, sysDescr ) == 0 ) {
status = pdu.VALUE.encode(SNMP_SYNTAX_OCTETS, locDescr);
} else if ( strcmp_P(oid, sysUpTime ) == 0 ) {
status = pdu.VALUE.encode(SNMP_SYNTAX_TIME_TICKS, locUpTime);
} else if ( strcmp_P(oid, sysName ) == 0 ) {
status = pdu.VALUE.encode(SNMP_SYNTAX_OCTETS, locName);
} else if ( strcmp_P(oid, sysContact ) == 0 ) {
status = pdu.VALUE.encode(SNMP_SYNTAX_OCTETS, locContact);
} else if ( strcmp_P(oid, sysLocation ) == 0 ) {
status = pdu.VALUE.encode(SNMP_SYNTAX_OCTETS, locLocation);
} else if ( strcmp_P(oid, sysServices) == 0 ) {
status = pdu.VALUE.encode(SNMP_SYNTAX_INT, locServices);
} else if ( strcmp_P(oid, sysObjectID) == 0 ) {
status = pdu.VALUE.encode(SNMP_SYNTAX_OCTETS, locObjectID);
} else if ( strcmp_P(oid, alarme1) == 0 ) {
status = pdu.VALUE.encode(SNMP_SYNTAX_INT, localarme1);
} else if ( strcmp_P(oid, alarme2) == 0 ) {
status = pdu.VALUE.encode(SNMP_SYNTAX_INT, localarme2);
} else if ( strcmp_P(oid, alarme3) == 0 ) {
status = pdu.VALUE.encode(SNMP_SYNTAX_INT, localarme3);
} else if ( strcmp_P(oid, relay) == 0 ) {
status = pdu.VALUE.encode(SNMP_SYNTAX_INT, locrele);
} else {
status = SNMP_ERR_NO_SUCH_NAME;
}
pdu.type = SNMP_PDU_RESPONSE;
pdu.error = status;
Agentuino.responsePdu(&pdu);
}
Agentuino.freePdu(&pdu);
}
void setup() {
Serial.begin(9600); // Inicia conexao serial para monitoramento
pinMode(switchPin1, INPUT); // switchPin1 is an input
digitalWrite(switchPin1, HIGH); // Activate internal pullup resistor
pinMode(switchPin2, INPUT); // switchPin1 is an input
digitalWrite(switchPin2, HIGH); // Activate internal pullup resistor
pinMode(switchPin3, INPUT); // switchPin1 is an input
digitalWrite(switchPin3, HIGH); // Activate internal pullup resistor
pinMode(rele, OUTPUT); // rele is an output
digitalWrite(rele, HIGH);
Ethernet.begin(mac);
disparou = false;
disptempo = true;
// Serial.println("Ethernet iniciado");
#ifdef AVR
Wire.begin();
#else
Wire1.begin(); // Shield I2C pins connect to alt I2C bus on Arduino Due
#endif
api_status = Agentuino.begin();
if ( api_status == SNMP_API_STAT_SUCCESS ) {
Agentuino.onPduReceive(pduReceived);
delay(10);
Serial.println("SNMP Agent Initiated...");
return;
} else
{
delay(10);
Serial.print("SNMP Agent failed!");
}
}
void loop() {
int somaledsyellow = 0; //variavel para somar os valores para acionar os leds amarelo via i2c
int somaledsred = 0; //variavel para somar os valores para acionar os leds vermelho via i2c
int totalleds = 0; //variavel para totalizar os valores para acionar os leds amarelo e vermelho via i2c
int reading1 = digitalRead(switchPin1); // estado do sensor magnetico 1
int reading2 = digitalRead(switchPin2); //estado do sensor magnetico 2
int reading3 = digitalRead(switchPin3); // estado do sensor magnetico 3
staterelay = digitalRead(rele); //estado do rele
// se os sensores magneticos nao foram acionados e depois de acionados passaram-se mais de 5 minutos acende os leds verdes
if ((reading1) && (reading2) && (reading3) && (disptempo)) {
digitalWrite(rele,HIGH); // rele e desligado
Wire.beginTransmission(32); //endereca o modulo I2c no endereco 32
Wire.write(248); // escreve o valor para acender todos os leds
Wire.endTransmission(); // finaliza a transmissao
}
else
{
if ((reading1 != lastswitch1State) || (reading2 != lastswitch2State) || (reading3 != lastswitch3State)) {
lastDebounceTime = millis(); // se mudou o estado de um dos sensores magneticos grava o tempo com a funcao millis
}
if ((millis() - lastDebounceTime) > debounceDelay) { //Se passou mais de 1500ms com o estado modificado o rele e acionado e toca a sirene
if ((reading1 == 0) || (reading2 == 0) || (reading3 == 0)) {
digitalWrite(rele,LOW); // o rele e ligado
}
}
if (reading1 == LOW) { //se o sensor magnetico 1 estiver em estado baixo ou seja acionado
statusalarme1 = 1; // o status do sensor magnetico 1 e colocado em 1
somaledsred = somaledsred + 8; //liga o primeiro led vermelho da esquerda pra direita
}
else
{
somaledsyellow = somaledsyellow + 1; //se o sensor nao foi acionado acende o primeiro led amarelo da esquerda pra direita
statusalarme1 = 0; // o status do sensor magnetico 1 e colocado em 0
}
if (reading2 == LOW) { //se o sensor magnetico 2 estiver em estado baixo ou seja acionado
statusalarme2 = 1; // o status do sensor magnetico 1 e colocado em 1
somaledsred = somaledsred + 16; //liga o segundo led vermelho da esquerda pra direita
}
else
{
somaledsyellow = somaledsyellow + 2; //se o sensor nao foi acionado acende o segundo led amarelo da esquerda pra direita
statusalarme2 = 0; // o status do sensor magnetico 2 e colocado em 0
}
if (reading3 == LOW) { //se o sensor magnetico 3 estiver em estado baixo ou seja acionado
statusalarme3 = 1; // o status do sensor magnetico 3 e colocado em 1
somaledsred = somaledsred + 32; //liga o terceiro led vermelho da esquerda pra direita
}
else
{
somaledsyellow = somaledsyellow + 4;//se o sensor nao foi acionado acende o terceiro led amarelo da esquerda pra direita
statusalarme3 = 0; // o status do sensor magnetico 3 e colocado em 0
}
totalleds = 255 - (somaledsyellow + somaledsred); //totaliza os valores de escrita para os leds amarelos e vermelhos
Wire.beginTransmission(32);
Wire.write(255);
Wire.write(totalleds); // escreve o valor correspondente para acionar ou desacionar os leds vermelhos e amarelos
Wire.endTransmission();
if (!disparou) { // se o alarme nao disparou
dispMillis = millis();
disptempo = false;
disparou = true;
}
//Aguarda 5 minutos para parar de tocar a sirene
if ((millis() - dispMillis > 300000) && (!disptempo)){
digitalWrite(rele,HIGH);
// Serial.print("Parar a sirene");
disptempo = true;
disparou = false;
}
}
lastswitch1State = reading1; //ultimo estado do sensor magnetico 1
lastswitch2State = reading2; //ultimo estado do sensor magnetico 2
lastswitch3State = reading3; //ultimo estado do sensor magnetico 3
Agentuino.listen(); //O agentuino fica em espera
// Atualiza os estados dos sensores para as variaveis a serem lidas via SNMP
localarme1 = statusalarme1;
localarme2 = statusalarme2;
localarme3 = statusalarme3;
locrele = staterelay; //atualiza o estado do rele para ser lido via SNMP
}
Observem que mais uma vez utilizamos o agentuino para disponibilizar os dados dos sensores e do relé para serem lidos pelo Zabbix (vide posts anteriores).
É isso aí pessoal. Quaisquer dúvidas entrem em contato!
Continuando com o projeto segue abaixo vídeo do alarme e do código implementado:
O código:
#include <Wire.h>
#include <SPI.h>
#include <Ethernet.h>
#include <Agentuino.h>
//#include "RTClib.h"
// this must be unique
static byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xF0, 0xDA };
// change network settings to yours
// change server to your email server ip or domain
// IPAddress server( 1, 2, 3, 4 );
//char server[] = "mail.sorocaba.unesp.br";
//char server[15] = "200.145.27.7";
EthernetClient client;
// RFC1213-MIB OIDs
// .iso (.1)
// .iso.org (.1.3)
// .iso.org.dod (.1.3.6)
// .iso.org.dod.internet (.1.3.6.1)
// .iso.org.dod.internet.mgmt (.1.3.6.1.2)
// .iso.org.dod.internet.mgmt.mib-2 (.1.3.6.1.2.1)
// .iso.org.dod.internet.mgmt.mib-2.system (.1.3.6.1.2.1.1)
// .iso.org.dod.internet.mgmt.mib-2.system.sysDescr (.1.3.6.1.2.1.1.1)
static char sysDescr[20] PROGMEM = "1.3.6.1.2.1.1.1.0"; // read-only (DisplayString)
// .iso.org.dod.internet.mgmt.mib-2.system.sysObjectID (.1.3.6.1.2.1.1.2)
static char sysObjectID[20] PROGMEM = "1.3.6.1.2.1.1.2.0"; // read-only (ObjectIdentifier)
// .iso.org.dod.internet.mgmt.mib-2.system.sysUpTime (.1.3.6.1.2.1.1.3)
static char sysUpTime[20] PROGMEM = "1.3.6.1.2.1.1.3.0"; // read-only (TimeTicks)
// .iso.org.dod.internet.mgmt.mib-2.system.sysContact (.1.3.6.1.2.1.1.4)
static char sysContact[20] PROGMEM = "1.3.6.1.2.1.1.4.0"; // read-write (DisplayString)
// .iso.org.dod.internet.mgmt.mib-2.system.sysName (.1.3.6.1.2.1.1.5)
static char sysName[20] PROGMEM = "1.3.6.1.2.1.1.5.0"; // read-write (DisplayString)
// .iso.org.dod.internet.mgmt.mib-2.system.sysLocation (.1.3.6.1.2.1.1.6)
static char sysLocation[20] PROGMEM = "1.3.6.1.2.1.1.6.0"; // read-write (DisplayString)
// .iso.org.dod.internet.mgmt.mib-2.system.sysServices (.1.3.6.1.2.1.1.7)
static char sysServices[20] PROGMEM = "1.3.6.1.2.1.1.7.0"; // read-only (Integer)
// Arduino defined OIDs
// .iso.org.dod.internet.private (.1.3.6.1.4)
// .iso.org.dod.internet.private.enterprises (.1.3.6.1.4.1)
// .iso.org.dod.internet.private.enterprises.arduino (.1.3.6.1.4.1.36582)
// .iso.org.dod.internet.private.enterprises.arduino.value.valA0-A5 (.1.3.6.1.4.1.36582.3.1-6)
/*
static char valA0[] PROGMEM = "1.3.6.1.4.1.36582.3.1.0"; // read-only (Integer)
static char valA1[] PROGMEM = "1.3.6.1.4.1.36582.3.2.0"; // read-only (Integer)
// .iso.org.dod.internet.private.enterprises.arduino.value.valD0-D13 (.1.3.6.1.4.1.36582.3.7-20)
static char valD0[] PROGMEM = "1.3.6.1.4.1.36582.3.7.0"; // read-only (Integer)
static char valD1[] PROGMEM = "1.3.6.1.4.1.36582.3.8.0"; // read-only (Integer)
*/
static char alarme1[24] PROGMEM = "1.3.6.1.4.1.36582.3.1.0"; // read-only (Integer)
static char alarme2[24] PROGMEM = "1.3.6.1.4.1.36582.3.2.0"; // read-only (Integer)
static char alarme3[24] PROGMEM = "1.3.6.1.4.1.36582.3.3.0"; // read-only (Integer)
static char relay[24] PROGMEM = "1.3.6.1.4.1.36582.3.7.0"; // read-only (Integer)
static char locDescr[20] = "Agentuino";
static char locObjectID[20] = "1.3.6.1.4.1.36582";
static uint32_t locUpTime = 0;
static char locContact[20] = "Eric Gionet";
static char locName[20] = "Agentuino";
static char locLocation[20] = "Nova Scotia, CA";
static int32_t locServices = 7;
boolean localarme1 = 0;
boolean localarme2 = 0;
boolean localarme3 = 0;
boolean locrele = 0;
boolean statusalarme1 = 0;
boolean statusalarme2 = 0;
boolean statusalarme3 = 0;
boolean statusrele = 0;
//uint32_t prevMillis = millis();
uint32_t dispMillis = 0;
char oid[SNMP_MAX_OID_LEN];
SNMP_API_STAT_CODES api_status;
SNMP_ERR_CODES status;
const int switchPin1 = 2; // Reed switch to digital pin 2
const int switchPin2 = 3; // Reed switch to digital pin 3
const int switchPin3 = 4; // Reed switch to digital pin 3
const int rele = 7;
boolean disparou;
boolean disptempo;
long lastDebounceTime = 0;
long debounceDelay = 1500;
int lastswitch1State = HIGH;
int lastswitch2State = HIGH;
int lastswitch3State = HIGH;
int staterelay = HIGH;
void pduReceived()
{
SNMP_PDU pdu;
Serial.println("UDP Packet Received...");
api_status = Agentuino.requestPdu(&pdu);
if ( (pdu.type == SNMP_PDU_GET || pdu.type == SNMP_PDU_GET_NEXT || pdu.type == SNMP_PDU_SET)
&& pdu.error == SNMP_ERR_NO_ERROR && api_status == SNMP_API_STAT_SUCCESS ) {
pdu.OID.toString(oid);
Serial.print("OID = ");
Serial.println(oid);
if ( pdu.type == SNMP_PDU_SET ) {
status = SNMP_ERR_READ_ONLY;
} else if ( strcmp_P(oid, sysDescr ) == 0 ) {
status = pdu.VALUE.encode(SNMP_SYNTAX_OCTETS, locDescr);
} else if ( strcmp_P(oid, sysUpTime ) == 0 ) {
status = pdu.VALUE.encode(SNMP_SYNTAX_TIME_TICKS, locUpTime);
} else if ( strcmp_P(oid, sysName ) == 0 ) {
status = pdu.VALUE.encode(SNMP_SYNTAX_OCTETS, locName);
} else if ( strcmp_P(oid, sysContact ) == 0 ) {
status = pdu.VALUE.encode(SNMP_SYNTAX_OCTETS, locContact);
} else if ( strcmp_P(oid, sysLocation ) == 0 ) {
status = pdu.VALUE.encode(SNMP_SYNTAX_OCTETS, locLocation);
} else if ( strcmp_P(oid, sysServices) == 0 ) {
status = pdu.VALUE.encode(SNMP_SYNTAX_INT, locServices);
} else if ( strcmp_P(oid, sysObjectID) == 0 ) {
status = pdu.VALUE.encode(SNMP_SYNTAX_OCTETS, locObjectID);
} else if ( strcmp_P(oid, alarme1) == 0 ) {
status = pdu.VALUE.encode(SNMP_SYNTAX_INT, localarme1);
} else if ( strcmp_P(oid, alarme2) == 0 ) {
status = pdu.VALUE.encode(SNMP_SYNTAX_INT, localarme2);
} else if ( strcmp_P(oid, alarme3) == 0 ) {
status = pdu.VALUE.encode(SNMP_SYNTAX_INT, localarme3);
} else if ( strcmp_P(oid, relay) == 0 ) {
status = pdu.VALUE.encode(SNMP_SYNTAX_INT, locrele);
} else {
status = SNMP_ERR_NO_SUCH_NAME;
}
pdu.type = SNMP_PDU_RESPONSE;
pdu.error = status;
Agentuino.responsePdu(&pdu);
}
Agentuino.freePdu(&pdu);
}
void setup() {
Serial.begin(9600); // Inicia conexao serial para monitoramento
pinMode(switchPin1, INPUT); // switchPin1 is an input
digitalWrite(switchPin1, HIGH); // Activate internal pullup resistor
pinMode(switchPin2, INPUT); // switchPin1 is an input
digitalWrite(switchPin2, HIGH); // Activate internal pullup resistor
pinMode(switchPin3, INPUT); // switchPin1 is an input
digitalWrite(switchPin3, HIGH); // Activate internal pullup resistor
pinMode(rele, OUTPUT); // rele is an output
digitalWrite(rele, HIGH);
Ethernet.begin(mac);
disparou = false;
disptempo = true;
// Serial.println("Ethernet iniciado");
#ifdef AVR
Wire.begin();
#else
Wire1.begin(); // Shield I2C pins connect to alt I2C bus on Arduino Due
#endif
api_status = Agentuino.begin();
if ( api_status == SNMP_API_STAT_SUCCESS ) {
Agentuino.onPduReceive(pduReceived);
delay(10);
Serial.println("SNMP Agent Initiated...");
return;
} else
{
delay(10);
Serial.print("SNMP Agent failed!");
}
}
void loop() {
int somaledsyellow = 0; //variavel para somar os valores para acionar os leds amarelo via i2c
int somaledsred = 0; //variavel para somar os valores para acionar os leds vermelho via i2c
int totalleds = 0; //variavel para totalizar os valores para acionar os leds amarelo e vermelho via i2c
int reading1 = digitalRead(switchPin1); // estado do sensor magnetico 1
int reading2 = digitalRead(switchPin2); //estado do sensor magnetico 2
int reading3 = digitalRead(switchPin3); // estado do sensor magnetico 3
staterelay = digitalRead(rele); //estado do rele
// se os sensores magneticos nao foram acionados e depois de acionados passaram-se mais de 5 minutos acende os leds verdes
if ((reading1) && (reading2) && (reading3) && (disptempo)) {
digitalWrite(rele,HIGH); // rele e desligado
Wire.beginTransmission(32); //endereca o modulo I2c no endereco 32
Wire.write(248); // escreve o valor para acender todos os leds
Wire.endTransmission(); // finaliza a transmissao
}
else
{
if ((reading1 != lastswitch1State) || (reading2 != lastswitch2State) || (reading3 != lastswitch3State)) {
lastDebounceTime = millis(); // se mudou o estado de um dos sensores magneticos grava o tempo com a funcao millis
}
if ((millis() - lastDebounceTime) > debounceDelay) { //Se passou mais de 1500ms com o estado modificado o rele e acionado e toca a sirene
if ((reading1 == 0) || (reading2 == 0) || (reading3 == 0)) {
digitalWrite(rele,LOW); // o rele e ligado
}
}
if (reading1 == LOW) { //se o sensor magnetico 1 estiver em estado baixo ou seja acionado
statusalarme1 = 1; // o status do sensor magnetico 1 e colocado em 1
somaledsred = somaledsred + 8; //liga o primeiro led vermelho da esquerda pra direita
}
else
{
somaledsyellow = somaledsyellow + 1; //se o sensor nao foi acionado acende o primeiro led amarelo da esquerda pra direita
statusalarme1 = 0; // o status do sensor magnetico 1 e colocado em 0
}
if (reading2 == LOW) { //se o sensor magnetico 2 estiver em estado baixo ou seja acionado
statusalarme2 = 1; // o status do sensor magnetico 1 e colocado em 1
somaledsred = somaledsred + 16; //liga o segundo led vermelho da esquerda pra direita
}
else
{
somaledsyellow = somaledsyellow + 2; //se o sensor nao foi acionado acende o segundo led amarelo da esquerda pra direita
statusalarme2 = 0; // o status do sensor magnetico 2 e colocado em 0
}
if (reading3 == LOW) { //se o sensor magnetico 3 estiver em estado baixo ou seja acionado
statusalarme3 = 1; // o status do sensor magnetico 3 e colocado em 1
somaledsred = somaledsred + 32; //liga o terceiro led vermelho da esquerda pra direita
}
else
{
somaledsyellow = somaledsyellow + 4;//se o sensor nao foi acionado acende o terceiro led amarelo da esquerda pra direita
statusalarme3 = 0; // o status do sensor magnetico 3 e colocado em 0
}
totalleds = 255 - (somaledsyellow + somaledsred); //totaliza os valores de escrita para os leds amarelos e vermelhos
Wire.beginTransmission(32);
Wire.write(255);
Wire.write(totalleds); // escreve o valor correspondente para acionar ou desacionar os leds vermelhos e amarelos
Wire.endTransmission();
if (!disparou) { // se o alarme nao disparou
dispMillis = millis();
disptempo = false;
disparou = true;
}
//Aguarda 5 minutos para parar de tocar a sirene
if ((millis() - dispMillis > 300000) && (!disptempo)){
digitalWrite(rele,HIGH);
// Serial.print("Parar a sirene");
disptempo = true;
disparou = false;
}
}
lastswitch1State = reading1; //ultimo estado do sensor magnetico 1
lastswitch2State = reading2; //ultimo estado do sensor magnetico 2
lastswitch3State = reading3; //ultimo estado do sensor magnetico 3
Agentuino.listen(); //O agentuino fica em espera
// Atualiza os estados dos sensores para as variaveis a serem lidas via SNMP
localarme1 = statusalarme1;
localarme2 = statusalarme2;
localarme3 = statusalarme3;
locrele = staterelay; //atualiza o estado do rele para ser lido via SNMP
}
Observem que mais uma vez utilizamos o agentuino para disponibilizar os dados dos sensores e do relé para serem lidos pelo Zabbix (vide posts anteriores).
É isso aí pessoal. Quaisquer dúvidas entrem em contato!
Assinar:
Postagens (Atom)