No lado do sensor vou usar um Arduino com dois sensores: um sensor de temperatura DS18B20 ligado ao pino D8 e um sensor de efeito Hall A1120 ligado ao pino D7. A minha primeira ideia era usar o sensor LM35, mas ele não funciona com 3V inviabilizando o meu próximo passo. O rádio é ligado da mesmo forma que o meu teste anterior.
O software no Arduino transmitirá em duas situações:
- De 10 em 10 minutos.
- Quando detectar mudança no sensor de efeito Hall (indicando que um imã foi colocado ou retirado da frente dele).
- Dois bytes com a leitura do sensor de temperatura (temperatura em décimo de graus centígrados)
- Um byte contendo 0 ou 1 conforme o sensor de efeito Hall estiver acionado.
- // Exemplo de sensor enviando dados através do nRF24L01+
- // Daniel Quadros, 13/10/15
- #include <SPI.h>
- #include <RF24.h>
- // Conexoes
- const int pinLED = 6;
- const int pinHall = 7;
- const int pinDS18B20 = 8;
- const int pinCE = 9;
- const int pinCSN = 10;
- // Este objeto encapsula o acesso ao nRF24L01+
- RF24 radio(pinCE, pinCSN);
- // Endereços
- byte addrLogger[6] = "DLogr";
- // Estado anterior do sensor de efeito Hall
- const uint8_t hallOFF = '0';
- const uint8_t hallON = '1';
- const uint8_t hallUNDEF = 'X';
- uint8_t hallAnt = hallUNDEF;
- // Tempo em minutos entre transmissões periodicas
- const unsigned long tempoTx = 10;
- // Próximo envio automático
- unsigned long proxEnvio;
- void setup()
- {
- // Serial para debug
- Serial.begin(9600);
- Serial.println("Sensor com nRF24L01+");
- // Iniciacao dos pinos de LED e sensores
- pinMode (pinLED, OUTPUT);
- pinMode (pinHall, INPUT);
- digitalWrite (pinHall, HIGH);
- setDQ(HIGH);
- // Inicia o rádio
- radio.begin();
- radio.setPayloadSize(3);
- radio.openWritingPipe(addrLogger);
- // Primeiro envio
- proxEnvio = millis() + tempoTx * 60000UL;
- }
- void loop()
- {
- uint8_t hall;
- uint8_t msg[3];
- uint16_t temp;
- hall = digitalRead(pinHall);
- if (hall == LOW)
- {
- hall = hallON;
- }
- else
- {
- hall = hallOFF;
- }
- if ((hall != hallAnt) || (millis() >= proxEnvio))
- {
- // Salva estado do sensor hall
- hallAnt = hall;
- // Indica transmissão
- digitalWrite (pinLED, HIGH);
- // Le a temperatura
- temp = leDS18B20();
- // Monta mensagem a enviar
- msg[0] = temp >> 8;
- msg[1]= temp & 0xFF;
- msg[2] = hall;
- // Envia
- Serial.print ("Transmitindo (");
- Serial.print (temp);
- Serial.print (' ');
- Serial.print ((char) hall);
- Serial.print ("): ");
- if (radio.write(msg, 3))
- Serial.println ("Ok");
- else
- Serial.println ("Erro");
- if (millis() >= proxEnvio)
- {
- // Programa próxima transmissão
- proxEnvio = millis() + tempoTx * 60000UL;
- }
- // Indica fim da transmissão
- digitalWrite (pinLED, LOW);
- }
- }
- // Leitura da temperatura
- // Retorna temperatura em décimos de grau
- // Considera que temos apenas um sensor conectado
- // e ele está com a configuração padrão
- // Ref: AN162 da Maxim
- uint16_t leDS18B20()
- {
- uint16_t valor;
- if (!OW_Reset())
- Serial.println("Nao achou sensor");
- OW_WriteByte (0xCC); // Skip ROM
- OW_WriteByte (0x44); // Start conversion
- delay(750); // aguarda fim da conversao
- OW_Reset();
- OW_WriteByte (0xCC); // Skip ROM
- OW_WriteByte (0xBE); // Read ScratchPAD
- valor = OW_ReadByte(); // LSB
- valor = (OW_ReadByte() << 8) + valor; // MSB
- OW_Reset(); // Nao queremos o restp
- valor = (valor * 100) / 16;
- return (valor+5)/10;
- }
- // OneWire reset
- // Retorna true se tem um sensor conectado
- uint8_t OW_Reset(void)
- {
- uint8_t resposta;
- setDQ(LOW);
- delayMicroseconds(480); // comanda reset
- setDQ(HIGH);
- delayMicroseconds(70); // aguarda sensor responder
- resposta = digitalRead(pinDS18B20); // le a resposta
- delayMicroseconds(240); // aguarda fim da resposta
- return resposta == LOW;
- }
- // OneWire Read Byte
- uint8_t OW_ReadByte(void)
- {
- uint8_t i, resp;
- for (i = 0; i < 8; i++)
- {
- // Pulso de 1uS abre janela para resposta
- setDQ(LOW);
- delayMicroseconds(1);
- setDQ(HIGH);
- // Dá um tempo para sensor colocar a resposta e a lê
- delayMicroseconds(10);
- resp = resp >> 1;
- if (digitalRead(pinDS18B20))
- {
- resp = resp | 0x80;
- }
- // Aguarda o final da janela
- delayMicroseconds(50);
- }
- return resp;
- }
- // OneWire Write Byte
- void OW_WriteByte(uint8_t valor)
- {
- uint8_t i;
- for (i = 0; i < 8; i++)
- {
- // Low inicia a janela
- setDQ(LOW);
- delayMicroseconds(1);
- if (valor & 0x01)
- {
- // Volta o nivel alto se for "1"
- setDQ(HIGH);
- }
- // Manter o bit até o final da janela
- delayMicroseconds(80);
- // Voltar ao repouso
- setDQ(HIGH);
- // Passar para o próximo bit
- valor = valor >> 1;
- }
- // Tempo de recuperação entre bytes
- delayMicroseconds(1);
- }
- // Controle da linha DQ do DS18B20
- void setDQ(uint8_t state)
- {
- if (state == LOW)
- {
- // LOW deve ser forçadp
- pinMode (pinDS18B20, OUTPUT);
- digitalWrite (pinDS18B20, LOW);
- }
- else
- {
- // HIGH é gerado pelo pullup interno
- pinMode (pinDS18B20, INPUT);
- digitalWrite (pinDS18B20, HIGH);
- }
- }
- from nrf24 import NRF24
- import time
- import datetime
- addrRx = "DLogr"
- radio = NRF24()
- radio.begin(0,0,25,24)
- radio.setPayloadSize(3)
- radio.openReadingPipe(1,addrRx)
- radio.startListening()
- radio.printDetails()
- try:
- while True:
- pipe = [0]
- if radio.available(pipe, False):
- dado = []
- radio.read(dado)
- agora = datetime.datetime.now().strftime("%d/%m/%y %H:%M:%S ")
- temperatura = ((dado[0]*256.0) + dado[1]) / 10.0
- linha = "{0} {1:c} {2:.1f}".format(agora, dado[2], temperatura)
- print linha
- log = open("dado.log", 'a')
- log.write(linha)
- log.write('\n')
- log.close()
- time.sleep(0.1)
- except KeyboardInterrupt:
- sys.exit(0)
4 comentários:
Boa tarde Daniel... primeiramente gostaria de parabeniza-lo pelo poste e pelo otimo trabalho que foi feito. No entanto apesar de esta muito bem feito eu tenho duvidas.
1- eu preciso fazer alguma configuração nos pinos SPI do Raspberry?
2-Voce poderia dizer qual pino do módulo foi conectado em qual pino do RPI?
Grato.
Ailton, dê uma olhada na Parte 1: http://dqsoft.blogspot.com.br/2015/10/usando-o-nrf24l01-com-o-raspberry-pi-um.html. Aqui no blog tem também mais informações sobre o nRF24L01, dê uma olhada nos post antigos,
Ola Daniel... Depois de muito penar conseguir com a ajuda de seu post fazer o codigo ser executado. Porem estou usando um raspberry pi 2 e na impressao dos detalhes do modulo esta todos os endereços zerados, vc saberia como devo conectar o mudulo a esse raspi? ja olhei em varios sites e sempre fica zerado.
Grato.
Em princípio a conexão é a mesma em todos os modelo. Eu fiz o teste com um B+.
Postar um comentário