Resultados da busca - %E5%8D%8E%E5%AE%87%E5%BD%A9%E7%A5%A8%E6%9C%89%E6%89%98%E5%90%97%E3%80%90%E2%94%8B%E7%A8%B3%E5%AE%9A2%E2%92%8F7%E2%92%8F01705%E2%94%8B%E6%89%A3%E3%80%93%E3%80%91
a no caso de a temperatura passar de um limite dito no código para o Arduíno. A comunicação da temperatura é feita usando um ethernet shield em uma rede local.
A ligação do motor do cooler é feito usando esquema a baixo. O transistor que estou usando é um TIP120 (neste caso acredito que não é necessária a utilização do diodo, mas em todo caso mantive por preciosismo).
O LM35 esta ligado em uma das portas analógicas.
O sistema todo vai pro espaço quando coloco o Shield e subo o código p/ o Arduíno. Quando o LM35 é ligado na porta A0 a resposta vai p/ 400, 500 C.Na porta A2 ele funciona normal, mas a leitura fica em torno de 30 - 33 C durante quatro ou cinco leituras e ai passa para valores muito mais altos(40 - 50 C) e a temperatura não sobe nem desce com fatores que deveriam muda-la (ferro de solda próximo ou algo que diminuía a temperatura).
Já tentei usar vários códigos e todos tem o mesmo comportamento, no momento estou tentando algo bem simples ainda sem o uso dos códigos para o Ethenet (mas ainda mantenho ele conectado, pois até sem ele o comportamento é o mesmo).
const int LM35 = A5; // Pino Analogico onde vai ser ligado ao pino 2 do LM35const int REFRESH_RATE = 2000; //Tempo de atualização entre as leituras em msconst float CELSIUS_BASE = 0.4887585532746823069403714565; //Base de conversão para Graus Celsius ((5/1023) * 100)const int LED_Controle = 8;float Controle;
#include <LiquidCrystal.h> //Inclui a biblioteca do LCDLiquidCrystal lcd(12, 11, 5, 4, 3, 2); //Configura os pinos do Arduino para se comunicar com o LCD
int temp; //Inicia uma variável inteira(temp), para escrever no LCD a contagem do tempo
void setup() { Serial.begin(9600); pinMode(LED_Controle, OUTPUT); lcd.begin(16, 2); //Inicia o LCD com dimensões 16x2(Colunas x Linhas)lcd.setCursor(0, 0); //Posiciona o cursor na primeira coluna(0) e na primeira linha(0) do LCDlcd.setCursor(0, 1); //Posiciona o cursor na primeira coluna(0) e na segunda linha(1) do LCD}
void loop() { Serial.print("Temperatura: "); Serial.println(readTemperature()); delay(REFRESH_RATE); Controle = readTemperature(); lcd.print(Controle); //Escreve no LCD "Olá Garagista!"
if(Controle > 33.00){digitalWrite(LED_Controle, HIGH);}else{digitalWrite(LED_Controle, LOW);}
lcd.setCursor(13, 1); //Posiciona o cursor na décima quarta coluna(13) e na segunda linha(1) do LCDlcd.print(temp); //Escreve o valor atual da variável de contagem no LCDdelay(1000); //Aguarda 1 segundotemp++; //Incrementa variável de contagem if(temp == 600) //Se a variável temp chegar em 600(10 Minutos),... { temp = 0; //...zera a variável de contagem }}
float readTemperature(){ return (analogRead(LM35) * CELSIUS_BASE); }
OBS: Como vou usar um display para informar offline, já coloquei isso no código.
Alguém já passou por algo assim? …
tive uma aula com o Elcids Chagas (usuário muito bom, era - pois está sumido já tem tempo - conhecido por responder com textos enormes e com uma quantidade igualmente enorme de conhecimento, as vezes mais conhecimento do que era necessário, mas aprendi que conhecimento nunca é demais) onde ele tratou desse assunto. Sei os motivos, mas não tenho capacidade de transmitir, NEM DE LONGE, com a precisão e didática que ele tem. Então serei simplista ok?)
Nos pinos analógicos do arduino, caso seja definido como entrada, você tem a opção de realizar uma leitura digital ou analógica.
A leitura digital (digitalRead()), retornará SEMPRE o valor 0 (0v) ou 1 (5v). É elementar, não precisa de mais explicações (acho que 3V, ainda retorna como HIGH/1/alto)
A leitura analógica (analogRead()) retornará um valor DE 0 (0v) ATÉ 1023 (5v).
O "arduino" possui apenas 1 entrada analógica real, entretanto ela é multiplexada (A0~A5), e fica num "loop" para trazer a informação ao usuário.
A vantagem, é que o usuário utiliza "6 entradas analógicas", e não apenas 1. E isso AMPLIA MUITO as possibilidades do produto (muito mesmo).
A desvantagem, de modo resumido, é que a mudança do canal do multiplexador gera uma capacitância parasita, com localização em uns 2 ou 3 subníveis do circuito. E esse é o motivo do ruído/variação.
Isso é um problema do "arduino"? não, é uma característica.
Isso é um problema para seu projeto? Depende do quão estável o sinal precisa ser para você.
Caso você precise de mais estabilidade do que ele fornece, então você irá precisar TRATAR o sinal para se adequar as suas necessidades. Para isso, existem 2 métodos: software e hardware (pode usar os 2 ao mesmo tempo também).
Por software
você poderá fazer uma média dos valores dentro de um determinado tempo. Ou seja, soma o valores "N" vezes, e depois divide por "N".
obs- Recomendo utilizar a lógica com millis(). Caso não saiba usar a função, veja este link: https://labdegaragem.com/forum/topics/aula-fun-o-millis
obs2- também pode usar uma soma direta, o resultado será parecido ex:
int var;
int count;
count = count + 1;
var = var + analogRead(pino);
if (count == 50){
var = var/50;
count = 0;
}
onde "var" será a referência do sinal do seu potenciometro.
Por hardware
você precisará fazer um filtro RC. Ele irá reduzir a capacitância parasita.
Sugestões para você assistir
- https://www.youtube.com/watch?v=pk1oV7GHaTI
- https://www.youtube.com/watch?v=zKMYsPMKYfQ
Após tratar este sinal, agora teremos um sinal mais estável. O que resta agora é LOGICA DE PROGRAMAÇÃO.
obs- caso eu tenha errado em algo, peço aos colegas que me corrijam. …
Adicionado por tiago merces ao 23:31 em 27 outubro 2022
eralmente em paredes, etc. Preciso incluir uma rotina para ler 2 sensores-chaves (micro-swiches) tipo bigode-de-gato, para que o robô saia desse "encosto". Produzí e tentei várias rotinas (uma já veio com o kit do robô, mas usando apenas uma chave), sem sucesso: Ou funcionam os motores+ultrassom, ou as chaves. Testei colocar a minha rotina em vários pontos do sketch. Atualmente dividi essa rotina para ver se funcionavam os dois sensores (2 chaves e o ultrassom). Não deu certo.
Abaixo cópia do sketch mais atual. Este tem 4 páginas em A4, sem espaços entre linhas. Vou copiar aqui é o sketch mesmo, tirado da IDE, ok?
//--------------- Programa JABUTINO sketch 20140510 ----------- #include
#include
//Instancia o objeto referente aos motores DC AF_DCMotor motorEsquerdo(1); //Motor esquerdo na conexão "M1"
AF_DCMotor motorDireito(2); //Motor direito na conexão "M2"
//Definições de velocidade em PWM de 0 a 255 const char VEL_MAX = 255;
const char VEL_MIN = 0;
const char VEL_MED = 200;
//Pinos para controle do Ultrassom HC-SR04 //usar as portas analógicas A0 e A1 como digitais
const int pinoTrigger = 14; // A0 = 14
const int pinoEcho = 15; // A1 = 15
//Servo Motor Servo meuServo;
const int pinoServo = 10; //o pino 10 é o pino de sinal da conexão "SERVO_2"
//Define as posições de calibragem do servo //Valores para conseguir um melhor alinhamento do servo, cada motor responde de forma diferente.
//Os valores devem variar de 0 a 180 graus, ajuste de acordo com seu motor na tentativa e erro.
const int OLHA_ESQ = 180; const int OLHA_DIR = 0;
const int OLHA_FRT = 90;
// Pino em que o BUZZER está conectado: const int pinoBuzzer = 9;
// PINOS que vão conectar as 2 CHAVES (sensores de colisão): const int ChaveE = 18;
const int ChaveD = 19;
//Método obrigatório //Realiza as definições dos pinos e faz a inicialização da biblioteca de servo.
void setup(void) {
// Inicializa os motores com velocidade máxima
motorEsquerdo.setSpeed(VEL_MAX);
motorDireito.setSpeed(VEL_MAX);
//atribui os pinos do ultrassom pinMode(pinoTrigger, OUTPUT);
pinMode(pinoEcho, INPUT);
Serial.begin(9600); /* função provisória, para controle da rotina das chaves.*/ /* define os pinos como entrada ligando um resistor pullup a eles */
pinMode(ChaveE, INPUT_PULLUP); // MUITO IMPORTANTE
pinMode(ChaveD, INPUT_PULLUP);
//inicia o Servo meuServo.attach(pinoServo);
//Coloca o servo virado para posicao frontal
meuServo.write(OLHA_FRT);
} // fim do setup //================================================
//Corpo principal do programa, repete infinitamente
void loop()
{
// Inicia andando para frente
andarpFrente(VEL_MAX);
// Faz a leitura dos sensores de CHAVES = colisão: int lerChaveE = digitalRead(ChaveE);
int lerChaveD = digitalRead(ChaveD);
//Enquanto não encontrar um obstáculo a menos de 10cm while(medeDistancia() > 10)
{
delay(100); //Faz uma leitura da distancia a cada 0,1 segundo
}
{ //imprime o valor chave Esq: if (lerChaveE == HIGH)
{ Serial.println("Esquerda");
tone(pinoBuzzer, 840); //envia um sinal de 740Hz para o pino 9 delay(100); //aguarda 0,1 segundo
noTone(pinoBuzzer); //interrompe o som no pino 9
girarpDireita(VEL_MED);
delay(500); //aguarda 1 segundo
}
else
// if (lerChaveD != lidoAntD)
{ // imprime o valor da chave Direita:
if (lerChaveD == HIGH)
{ Serial.println("Direita");
tone(pinoBuzzer, 840); //envia um sinal de 840Hz para o pino 9 delay(100); //aguarda 0,1 segundo
noTone(pinoBuzzer); //interrompe o som no pino 9
girarpEsquerda(VEL_MED);
delay(500); //aguarda 0,5 segundo
}
}
//Se encontrou um obstáculo recua por 1 segundo e pára
andarpTras(VEL_MED);
delay(1000);
pararMotores();
//Verifica qual lado tem maior distância até um obstáculo int esquerda = 0, direita = 0;
meuServo.write(OLHA_ESQ); //vira o servo para a esquerda delay(500); //aguarda o servo completar o movimento
esquerda = medeDistancia(); //mede a distância na esquerda
meuServo.write(OLHA_DIR); //vira o servo para a direita
delay(500); //aguarda o servo completar o movimento
direita = medeDistancia(); //mede a distância na direita meuServo.write(OLHA_FRT); //olha pra frente novamente
delay(500); //aguarda o servo completar o movimento
if(esquerda > direita) /*se a distancia do obstáculo na esquerda for maior que na direita vira para esquerda */
{
girarpEsquerda(VEL_MAX);
}
else /* se a distância do obstáculo na direita for maior ou igual que na esquerda
vira para a direita */
{
girarpDireita(VEL_MAX);
}
//Aguarda alguns instantes para o robô virar
delay(500); //<< modifique esse tempo se desejar que ele vire por mais ou menos tempo // Fim da rotina de obstáculos // Inicio da rotina das CHAVES / colisão: // ==> tirado daqui e dividido, para tentar o funcionamento.
// armazena o valor lido para monitorar as próximas mudanças: // lidoAntE = lerChaveE;
// lidoAntD = lerChaveD;
// aguarda minimamente para eliminar ruidos: delay(5);
int lerChaveE = LOW; // Garante que a chave Esq estará em LOW.
int lerChaveD = LOW; // Garante que a chave Dir estará em LOW.
}
// final da rotina das CHAVES
} // Fim do LOOP
//Utiliza o sensor de Ultrassom HC-SR04 para medir a distância em centímetros int medeDistancia()
{
//Garante que o pino de Trigger está LOW
digitalWrite(pinoTrigger, LOW);
delayMicroseconds(2);
//cria um pulso de 5 microssegundos no Trigger
digitalWrite(pinoTrigger, HIGH);
delayMicroseconds(5);
digitalWrite(pinoTrigger, LOW);
//aguarda o echo long microssegundos = pulseIn(pinoEcho, HIGH);
// A velocidade do som é 340 m/s ou aproximadamente 29 microssegundos por centimetro.
// O pulso faz uma viagem de ida e volta do sensor até o obstáculo
// assim, para calcular a distancia temos que dividir esse tempo pela metade
// desta forma...
return int(microssegundos / 29 / 2);
} // Fim do CalcularDistancia
// ======== void's dos motores: =============
//Gira as duas rodas para frente //Como os motores estão virados para lados opostos eles devem
//girar em sentidos opostos para que as rodas girem na mesma direção
void andarpFrente(char velocidade) {
motorEsquerdo.setSpeed(velocidade);
motorDireito.setSpeed(velocidade);
motorEsquerdo.run(FORWARD);
motorDireito.run(BACKWARD);
}
//Gira as duas rodas para trás //Como os motores estão virados para lados opostos eles devem
//girar em sentidos opostos para que as rodas girem na mesma direção
void andarpTras(char velocidade)
{
motorEsquerdo.setSpeed(velocidade);
motorDireito.setSpeed(velocidade);
motorEsquerdo.run(BACKWARD);
motorDireito.run(FORWARD);
}
//Gira as duas rodas em sentido inverso, girando no próprio eixo void girarpEsquerda (char velocidade)
{
motorEsquerdo.setSpeed(velocidade);
motorDireito.setSpeed(velocidade);
motorEsquerdo.run(BACKWARD);
motorDireito.run(BACKWARD);
}
//Gira as duas rodas em sentido inverso, girando no próprio eixo void girarpDireita(char velocidade)
{
motorEsquerdo.setSpeed(velocidade);
motorDireito.setSpeed(velocidade);
motorEsquerdo.run(FORWARD);
motorDireito.run(FORWARD);
}
//Pára os motores definindo os dois pinos Enable em estado Low void pararMotores()
{
motorEsquerdo.run(RELEASE);
motorDireito.run(RELEASE);
}…
eralmente em paredes, etc. Preciso incluir uma rotina para ler 2 sensores-chaves (micro-swiches) tipo bigode-de-gato, para que o robô saia desse "encosto". Produzí e tentei várias rotinas (uma já veio com o kit do robô, mas usando apenas uma chave), sem sucesso: Ou funcionam os motores+ultrassom, ou as chaves. Testei colocar a minha rotina em vários pontos do sketch. Atualmente dividi essa rotina para ver se funcionavam os dois sensores (2 chaves e o ultrassom). Não deu certo. Abaixo cópia do sketch mais atual. Este tem 4 páginas em A4, sem espaços entre linhas. Vou copiar aqui é o sketch mesmo, tirado da IDE, ok?
//--------------- Programa JABUTINO sketch 20140510 ----------- #include #include
//Instancia o objeto referente aos motores DC AF_DCMotor motorEsquerdo(1); //Motor esquerdo na conexão "M1" AF_DCMotor motorDireito(2); //Motor direito na conexão "M2"
//Definições de velocidade em PWM de 0 a 255 const char VEL_MAX = 255; const char VEL_MIN = 0; const char VEL_MED = 200;
//Pinos para controle do Ultrassom HC-SR04 //usar as portas analógicas A0 e A1 como digitais const int pinoTrigger = 14; // A0 = 14 const int pinoEcho = 15; // A1 = 15
//Servo Motor Servo meuServo; const int pinoServo = 10; //o pino 10 é o pino de sinal da conexão "SERVO_2"
//Define as posições de calibragem do servo //Valores para conseguir um melhor alinhamento do servo, cada motor responde de forma diferente. //Os valores devem variar de 0 a 180 graus, ajuste de acordo com seu motor na tentativa e erro.
const int OLHA_ESQ = 180; const int OLHA_DIR = 0; const int OLHA_FRT = 90;
// Pino em que o BUZZER está conectado: const int pinoBuzzer = 9;
// PINOS que vão conectar as 2 CHAVES (sensores de colisão): const int ChaveE = 18; const int ChaveD = 19;
//Método obrigatório //Realiza as definições dos pinos e faz a inicialização da biblioteca de servo.
void setup(void) { // Inicializa os motores com velocidade máxima motorEsquerdo.setSpeed(VEL_MAX); motorDireito.setSpeed(VEL_MAX);
//atribui os pinos do ultrassom pinMode(pinoTrigger, OUTPUT); pinMode(pinoEcho, INPUT);
Serial.begin(9600); /* função provisória, para controle da rotina das chaves.*/ /* define os pinos como entrada ligando um resistor pullup a eles */ pinMode(ChaveE, INPUT_PULLUP); // MUITO IMPORTANTE pinMode(ChaveD, INPUT_PULLUP);
//inicia o Servo meuServo.attach(pinoServo); //Coloca o servo virado para posicao frontal meuServo.write(OLHA_FRT);
} // fim do setup //================================================ //Corpo principal do programa, repete infinitamente void loop() { // Inicia andando para frente andarpFrente(VEL_MAX);
// Faz a leitura dos sensores de CHAVES = colisão: int lerChaveE = digitalRead(ChaveE); int lerChaveD = digitalRead(ChaveD);
//Enquanto não encontrar um obstáculo a menos de 10cm while(medeDistancia() > 10) { delay(100); //Faz uma leitura da distancia a cada 0,1 segundo }
{ // chave Esq: if (lerChaveE == HIGH) { Serial.println("Esquerda");
tone(pinoBuzzer, 840); //envia um sinal de 740Hz para o pino 9 delay(100); //aguarda 0,1 segundo noTone(pinoBuzzer); //interrompe o som no pino 9 girarpDireita(VEL_MED); delay(500); //aguarda 1 segundo } else { // chave Direita: if (lerChaveD == HIGH) { Serial.println("Direita");
tone(pinoBuzzer, 840); //envia um sinal de 840Hz para o pino 9 delay(100); //aguarda 0,1 segundo noTone(pinoBuzzer); //interrompe o som no pino 9 girarpEsquerda(VEL_MED); delay(500); //aguarda 0,5 segundo } } //Se encontrou um obstáculo recua por 1 segundo e pára andarpTras(VEL_MED); delay(1000); pararMotores();
//Verifica qual lado tem maior distância até um obstáculo int esquerda = 0, direita = 0;
meuServo.write(OLHA_ESQ); //vira o servo para a esquerda delay(500); //aguarda o servo completar o movimento esquerda = medeDistancia(); //mede a distância na esquerda meuServo.write(OLHA_DIR); //vira o servo para a direita delay(500); //aguarda o servo completar o movimento
direita = medeDistancia(); //mede a distância na direita meuServo.write(OLHA_FRT); //olha pra frente novamente delay(500); //aguarda o servo completar o movimento
if(esquerda > direita) /*se a distancia do obstáculo na esquerda for maior que na direita vira para esquerda */ { girarpEsquerda(VEL_MAX); } else /* se a distância do obstáculo na direita for maior ou igual que na esquerda vira para a direita */ { girarpDireita(VEL_MAX); } //Aguarda alguns instantes para o robô virar delay(500); // modifique esse tempo se desejar que ele vire por mais ou menos tempo // Fim da rotina de obstáculos
// Inicio da rotina das CHAVES / colisão: // ==> tirado daqui e dividido, para tentar o funcionamento.
// aguarda minimamente para eliminar ruidos:
delay(5); int lerChaveE = LOW; // Garante que a chave Esq estará em LOW. int lerChaveD = LOW; // Garante que a chave Dir estará em LOW. } // final da rotina das CHAVES
} // Fim do LOOP
//Utiliza o sensor de Ultrassom HC-SR04 para medir a distância em centímetros int medeDistancia() { //Garante que o pino de Trigger está LOW digitalWrite(pinoTrigger, LOW); delayMicroseconds(2); //cria um pulso de 5 microssegundos no Trigger digitalWrite(pinoTrigger, HIGH); delayMicroseconds(5); digitalWrite(pinoTrigger, LOW);
//aguarda o echo long microssegundos = pulseIn(pinoEcho, HIGH); // A velocidade do som é 340 m/s ou aproximadamente 29 microssegundos por centimetro. // O pulso faz uma viagem de ida e volta do sensor até o obstáculo // assim, para calcular a distancia temos que dividir esse tempo pela metade // desta forma... return int(microssegundos / 29 / 2); } // Fim do CalcularDistancia
// ======== void's dos motores: =============
//Gira as duas rodas para frente //Como os motores estão virados para lados opostos eles devem //girar em sentidos opostos para que as rodas girem na mesma direção
void andarpFrente(char velocidade) { motorEsquerdo.setSpeed(velocidade); motorDireito.setSpeed(velocidade); motorEsquerdo.run(FORWARD); motorDireito.run(BACKWARD); }
//Gira as duas rodas para trás //Como os motores estão virados para lados opostos eles devem //girar em sentidos opostos para que as rodas girem na mesma direção void andarpTras(char velocidade) { motorEsquerdo.setSpeed(velocidade); motorDireito.setSpeed(velocidade); motorEsquerdo.run(BACKWARD); motorDireito.run(FORWARD); }
//Gira as duas rodas em sentido inverso, girando no próprio eixo void girarpEsquerda (char velocidade) { motorEsquerdo.setSpeed(velocidade); motorDireito.setSpeed(velocidade); motorEsquerdo.run(BACKWARD); motorDireito.run(BACKWARD); }
//Gira as duas rodas em sentido inverso, girando no próprio eixo void girarpDireita(char velocidade) { motorEsquerdo.setSpeed(velocidade); motorDireito.setSpeed(velocidade); motorEsquerdo.run(FORWARD); motorDireito.run(FORWARD); }
//Pára os motores definindo os dois pinos Enable em estado Low void pararMotores() { motorEsquerdo.run(RELEASE); motorDireito.run(RELEASE); }…
depois disso eles ficaram congelados. Ja tentei reiniciar o servidor, aumentar o tempo de atualização, mas nada funcionou. Segue o novo codigo utilizado no arduino e algumas imagens das minhas configurações.
Espero que alguém possa dar uma luz de como resolver isso,
desde já grato a todos !!
void configure_mb_slave(long baud, char parity, char txenpin);
/* * update_mb_slave(slave_id, holding_regs_array, number_of_regs) * * checks if there is any valid request from the modbus master. If there is, * performs the action requested * * slave: slave id (1 to 127) * regs: an array with the holding registers. They start at address 1 (master point of view) * regs_size: total number of holding registers. * returns: 0 if no request from master, * NO_REPLY (-1) if no reply is sent to the master * an exception code (1 to 4) in case of a modbus exceptions * the number of bytes sent as reply ( > 4) if OK. */
int update_mb_slave(unsigned char slave, int *regs,unsigned int regs_size);
/* Modbus RTU common parameters, the Master MUST use the same parameters */enum { MB_SLAVE = 1, /* modbus slave id */};/* slave registers example */enum { MB_REG0, MB_REG1, MB_REG2, MB_REG3, MB_REG4, MB_REG5, MB_REG6, MB_REGS /* total number of registers on slave */};
int regs[MB_REGS]; /* this is the slave's modbus data map *///Vibracaoint vib;
//Pressao#include <Wire.h>
#define BMP085_ADDRESS 0x77 // I2C address of BMP085
const unsigned char OSS = 0; // Oversampling Setting
// Calibration valuesint ac1;int ac2; int ac3; unsigned int ac4;unsigned int ac5;unsigned int ac6;int b1; int b2;int mb;int mc;int md;long b5; // // b5 is calculated in bmp085GetTemperature(...), this variable is also used in bmp085GetPressure(...) so ...Temperature(...) must be called before ...Pressure(...).short temperature;long pressure;
//Sonar#include "Ultrasonic.h"Ultrasonic ultrasonic(13,12);
//Sensor de Gasconst int analogInPin = A1; int sensorValue = 0;
//Humidade#include "DHT.h"#define DHTPIN 2#define DHTTYPE DHT11DHT dht(DHTPIN, DHTTYPE);
void setup() { /* Modbus setup example, the master must use the same COM parameters */ /* 115200 bps, 8N1, two-device network */ configure_mb_slave(9600, 'n', 0);//Pressao Wire.begin(); bmp085Calibration();//Humidadedht.begin();}
void loop() { /* This is all for the Modbus slave */ update_mb_slave(MB_SLAVE, regs, MB_REGS);
/* your code goes here */{//Vibracao vib=analogRead(3); if(vib>0) {regs[1]=vib; // vibracao 2
} else {regs[1]=0; // vibracao 0 }
//Pressao temperature = bmp085GetTemperature(bmp085ReadUT()); pressure = bmp085GetPressure(bmp085ReadUP());regs[3]=temperature*0.1, DEC; // temp interna 3regs[2]=pressure, DEC; // pressao 2
//Sonarregs[0]=ultrasonic.Ranging(CM); //sonar 0
//Gas sensorValue = analogRead(analogInPin); regs[6]=sensorValue; // gas 6 //Humidade float h = dht.readHumidity(); float t = dht.readTemperature(); regs[5]=h; //humidade 5regs[4]=t; //temp externa 4
//Timer delay(200);}
} // Calibrando Pressaovoid bmp085Calibration(){ ac1 = bmp085ReadInt(0xAA); ac2 = bmp085ReadInt(0xAC); ac3 = bmp085ReadInt(0xAE); ac4 = bmp085ReadInt(0xB0); ac5 = bmp085ReadInt(0xB2); ac6 = bmp085ReadInt(0xB4); b1 = bmp085ReadInt(0xB6); b2 = bmp085ReadInt(0xB8); mb = bmp085ReadInt(0xBA); mc = bmp085ReadInt(0xBC); md = bmp085ReadInt(0xBE);}
// Calculate temperature given ut.// Value returned will be in units of 0.1 deg Cshort bmp085GetTemperature(unsigned int ut){ long x1, x2; x1 = (((long)ut - (long)ac6)*(long)ac5) >> 15; x2 = ((long)mc << 11)/(x1 + md); b5 = x1 + x2;
return ((b5 + 8)>>4); }
// Calculate pressure given up// calibration values must be known// b5 is also required so bmp085GetTemperature(...) must be called first.// Value returned will be pressure in units of Pa.long bmp085GetPressure(unsigned long up){ long x1, x2, x3, b3, b6, p; unsigned long b4, b7; b6 = b5 - 4000; // Calculate B3 x1 = (b2 * (b6 * b6)>>12)>>11; x2 = (ac2 * b6)>>11; x3 = x1 + x2; b3 = (((((long)ac1)*4 + x3)<<OSS) + 2)>>2; // Calculate B4 x1 = (ac3 * b6)>>13; x2 = (b1 * ((b6 * b6)>>12))>>16; x3 = ((x1 + x2) + 2)>>2; b4 = (ac4 * (unsigned long)(x3 + 32768))>>15; b7 = ((unsigned long)(up - b3) * (50000>>OSS)); if (b7 < 0x80000000) p = (b7<<1)/b4; else p = (b7/b4)<<1; x1 = (p>>8) * (p>>8); x1 = (x1 * 3038)>>16; x2 = (-7357 * p)>>16; p += (x1 + x2 + 3791)>>4; return p;}
// Read 1 byte from the BMP085 at 'address'char bmp085Read(unsigned char address){ unsigned char data; Wire.beginTransmission(BMP085_ADDRESS); Wire.send(address); Wire.endTransmission(); Wire.requestFrom(BMP085_ADDRESS, 1); while(!Wire.available()) ; return Wire.receive();}
// Read 2 bytes from the BMP085// First byte will be from 'address'// Second byte will be from 'address'+1int bmp085ReadInt(unsigned char address){ unsigned char msb, lsb; Wire.beginTransmission(BMP085_ADDRESS); Wire.send(address); Wire.endTransmission(); Wire.requestFrom(BMP085_ADDRESS, 2); while(Wire.available()<2) ; msb = Wire.receive(); lsb = Wire.receive(); return (int) msb<<8 | lsb;}
// Read the uncompensated temperature valueunsigned int bmp085ReadUT(){ unsigned int ut; // Write 0x2E into Register 0xF4 // This requests a temperature reading Wire.beginTransmission(BMP085_ADDRESS); Wire.send(0xF4); Wire.send(0x2E); Wire.endTransmission(); // Wait at least 4.5ms delay(5); // Read two bytes from registers 0xF6 and 0xF7 ut = bmp085ReadInt(0xF6); return ut;}
// Read the uncompensated pressure valueunsigned long bmp085ReadUP(){ unsigned char msb, lsb, xlsb; unsigned long up = 0; // Write 0x34+(OSS<<6) into register 0xF4 // Request a pressure reading w/ oversampling setting Wire.beginTransmission(BMP085_ADDRESS); Wire.send(0xF4); Wire.send(0x34 + (OSS<<6)); Wire.endTransmission(); // Wait for conversion, delay time dependent on OSS delay(2 + (3<<OSS)); // Read register 0xF6 (MSB), 0xF7 (LSB), and 0xF8 (XLSB) Wire.beginTransmission(BMP085_ADDRESS); Wire.send(0xF6); Wire.endTransmission(); Wire.requestFrom(BMP085_ADDRESS, 3); // Wait for data to become available while(Wire.available() < 3) ; msb = Wire.receive(); lsb = Wire.receive(); xlsb = Wire.receive(); up = (((unsigned long) msb << 16) | ((unsigned long) lsb << 8) | (unsigned long) xlsb) >> (8-OSS); return up;}/**************************************************************************** * BEGIN MODBUS RTU SLAVE FUNCTIONS ****************************************************************************/
/* global variables */unsigned int Txenpin = 0; /* Enable transmission pin, used on RS485 networks */
/* enum of supported modbus function codes. If you implement a new one, put its function code here ! */enum { FC_READ_REGS = 0x03, //Read contiguous block of holding register FC_WRITE_REG = 0x06, //Write single holding register FC_WRITE_REGS = 0x10 //Write block of contiguous registers};
/* supported functions. If you implement a new one, put its function code into this array! */const unsigned char fsupported[] = { FC_READ_REGS, FC_WRITE_REG, FC_WRITE_REGS };
/* constants */enum { MAX_READ_REGS = 0x7D, MAX_WRITE_REGS = 0x7B, MAX_MESSAGE_LENGTH = 256 };
enum { RESPONSE_SIZE = 6, EXCEPTION_SIZE = 3, CHECKSUM_SIZE = 2 };
/* exceptions code */enum { NO_REPLY = -1, EXC_FUNC_CODE = 1, EXC_ADDR_RANGE = 2, EXC_REGS_QUANT = 3, EXC_EXECUTE = 4 };
/* positions inside the query/response array */enum { SLAVE = 0, FUNC, START_H, START_L, REGS_H, REGS_L, BYTE_CNT };
/*CRC INPUTS: buf -> Array containing message to be sent to controller. start -> Start of loop in crc counter, usually 0. cnt -> Amount of bytes in message being sent to controller/ OUTPUTS: temp -> Returns crc byte for message. COMMENTS: This routine calculates the crc high and low byte of a message. Note that this crc is only used for Modbus, not Modbus+ etc. ****************************************************************************/
unsigned int crc(unsigned char *buf, unsigned char start,unsigned char cnt) { unsigned char i, j; unsigned temp, temp2, flag;
temp = 0xFFFF;
for (i = start; i < cnt; i++) { temp = temp ^ buf[i];
for (j = 1; j <= 8; j++) { flag = temp & 0x0001; temp = temp >> 1; if (flag) temp = temp ^ 0xA001; } }
/* Reverse byte order. */ temp2 = temp >> 8; temp = (temp << 8) | temp2; temp &= 0xFFFF;
return (temp);}
/*********************************************************************** * * The following functions construct the required query into * a modbus query packet. * ***********************************************************************/
/* * Start of the packet of a read_holding_register response */void build_read_packet(unsigned char slave, unsigned char function,unsigned char count, unsigned char *packet) { packet[SLAVE] = slave; packet[FUNC] = function; packet[2] = count * 2;}
/* * Start of the packet of a preset_multiple_register response */void build_write_packet(unsigned char slave, unsigned char function,unsigned int start_addr, unsigned char count,unsigned char *packet) { packet[SLAVE] = slave; packet[FUNC] = function; packet[START_H] = start_addr >> 8; packet[START_L] = start_addr & 0x00ff; packet[REGS_H] = 0x00; packet[REGS_L] = count;}
/* * Start of the packet of a write_single_register response */void build_write_single_packet(unsigned char slave, unsigned char function, unsigned int write_addr, unsigned int reg_val, unsigned char* packet) { packet[SLAVE] = slave; packet[FUNC] = function; packet[START_H] = write_addr >> 8; packet[START_L] = write_addr & 0x00ff; packet[REGS_H] = reg_val >> 8; packet[REGS_L] = reg_val & 0x00ff;}
/* * Start of the packet of an exception response */void build_error_packet(unsigned char slave, unsigned char function,unsigned char exception, unsigned char *packet) { packet[SLAVE] = slave; packet[FUNC] = function + 0x80; packet[2] = exception;}
/************************************************************************* * * modbus_query( packet, length) * * Function to add a checksum to the end of a packet. * Please note that the packet array must be at least 2 fields longer than * string_length. **************************************************************************/
void modbus_reply(unsigned char *packet, unsigned char string_length) { int temp_crc;
temp_crc = crc(packet, 0, string_length); packet[string_length] = temp_crc >> 8; string_length++; packet[string_length] = temp_crc & 0x00FF;}
/*********************************************************************** * * send_reply( query_string, query_length ) * * Function to send a reply to a modbus master. * Returns: total number of characters sent ************************************************************************/
int send_reply(unsigned char *query, unsigned char string_length) { unsigned char i;
if (Txenpin > 1) { // set MAX485 to speak mode UCSR0A=UCSR0A |(1 << TXC0); digitalWrite( Txenpin, HIGH); delay(1); }
modbus_reply(query, string_length); string_length += 2;
for (i = 0; i < string_length; i++) { Serial.print(query[i], BYTE); }
if (Txenpin > 1) {// set MAX485 to listen mode while (!(UCSR0A & (1 << TXC0))); digitalWrite( Txenpin, LOW); }
return i; /* it does not mean that the write was succesful, though */}
/*********************************************************************** * * receive_request( array_for_data ) * * Function to monitor for a request from the modbus master. * * Returns: Total number of characters received if OK * 0 if there is no request * A negative error code on failure ***********************************************************************/
int receive_request(unsigned char *received_string) { int bytes_received = 0;
/* FIXME: does Serial.available wait 1.5T or 3.5T before exiting the loop? */ while (Serial.available()) { received_string[bytes_received] = Serial.read(); bytes_received++; if (bytes_received >= MAX_MESSAGE_LENGTH) return NO_REPLY; /* port error */ }
return (bytes_received);}
/********************************************************************* * * modbus_request(slave_id, request_data_array) * * Function to the correct request is returned and that the checksum * is correct. * * Returns: string_length if OK * 0 if failed * Less than 0 for exception errors * * Note: All functions used for sending or receiving data via * modbus return these return values. * **********************************************************************/
int modbus_request(unsigned char slave, unsigned char *data) { int response_length; unsigned int crc_calc = 0; unsigned int crc_received = 0; unsigned char recv_crc_hi; unsigned char recv_crc_lo;
response_length = receive_request(data);
if (response_length > 0) { crc_calc = crc(data, 0, response_length - 2); recv_crc_hi = (unsigned) data[response_length - 2]; recv_crc_lo = (unsigned) data[response_length - 1]; crc_received = data[response_length - 2]; crc_received = (unsigned) crc_received << 8; crc_received = crc_received | (unsigned) data[response_length - 1];
/*********** check CRC of response ************/ if (crc_calc != crc_received) { return NO_REPLY; }
/* check for slave id */ if (slave != data[SLAVE]) { return NO_REPLY; } } return (response_length);}
/********************************************************************* * * validate_request(request_data_array, request_length, available_regs) * * Function to check that the request can be processed by the slave. * * Returns: 0 if OK * A negative exception code on error * **********************************************************************/
int validate_request(unsigned char *data, unsigned char length,unsigned int regs_size) { int i, fcnt = 0; unsigned int regs_num = 0; unsigned int start_addr = 0; unsigned char max_regs_num;
/* check function code */ for (i = 0; i < sizeof(fsupported); i++) { if (fsupported[i] == data[FUNC]) { fcnt = 1; break; } } if (0 == fcnt) return EXC_FUNC_CODE;
if (FC_WRITE_REG == data[FUNC]) { /* For function write single reg, this is the target reg.*/ regs_num = ((int) data[START_H] << 8) + (int) data[START_L]; if (regs_num >= regs_size) return EXC_ADDR_RANGE; return 0; } /* For functions read/write regs, this is the range. */ regs_num = ((int) data[REGS_H] << 8) + (int) data[REGS_L]; /* check quantity of registers */ if (FC_READ_REGS == data[FUNC]) max_regs_num = MAX_READ_REGS; else if (FC_WRITE_REGS == data[FUNC]) max_regs_num = MAX_WRITE_REGS;
if ((regs_num < 1) || (regs_num > max_regs_num)) return EXC_REGS_QUANT;
/* check registers range, start address is 0 */ start_addr = ((int) data[START_H] << 8) + (int) data[START_L]; if ((start_addr + regs_num) > regs_size) return EXC_ADDR_RANGE;
return 0; /* OK, no exception */}
/************************************************************************ * * write_regs(first_register, data_array, registers_array) * * writes into the slave's holding registers the data in query, * starting at start_addr. * * Returns: the number of registers written ************************************************************************/
int write_regs(unsigned int start_addr, unsigned char *query, int *regs) { int temp; unsigned int i;
for (i = 0; i < query[REGS_L]; i++) { /* shift reg hi_byte to temp */ temp = (int) query[(BYTE_CNT + 1) + i * 2] << 8; /* OR with lo_byte */ temp = temp | (int) query[(BYTE_CNT + 2) + i * 2];
regs[start_addr + i] = temp; } return i;}
/************************************************************************ * * preset_multiple_registers(slave_id, first_register, number_of_registers, * data_array, registers_array) * * Write the data from an array into the holding registers of the slave. * *************************************************************************/
int preset_multiple_registers(unsigned char slave,unsigned int start_addr,unsigned char count, unsigned char *query,int *regs) { unsigned char function = FC_WRITE_REGS; /* Preset Multiple Registers */ int status = 0; unsigned char packet[RESPONSE_SIZE + CHECKSUM_SIZE];
build_write_packet(slave, function, start_addr, count, packet);
if (write_regs(start_addr, query, regs)) { status = send_reply(packet, RESPONSE_SIZE); }
return (status);}
/************************************************************************ * * write_single_register(slave_id, write_addr, data_array, registers_array) * * Write a single int val into a single holding register of the slave. * *************************************************************************/
int write_single_register(unsigned char slave, unsigned int write_addr, unsigned char *query, int *regs) { unsigned char function = FC_WRITE_REG; /* Function: Write Single Register */ int status = 0; unsigned int reg_val; unsigned char packet[RESPONSE_SIZE + CHECKSUM_SIZE];
reg_val = query[REGS_H] << 8 | query[REGS_L]; build_write_single_packet(slave, function, write_addr, reg_val, packet); regs[write_addr] = (int) reg_val;/* written.start_addr=write_addr; written.num_regs=1;*/ status = send_reply(packet, RESPONSE_SIZE);
return (status);}
/************************************************************************ * * read_holding_registers(slave_id, first_register, number_of_registers, * registers_array) * * reads the slave's holdings registers and sends them to the Modbus master * *************************************************************************/
int read_holding_registers(unsigned char slave, unsigned int start_addr,
unsigned char reg_count, int *regs) { unsigned char function = 0x03; /* Function 03: Read Holding Registers */ int packet_size = 3; int status; unsigned int i; unsigned char packet[MAX_MESSAGE_LENGTH];
build_read_packet(slave, function, reg_count, packet);
for (i = start_addr; i < (start_addr + (unsigned int) reg_count); i++) { packet[packet_size] = regs[i] >> 8; packet_size++; packet[packet_size] = regs[i] & 0x00FF; packet_size++; }
status = send_reply(packet, packet_size);
return (status);}
void configure_mb_slave(long baud, char parity, char txenpin){ Serial.begin(baud);
switch (parity) { case 'e': // 8E1 UCSR0C |= ((1<<UPM01) | (1<<UCSZ01) | (1<<UCSZ00)); // UCSR0C &= ~((1<<UPM00) | (1<<UCSZ02) | (1<<USBS0)); break; case 'o': // 8O1 UCSR0C |= ((1<<UPM01) | (1<<UPM00) | (1<<UCSZ01) | (1<<UCSZ00)); // UCSR0C &= ~((1<<UCSZ02) | (1<<USBS0)); break; case 'n': // 8N1 UCSR0C |= ((1<<UCSZ01) | (1<<UCSZ00)); // UCSR0C &= ~((1<<UPM01) | (1<<UPM00) | (1<<UCSZ02) | (1<<USBS0)); break; default: break; }
if (txenpin > 1) { // pin 0 & pin 1 are reserved for RX/TX Txenpin = txenpin; /* set global variable */ pinMode(Txenpin, OUTPUT); digitalWrite(Txenpin, LOW); }
return;}
/* * update_mb_slave(slave_id, holding_regs_array, number_of_regs) * * checks if there is any valid request from the modbus master. If there is, * performs the action requested */
unsigned long Nowdt = 0;unsigned int lastBytesReceived;const unsigned long T35 = 5;
int update_mb_slave(unsigned char slave, int *regs,unsigned int regs_size) { unsigned char query[MAX_MESSAGE_LENGTH]; unsigned char errpacket[EXCEPTION_SIZE + CHECKSUM_SIZE]; unsigned int start_addr; int exception; int length = Serial.available(); unsigned long now = millis();
if (length == 0) { lastBytesReceived = 0; return 0; }
if (lastBytesReceived != length) { lastBytesReceived = length; Nowdt = now + T35; return 0; } if (now < Nowdt) return 0;
lastBytesReceived = 0;
length = modbus_request(slave, query); if (length < 1) return length;
exception = validate_request(query, length, regs_size); if (exception) { build_error_packet(slave, query[FUNC], exception, errpacket); send_reply(errpacket, EXCEPTION_SIZE); return (exception); } start_addr = ((int) query[START_H] << 8) + (int) query[START_L]; switch (query[FUNC]) { case FC_READ_REGS: return read_holding_registers(slave, start_addr, query[REGS_L], regs); break; case FC_WRITE_REGS: return preset_multiple_registers(slave, start_addr, query[REGS_L], query, regs); break; case FC_WRITE_REG: write_single_register(slave, start_addr, query, regs); break; }}
…
e PVC super leve e as partes internas das pinças possuem material antideslizante.
Especificações
Tensão nominal: 12V DC
Faixa de tensão operacional: 5V - 12V DC
Corrente nominal: 450mA
Corrente de "stall": 1700mA
Peso da garra: 0,05kg
Velocidade da garra (de fechada para totalmente aberta): 1 segundo
Carga máxima suportável: 0,6kg
Algumas informações foram obtidas da página oficial do produto e também da embalagem do mesmo.
Divertindo-se
Inicialmente fiz alguns testes usando o aplicativo da Makeblock rodando em um smartphone com Android, conectado via bluetooth à placa mCore, que é a controladora do robô mBot.
Para testar a garra de uma maneira mais divertida, fiz um braço simples com dois graus de liberdade mais a garra.
A montagem inclui uma base feita de MDF, perfis e suportes de alumínio e peças da Makeblock.
O braço é controlado por um controle sem fio de PlayStation 2 e uma placa Arduino.
Usarei este método para controlar remotamente o MDi #4.
Informações adicionais
http://mech-dickel.blogspot.com.br/2016/02/makeblock-robot-gripper-unboxing-and.html - Postagem em meu blog com o mesmo conteúdo, mas em inglês.…