erto, entendo sua frustração, uma vez que usando um circuito discreto é perfeitamente possível sua implementação (mas claro que aí não terá a mesma flexibilidade e "sofisticação").
Então, partindo de que entendi corretamente, implementei seu Sistema no Arduino, e ele funcionou perfeitamente. Inclusive também fiz a simulação do mesmo, a qual também funcionou como esperado.
Para isto, implementei uma Máquina de Estados, que controla a geração dos pulsos, baseado no valor atual do "tempo de bico" (um nome um tanto esquisito, né?). E foram necessários apenas 2 estados para a implementação (um tanto surpreendente, pois diversas outras Máquinas que já implementei aqui no LDG tinham mais estados).
Claro, além da implementação da Máquina de Estados, tive que utilizar algumas técnicas "especiais", e sobre algumas dessas técnicas falarei mais à frente.
Mas antes Leonardo, gostaria de esclarecer um ponto: não era exatamente o "delay" o culpado pelos problemas que vc estava tendo. Eram vários culpados (e o "delay" era o menos culpado). Mas claro, em Sistemas de "tempo real", deve-se evitar o uso do "delay" a todo custo (no código que implementei não há nenhum), pois ele geralmente compromete as temporizações existentes no Sistema.
Outro detalhe: como vc não disse praticamente nada sobre o Hardware, testei com o Arduino UNO (e a simulação também fiz com o UNO).
Assim, a implementação de Hardware pode ser vista na figura a seguir, onde já mostro o resultado da simulação:
(clique na figura para "zoom")
Sobre esta implementação e resultado, farei algumas observações relevantes:
1) observe o sinal na cor amarela no Osciloscópio: são os pulsos do Sensor Hall. O código implementado, não depende da largura destes pulsos do Sensor, o que é ótimo. Mas como na simulação eu tinha que colocar uma largura para eles, coloquei em 500us. Se na prática for maior ou menor, não haverá problema, pois o código trata isso sempre de forma adequada.
2) o sinal na cor azul no Osciloscópio, são os pulsos de acionamento dos bicos injetores. A largura destes é determinada pelo valor lido do Potenciômetro, conforme vc disse que deveria ser. Sempre que o valor lido do Potenciômetro entra numa nova faixa, a largura dos pulsos muda de acordo com esta faixa. Os períodos dos pulsos que medi estavam bem precisos, e isto é devido a algumas das "técnicas especiais" que apliquei.
3) para a geração dos pulsos do Sensor Hall, na simulação foi utilizado um Gerador de Pulsos (na prática usei um Sensor Hall mesmo). Veja que na simulação, o valor da Frequência do Gerador, está em 80 Hz, ou seja, 80 pulsos por segundo. Isto corresponde a 4800 RPM, já que a rotação do motor em RPM = Frequência x 60 (ou seja, 80 x 60 = 4800 RPM), isso considerando que há apenas um único ímã acoplado ao eixo do Motor (se fossem dois, a frequência dobraria). Assim, para alterar a rotação na simulação, basta alterar o parâmetro "Frequência" do Gerador de Pulsos.
4) observe que há um Capacitor (o "C1") conectado entre o "A0" e o GND do circuito. Aconselho fortemente que vc o conecte. Na simulação não há ruídos, mas na prática os Sistemas em ambientes com Motores, costumam ter um bom nível de ruídos. E o capacitor é justamente para filtrar estes ruídos do sinal vindo do Potenciômetro (e também para minimizar a "injeção de carga" existente no circuito interno do Processador do Arduino). O valor pode estar entre 100kpF (que é o que eu coloquei na simulação), e 1uF. Use capacitor cerâmico, ou de tântalo (não use outros tipos!!!).
5) na simulação, conectei também um Voltímetro no pino "A0", de forma a poder conferir o valor indicado nele com o medido pelo Arduino (bateu sempre). Na prática, se vc for conectar algum voltímetro ou multímetro ali, apenas faça isso se tiver colocado o capacitor "C1".
6) o LED conectado na simulação (também conectei na prática), é quase um "enfeite". Mas é interessante, pois piscará na frequência dos pulsos gerados.
7) observe que no Terminal do Arduino (a Serial padrao), é possível ver os valores atuais da tensão medida no Potenciômetro, e "tempo de bico" correspondente. O sistema é otimizado, e apenas atualiza o Terminal, quando o "tempo de bico" muda. Isso é importante, pois a Serial consome alguma performance do Arduino, e então isso é minimizado com a técnica utilizada. Vc pode facilmente desligar essa exibição no Terminal, veja como: no código, há um #define com o nome "SYS_DEBUG_ON", que pode assumir "1" ou "0". Se colocar "1", você verá as informações no Terminal do Arduino. Se colocar "0", o sistema não exibirá no Terminal. Este #define do "SYS_DEBUG_ON" está no início do código, facilmente encontrado.
Agora falando sobre uma das técnicas utilizadas para garantir maior performance do Sistema, o que é muito importante, pois o Processador AVR8 do Arduino não é nenhum foguete. Você verá que no tratamento interno, a tensão medida é multiplicada por 1000 (mil, isso mesmo). Isso converte o valor "float" para um valor inteiro com até 4 dígitos. Este valor é então utilizado para determinar qual a faixa do "tempo de bico" correspondente. Mas por que? Ocorre que as rotinas de Ponto Flutuante do Arduino não são nada velozes, então no caso deste Sistema é melhor evitá-las sempre que possível. Claro, se em algum momento vc precisar do valor original em Volts, bastará dividir por 1000, mas evite fazer isso, e se fizer use uma temporização como a que utilizei em diversas partes do código.
O código está todo comentado e com observações importantes. Então está bem acessível de seguir e entender.
A Máquina de Estados implementada, é extremamente simples, já que tem apenas 2 estados. Se quiser aprender sobre como funciona, eu já postei aqui no LDG diversas outras Máquinas também simples, que irão ajudar nesse processo. Na figura a seguir, vc pode ver o Diagrama de Estados, a partir do qual implementei a Máquina de Estados deste Sistema:
(clique na figura para "zoom")
Segue o código, incluindo os arquivos de simulação no Proteus, e o Diagrama de Estados (formato Visio e PDF).
Código: Injecao_Bicos_02.zip
Caso tenha alguma dúvida ou comentário, não deixe de postar.
Espero ter ajudado.
Abrçs,
Elcids…
Adicionado por Elcids Chagas ao 9:57 em 17 julho 2019
erá a água que sai da máquina de lavar ir para uma caixa a parte que denominei como caixa principal.
Caso tenham alguma dúvida pode me contatar..
Abraços
int CHG = 2; // Chave Geral
int BCXP = 3; // Chave bóia caixa principal
int BCXA = 4; // Chave bóia caixa acoplada
int VSFAR = 5; // Válvula solenóide fecha água da rua
int BOMBA = 6; // Bomba d'água
int LEDCXPO = 7; // Led caixa principal nível OK
int LEDCXPB = 8; // Led caixa principal nível Baixo
int LEDCXAO = 9; // Led caixa acoplada nível OK
int LEDCXAB = 10; // Led caixa acoplada nível Baixo
int leituraCHG; // Leitura Chave Geral
int leituraBCXP; // Leitura Chave bóia caixa principal
int leituraBCXA; // Leitura Chave bóia caixa acoplada
int leituraVSFAR; // Leitura Válvula solenóide fecha água da rua
int leituraBOMBA; // Leitura Bomba d'água
int leituraLEDCXPO; // Leitura Led caixa principal nível OK
int leituraLEDCXPB; // Leitura Led caixa principal nível Baixo
int leituraLEDCXAO; // Leitura Led caixa acoplada nível OK
int leituraLEDCXAB; // Leitura Led caixa acoplada nível Baixo
byte comando=0;//tipo de comando a ser utilizado
String modo= "Em condições de operação";
void setup()
{
Serial.begin(9600);
pinMode(CHG,INPUT);
pinMode(BCXP,INPUT);
pinMode(BCXA,INPUT);
pinMode(VSFAR,OUTPUT);
pinMode(BOMBA,OUTPUT);
pinMode(LEDCXPO,OUTPUT);
pinMode(LEDCXPB,OUTPUT);
pinMode(LEDCXAO,OUTPUT);
pinMode(LEDCXAB,OUTPUT);
}
void loop()
{
leituraCHG=digitalRead(CHG);
leituraBCXP=digitalRead(BCXP);
leituraBCXA=digitalRead(BCXA);
leituraVSFAR=digitalRead(VSFAR);
leituraBOMBA=digitalRead(BOMBA);
leituraLEDCXPO=digitalRead(LEDCXPO);
leituraLEDCXPB=digitalRead(LEDCXPB);
leituraLEDCXAO=digitalRead(LEDCXAO);
leituraLEDCXAB=digitalRead(LEDCXAB);
// INICIO DA LÓGICA DO COMANDO
if(leituraCHG==LOW)//Chave geral desligada
{comando=0;}
else//Chave geral ligada
{
if(leituraBCXP==LOW && leituraBCXA==LOW)// As chaves de bóia no nível baixo
{comando=1;}
else if (leituraBCXP==LOW && leituraBCXA==HIGH)// Caixa principal vazia e caixa acoplada cheia
{comando=2;}
else if (leituraBCXP==HIGH && leituraBCXA==LOW)// Caixa principal cheia e caixa acoplada vazia
{comando=3;}
else if (leituraBCXP==HIGH && leituraBCXA==HIGH)// As chave de bóia no nível alto
{comando=4;}
}
//TIPOS DE COMANDOS
switch(comando)
{
case 0:// Comando desligado
modo= "Chave Geral Desligada";
Serial.print(modo);
digitalWrite(VSFAR,LOW);
digitalWrite(BOMBA,LOW);
digitalWrite(LEDCXPO,LOW);
digitalWrite(LEDCXPB,LOW);
digitalWrite(LEDCXAO,LOW);
digitalWrite(LEDCXAB,HIGH);
delay(1000);
digitalWrite(LEDCXPB,HIGH);
digitalWrite(LEDCXAB,LOW);
delay(1000);
case 1:// As chaves de bóia no nível baixo
modo= "Enchimento pela água da rua";
Serial.print(modo);
digitalWrite(VSFAR,LOW);
digitalWrite(BOMBA,LOW);
digitalWrite(LEDCXPO,LOW);
digitalWrite(LEDCXPB,HIGH);
digitalWrite(LEDCXAO,LOW);
digitalWrite(LEDCXAB,HIGH);
break;
case 2:// Caixa principal vazia e caixa acoplada cheia
modo= "Sem água na caixa principal";
Serial.print(modo);
digitalWrite(VSFAR,LOW);
digitalWrite(BOMBA,LOW);
digitalWrite(LEDCXPO,LOW);
digitalWrite(LEDCXPB,HIGH);
digitalWrite(LEDCXAO,HIGH);
digitalWrite(LEDCXAB,LOW);
break;
case 3:// Caixa principal cheia e caixa acoplada vazia
modo= "Enchimento pela caixa da caixa principal";
Serial.print(modo);
digitalWrite(VSFAR,HIGH);
digitalWrite(BOMBA,HIGH);
digitalWrite(LEDCXPO,HIGH);
digitalWrite(LEDCXPB,LOW);
digitalWrite(LEDCXAO,LOW);
digitalWrite(LEDCXAB,HIGH);
break;
case 4:// As chave de bóia no nível alto
modo= "Caixas cheias";
Serial.print(modo);
digitalWrite(VSFAR,LOW);
digitalWrite(BOMBA,LOW);
digitalWrite(LEDCXPO,HIGH);
digitalWrite(LEDCXPB,LOW);
digitalWrite(LEDCXAO,HIGH);
digitalWrite(LEDCXAB,LOW);
break;
}
}
…
todo louco botoes param de funcionar etc. dessa maneira que esta o codigo agora tudo esta funcionando, mas o problema é que o tempo ficou fora de sincronia e os botoes só funcionam depois de segurar por uns 2 segundos e soltar, se so apertar e soltar nao funciona, alguem poderia me dar uma luz ai, Segue o Codigo
Obs: primeiro post, nao achei como coloca o Codigo em Code :(
//Programa: Arduino e DS18B20 controle de rele por temperatura e timer//Autor: Junior Oliveira
#include <LiquidCrystal.h>#include <OneWire.h>#include <DallasTemperature.h>
int posicao = 0;int temp_min = 24; // TEMPERATURA MINIMA PARA DESLIGARint temp_max = 28; // TEMPERATURA MAXIMA PARA LIGARint ahoras = 0; //VARIAVEL PARA MOSTRAR HORAS NO LCDint aminutos = 0; //VARIAVEL PARA MOSTRAR MINUTOS NO LCDint asegundos = 0; //VARIAVEL PARA MOSTRAR SEGUNDOS NO LCDint segundostotal = 0; //Tempo totalint msg = 0; //BARREIRA PARA MENSAGEM DE BEM VINDOint empieza = 1024; // VARIAVEL PARA BOTAO DE START FUNCIONARint varbuth = 0; //VARIAVEL PARA MUDAR VALOR DE HORASint varbutm = 0; //VARIAVEL PARA MUDAR VALOR DE MINUTOSint varbuts = 0; //VARIAVEL PARA MUDAR VALOR DE SEGUNDOS
// CONFIGURACOES DE PINOS PARA O CIRCUITO
int rele_timer = 13; // PINO DIGITAL PARA RELE TIMERint rele_temp = 12; // PINO DIGITAL RELE TEMPERATURAint start = A2; //PINO ANALOGICO PARA BOTAO DE STARTint buth = A0; //PINO ANALOGICO BOTAO HORASint butm = A1; //PINO ANALOGICO BOTAO MINUTOSint buts = A3; //PINO ANALOGICO BOTAO SEGUNDOS#define ONE_WIRE_BUS 10 // PINO DIGITAL SENSOR DE TEMPERATURA#define pino_aumenta 2 // BOTAO AUMENTA TEMPERATURA MAXIMA#define pino_diminui 3 // DIMINUI TEMPERATURA MAXIMA
OneWire oneWire(ONE_WIRE_BUS);DallasTemperature sensors(&oneWire);
LiquidCrystal lcd(9, 8, 7, 6, 5, 4);
int temperatura;int aumenta, diminui;
unsigned long previousMillis = 0;//Intervalo de medicao temperaturaconst long interval = 2000;
void setup(void){ lcd.begin(16, 2); Serial.begin(9600); pinMode(rele_temp, OUTPUT); pinMode(rele_timer, OUTPUT); pinMode(pino_aumenta, INPUT); pinMode(pino_diminui, INPUT); digitalWrite(rele_timer, HIGH); digitalWrite(rele_temp, LOW); msg = 0; //BARREIRA MENSAGEM BEM VINDO empieza = 1024; //BARREIRA START
varbuth = 1; //BARREIRA DE HORAS varbutm = 1; //BARREIRA DE MINUTOS varbuts = 1; //BARREIRA DE SEGUNDOS sensors.begin();}
void loop(void){ do { sensors.requestTemperatures(); // REQUISITA TEMPERATURA DOS SENSORES
varbuth = analogRead(buth); //LEITURA BOTAO HORAS varbutm = analogRead(butm); //LEITURA BOTAO MINUTOS varbuts = analogRead(buts); //LEITURA BOTAO SEGUNDOS
if (varbuth == 0) //SE PRESSIONAR O BOTAO AUMENTA UMA HORA { ahoras = ahoras + 1 ; delay(250); }
if (varbutm == 0) //SE PRESSIONAR O BOTAO AUMENTA UM MINUTO { aminutos = aminutos + 1; delay(250); }
if (varbuts == 0) //SE PRESSIONAR O BOTAO AUMENTA UM SEGUNDO { asegundos = asegundos + 1; delay(250); } lcd.setCursor(1, 1);
if (ahoras < 10) lcd.print("0"); // SE AS HORAS FOREM MENOR QUE "10" É COLOCADO UM "0" NA FRENTE lcd.print(ahoras); // SEM ESSE CODIGO SE MOSTARIA ASSIM: H:M:S (1:M:S) lcd.print(":");
if (aminutos < 10) lcd.print("0"); // SE OS MINUTOS FOREM MENOR QUE "10" É COLOCADO UM "0" NA FRENTE lcd.print(aminutos); // SEM ESSE CODIGO SE MOSTARIA ASSIM: H:M:S (H:1:S)
lcd.print(":"); if (asegundos < 10) lcd.print("0"); // SE OS SEGUNDOS FOREM MENOR QUE "10" É COLOCADO UM "0" NA FRENTE lcd.print(asegundos); // SEM ESSE CODIGO SE MOSTARIA ASSIM: H:M:S (H:M:1)
empieza = analogRead(start); //LEITURA DO BOTAO DE START
if (empieza == 0) //Si el boton de arranque, fue pulsado... { segundostotal = asegundos + (aminutos * 60) + (ahoras * 60 * 60); // CONVERTE TEMPO TOTAL EM SEGUNDOS } //botao aumenta temperatura aumenta = digitalRead(pino_aumenta); if (aumenta == 0) { temp_max++; } while (digitalRead(pino_aumenta) == 0) { delay(10); }
//botao diminui temperatura diminui = digitalRead(pino_diminui); if (diminui == 0) { temp_max--; } while (digitalRead(pino_diminui) == 0) { delay(10); } lcd.setCursor(0, 0); lcd.print(temperatura); lcd.setCursor(2, 0); lcd.print("C"); lcd.setCursor(4, 0); lcd.print("MIN"); lcd.setCursor(8, 0); lcd.print(temp_max); lcd.setCursor(10, 0); lcd.print("C"); if (temp_min >= temperatura){ digitalWrite(rele_temp, LOW);}else if (temp_max <= temperatura){ digitalWrite(rele_temp, HIGH);} unsigned long currentMillis = millis(); //Timer para ler o valor da temperatura if (currentMillis - previousMillis >= interval) { temperatura = sensors.getTempCByIndex(0); previousMillis = currentMillis; } } while (empieza != 0); // VOLTA AO MENU DE AJUSTE PARA APENAS APERTAR O BOTAO START while (segundostotal > 0) { sensors.requestTemperatures(); // REQUISITA TEMPERATURA DOS SENSORES delay (235); //DESCONTADO 1 SEGUNDO DO TIMER segundostotal--;
ahoras = ((segundostotal / 60) / 60); //CONVERTE OS SEGUNDOS TOTAIS EM HORAS aminutos = (segundostotal / 60) % 60; //CONVERTE OS SEGUNDOS TOTAIS EM MINUTOS asegundos = segundostotal % 60; //CONVERTE OS SEGUNDOS TOTAIS EM SEGUNDOS
lcd.setCursor(1, 1); if (ahoras < 10) lcd.print("0"); // SE AS HORAS FOREM MENOR QUE "10" É COLOCADO UM "0" NA FRENTE lcd.print(ahoras); // SEM ESSE CODIGO SE MOSTARIA ASSIM: H:M:S (1:M:S) lcd.print(":");
if (aminutos < 10) lcd.print("0"); // SE OS MINUTOS FOREM MENOR QUE "10" É COLOCADO UM "0" NA FRENTE lcd.print(aminutos); // SEM ESSE CODIGO SE MOSTARIA ASSIM: H:M:S (H:1:S)
lcd.print(":"); if (asegundos < 10) lcd.print("0"); // SE OS SEGUNDOS FOREM MENOR QUE "10" É COLOCADO UM "0" NA FRENTE lcd.print(asegundos); // SEM ESSE CODIGO SE MOSTARIA ASSIM: H:M:S (H:M:1)
if (segundostotal == 0) //FINALIZA O TEMPO DO TIMER { while (1) //FINALIZA O TEMPO E DESARMA O RELE { digitalWrite(rele_timer, LOW); delay(200); lcd.clear(); lcd.setCursor(1, 0); lcd.print("TEMPO ESGOTADO"); lcd.setCursor(5, 1); lcd.print("By: Jr"); } } //botao aumenta temperatura aumenta = digitalRead(pino_aumenta); if (aumenta == 0) { temp_max++; } while (digitalRead(pino_aumenta) == 0) { delay(10); }
//botao diminui temperatura diminui = digitalRead(pino_diminui); if (diminui == 0) { temp_max--; } while (digitalRead(pino_diminui) == 0) { delay(10); } lcd.setCursor(0, 0); lcd.print(temperatura); lcd.setCursor(2, 0); lcd.print("C"); lcd.setCursor(4, 0); lcd.print("MIN"); lcd.setCursor(8, 0); lcd.print(temp_max); lcd.setCursor(10, 0); lcd.print("C"); if (temp_min >= temperatura){ digitalWrite(rele_temp, LOW);}else if (temp_max <= temperatura){ digitalWrite(rele_temp, HIGH);} unsigned long currentMillis = millis(); //Timer para ler o valor da temperatura if (currentMillis - previousMillis >= interval) { temperatura = sensors.getTempCByIndex(0); previousMillis = currentMillis; } }}
…
utorials/serial-peripheral-interface-spi/all
* https://arduino.stackexchange.com/questions/16348/how-do-you-use-spi-on-an-arduino/16349
Explicando este experimento:
* Neste experimento são necessários 2 Arduinos, um para master e outro para slave.
* O Arduino master enviará automaticamente e seguidamente, a cada 5 segundos, duas sequências de caracteres...
* A primeira sequência de caracteres é composta de um caracter 'a' seguido dos números 10, 17, 33 e 42, da seguinte forma:
* 1. o slave recebe o primeiro byte do master, o caracter 'a' e espera pelo próximo byte do master. O caracter 'a' sinaliza para o slave adicionar 10 aos números que receber a seguir
* 2. o slave receber o segundo byte, o número 10, e então adiciona 10 ao número 10 recebido, resultando 20, e espera
* 3. o slave recebe o terceiro byte do master, o número 17, somando 10 a ele, e aproveita esta conexão para enviar, ao mesmo tempo (comunicação full duplex) em que recebe, o resultado da operação de adição anterior, o númro 20
* 4. o slave recebe o quarto byte do master, o número 33, somando 10 a ele, e aproveita esta conexão para enviar, ao mesmo tempo (comunicação full duplex) em que recebe, o resultado da operação de adição anterior, o número 27
* 5. o slave recebe o quinto byte do master, o número 42, somando 10 a ele, e aproveita esta conexão para enviar, ao mesmo tempo (comunicação full duplex) em que recebe, o resultado da operação de adição anterior, o número 43
* 6. o master não tem mais números a enviar para o slave mas o slave tem uma resposta a enviar para o master, o número 52, resultado da adição de 10 + 42
* 7. então o master, para não ficar sem esse resultado, envia um caracter qualquer para o slave e o slave aproveita esta conexão para enviar o número 52 para o master, finalizando a sequencia numérica enviada pelo master
* A segunda sequência de caracteres é composta de um caracter 's' seguido dos mesmos números 10, 17, 33 e 42, porém o 's' sinaliza para o slave agora fazer a subtração de 10 nestes números na mesma sequencia anterior
Pinagem entre os dois Arduinos Uno:
* Master <==> Slave
* D10 (SS) D10 (SS)
* D11 (MOSI) D11 (MOSI)
* D12 (MISO) D12 (MISO)
* D13 (SCK) D13 (SCK)
* 5V Vin
* GND GND
Código (sketch) para o Arduino master:
* Neste sketch (master) usaremos a biblioteca <SPI.h>
-------------------------------------------------------------------------------------------------------------------------------------------------
#include <SPI.h>
SPISettings settings(4000000, MSBFIRST, SPI_MODE0); // define velocidade desta conexão SPI em
// 4MHz (16MHz do Uno / 4 = 4MHz, default)
void setup(){ Serial.begin (9600); Serial.println();
digitalWrite(SS, HIGH); // desabilitar comunicação com o slave. Garantir que o pino SS do
// master não inicie habilitando a comunicação com o slave (SS em
//estado ALTO = desconectado) SPI.begin();}
byte charInOut(const byte charOut){ // rotina para transferir 1 byte do master para o slave byte charIn = SPI.transfer(charOut); // transfer 1 byte para o slave e, ao mesmo tempo, recebe 1
// byte do slave armazenando-o em 'a' delayMicroseconds(20); // pausa por 0,000.02 segundos ou 20 microsegundos return charIn;}
void loop(){ byte a, b, c, d; digitalWrite(SS, LOW); // habilitar comunicação SPI com o slave SPI.beginTransaction(settings); // inicializar a conexão SPI usando o SPIsettings definido charInOut('a'); // enviar o caracter 'a' para o slave. Neste sketch o caracter 'a'
// sinaliza para o slave fazer uma operação de adição charInOut(10); // enviar o número 10 para o slave e, ao mesmo tempo, não
// receber o que quer que seja do slave a = charInOut(17); // enviar o número 17 para o slave e, ao mesmo tempo, receber
// o dado enviado do slave armazenando-o na variável "a" b = charInOut(33); // enviar o número 33 para o slave e, ao mesmo tempo, receber
// o dado enviado do slave armazenando-o na variável "b" c = charInOut(42); // enviar o número 42 para o slave e, ao mesmo tempo, receber
// o dado enviado do slave armazenando-o na variável "c" d = charInOut(0); // enviar o número 0 (ou qualquer outro caracter) para o slave e,
// ao mesmo tempo, receber o dado enviado do slave
// armazenando-o na variável "d". Esta operação só existe para
// receber dado do slave SPI.endTransaction(); // finalizar a conexão SPI digitalWrite(SS, HIGH); // desabilitar comunicação SPI com slave
Serial.print("O números são 10, 17, 33 e 42. Adicionando 10: "); Serial.print(a, DEC); Serial.print(", "); Serial.print(b, DEC); Serial.print(", "); Serial.print(c, DEC); Serial.print(", "); Serial.print(d, DEC);
digitalWrite(SS, LOW); // habilitar comunicação SPI com o slave SPI.beginTransaction(settings); // inicializar a conexão SPI usando o SPIsettings definido charInOut('s'); // enviar o caracter 's' para o slave. Neste sketch o caracter 's'
// sinaliza para o slave fazer uma operação de subtração charInOut(10); // enviar o número 10 para o slave e, ao mesmo tempo, não
// receber o que quer que seja do slave a = charInOut(17); // enviar o número 17 para o slave e, ao mesmo tempo, receber o
// dado enviado do slave armazenando-o na variável "a" b = charInOut(33); // enviar o número 33 para o slave e, ao mesmo tempo, receber o
// dado enviado do slave armazenando-o na variável "b" c = charInOut(42); // enviar o número 42 para o slave e, ao mesmo tempo, receber o
// dado enviado do slave armazenando-o na variável "c" d = charInOut(0); // enviar o número 0 (ou qualquer outro caracter) para o slave e,
// ao mesmo tempo, receber o dado enviado do slave
// armazenando-o na variável "d". Esta operação só existe para
// receber dado do slave SPI.endTransaction(); // finalizar a conexão SPI digitalWrite(SS, HIGH); // desabilitar comunicação SPI com slave
Serial.print(". Subtraindo 10: "); Serial.print(a, DEC); Serial.print(", "); Serial.print(b, DEC); Serial.print(", "); Serial.print(c, DEC); Serial.print(", "); Serial.println(d, DEC);
Serial.println(); delay (5000); // esperar 5 segundos para fazer isso tudo novamente}
-------------------------------------------------------------------------------------------------------------------------------------------------
Código (sketch) para o Arduino slave:
* Neste sketch não usaremos a biblioteca <SPI.h> mas trabalharemos diretamente com os registradores SPI
-------------------------------------------------------------------------------------------------------------------------------------------------
volatile byte command = 'x'; // Para ter certeza que dados de variáveis globais sejam
// passados entre as ISRs e o programa principal, use definir
// a variável como "volatile"
void setup(){ pinMode(MISO, OUTPUT); // pino MISO deste slave é definido como de output
SPCR |= _BV(SPE); // Habilitar a comunicação SPI neste slave atribuindo 1 ao bit
// SPE do registrador SPCR do SPI do Arduino, ou seja,
// habilitar SPI neste slave SPCR |= _BV(SPIE); // Habilitar a interrupção SPI atribuindo 1 ao bit SPIE do
// registrador SPCR do SPI do Arduino }
ISR(SPI_STC_vect){ // Interrupt Service Routine (ISR), SPI_STC_vect, esta
// interrupção será executada enquanto estiver recebendo
// dados do master, ou seja, a interrupt do pino SS em estado
// BAIXO byte c = SPDR; // lê o registrador "de troca" SPDR que contém o dado (o byte)
// enviado pelo master, armazenado-o na variável 'c' switch (command){ case 'x': // se 'command' = 0, ou seja, se não tem uma ação de adição
// ou subtração command = c; // atribui à variável 'command' o caracter recebido na variável 'c' SPDR = 0; // escreve o número 0 no registrador SPDR, enviando-o ao
// master break; case 'a': // se 'command' = 'a' (de adição) SPDR = c + 10; // soma 10 ao número armazenado em 'c' escrevendo o
// resultado no registrador SPDR, enviando-o ao master break; case 's': // se 'command' = 's' (de subtração) SPDR = c - 10; // subtrai 10 ao número armazenado em 'c' escrevendo o
// resultado no registrador SPDR, enviando-o ao master break; } }
void loop(){ // permanecerá dentro do void loop() enquanto a interrupção
// ISR(SPI_STC_vect) estiver em estado ALTO, ou seja, com a
// SPI inativa if (digitalRead (SS) == HIGH) // se a interrupção estiver em estado ALTO, ou seja, se SPI
// inativa (não estiver recebendo dados do master) command = 'x'; }
-------------------------------------------------------------------------------------------------------------------------------------------------…
ar cancela deve parar o programa
Programa só inicia quando
pin11 der 1 pulso high durante 5 segundos
Quando iniciar programa pin10 em high
se o programa parar pin 10 em low
Se pin 3 ficar High a qualquer momento para o programa
Se pin1 ficar High a qualquer momento para o programa
Verifica se pin1 está em LOW
Low prossegue
High cancela ou ficar high a qualquer momento cancela
Verifica se pin2 está em LOW
Low prossegue
High cancela
tempo de 10s
repete
Verifica se pin1 está em LOW
Low prossegue
High cancela ou ficar high a qualquer momento cancela
Verifica se pin2 está em LOW
Low prossegue
High cancela
se prossegue aciona
pin5 em high
permanece 30s em high
pin6 em high
permanece 30s em high
desativa pin5 e pin6 para low
aguarda 3s
aciona pin7 para high
aciona pin8 para high
aguarda 3 s
aciona pin4 para high
aguarda 20 minutos
pin 4 para low
aguarda 3s
pin7 para low
pin8 para low
aguarda 1 s
aciona pin9 para High
pin 9 permanece em high até
pin1 ou pin 2 ficar em high
quando ficar em high pin1 e pin2
pin9 fica em low
…