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
peito a eficiência da interface de programação, pois acredito que possa deixar os processos mais rápidos do que já estão.
Eis o vídeo da minha placa seguidora de movimento na pan/tilt
http://www.youtube.com/watch?v=jeU8o2ozeI0
Se leram a descrição do vídeo no YouTube notaram que eu falei que o servo do eixo horizontal queimou a placa, então o religuei como simples motor CC com caixa de redução até chegar um novo servo. Digo isso para não estranharem o código C#.
Código em C#
--------------------------------------------------------------------------------------------------------------------------------------------
#include <Servo.h> #define Leitura 200 // Leitura do sensor - calibrei todos os sensores a terem o mesmo valor, por isso apenas um valor como base
int Sensor_Hor_Esq = A0; // Sensor IR horizontal Esquerdo int Sensor_Hor_Dir = A1; // Sensor IR horizontal Direito int Sensor_Ver_Sup = A2; // Sensor IR Vertiacal Superior int Sensor_Ver_Inf = A3; // Sensor IR Vertical Inferior int moverV = 2300; // Define posição inicial servo
int pino_motor_Hor_A = 6; int pino_motor_Hor_B = 5; Servo servo_Ver; // Objeto para controlar servo Horizontal
void setup() { Serial.begin(9600); servo_Ver.attach(10); pinMode(pino_motor_Hor_A, OUTPUT); pinMode(pino_motor_Hor_B, OUTPUT); servo_Ver.writeMicroseconds(moverV); }
void loop() { // Serial.println(" Sensor Horizontal | Sensor Vertical |"); // Serial.println(" | |"); // Serial.print("Esquerda: "); // Serial.print(analogRead(Sensor_Hor_Esq)); // Serial.print(" |Superior: "); // Serial.print(analogRead(Sensor_Ver_Sup)); // Serial.println(" |"); // Serial.print("Direita: "); // Serial.print(analogRead(Sensor_Hor_Dir)); // Serial.print(" |Inferior: "); // Serial.print(analogRead(Sensor_Ver_Inf)); // Serial.println(" |"); // Serial.println(" "); // Serial.println(" "); // Serial.println("--------------------------------------------------------------------------"); // Serial.println(" "); // Serial.println(" ");
if(analogRead(Sensor_Hor_Esq) < Leitura && analogRead(Sensor_Hor_Dir) > Leitura) { digitalWrite(pino_motor_Hor_A, HIGH); digitalWrite(pino_motor_Hor_B, LOW); delay(1); digitalWrite(pino_motor_Hor_A, LOW); digitalWrite(pino_motor_Hor_B, LOW); } else if(analogRead(Sensor_Hor_Esq) > Leitura && analogRead(Sensor_Hor_Dir) < Leitura) { digitalWrite(pino_motor_Hor_A, LOW); digitalWrite(pino_motor_Hor_B, HIGH); delay(1); digitalWrite(pino_motor_Hor_A, LOW); digitalWrite(pino_motor_Hor_B, LOW);
} if(analogRead(Sensor_Ver_Sup) < Leitura && analogRead(Sensor_Ver_Inf) > Leitura && moverV > 1500) // 1500 movimento minimo limitado pela pan/tilt { moverV -=1; servo_Ver.writeMicroseconds(moverV); delayMicroseconds(100); } else if(analogRead(Sensor_Ver_Sup) > Leitura && analogRead(Sensor_Ver_Inf) < Leitura && moverV < 2300) // 2300 movimento máximo na pan/tilt { moverV +=1; servo_Ver.writeMicroseconds(moverV); delayMicroseconds(100); }
}
------------------------------------------------------------------------------------------------------------------------------------------
Alguém vê a possibilidade de conseguir melhorar a velocidade dos processos ?? principalmente a respeito do do movimento Vertical, que esta usando um servo motor. Pois o horizontal esta o mais breve possível usando motores CC, não tendo como diminuir.
--------------------------------------------------------------------------------------------------------------------------------------------
Editado - Acrescentando esquema elétrico da placa mediante a pedido.
--------------------------------------------------------------------------------------------------------------------------------------------
Este é o esquema ilustrado da placa, com detalhes da montagem e valores dos componentes.
Veja que os componentes foram dispostos conforme a montagem original da placa, isso para facilitar caso alguém venha querer fazer a montagem da mesma em uma placa protótipo.
E aqui uma foto da placa vista de frente, para se ter uma ideia.
(foto com meu celular já meio antigo, desculpe a qualidade.)
Qualquer outra informação, basta perguntar.…
uele código faz.
2) sobre a questão da velocidade do Processador. Veja: no UNO o clock do Processador é de 16 MHz, o que dá um ciclo de 62.5 ns, que é o tempo de execução da instrução mais curta do AVR. Isto é bem maior que os tempos mínimos necessários para o HC595 (setup, hold, twH e twL, @5V). Além disso sabemos que a função "digitalWrite" é bem mais lenta que isso. Então no UNO não há problemas. Mas no ESP8266 vc pode estar usando o clock de 80 MHz ou o de 160 MHz, correspondendo a períodos de 12.5 ns e 6.5 ns, respectivamente. Veja que estes tempos podem não atender as especificações de temporização do HC595, caso o código de I/O resulte efetivamente em uma única instrução (o que é perfeitamente possível de ocorrer). Isto vai depender do Compilador C/C++, e de otimizações feitas por ele. Uma vez que o código tenha sido lido da Flash para a RAM do ESP8266, ele executará absurdamente mais rápido que o UNO. Então cuidados devem ser tomados para não depender do resultado da Compilação. Os tempos de 1us que acrescentei, garantem isso, sem acrescentar um "overhead" no funcionamento do seu Sistema, então aconselho manter essa temporização.
3) sobre o Capacitor C3. Nenhum CI Digital convencional tolera altas capacitâncias ligadas às suas saídas (sejam MOSFETs ou BJTs). E estamos falando de dezenas a centenas de nF (nano Farad). Então imagina esse C3 que vc usou. A consequência disto, irá variar conforme a tecnologia do CI, podendo apenas causar anomalias no funcionamento, ou mesmo um dano permanente. Cuidado aqui, pois danos permanentes nos circuitos internos dos CIs HCMOS, são extremamente traiçoeiros, podendo levar vc a confundir o que está de fato causando o problema (o motivo disso é que a coisa é digital, ou seja, se vc estiver no "limiar", poderá ser decidido para "0" ou para "1", e isto poderá corresponder ou não ao resultado que vc espera, o que certamente vai te pregar uma grande peça, e uma grande dor de cabeça).
Se vc ligou a alimentação, e acionou de "0" para "1", ou de "1" para "0", aquele C3 pode ter feito um estrago interno no HC595 (ou seja: não se restringe apenas aos dois MOSFETs de saída daquele pino 5), e portanto este CI não é mais confiável. Então a regra é clara: elimine o C3, e substitua aquele HC595. Mas veja: não adianta eliminar C3 e manter o dreno de corrente para o Backlight do Display, se esta corrente for demasiada para uma saída do HC595.
Sobre o "fader", não adianta vc colocar "Diodo-->Resistor-->Capacitor", pois provavelmente a corrente DC drenada será muito além dos limites do HC595. Então essa topologia não adiantaria. Use um MOSFET canal P para drivar o Anodo do Backlight do Display. Entre o pino do Backlight e o GND, coloque um Resistor de 10k, para fechar o circuito do MOSFET. Acrescente também um Resistor de 1k entre o Source e o Gate do MOSFET, e outro Resistor entre o Gate e o pino de controle (HC595 ou ESP). Então vc pode usar PWM para controlar a intensidade luminosa do Backlight, ou simplesmente fazer um ON/OFF simples. Claro, se usar um MOSFET adequado, poderá acrescentar uma Capacitância alta como seu C3. Mas veja: temporizações são muitas vezes controladas pela constante de tempo "RC" (acredite: Resistência Elétrica multiplicada pela Capacitância, resulta em unidades de tempo), e assim um "RC" adequado em um circuito onde "C" tem baixa capacitância pode eventualmente ser uma opção.
A outra técnica (que já usei também), é implementar uma Fonte de Corrente para o Backlight, e controlar esta corrente (pode ser via DAC discreto, aproveitando saídas que estão sobrando dos HC595). O circuito é simples, mas como sua placa já está pronta, teria que ser feito fora dela. Isso é mais usado quando há DACs disponíveis na CPU. A opção do PWM via MOSFET, é mais efetiva e mais simples, e portanto a melhor opção.
4) sobre o "R20". Ficou clara sua jsutificativa. Porém em Projetos não fazemos isso. O "correto" seria acrescentar um AmpOp configurado como seguidor de tensão após o 4051, e então fazer o divisor de tensão após o AmpOp, mas usando Resistores entre 1k e 3k3. Ou seja: para sinais enviados a um ADC, não se usa divisores com altas impedâncias. O motivo? Basicamente dois: garantir que o sample_&_hold se complete corretamente no ADC, e impedir que ruídos de alta frequência tenham amplitude considerável em relação do step do ADC (ou seja, garantir uma boa relação sinal ruído, do contrário pode ser um desastre, pois implicaria em sub-amostragem e nenhum DSP no planeta conseguiria eliminar esse ruído com pós-processamento digital).
5) sobre o HC594 x HC595, peço que veja os links que mostrei no post anterior. Uma coisa que ajuda vc a entender, é o olhar o circuito lógico interno dos dois CIs, e certamente isso irá lhe acrescentar know-how. O HC595 é mais adequado para barramentos tri-state. o HC594 é mais adequado para I/Os convencionais, onde um "PUC" (Power Up Clear) é desejado.
6) sobre o layout. Rapaz, quase dá pra dizer que não há padrão no seu layout. Mas isto seria uma injustiça, pois vc pode usar um padrão que vc determinou, e sempre seguir o mesmo em todas as suas placas. O assunto layout é algo extremamente denso e minucioso. Há uma infinidade de aspectos a serem considerados. Além disso, a prática e o tempo de experiência acumulados são essenciais. Então isso poderia nos levar a pensar: "ah, então qualquer um que comece a fazer layouts, nunca irá ter bom resultados". Mas não é bem assim, afinal existem cursos de layout e técnicas para aprender.
Quando eu carreguei o layer de cobre "Bottom", o View Mate já indicou um problema, que mostro na figura a seguir:
(clique nas figuras para "zoom")
Este problema em específico geralmente ocorre devido a uma distração do layoutista. Mas se vc usar programas de layout que façam verificação de erros (Design Errors Check), eles irão apontar isso antes, e vc poderá corrigir.
O Polígono problemático em questão, eu salientei na figura a seguir.
(clique na figura para "zoom")
Confira ele no seu layout. A versão do Proteus que tenho aqui não abre seus arquivos, pois eles são de uma versão mais recente. Por isso usei o View Mate para ver o Gerber. Mas essencialmente, em algum ponto vc "dobrou" o Polígono sobre ele mesmo, e dependendo de onde isto ocorreu, poderá ou não ser um problema para seu circuito (isto não dá pra explicar aqui, pois estenderia muito).
A sua placa, com "Top", "Bottom", "Sold Masks", e "Silk", mostrada na figura a seguir (capturada do Gerber), revela algumas coisas estranhas.
(clique na figura para "zoom")
Veja no "Bottom" alguns pontos que salientei:
(clique na figura para "zoom")
Além disso, nem sempre um sinal correndo paralelo a uma trilha de GND, é a opção adequada, pois isto aumenta a capacitância entre o sinal e o GND, e se a frequência desse sinal for alta, já sabe o que pode acontecer. Outro exemplo que contraria o que seria corretamente óbvio, é quando vc tem AmpOps de alta-frequência: colocar um plano de GND ou VCC logo abaixo dos sinais, provavelmente será um desastre (por exemplo, veja o datasheet do THS4131 neste link ). Então "espalhar" áreas de cobre de GND pela placa, pode não combinar com alguns circuitos.
Sobre padrões, certamente uma coisa que chama a atenção no seu layout, é a referência para os CIs. Geralmente se usa "U" para essa referência. Vc usou o próprio nome dos CIs. Na indústria isso não seria tolerável, mas como o layout é particular e seu, tudo bem, é vc quem irá usá-lo e assim faz do jeito que achar mais adequado.
Mas ainda há uma série de outros pontos, que não dá pra abordar aqui, por exemplo as regras de Design. Eu uso o Eagle, e capturei algumas figuras para mostrar alguns settings:
(clique nas figuras para "zoom")
Veja, vc pode especificar os settings. Mas há regras, há limites, há padrões. Uma fábrica de PCIs que se preze, irá reportar a vc problemas relacionados a esses padrões, antes de iniciar a fabricação, te dando a chance de corrigir esses "problemas".
Uma boa maneira de aprender sobre layout (além da prática é claro), é ler "APP-Notes" dos Fabricantes. Eles são mais curtos para se ler do que livros, e vão mais direto ao ponto, reduzindo o tempo de aprendizado. Bons fabricantes tem muitos "APP-Notes" para isso, como é o caso da Texas (recomendo muito), Microchip, NXP, e até mesmo Intel. Geralmente são ótimos. Mas estão em inglês, e exigem também outros conhecimentos técnicos (principalmente em Circuitos). Então nem sempre será um caminho fácil, já que é um assunto denso e muito técnico.
Sobre o problema com o HC595, vamos torcer pra que seja algo pontual nesta placa. O mais provável é que seja uma bobagem (estas coisas são muito traiçoeiras e confundem muito, dando pistas erradas). Mas uma técnica adequada de depuração do Hardware, sempre irá convergir para o problema.
abrçs,
Elcids…
Adicionado por Elcids Chagas ao 19:57 em 31 agosto 2021
ara consumo próprio e de amigos, sem fins lucrativos:
o projetinho original tinha mais botões, por isso é que tem 4 botões declarados, como só uso 2, deixeis o restante declarado para não ter problema.
O que estou buscando ajuda seria alterar o valor de delay da linha abaixo usando o LCD dentro de uma nova janela onde a chamaria de SETUP. criar a nova janela eu já consigo fazer sozinho.
digitalWrite(aliviol,HIGH); // fecha escape lentodelay(10000);
pois caso no meio do envase eu tenha que reduzir ou aumentar este tempo, tenho que conectar o note e transferir o código.
// --- Bibliotecas Auxiliares ---#include <LiquidCrystal.h> //Biblioteca para o display LCD
// ATENCAO PARA TROCAR AS PORTAS DO LCD
// --- Mapeamento de Hardware --- #define butUp 10 //Botão para selecionar tela acima no digital 12#define butDown 12 //Botão para selecionar tela abaixo no digital 11 #define butP 11 //Botão de ajuste mais no digital 10#define butM 13 //Botão de ajuste menos no digital 9#define co2 A0 //Saída para rele co2 no A0 (será usado como digital)#define beer A1 //Saída para rele beer no A1 (será usado como digital)#define alivior A2 //Saída para rele alivio rapido no A2 (será usado como digital)#define aliviol A3 //Saída para rele alivio lento no A3 (será usado como digital) #define buzzer A4 //Saída para buzzer anuncio garrafa cheia (será usada como digital)
// --- Protótipo das Funções Auxiliares ---void changeMenu(); //Função para modificar o menu atualvoid dispMenu(); //Função para mostrar o menu atualvoid GARRAFA300ML(); //Função 3void GARRAFA500ML(); //Função 4
// --- Variáveis Globais ---char menu = 0x01; //Variável para selecionar o menuchar set1 = 0x00, set2 = 0x00; //Controle das lâmpadasboolean t_butUp, t_butDown, t_butP, t_butM; //Flags para armazenar o estado dos botões
// --- Hardware do LCD ---LiquidCrystal disp(7, //RS no digital 7 8, //EN no digital 8 6, //D4 no digital 6 5, //D5 no digital 5 4, //D6 no digital 4 3); //D7 no digital 3
// --- Configurações Iniciais ---void setup(){ disp.begin(16,2); //Inicializa LCD 16 x 2 for(char i=9; i<13; i++) pinMode(i, INPUT_PULLUP); //Entrada para os botões (digitais 9 a 12) com pull-ups internos pinMode(co2, OUTPUT); //Configura saída para rele co2 pinMode(beer, OUTPUT); //Configura saída para rele beer pinMode(alivior, OUTPUT); //Configura saída para rele alivio r pinMode(aliviol, OUTPUT); //Configura saída para rele alivio l pinMode(buzzer, OUTPUT); t_butUp = 0x00; //limpa flag do botão Up t_butDown = 0x00; //limpa flag do botão Down t_butP = 0x00; //limpa flag do botão P t_butM = 0x00; //limpa flag do botão M digitalWrite(co2, HIGH); //Lâmpada 1 inicia apagada digitalWrite(beer, HIGH); //Lâmpada 2 inicia apagada digitalWrite(alivior, HIGH); //Lâmpada 1 inicia apagada digitalWrite(aliviol, HIGH); //Lâmpada 2 inicia apagada digitalWrite(buzzer, LOW);} //end setup
// --- Loop Infinito ---void loop(){ changeMenu(); dispMenu();
} //end loop
//****************************************** Desenvolvimento das Funções Auxiliares********************************************************
void changeMenu() //Modifica o menu atual{ if(!digitalRead(butUp)) t_butUp = 0x01; //Botão Up pressionado? Seta flag if(!digitalRead(butDown)) t_butDown = 0x01; //Botão Down pressionado? Seta flag if(digitalRead(butUp) && t_butUp) //Botão Up solto e flag setada? { //Sim... t_butUp = 0x00; //Limpa flag disp.clear(); //Limpa display menu++; //Incrementa menu if(menu > 0x06) menu = 0x01; //Se menu maior que 6, volta a ser 1 } //end butUp if(digitalRead(butDown) && t_butDown) //Botão Down solto e flag setada? { //Sim... t_butDown = 0x00; //Limpa flag disp.clear(); //Limpa display menu--; //Decrementa menu if(menu < 0x01) menu = 0x06; //Se menu menor que 1, volta a ser 6 } //end butDown
} //end changeMenu
//******************************* CONTROLE DOS MENUS **********************************************************************************************************************
void dispMenu() //Mostra o menu atual{
disp.setCursor(4,1); //Posiciona cursor na coluna 4, linha 1disp.print("FULL JAZZ"); //Imprime mensagemdelay(100);
switch(menu) //Controle da variável menu { case 0x01: //Caso 1 GARRAFA300ML(); //GARRAFA 300ML break; //break
case 0x02: //Caso 2 GARRAFA500ML(); //GARRAFA 500ML break; //break
} //end switch menu
} //end dispMenu
// *************************************** GARRAFAS DE 300ML*****************************************************************************************************************************
void GARRAFA300ML() { disp.setCursor(0,0); //Posiciona cursor na coluna 1, linha 1 disp.print("GARRAFA 300ML"); //Imprime mensagem do menu 3 if(!digitalRead(butP)) t_butP = 0x01; //Botão P pressionado? Seta flag if(!digitalRead(butM)) t_butM = 0x01; //Botão M pressionado? Seta flag if(digitalRead(butP) && t_butP) //Botão P solto e flag setada? { //Sim... t_butP = 0x00; //Limpa flag set1++; //Incrementa set1 if(set1 > 2) set1 = 0x01; //Se maior que 2, volta a ser 1 switch(set1) //Controle do set1 { case 0x01: //Caso 1 // disp.setCursor(4,1); //Posiciona cursor na coluna 1, linha 2 // disp.print("ENCHENDO....."); //Imprime mensagem
disp.clear();
disp.setCursor(0,0);disp.print(" REMOVE OXIGENIO");
digitalWrite(co2,LOW); //liga co2delay(2000);
digitalWrite(co2,HIGH); // fecha co2delay(500);
digitalWrite(alivior,LOW); // abre escape rapidodelay(2000); digitalWrite(alivior,HIGH); // fecha escape rapidodelay(500);disp.clear();
// ******** GARRAFA SEM O2
disp.setCursor(0,0);disp.print(" INJETA CO2");digitalWrite(co2,LOW); // liga co2 delay(2000);digitalWrite(co2,HIGH); // fecha co2delay(1000);disp.clear();
// ******* GARRAFA PRESSURIZADA COM CO2
digitalWrite(beer,LOW); // abre beerdelay(3000);disp.setCursor(0,0);disp.print("ENCHENDO....");digitalWrite(aliviol,LOW); // abre escape lentodelay(24000);
disp.clear();disp.setCursor(0,0); disp.print("GARRAFA CHEIA");
digitalWrite(aliviol,HIGH); // fecha escape lentodelay(10000);
digitalWrite(beer,HIGH); // fecha beerdelay(1000);disp.clear();disp.setCursor(0,0); disp.print("AGUARDE");
digitalWrite(alivior,LOW); // abre escape rapidodelay(3000); digitalWrite(alivior,HIGH); // fecha escape rapidodelay(500); digitalWrite(buzzer,HIGH); delay(500); digitalWrite(buzzer,LOW); delay(500);
digitalWrite(buzzer,HIGH); delay(500); digitalWrite(buzzer,LOW); delay(500);
digitalWrite(buzzer,HIGH); delay(500); digitalWrite(buzzer,LOW); delay(500);
digitalWrite(buzzer,HIGH); delay(50); digitalWrite(buzzer,LOW); delay(50);
digitalWrite(buzzer,HIGH); delay(50); digitalWrite(buzzer,LOW); delay(50);
digitalWrite(buzzer,HIGH); delay(50); digitalWrite(buzzer,LOW); delay(50);
digitalWrite(buzzer,HIGH); delay(50); digitalWrite(buzzer,LOW); delay(50);
disp.clear(); disp.print("PROXIMA GARRAFA"); delay(5000); disp.clear();
//******** GARRAFA CHEIA break; //Break
} //end switch set1 } //end butM
} // FECHA ETAPA 300ML //************************************************************GARRAFAS DE 500ML************************************************************************************************************
void GARRAFA500ML() { disp.setCursor(0,0); //Posiciona cursor na coluna 1, linha 1 disp.print("GARRAFA 500ML"); //Imprime mensagem do menu 3 if(!digitalRead(butP)) t_butP = 0x01; //Botão P pressionado? Seta flag if(!digitalRead(butM)) t_butM = 0x01; //Botão M pressionado? Seta flag if(digitalRead(butP) && t_butP) //Botão P solto e flag setada? { //Sim... t_butP = 0x00; //Limpa flag set1++; //Incrementa set1 if(set1 > 2) set1 = 0x01; //Se maior que 2, volta a ser 1 switch(set1) //Controle do set1 { case 0x01: //Caso 1 // disp.setCursor(4,1); //Posiciona cursor na coluna 1, linha 2 // disp.print("ENCHENDO....."); //Imprime mensagem
disp.clear();
disp.setCursor(0,0);disp.print(" REMOVE OXIGENIO");
digitalWrite(co2,LOW); //liga co2delay(2000);
digitalWrite(co2,HIGH); // fecha co2delay(500);
digitalWrite(alivior,LOW); // abre escape rapidodelay(4000); digitalWrite(alivior,HIGH); // fecha escape rapidodelay(500);disp.clear();
// ******** GARRAFA SEM O2
disp.setCursor(0,0);disp.print(" INJETA CO2");digitalWrite(co2,LOW); // liga co2 delay(2000);digitalWrite(co2,HIGH); // fecha co2delay(1000);disp.clear();
// ******* GARRAFA PRESSURIZADA COM CO2
digitalWrite(beer,LOW); // abre beerdelay(500);disp.setCursor(0,0);disp.print("ENCHENDO....");digitalWrite(alivior,LOW); // abre escape lentodelay(20000);disp.clear();
disp.setCursor(0,0); disp.print("AGUARDE");
digitalWrite(beer,HIGH); // fecha beerdelay(2000);digitalWrite(alivior,HIGH); // fecha escape lentodelay(400); disp.clear();
delay(500);disp.setCursor(0,0); disp.print("GARRAFA CHEIA"); digitalWrite(buzzer,HIGH); delay(500); digitalWrite(buzzer,LOW); delay(50); delay(500); digitalWrite(buzzer,HIGH); delay(500); digitalWrite(buzzer,LOW); delay(50); disp.clear(); disp.print("PROXIMA GARRAFA"); delay(3000); disp.clear();
//******** GARRAFA CHEIA break; //Break
} //end switch set1 } //end butM
} // FECHA ETAPA 500ML
…