ções principais foi colocar a variável "dimming" variar de 0 a 100. Com isso, eliminei os cálculos matemáticos para converter em porcentagem. Melhorando o tempo no processamento, acredito que isso seja o problema do módulo RF 433 MHz não receber o dados corretamente.
Sugiro que faça os códigos e os testes, passo a passo, por exemplo, tentar controlar a lâmpada utilizando somente o módulo RF 433 Mhz. Feito teste e funcionando normalmente, implementa a comunicação serial.
E assim por diante.
Segue o código:
#include <VirtualWire.h>
//------------------------------------------------------------------------//Define pino ledint ledPin = 13; // original 5int valor_recebido_RF; // original intchar recebido_RF_char[4]; char Valor_CharMsg[4];//------------------------------------------------------------------------
//------------------------------------------------------------------------int AC_LOAD = 3;// Dará o pulso no Triac pinint dimming = 50;// Dimming level (0-100) 0 = ON, 100 = OFFunsigned long time;//Contará o tempounsigned long timeout;//Estouroint brilho[3];//Recebe os valores da serialint i=0;//Quantidade de caracteres recebida pela serialint flag=0;//Indica que foi recebida informação pela serialchar temp;//Armazena dados recebidos pela serialint x,y;//Variaveis auxiliares//------------------------------------------------------------------------
//------------------------------------------------------------------------void setup() { Serial.begin(9600); pinMode(ledPin, OUTPUT);
//Pino ligado ao pino DATA do receptor RF vw_set_rx_pin(7); //Velocidade de comunicacao (bits por segundo) vw_setup(1200); //Inicia a recepcao vw_rx_start(); Serial.println("Recepcao modulo RF - Aguardando...");
pinMode(AC_LOAD, OUTPUT);// Disparo do Triac pino 3 attachInterrupt(0, zero_crosss_int, RISING);// Interrupção detecta a passagem por 0, quando passa de nível baixo para auto pinMode(4, INPUT);// Configura o pino 4 como entrada pinMode(5, INPUT);// Configura o pino 5 como entrada}//------------------------------------------------------------------------
//------------------------------------------------------------------------// Função que detecta a passagem por 0void zero_crosss_int() { // Calculo do ângulo de disparo :: 60Hz-> 8.33ms (1/2 Cycle) // (8333us - 8.33us) / 100 = 83 (Approx), o dimming vai variar de 0 a 100 int dimtime = (83*(100-dimming)); //O powertime é o tempo que o TRIAC permanescerá desligado quando é detectado o ponto 0 da senóide //e varia de 0 a 8300 microsegundos //Se o powertime for menor ou igual a 300 microsegundos, dar o comando de ligar a lâmpada (carga) - potência total fornecida if(dimtime <= 300) { //Liga o pulso do sinal ao TRIAC para que ele passe a conduzir, coloca o pino digital "load" em nível alto digitalWrite(AC_LOAD, HIGH); } //Se o powertime for menor ou igual a 8000 microsegundos, dar o comando de desligar a lâmpada (carga) - potência zero fornecida else if(dimtime >= 8000) { //Desliga o pulso do sinal ao TRIAC para que ele não conduza, coloca o pino digital "load" em nível baixo digitalWrite(AC_LOAD, LOW); } //Se o powertime estiver entre 300 microsegundos a 8000 microsegundos else if((dimtime > 300) && (dimtime < 8000)) { //Mantém o circuito desligado por powertime microssegundos (espera powertime microssegundos) delayMicroseconds(dimtime); //Envia sinal ao TRIAC para que ele passe a conduzir, coloca o pino digital "load" em nível alto digitalWrite(AC_LOAD, HIGH); //Espera 8,33 microssegundos para que o TRIAC perceba o pulso delayMicroseconds(8.33); //Desliga o pulso do TRIAC, coloca o pino digital "load" em nível baixo digitalWrite(AC_LOAD, LOW); } }//------------------------------------------------------------------------
//------------------------------------------------------------------------void loop(){ //------------------------------------------------------------------------------------------- uint8_t buf[VW_MAX_MESSAGE_LEN]; uint8_t buflen = VW_MAX_MESSAGE_LEN;
if (vw_get_message(buf, &buflen)) { int i; for (i = 0; i < buflen; i++) { //Armazena os caracteres recebidos recebido_RF_char[i] = char(buf[i]); } recebido_RF_char[buflen] = '\0';
//Converte o valor recebido para inteiro valor_recebido_RF = atoi(recebido_RF_char); //Mostra no serial monitor o valor recebido Serial.print("Recebido: "); Serial.print(valor_recebido_RF); // realiza as acoes conforme desejado if (valor_recebido_RF == 1) { digitalWrite(ledPin, HIGH); Serial.println(" - Led aceso !"); } else if (valor_recebido_RF == 0) { digitalWrite(ledPin, LOW); Serial.println(" - Led apagado !"); } // recebe o comando que se for igual a 50 atribui a variavel temp //o valor desejado para dimerizar a lampada atraves do Dimmer Shield else if (valor_recebido_RF == 50) { dimming = 50; // dimeriza em 50% Serial.println(" - Dimmer em 50% !"); } // recebe o comando que se for igual a 100 atribui a variavel temp //o valor desejado para dimerizar a lampada atraves do Dimmer Shield else if (valor_recebido_RF == 100) { dimming = 100; // dimeriza em 100% Serial.println(" - Dimmer em 100% !"); } } //-------------------------------------------------------------------------------------------
//Não entendi essa parte do código********************************************************** //------------------------------------------------------------------------------------------ // Retorna o tempo em milisegundos desde que o Arduíno começou a rodar, time = millis()%2;//Divide por 2 e salva o resto if(time==1||time==0)//Compara se o resto é igual a 0 ou 1 e sempre vai ser { timeout++;// Cronômetro // Compara se houve estouro do tempo if (timeout > 500) { i=0;// Zera o quantidades de caracteres recebidos flag=0;// Zera o aviso de que foi recebido algum dado na serial } } //------------------------------------------------------------------------------------------- //Não entendi essa parte do código*********************************************************** //------------------------------------------------------------------------------------------- //Aumenta a intensidade if(digitalRead(4) == HIGH)// Compara se o botão foi pressionado e se o dimming é maior que 10 seu limite máximo { //Se power (porcentagem) for menor que 100, executa if(dimming < 100) { dimming += 10; //Faz a soma do power anterior com 10 (incremento de 10) } Serial.println("Resolucao: "); Serial.print(dimming); Serial.println("%"); delay(100);// Aguarda um tempo até o próximo acionamento } //------------------------------------------------------------------------------------------- //------------------------------------------------------------------------------------------- //Diminui a intensidade if(digitalRead(5) == HIGH) { //Se power (porcentagem) for menor que 100, executa if(dimming > 0) { dimming -= 10; //Faz a soma do power anterior com 10 (incremento de 10) } Serial.println("Resolucao: "); Serial.print(dimming); Serial.println("%"); delay(100);// Aguarda um tempo até o próximo acionamento } //------------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------------- if (Serial.available() > 0)// Verifica se houve recepção { flag=1;//Sinaliza que houve recepção timeout=0;// Zera o o tempo de reset //------------------------------------------------------------------------------------------ temp = Serial.read();// Armazena o que foi recebido pela serial brilho[i] = temp - 48;// Decrementa 48 na tabela ascii para converter de decimal para char i++;// Contabiliza um recebimento } //------------------------------------------------------------------------------------------- //Não entendi essa parte do código*********************************************************** //--------------------------------------------------------------------------- if (timeout > 200 && flag == 1)// Compara se houve estouro do timeout(se ficou um tempo sem recepção) e se houve recepção { flag=0;// Sera aviso de recepção
// Verifica a quantidade de informação recebida switch(i) { case 1: x = brilho[0];//Unidade break;
case 2: x=brilho[0] * 10 + brilho[1];//Dezena e unidade break;
case 3: x=brilho[0] * 100 + brilho[1] * 10 + brilho[2];//Centena, Dezena, Unidade break; } // Envia para serial informações em % e resolução de disparo Serial.print(x); Serial.println("%"); delay(30);
if(x > 100 || x < 0)// Proteção para se foi inserido um valor mair que 100% { Serial.println("Excedeu o limite"); } else// Se estiver tudo OK { //Fiz modificações aqui********************** dimming = x; Serial.print("Resolucao: "); Serial.println(dimming); } } //--------------------------------------------------------------------------- //Não entendi essa parte do código*********************************************************** }
Att.
André Kuhn.…
trolado por um Arduino Nano. Normalmente encontra-se na WEB, inúmeros circuitos desses, mas somente controlando os pinos de sentido de rotação (DIR) e dos pulsos dos passos (STEP).
Resolvi fazer uma montagem de teste usando todas as portas de controle do Módulo A4988 ! Outra dúvida minha era se eu conseguiria usar o meu Motor NEMA17 Unipolar de seis fios no modo Bipolar, já que o chip A4988 foi projetado para motores Bipolares somente. E tudo funcionou perfeitamente.
Esse é o diagrama da minha montagem :
Observações importantes :
- A tensão de alimentação do Motor deve ser entre 8V e 35 V (não pode usar motores com 5V somente).
- A corrente não pode ultrapassar 2A em cada bobina do motor.
- Use um capacitor (C1) de no mínimo 100 uF para filtrar ruidos na alimentação do motor.
- Use um capacitor (C2) de no mínimo 10 uF para filtrar ruidos na alimentação do chip A4988.
- Não se esqueça de conectar o terra do Arduino.
Vejam que eu usei somente quatro fios do motor, já que estou usando a ligação Bipolar. Os fios dos terminais centrais dos enrolamentos devem ficar isolados do circuito - Fio 2 (branco) e Fio 5 (preto).
O Módulo Driver A4988 tem um potênciomentro (POT) de ajuste de corrente máxima. Se a corrente ultrapassar o limite, o chip é desativado para proteção dos circuitos. Explicarei como isso funciona e como ajustar em outro tópico. (não mexa ainda nesse ajuste) . No meu módulo ele já veio ajustado para corrente máxima de 1,25 ampéres.
Criei um Sketch para permitir o teste de todos os pinos de controle / funções do Módulo A4988. Usei oito portas digitais do Arduino. A designação de cada porta foi escolha minha. Nada impede que você utilize outras portas, desde que altere as ligações e o seu sketch de acordo com o novo circuito.
Esse é o Sketch de teste. Fiz ele com propósitos didáticos. Como eu ainda não sei como criar bibliotecas para o Arduino, usei uma programação estruturada com várias funções. Se acharem interessante, poderemos até criar uma biblioteca específica. O Sketch pemite o uso de todos os modos de passo : Full, Half, Micro-passo de 1/4, Micro-passo de 1/8 e Micro-passo de 1/16. Permite também que configure a frequência dos pulsos (passos), a quantidade de passos,o sentido de rotação, etc.
Anexei o arquivo do Sketch : A4988a.INO
// Controle de Motor de Passo NEMA17 com Modulo driver A4988 // http://labdegaragem.com/forum/topics/tutorial-arduino-motor-de-pass...
// Motor Minebea NEMA 17 Unipolar / Modulo A4988 / Arduino Nano / IDE 1.6.7
// OBS: Motor Unipolar 6 fios configurado como Bipolar
// Gustavo Murta 02/abr/2016
// Definições das Portas Digitais do Arduino
int RST = 8; // Porta digital D08 - reset do A4988 int SLP = 9; // Porta digital D09 - dormir (sleep) A4988
int ENA = 7; // Porta digital D07 - ativa (enable) A4988
int MS1 = 4; // Porta digital D04 - MS1 do A4988
int MS2 = 5; // Porta digital D05 - MS2 do A4988
int MS3 = 6; // Porta digital D06 - MS3 do A4988
int DIR = 3; // Porta digital D03 - direção (direction) do A4988
int STP = 2; // Porta digital D02 - passo(step) do A4988
int atraso = 0; // Atraso no pulso em microsegundos
float FREQ = 200; // Frequências dos pulsos (100.7 Hz medido com scope = 100 Hz)
boolean sentido = true; // Variavel de sentido
int CONTADOR = 200; // Número de pulsos (passos por volta)
// FULL = 200 passos / HALF = 400 passos / P1_4 = 800 passos / P1_8 = 1600 passos / P1_16 = 3200 passos
void setup() {
Serial.begin(9600);
DDRD = DDRD | B11111100; // Configura Portas D02 até D07 como saída
digitalWrite(ENA, HIGH); // Desativa o chip A4988
FULL() ; // Configura modo de avanço do motor FULL, HALF, P1_4, P1_8 ou P1_16
DDRB = 0x0F; // Configura Portas D08,D09,D10 e D11 como saída
digitalWrite(SLP, HIGH); // Desativa sleep do A4988
rst_A4988(); // Reseta o chip A4988
digitalWrite(ENA, LOW); // Ativa o chip A4988
FREQUENCIA(); // Calcula o período do sinal STEP
//Serial.println(atraso) ; // Imprime na Console, o tempo em microsegundos
}
void rst_A4988() {
digitalWrite(RST, LOW); // Realiza o reset do A4988
delay (10); // Atraso de 10 milisegundos
digitalWrite(RST, HIGH); // Libera o reset do A4988
}
void HOR() // Configura o sentido de rotação do Motor {
digitalWrite(DIR, HIGH); // Configura o sentido HORÁRIO
}
void AHR() // Configura o sentido de rotação do Motor {
digitalWrite(DIR, LOW); // Configura o sentido ANTI-HORÁRIO
}
void PASSO() // Pulso do passo do Motor {
digitalWrite(STP, LOW); // Pulso nível baixo
delayMicroseconds (atraso); // Atraso de X microsegundos
digitalWrite(STP, HIGH); // Pilso nível alto
delayMicroseconds (atraso); // Atraso de X microsegundos
}
void FREQUENCIA() // Configura quantos pulsos por segundo (Hz) {
atraso = 1000000 / (2*FREQ); // calculo do tempo de atraso (1/2 periodo) em us
}
void FULL() {
digitalWrite(MS1, LOW); // Configura modo Passo completo (Full step)
digitalWrite(MS2, LOW);
digitalWrite(MS3, LOW);
}
void HALF() {
digitalWrite(MS1, HIGH); // Configura modo Meio Passo (Half step)
digitalWrite(MS2, LOW);
digitalWrite(MS3, LOW);
}
void P1_4() {
digitalWrite(MS1, LOW); // Configura modo Micro Passo 1/4
digitalWrite(MS2, HIGH);
digitalWrite(MS3, LOW);
}
void P1_8() {
digitalWrite(MS1, HIGH); // Configura modo Micro Passo 1/8
digitalWrite(MS2, HIGH);
digitalWrite(MS3, LOW);
}
void P1_16() {
digitalWrite(MS1, HIGH); // Configura modo Micro Passo 1/16
digitalWrite(MS2, HIGH);
digitalWrite(MS3, HIGH);
}
void TesteMotor() {
HOR();
for(int i=0; i <= CONTADOR; i++) // Incrementa o Contador
{
PASSO(); // Avança um passo no Motor
}
delay (750) ; // Atraso de 500 mseg
AHR();
for(int i=0; i <= CONTADOR; i++) // Incrementa o Contador
{
PASSO(); // Avança um passo no Motor
}
delay (1500) ; // Atraso de 500 mseg
}
void loop()
{
FULL();
FREQ = 200;
FREQUENCIA();
CONTADOR = 200;
Serial.print(atraso);
Serial.println(" us Full, 200 passos, 200 Hz");
Serial.println();
TesteMotor();
HALF();
FREQ = 600;
FREQUENCIA();
CONTADOR = 400;
Serial.print(atraso);
Serial.println(" us Half, 200 passos, 600 Hz");
Serial.println();
TesteMotor();
P1_4(); FREQ = 1600;
FREQUENCIA();
CONTADOR = 800;
Serial.print(atraso);
Serial.println(" us Micro 1/4, 800 passos, 1600 Hz");
Serial.println();
TesteMotor();
P1_8(); FREQ = 3600;
FREQUENCIA();
CONTADOR = 1600;
Serial.print(atraso);
Serial.println(" us Micro 1/8, 1600 passos, 3600 Hz");
Serial.println();
TesteMotor();
P1_16(); FREQ = 6600;
FREQUENCIA();
CONTADOR = 3200;
Serial.print(atraso);
Serial.println(" us Micro 1/16, 3200 passos, 6600 Hz");
Serial.println();
TesteMotor();
}
Para que possam ver como o teste é realizado estou divulgando esse video , onde estou rodando o mesmo Sketch.
Motor NEMA17 + Driver A4988 - teste do Motor
…
oop ( serial monitor) e se iniciam corretamente. Não sou programador, e tenho aprendido por aqui mesmo. (Obs: algumas bibliotecas se referem a módulos chineses alternativos que tenho e são um pouco diferente dos demais módulos - DHT11, COMPASS HMC5883 ). Ainda não comprei o motor com pás para medir a velocidade do vento, e o sensor de chuva. Mas já deixo instalado o sensor sônico para o pluviômetro, pode ser usado com cartão SD( o meus queimei por descuido, mas estava nesta programação, retirei) e o conjunto ficará em um balão amarado, que subirá aos poucos, poderá girar em seu eixo e inclinar conforme o vento. Também poderá ser usado em drones, por quem quiser usar o projeto.
Por favor vejam que o foco inicial é saber como testar no setup() se eles estão ok.
Atenção: Qualquer um que usar balões deve ter autorização de manejo de acordo com o estado e instituição de ensino, não deve realizar qualquer teste em condições de céu nublado ou chuva sem tomar orientação sobre os riscos, não me responsabilizo pelas tentativas de teste que causem risco de morte e contravenção da lei dos balões RJ.
// Marcelo da Silva Santos (Designer, esp. animador, estudante de engenharia mecanica)// Estacao meteriologica feita em casa / HOME MADE Meteriologoc station prototype// Portugues - Brasil - BR_pt (Lingua).// Rio de Janeiro 22:09 / Sexta-feira / 09 / Agosto / 2019.// 1.0v Dados livres. Obg a todos / FreeData. Tks Everybody!// Rascunho na memoria do uno / UNO Sketch memory 88%...!!! :(
#include <Ultrasonic.h>#define pino_trigger A0#define pino_echo A1Ultrasonic ultrasonic(pino_trigger, pino_echo);float cmMsec, inMsec;long microsec = ultrasonic.timing();//----------------------------------------------------------------------------------#include <dht.h>#define pinoDHT11 9dht sensorDHT11;//----------------------------------------------------------------------------------#include <Adafruit_Sensor.h> #include <Adafruit_BMP280.h> float PressaoDoDia;int Atm = 0; Adafruit_BMP280 bmp; //----------------------------------------------------------------------------------
#include <Wire.h>#include <MechaQMC5883.h>MechaQMC5883 qmc; int x, y, z; int azimuth;
//----------------------------------------------------------------------------------//#include <SD.h>
//Sd2Card SDcard;//SdVolume volume;
//const int chipSelect = 10; //----------------------------------------------------------------------------------#include <DS3232RTC.h>
const int MPU=0x68; int AcX,AcY,AcZ,Tmp,GyX,GyY,GyZ;
long ContadorLoop = 0; // CONTADOR DE LOOP(Tipo de Timer primitivo).int Ciclos =0; // contador de ciclos cheios do contador de loop.//----------------------------------------------------------------------------------
void setup(){ Serial.begin(9600); Wire.begin(); setSyncProvider(RTC.get); Wire.beginTransmission(MPU); Wire.write(0x6B); Wire.write(0); Wire.endTransmission(true); cmMsec = ultrasonic.convert(microsec, Ultrasonic::CM); inMsec = ultrasonic.convert(microsec, Ultrasonic::IN); if(!Serial) // 1 { Serial.println("Erro ao iniciar Serail! Verifique as conexões."); Serial.println("Verifique o Modulo, conexoes e reinicie o Arduino..."); Serial.print("Erro no Loop: "); Serial.println(ContadorLoop); } else { Serial.println("Serial iniciado!"); Serial.print("Inicio no Loop: "); Serial.println(ContadorLoop); } if(!bmp.begin(0x76)) // 2 { Serial.println("Sensor BMP280 não foi identificado! Verifique as conexões."); Serial.println("Verifique o Modulo, conexoes e reinicie o Arduino..."); Serial.print("Erro no Loop: "); Serial.println(ContadorLoop); } else { Serial.println("Sensor BMP280 foi identificado!");Serial.print("Inicio no Loop: "); Serial.println(ContadorLoop); } if(timeStatus() != timeSet) // 3 { Serial.println("Impossivel sincronismo com RTC"); Serial.println("Verifique o Modulo, conexoes e reinicie o Arduino..."); Serial.print("Erro no Loop: "); Serial.println(ContadorLoop); } else { Serial.println("RTC Esta definindo o tempo do sistema"); Serial.println("Módulo RTC foi identificado!"); Serial.print("Inicio no Loop: "); Serial.println(ContadorLoop); } if(!MPU, 0x6B) // 4 { Serial.println("Impossivel sincronismo com MPU6050"); Serial.println("Verifique o Modulo, conexoes e reinicie o Arduino..."); Serial.print("Erro no Loop: "); Serial.println(ContadorLoop); } else { Serial.println("Sincronismo com MPU6050, ok!"); Serial.print("Inicio no Loop: "); Serial.println(ContadorLoop); } if(inMsec=0) // 5 { Serial.println("Nenhum pulso detectado de Ultrasonico!"); Serial.println("Esperando para teste, sincronismo com Ultrasonic"); delay(2500); Serial.println("Novo teste iniciado!"); cmMsec = ultrasonic.convert(microsec, Ultrasonic::CM); inMsec = ultrasonic.convert(microsec, Ultrasonic::IN); if((inMsec=0) && (cmMsec=0 )) { Serial.println("Impossivel sincronismo com Ultrasonic"); Serial.println("Verifique o Modulo, conexoes e reinicie o Arduino..."); Serial.print("Erro no Loop: "); Serial.println(ContadorLoop); } else { Serial.println("Detectado sincronismo com Ultrasonic no segundo teste!"); } } else { Serial.println("Sincronismo com Ultrasonic, ok!"); Serial.print("Inicio no Loop: "); Serial.println(ContadorLoop); } sensorDHT11.read11(pinoDHT11); if((sensorDHT11.humidity=0) && ((sensorDHT11.temperature)=0)) // 6 { sensorDHT11.read11(pinoDHT11); delay(2500); if((sensorDHT11.humidity=0) && ((sensorDHT11.temperature)=0)) { Serial.println("Impossivel sincronismo com DHT_11"); Serial.println("Verifique o Modulo, conexoes e reinicie o Arduino..."); Serial.print("Erro no Loop: "); Serial.println(ContadorLoop); } else { Serial.println("Sincronismo com DHT_11, ok!"); Serial.print("Inicio no Loop: "); Serial.println(ContadorLoop); } } else { Serial.println("Sincronismo com DHT_11, ok!"); Serial.print("Inicio no Loop: "); Serial.println(ContadorLoop); } if((x=-1) && ( y=-1)) // 7 { x=0; y=0; z=0; delay(2500); if((x=-1) && (y=-1)) { Serial.println("Impossivel sincronismo com Bussola!"); Serial.println("Verifique o Modulo, conexoes e reinicie o Arduino..."); Serial.print("Erro no Loop: "); Serial.println(ContadorLoop); } else { Serial.println("Sincronismo com a Busola na segundo teste, ok!"); Serial.print("Inicio no Loop: "); Serial.println(ContadorLoop); } } else { Serial.println("Sincronismo com a bussola, ok!"); Serial.print("Inicio no Loop: "); Serial.println(ContadorLoop); }}
void loop(){ Serial.println("----------------------------------------------------------------------------------"); // ________________________ RTC ___________________________________________________________________________________________________ digitalClockDisplay(); // _______________________ DHT 11 _________________________________________________________________________________________________ sensorDHT11.read11(pinoDHT11); // _______________________ BMP 280 ________________________________________________________________________________________________ PressaoDoDia = 1013,25; // pressao ao nivel do mar, // ajustar este valor pela internet no mesmo dia. // _______________________ BUSSOLA ________________________________________________________________________________________________ qmc.read(&x, &y, &z,&azimuth); // _______________________ MPU 6050 _______________________________________________________________________________________________ Wire.beginTransmission(MPU); Wire.write(0x3B); Wire.endTransmission(false); Wire.requestFrom(MPU,14,true); AcX=Wire.read()8|Wire.read(); //0x3B (ACCEL_XOUT_H) & 0x3C (ACCEL_XOUT_L) AcY=Wire.read()8|Wire.read(); //0x3D (ACCEL_YOUT_H) & 0x3E (ACCEL_YOUT_L) AcZ=Wire.read()8|Wire.read(); //0x3F (ACCEL_ZOUT_H) & 0x40 (ACCEL_ZOUT_L) Tmp=Wire.read()8|Wire.read(); //0x41 (TEMP_OUT_H) & 0x42 (TEMP_OUT_L) GyX=Wire.read()8|Wire.read(); //0x43 (GYRO_XOUT_H) & 0x44 (GYRO_XOUT_L) GyY=Wire.read()8|Wire.read(); //0x45 (GYRO_YOUT_H) & 0x46 (GYRO_YOUT_L) GyZ=Wire.read()8|Wire.read(); //0x47 (GYRO_ZOUT_H) & 0x48 (GYRO_ZOUT_L) // _____________________________ Escrevendo no Serial _____________________________________________________________________________ if (ContadorLoop>0) { Serial.println("Iniciando Sistema, preparando CAIXA PRETA!"); Serial.print("INICIO DE Loop: "); Serial.println(ContadorLoop); Serial.println("-----------------------------Ultrasonic--------------------------------------------"); Serial.print("Distancia em cm: "); Serial.print(cmMsec); Serial.print(" - Distancia em polegadas: "); Serial.println(inMsec); Serial.println("-----------------------------DHT11------------------------------------------------"); Serial.print("Umidade: "); Serial.print(sensorDHT11.humidity); Serial.print("%"); Serial.print(" - Temperatura_1: "); Serial.print(sensorDHT11.temperature,0); Serial.println("C"); Serial.println("----------------------------BMP 280-----------------------------------------------"); Serial.print("Temperatura_2: "); Serial.print(bmp.readTemperature()); Serial.print(" *C (Grau Celsius)"); Serial.print(" - Pressao: "); Serial.print(bmp.readPressure()); Serial.print(" Pa (Pascal)"); Serial.print(" - Atmosfera: "); Atm = (((bmp.readPressure())/PressaoDoDia),1); Serial.println(Atm); Serial.println("-----------------------------Bussola----------------------------------------------"); Serial.print("x: "); Serial.print(x); Serial.print(" - y: "); Serial.print(y); Serial.print(" - z: "); Serial.print(z); Serial.print(" ROTACAO EM RELACAO AO NORTE: "); Serial.print(azimuth); Serial.println(); Serial.println("-----------------------------MPU 6050---------------------------------------------"); Serial.print("AcX = "); Serial.print(AcX); Serial.print(" | AcY = "); Serial.print(AcY); Serial.print(" | AcZ = "); Serial.print(AcZ); Serial.print(" | Tmp = "); Serial.print(Tmp/340.00+36.53); Serial.print(" | GyX = "); Serial.print(GyX); Serial.print(" | GyY = "); Serial.print(GyY); Serial.print(" | GyZ = "); Serial.println(GyZ); Serial.println("----------------------------------------------------------------------------------"); } if (ContadorLoop >=2147483646) { ContadorLoop=0; Ciclos=Ciclos+1; Serial.println(ContadorLoop); Serial.println(Ciclos); } Serial.print("FIM DE Loop: "); Serial.println(ContadorLoop); Serial.println("----------------------------------------------------------------------------------"); Serial.println(" "); Serial.println(" "); ContadorLoop = ContadorLoop + 1; } // _____________________________ Escrevendo no Serial Fim _________________________________________________________________________
void digitalClockDisplay(){ Serial.print(hour()); printDigits(minute()); printDigits(second()); Serial.print(' '); Serial.print(day()); Serial.print(' '); Serial.print(month()); Serial.print(' '); Serial.print(year()); Serial.println();}
void printDigits(int digits){ Serial.print(':'); if(digits < 10) { Serial.print('0'); Serial.print(digits); }}…
ores e do "Fim de Curso", pois senão seu Sistema provavelmente não será "robusto" o suficiente para os problemas que ocorrem quando os "fios" são bem longos (e veja: o tratamento que fiz, é o básico).
Agora sobre o código, o do último post está bastante preparado pra atender as requisições que vc mencionou, e na realidade faltam apenas alguns "acréscimos" pra isso.
No entanto, eu percebo uma certa dificuldade em expressar com mais clareza estas requisições, e provavelmente isso ocorre justamente devido à questão "verde" que mencionei antes. Mas com uma pequena ajuda facilmente isto é superado, e vou te mostrar como.
Mas antes entenda que numa primeira instância, não é necessário que vc descreva a "real forma" que constitui seu Sistema, ou seja, não é necessário saber se são tratores ou se são outras coisas, ou se o líquido é água ou outra coisa. Na forma como estamos fazendo aqui via internet (e fórum), o que é preciso saber é quais são os elementos "medidos" pelo Sistema, e isso vc deixou claro: dois Sensores de Fluxo e um "Fim de Curso". E claro também como o Sistema deve funcionar.
Veja, está claro que existem dois Fluxos, e que a vazão destes é indicada por dois Sensores de Fluxo. O Sistema então deve medir esta vazão (a partir dos pulsos dos Sensores), exibir estes valores no Display, e também calcular as Médias em um certo período de tempo, sendo estas Médias também exibidas no Display. Isto já está sendo feito no Sistema que postei (o primeiro tinha apenas um Sensor de Fluxo, mas o segundo Sistema já tem os dois). Então o que falta agora é processar de forma adequada estas informações. Então vou dar um exemplo de como se descreve isto de forma que se possa usar estas informações no código, e assim vc entendendo isso, poderá postar dessa forma aqui, sem deixar dúvidas de como a coisa deve ser de fato.
Então segue um exemplo da descrição do seu Sistema (por favor, leia com atenção, pois a maior parte da descrição, acredito ser como seu Sistema deve funcionar):
1) dois Sensores indicam o Fluxo de Líquidos. São sensores semelhantes ao "YF-S201C". Os sinais dos Sensores são aplicados aos pinos "2" e "3" de um Arduino UNO, a fim de medir o Fluxo em cada sensor, em Litros/segundo.
2) há também no Sistema, uma chave (ou botão) "Fim de Curso", conectada ao pino "4" do Arduino. A chave será acionada após um certo tempo "Ta" (abreviando "Tempo de avaliação"), e este tempo "Ta" é contado a partir do momento que as medições são iniciadas (ou seja, praticamente após o Arduino ser ligado).
3) os Fluxos dos dois Sensores, são exibidos no Display a cada segundo. Também é exibido no Display, uma contagem de tempo, que sempre inicia em 0 (zero) segundos, e vai até 59 segundos. Esta contagem volta a zero após passado 1 minuto, e a contagem em segundos se repete.
4) quando é completado 1 minuto, é calculada a Média dos Fluxos neste período de tempo (60 segundos). As Médias de cada Fluxo são então exibidas no Display, e esta exibição dura alguns segundos (por exemplo 5 segundos).
5) quando o "Fim de Curso" é acionado, são então calculadas em Litros, as quantidades de líquido de cada Fluxo. Então, a quantidade do Sensor 2 é subtraída da quantidade do Sensor 1, obtendo-se assim uma diferença entre as duas quantidades. Vamos chamar esta diferença de "dQ" (abreviando "diferença das Quantidades"). Então este valor "dQ" é exibido no Display (por algum tempo).
6) uma vez calculado o valor "dQ", ele é multiplicado por um fator "K" (seria o "238" do exemplo que vc descreveu Franciel). Vamos chamar este resultado que foi calculado, de "QT" (abreviatura de "Quantidade Total"). Então este valor "QT" é exibido no Display (também por um certo tempo).
7) então após este ciclo completo, o Sistema reinicia tudo, zerando a quantidade de Líquido dos dois Fluxos, e repetindo o ciclo.
Veja Franciel, uma descrição dessa forma permite que o código execute precisamente o comportamento descrito. Então veja como ela é importante.
Claro, para a descrição que coloquei, apenas segui o que seu código original estava fazendo e inclui as informações de funcionamento que vc passou até aqui.
Mas não sei se é exatamente isso, porque é apenas minha interpretação das coisas. E vc é quem pode dizer como realmente o Sistema deve se comportar.
Assim, aguardo suas informações a respeito, para que eu possa aplicar ao código e postá-lo aqui, incluindo uma Simulação do funcionamento.
Uma questão: vc não acha que seria interessante ao invés de usar um Display LCD 16x2, usar-se o mesmo tipo de Display LCD I2C, porém aquele de 20x4, pois assim teria mais caracteres em uma linha e duas linhas a mais, o que facilitaria a exibição dos dados.
Veja se é interessante também, incluir um "Módulo Buzzer", desses pra Arduino que todo mundo usa. Assim, quando o Sistema completar um ciclo e exibir os resultados, o Buzzer seria acionado indicando que os dados estão disponíveis. Você pode inclusive acrescentar um Botão, e após um ciclo terminar e este Botão ser acionado, então o Sistema reinicia todo o processo (ou ciclo), sem precisar desligar o Arduino.
Fico no aguardo...
Abrçs,
Elcids…
Adicionado por Elcids Chagas ao 13:34 em 2 abril 2020
do Terminal do Arduino (estas marcações de tempo são fundamentais, mas eu esqueci de colocar algo assim no código, para o caso do "timestamp" do Terminal estar desligado).
Vamos então às conclusões dessa análise "preliminar":
O "travamento" que ocorreu conforme vc descreveu, eu acredito que seja por causa do uso da função "maintain" da "UIP", e explico isso mais adiante.
Os dados impressos no Terminal, mostram que ocorrem momentos que o "Cliente" (o Arduino) não conseguiu se conectar ao "Host" (o Modem), mas logo em seguida conseguiu a conexão, e aí o "Host' respondeu de acordo. Estas falhas ocorrem em três momentos, e nos dois primeiros, o Sistema conseguiu se recuperar. Mas na terceira, vemos que a última mensagem foi "não recebeu o Sinal", e depois disso nenhuma msg foi "impressa". Veja a sequência que ocorre:
a) 25 respostas OK do Host, num período de 13 segundos.
b) 2 falhas de conexão do Cliente, num período menor que 0.5 segundo.
c) 14 respostas OK do Host, num período de 7 segundos.
d) 2 falhas de conexão do Cliente, num período menor que 0.5 segundo.
e) 15 respostas OK do Host, num período de 8 segundos.
f) 1 falha de conexão do Cliente, então "trava", e não há mais respostas.
Como se vê, embora o período de teste não seja muito grande, parece que estava se formando um padrão de comportamento. Lembrando que no teste, eram feitas requisições a cada 250 ms (ou seja, 4 vezes por segundo).
Uma coisa muito importante, é que a RAM "livre" ficou estável o tempo todo, o que é um ótimo sinal, pois indica que a LIB "UIP" não está "largando" objetos no "Heap" do Arduino (se estivesse "largando" poderia levar a um "crash" do Sistema). E pela quantidade total de requisições, esta conclusão é praticamente definitiva sobre esta versão do código.
As falhas de conexão do "Cliente", são evidentes porque naqueles momentos não são impressas as msgs de RAM "free" de (3) a (5), mas sempre foi impressa a msg (6). E não foi ocorrência do "timeout" que eu implementei, pois para isso teriam que ter sido impressas as msgs de (3) até (5). Então sobre isso não há dúvida.
Então o que causou o "travamento" ??? Eu tenho um palpite, e ele pode ser evidenciado na figura a seguir, que mostra uma observação que "fizeram" no código fonte da LIB "UIP", especificamente na função "maintain" (veja principalmente o texto que eu marquei em amarelo) :
(clique na figura para "zoom")
Eu suspeito que o tratamento de algum desses "IP events", tenha falhado por algum motivo, e como não implementaram um "timeout" nestes casos, a função "maintain" não retorna (como explicado na figura anterior), causando o Sistema travar. Pode ser um bug da "UIP", por que provavelmente o "maintain" é muito pouco usado (eu realmente nunca vi alguém usando isso no "UIP") e então talvez ninguém tenha detectado isso (ou detectaram e deixaram pra lá).
Ocorre que como o "Ethernet.begin" não está mais no "loop" do Arduino, então eu coloquei o "maintain" executando ali, de forma a renovar o IP automaticamente caso necessário (via DHCP como descrito na própria funcionalidade do "maintain"). Mas talvez essa não tenha sido uma boa ideia.
Então minhas sugestões são:
Opção 1: usar a função "maintain" da LIB, mas com uma temporização própria, pois atualmente ele está sendo executado logo após a conclusão de cada requisição ao Host . E também nunca executar antes de um certo tempo depois da conclusão da comunicação com o Host.
Opção 2: usar a função "linkStatus" da LIB para detectar que ocorreu uma desconexão. E isto também de forma temporizada, ou seja da mesma forma que na "Opção 1". Mas o "linkStatus" não tem o problema do "maintain". E quando o "linkStatus" indicar uma desconexão, então usamos o "Ethernet.begin" para reconectar. Neste caso, é muito importante acompanhar o histórico das mensagens de RAM "free", para constatarmos que após uma reconexão, a LIB "UIP" não está alocando mais Memória, ou seja, não está gradativamente diminuindo o RAM "free" (se for diminuindo, isto pode levar ao "crash" do Sistema).
Eu voto pela "Opção 2". É mais radical, mas me parece mais sensata neste momento. E na "Opção 1", nada garante que o "maintain" não vá causar problemas, mesmo que mais esparsos.
Aguardo sua opinião.
(não se preocupe, pois é tranquilo de fazer estas implementações no código)
Abrçs,
Elcids…
Adicionado por Elcids Chagas ao 1:46 em 2 outubro 2020
s botoes alguem sabe se isso daria certo? ou daria sobrecarga ou curto?
pois pretendo usar esse codigo para os macros...
//projeto Macro mouse generico int botDIR=13;//entrada botao direito int botdir=12;//saida transistor direita int botESQ=11;//entrdada botao esquerdo int botesq=10;//saida transistor esquerda int botCTR=9;//entrada botao central(roda do mouse) int botctr=8;//saida botaocentral(roda do mouse) int bot1LTR=7;//entrada 1 botao lateral int botltr1=6;//saida de transistor botao lateral int bot2LTR=5;//entrada 2 botao lateral int botltr2=4;//saida botao lateral int botMODE=3;//entrada botao Mode gamming (CPI) int mode=0;
#define t_500 delay(500); //ativa e desativa os botoes #define ligEsq digitalWrite(botesq, HIGH);//liga e deslia esq #define desEsq digitalWrite(botesq, LOW); #define ligDir digitalWrite(botdir, HIGH);//liga e desliga direito #define desDir digitalWrite(botdir, LOW); #define ligLtr1 digitalWrite(botltr1, HIGH);//liga e desliga o lateral 1 #define desLtr1 digitalWrite(botltr1, LOW); #define ligLtr2 digitalWrite(botltr2, HIGH);//liga e desliga o lateral 2 #define desLtr2 digitalWrite(botltr2, LOW); #define ligCtr digitalWrite(botctr, HIGH);//liga e desliga o central #define desCtr digitalWrite(botctr, LOW); //Principais Skills do Macro---------------------------------------------------------------------------------------------------------------------------------------------- #define Pressed_Dir int botDIR1 = digitalRead(botDIR); if(botDIR1 == LOW){ligDir;}else{desDir;} #define Pressed_Esq int botESQ1 = digitalRead(botESQ); if(botESQ1 == LOW){ligEsq;}else{desEsq;} #define Pressed_Esq_3kill int botESQ1 = digitalRead(botESQ); if(botESQ1 == LOW){int conte=0; if(conte <3){ ligEsq; t_500; desEsq; t_500; conte++;}}else{desEsq;} #define Pressed_Esq_Scope int botESQ1 = digitalRead(botESQ); if(botESQ1 == LOW){ligDir; t_500; ligEsq; t_500; desEsq; desDir;} #define Pressed_1Ltr int botLTR1 = digitalRead(bot1LTR); if(botLTR1 == LOW){ligLtr1; }else{desLtr1;} #define Pressed_2Ltr int botLTR2 = digitalRead(bot2LTR); if(botLTR2 == LOW){ligLtr2;}else{desLtr2;} #define Pressed_Ctr int botCTR1 = digitalRead(botCTR); if(botCTR1 == LOW){ligCtr; }else{desCtr;} #define Pressed_Mode int botMODE1 = digitalRead(botMODE); if(botMODE1 == LOW){mode++; t_500;}if(mode == 5){mode=0;}//seleciona o n max de perfis que atualmente é 5 //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
void setup(){ //PULLUP PERMITE LIGAR UM BOTAO AO TERRA DIRETAMENTE pinMode(botDIR,INPUT_PULLUP);//Entrada direita pinMode(botdir,OUTPUT);//saida direita pinMode(botESQ,INPUT_PULLUP);//Entrada esquerda pinMode(botesq,OUTPUT);//saida esquerda pinMode(botCTR,INPUT_PULLUP); //Entrada do botao da roda do mouse pinMode(botctr,OUTPUT);//saida do botao da roda do mouse pinMode(bot1LTR,INPUT_PULLUP);//Entrada do botao lateral 1 pinMode(botltr1,OUTPUT);//saida botao lateral 1 pinMode(bot2LTR,INPUT_PULLUP);// Entrada do botao lateral 2 pinMode(botltr2,OUTPUT);//saida botao lateral 2 pinMode(botMODE,INPUT_PULLUP);// Entrada do botao CPI do mouse }//fim do void setup
void loop(){ Pressed_Mode; //perfil normal if(mode == 0){ Pressed_Dir; Pressed_Esq; Pressed_1Ltr; Pressed_2Ltr; Pressed_Ctr; } //fim do perfil normal //perfil sniper if(mode == 1){ Pressed_Esq_Scope; Pressed_Dir; Pressed_1Ltr; Pressed_2Ltr; Pressed_Ctr; } //fim do perfil sniper //perfil 3balas por vez if(mode == 2){ Pressed_Dir; Pressed_Esq_3kill; Pressed_1Ltr; Pressed_2Ltr; Pressed_Ctr; } //fim do perfil 3balas }//fim do void loop
…
o motor de passo tem que dar uma volta completa, e conforme o andar vai mudando deverá aparecer no LCD o andar que está.
Eu comecei a fazer o programa, cada volta do motor de passo é equivalente 200 no registrador. Fiz com que a cada tecla apertada (1, 2, 3 e 4) o motor gire correspondente com a tecla. O LCD não está funcionando, no programa há outras teclas habilitadas, mas não usarei elas.
A minha dificuldade no momento é fazer com que se caso a tecla 1 for apertada e após o motor ter girado uma volta completa vier uma pessoa e apertar a tecla 2 o motor deverá girar mais uma volta completa, totalizando duas voltas e parando no andar 2. Tenho em mente em colocar algo relacionado :
JB BIT 2,(vá para uma outra instrução, que no caso no momento não é necessário saber) ;se a tecla 2 for apertada=vai para a instrução abaixo)
ANDAR1: MOV R4,#200RET0: RL A ;movendo para direita (motor andando) MOV P1,A CALL DELAY DJNZ R4,RET0 JMP STOP RET
Também preciso fazer com que o motor volte dependendo da tecla pressionada e andar atual. Pensei em fazer igual ao de cima, porém com RR A no lugar do RL A.
Eu tentei fazer dessa maneira que descrevi, porém não obtive resultado. Alguém pode me ajudar?
Segue o programa que fiz até o momento:
;#########################################################################################; Leitura de Teclado;#########################################################################################
LCD XDATA 0FF40HLINHA XDATA 0FF60HCOLUNA XDATA 0FF50HTLIDA DATA 020HBIT0 BIT 00HBIT1 BIT 01HBIT2 BIT 02HBIT3 BIT 03HBIT4 BIT 04HBIT5 BIT 05HBIT6 BIT 06HBIT7 BIT 07HK7 EQU 'A'K8 EQU 'B'K9 EQU 'C'K4 EQU 'F'K2 EQU 'D'K3 EQU 'E'K12 EQU '7'K13 EQU '8'K14 EQU '9'K17 EQU '4'K18 EQU '5'K19 EQU '6'K22 EQU '1'K23 EQU '2'K24 EQU '3'K27 EQU '#'K28 EQU '0'K29 EQU '.'
;#################################################################################; PROGRAMA PRINCIPAL;#################################################################################
MAIN: MOV SP,#25H MOV TMOD,#10H MOV TCON,#0 CLR EA
INICIO: CALL INILCD MOV A, #80H CALL CMLCD CALL LETECL CJNE A,#255, ESCREVE LJMP INICIO
ESCREVE: CALL WRLCD CALL ESPETEC LJMP INICIO ;#################################################################################; ROTINA DE LEITURA DE TECLADO;#################################################################################
LETECL: MOV A,#11111110B MOV DPTR,#LINHA MOVX @DPTR,A MOV DPTR,#COLUNA MOVX A,@DPTR MOV TLIDA,A JB BIT3,NOK2 MOV A,#K2 RET
NOK2: JB BIT2,NOK3 MOV A,#K3 RET
NOK3: JB BIT1,NOK4 MOV A,#K4 RET
NOK4: MOV A,#11111101B MOV DPTR,#LINHA MOVX @DPTR,A MOV DPTR,#COLUNA MOVX A,@DPTR MOV TLIDA,A JB BIT3,NOK7 MOV A,#K7 RET
NOK7: JB BIT2,NOK8 MOV A,#K8 RET
NOK8: JB BIT2,NOK9 MOV A,#K9 RET
NOK9: MOV A,#11111011B MOV DPTR,#LINHA MOVX @DPTR,A MOV DPTR,#COLUNA MOVX A,@DPTR MOV TLIDA,A JB BIT3,NOK12 MOV A,#K12 RET
NOK12: JB BIT2,NOK13 MOV A,#K13 RET
NOK13: JB BIT1,NOK14 MOV A,#K14 RET
NOK14: MOV A,#11110111B MOV DPTR,#LINHA MOVX @DPTR,A MOV DPTR,#COLUNA MOVX A,@DPTR MOV TLIDA,A JB BIT3,NOK17 ;se clicar na tecla 4= o motor dá 4 voltas MOV A,#K17;########################################################################; ANDAR 4;########################################################################ANDAR4: MOV R4,#200RET6: RL A ;movendo para direita (motor andando) MOV P1,A CALL DELAY DJNZ R4,RET6
ANDAR4A: MOV R4,#200RET7: RL A ;movendo para direita (motor andando) MOV P1,A CALL DELAY DJNZ R4,RET7 ANDAR4AN: MOV R4,#200RET8: RL A ;movendo para direita (motor andando) MOV P1,A CALL DELAY DJNZ R4,RET8 ANDAR4AND: MOV R4,#200RET9: RL A ;movendo para direita (motor andando) MOV P1,A CALL DELAY DJNZ R4,RET9 JMP STOP RET
;#################################################################################
NOK17: JB BIT2,NOK18 MOV A,#K18 RET
NOK18: JB BIT1,NOK19 MOV A,#K19 RET
NOK19: MOV A,#11101111B MOV DPTR,#LINHA MOVX @DPTR,A MOV DPTR,#COLUNA MOVX A,@DPTR MOV TLIDA,A JB BIT3,NOK22 ;se clicar na tecla 1= o motor dá uma volta MOV A,#K22;###############################################################################; ANDAR 1;###############################################################################
ANDAR1: MOV R4,#200RET0: RL A ;movendo para direita (motor andando) MOV P1,A CALL DELAY DJNZ R4,RET0 JMP STOP RET
;################################################################################; ANDAR 2;################################################################################NOK22: JB BIT2,NOK23 ;se clicar na tecla 2= o motor dá 2 voltas MOV A,#K23ANDAR2: MOV R4,#200RET1: RL A ;movendo para direita (motor andando) MOV P1,A CALL DELAY DJNZ R4,RET1
ANDAR2A: MOV R5,#200RET2: RL A ;movendo para direita (motor andando) MOV P1,A CALL DELAY DJNZ R5,RET2 JMP STOP RET;###############################################################################NOK23: JB BIT1,NOK24 ;se clicar na tecla 3= o motor dá 3 voltas MOV A,#K24;###############################################################################; ANDAR 3;###############################################################################ANDAR3: MOV R4,#200RET3: RL A ;movendo para direita (motor andando) MOV P1,A CALL DELAY DJNZ R4,RET3
ANDAR3A: MOV R4,#200RET4: RL A ;movendo para direita (motor andando) MOV P1,A CALL DELAY DJNZ R4,RET4 ANDAR3AN: MOV R4,#200RET5: RL A ;movendo para direita (motor andando) MOV P1,A CALL DELAY DJNZ R4,RET5 JMP STOP RET
;#################################################################################
NOK24: MOV A,11011111B MOV DPTR,#LINHA MOVX @DPTR,A MOV DPTR,#COLUNA MOVX A,@DPTR MOV TLIDA,A JB BIT3,NOK27 MOV A,#K27 RET
NOK27: JB BIT2,NOK28 MOV A,#K28 RET
NOK28: JB BIT1,NOK29 MOV A,#K29 RET
NOK29: MOV A,#255 RET ;#################################################################################; ROTINA DO INICIALIZAÇÃO DO LCD;#################################################################################
INILCD: MOV A,#039H CALL CMLCD MOV A,#006H CALL CMLCD MOV A,#001H CALL CMLCD MOV A,#00EH CALL CMLCD RET
;#################################################################################; ROTINA DE ESCRITA DE UM COMANDO PARA O DISPLAY LCD;################################################################################CMLCD: MOV DPTR,#LCD MOVX @DPTR,A MOV R6,#250CMLCDT: NOP NOP NOP NOP DJNZ R6,CMLCDT RET;#################################################################################; ROTINA DE ESCRITA DE UM CARACTER NO DISPLAY;#################################################################################WRLCD: MOV R4,DPL MOV R5,DPH MOV DPTR,#LCD INC DPTR MOVX @DPTR,A MOV R6,#200 DJNZ R6,$ MOV DPL,R4 MOV DPH,R5 RET;#################################################################################; ROTINA DE ESPERA DE 30MS E SOLTAR TECLA;#################################################################################
ESPETEC: MOV R5,#15INI: MOV TH1,#HIGH(65535-40000) MOV TL1,#LOW(65535-40000) SETB TR1 JNB TF1,$ CLR TF1 DJNZ R5,INI CLR TR1
ESPSOL: CALL LETECL CJNE A,#255,ESPSOL RET
DELAY: MOV R7,#09FHL1: MOV R6,#04FHL2: DJNZ R6,L2 DJNZ R7,L1 RET STOP: MOV A,#0 MOV R4,#0 JMP $ RET
END
…
e "atmega328lib.inc"; diretiva de inclusão de arquivo de biblioteca com rotinas pré -programadas
setup: ; nome da linha (rótulo ou label)sbi ddrd, 2 ; D2->saida lógica (pino2)sbi ddrd, 3 ; D3->saida lógica (pino3)sbi ddrd, 4 ; D4->saida lógica (pino4)sbi ddrd, 5 ; D5->saida lógica (pino5)sbi ddrb, 0 ; B0->saida lógica (pino8)sbi ddrb, 1 ; B1->saida lógica (pino9)sbi ddrb, 2 ; B2->saida lógica (pino10)sbi ddrb, 3 ; B3->saida lógica (pino11)call defesa; chama rotina de defesa (servo em 0 graus)cpi w, '0' ; compara o valor do reg trabalho w (r16) com o caracter zero brne pc + 2 ;call parado ; chama rotina de robo paradocpi w, '1' ; compara o valor do reg trabalho w (r16) com o caracter zero brne pc + 2 ;call avanco ; chama rotina de avanco do robo cpi w, '5' ; compara o valor do reg trabalho w (r16) com o caracter zero brne pc + 2 ;call reverso ; chama rotina de reversao do robo cpi w, '3' ; compara o valor do reg trabalho w (r16) com o caracter zero brne pc + 2 ;call direita ; chama rotina de de girar o robo para direitacpi w, '7' ; compara o valor do reg trabalho w (r16) com o caracter zero brne pc + 2 ;call esquerda ; chama rotina de de girar o robo para esquerdacpi w, 'A' ; compara o valor do reg trabalho w (r16) com o caracter zero brne pc + 2 ;call ataque ; chama rotina de ataque (servomotor em 90 graus)cpi w, 'B' ; compara o valor do reg trabalho w (r16) com o caracter zero brne pc + 2 ;call defesa ; chama rotina de defesa (servomotor em 0)
parado: ; nome da rotina; motores direitasbi portd, 2 ; D2 (pino2) em Hsbi portd, 3 ; D3 (pino3) em Hsbi portd, 5 ; D5 (pino5) em Hsbi portd, 4 ; D4 (pino4) em H; motores esquerdasbi portb, 0 ; B0 (pino8) em Hsbi portb, 1 ; B1 (pino9) em Hsbi portb, 3 ; B3 (pino11) em Hsbi portb, 2 ; B2 (pino10) em H
avanco: ; nome da rotina; motores direitacbi portd, 2 ; D2 (pino2) em Lsbi portd, 3 ; D3 (pino3) em Hsbi portd, 5 ; D5 (pino5) em Hcbi portd, 4 ; D4 (pino4) em L; motores esquerdacbi portb, 0 ; B0 (pino8) em Lsbi portb, 1 ; B1 (pino9) em Hsbi portb, 3 ; B3 (pino11) em Hcbi portb, 2 ; B2 (pino10) em L
reverso: ; nome da rotina; motores direitasbi portd, 2 ; D2 (pino2) em Hcbi portd, 3 ; D3 (pino3) em Lcbi portd, 5 ; D5 (pino5) em Lsbi portd, 4 ; D4 (pino4) em H; motores esquerdasbi portb, 0 ; B0 (pino8) em Hcbi portb, 1 ; B1 (pino9) em Lcbi portb, 3 ; B3 (pino11) em Lsbi portb, 2 ; B2 (pino10) em H
direita: ; nome da rotina; motores esquerdacbi portb, 0 ; B0 (pino8) em Lsbi portb, 1 ; B1 (pino9) em Hsbi portb, 3 ; B3 (pino11) em Hcbi portb, 2 ; B2 (pino10) em L; motores direitasbi portd, 2 ; D2 (pino2) em Hcbi portd, 3 ; D3 (pino3) em Lcbi portd, 5 ; D5 (pino5) em Lsbi portd, 4 ; D4 (pino4) em Hret ; retorna da chamda da rotina
esquerda: ; nome da rotina; motores direitacbi portd, 2 ; D2 (pino2) em Lsbi portd, 3 ; D3 (pino3) em Hsbi portd, 5 ; D5 (pino5) em Hcbi portd, 4 ; D4 (pino4) em L; motores esquerdasbi portb, 0 ; B0 (pino8) em Hcbi portb, 1 ; B1 (pino9) em Lcbi portb, 3 ; B3 (pino11) em Lsbi portb, 2 ; B2 (pino10) em Hret ; retorna da chamada da rotina
defesa: ; nome da rotinasbi portb, 4 ; pulso em Hldi w, 1 ; carrega o registra w com o valor 1call delay_ms ; chama rotina de pausa em ms com o valor de wcbi portb, 4 ; pulso em Lldi w, 19 ; carrega o registra w com o valor 19call delay_ms ; chama rotina de pausa em ms com o valor de wsbi portb, 4 ; pulso em Hldi w, 1 ; carrega o registra w com o valor 1call delay_ms ; chama rotina de pausa em ms com o valor de wcbi portb, 4 ; pulso em Lldi w, 19 ; carrega o registra w com o valor 19call delay_ms ; chama rotina de pausa em ms com o valor de wret ; retorna da chamada da rotina
ataque: ; nome da rotinasbi portb, 4 ; pulso em Hldi w, 1 ; carrega o registra w com o valor 1call delay_ms ; chama rotina de pausa em ms com o valor de wldi w, 200 ; carrega o registra w com o valor 200call delay_us ; chama rotina de pausa em ms com o valor de wldi w, 200 ; carrega o registra w com o valor 200call delay_us ; chama rotina de pausa em ms com o valor de wldi w, 100 ; carrega o registra w com o valor 100call delay_us ; chama rotina de pausa em ms com o valor de wcbi portb, 4 ; pulso em Lldi w, 18 ; carrega o registra w com o valor 18call delay_ms ; chama rotina de pausa em ms com o valor de wldi w, 200 ; carrega o registra w com o valor 200call delay_us ; chama rotina de pausa em ms com o valor de wldi w, 200 ; carrega o registra w com o valor 200call delay_us ; chama rotina de pausa em ms com o valor de wldi w, 100 ; carrega o registra w com o valor 100call delay_us ; chama rotina de pausa em ms com o valor de wsbi portb, 4 ; pulso em Hldi w, 1 ; carrega o registra w com o valor 1call delay_ms ; chama rotina de pausa em ms com o valor de wldi w, 200 ; carrega o registra w com o valor 200call delay_us ; chama rotina de pausa em ms com o valor de wldi w, 200 ; carrega o registra w com o valor 200call delay_us ; chama rotina de pausa em ms com o valor de wldi w, 100 ; carrega o registra w com o valor 100call delay_us ; chama rotina de pausa em ms com o valor de wcbi portb, 4 ; pulso em Lldi w, 18 ; carrega o registra w com o valor 18call delay_ms ; chama rotina de pausa em ms com o valor de wldi w, 200 ; carrega o registra w com o valor 200call delay_us ; chama rotina de pausa em ms com o valor de wldi w, 200 ; carrega o registra w com o valor 200call delay_us ; chama rotina de pausa em ms com o valor de wldi w, 100 ; carrega o registra w com o valor 100call delay_us ; chama rotina de pausa em ms com o valor de wret ; retorna da chamada da rotina…