1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197
| /***************** TRANSMETTEUR POUR ALARME D'EVACUATION ********************
L'ATtiny85 et le module radio sont normalement en mode sommeil.
Au réveil du WDT, celui-ci détecte s'il y a changement d'état
du pin défini pour déclencher l'alarme.
** Hardware configuration **
pour moi, voir "Watchdog Timer et ATtiny85.docx"
ATtiny85 Pin map with CE_PIN 3 and CSN_PIN 4
+-\/-+
NC ---| PB5 1|o |8 Vcc --- |nRF24L01 VCC, pin2
nRF24L01 CE, pin3 ---| PB3 2| |7 PB2 --- |nRF24L01 SCK, pin5
nRF24L01 CSN, pin4 ---| PB4 3| |6 PB1 --- |nRF24L01 MOSI, pin7
nRF24L01 GND, pin1 ---| GND 4| |5 PB0 --- |nRF24L01 MISO, pin6
+----+
*/
#include "RF24.h"
#include "nRF24L01.h"
#include <avr/sleep.h>
#include <avr/power.h>
#include <avr/wdt.h>
byte compteur=40; // émet 40 fois un signal d'alarme d'une durée de 0.5sec. soit un total d'env.: 20secondes.
#ifndef cbi
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#endif
#ifndef sbi
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
#endif
#define CE_PIN 3
#define CSN_PIN 4
int declencheur = 2; // Déclare le déclencheur sur le pin 2 branché en commun avec SCK.
int pinalarme = 0; // pinalarme branché en commun avec MOSI (broche 5), pin 0 de l'attiny85.
byte alarme;
volatile boolean f_wdt = 1;
//************* Configuration radio *****************************/
RF24 radio (CE_PIN, CSN_PIN); // RF24 radio(3,4);
const byte rxAddr[6] = "01924";
//*****************************************************************/
void setup(void)
{
pinMode(pinalarme,OUTPUT);
pinMode(declencheur, INPUT_PULLUP); // active pullup
digitalWrite(declencheur, LOW);
setup_watchdog(8); // en sommeil environ 4 secondes
}
void emission()
{
delay(250);
radio.begin();
radio.setChannel(1);
radio.setPALevel(RF24_PA_HIGH);
radio.setDataRate(RF24_250KBPS);
radio.setRetries(1,15);
radio.setCRCLength(RF24_CRC_8);
radio.openWritingPipe(rxAddr);
radio.stopListening();
delay(250);
}
void reception()
{
radio.begin();
radio.setChannel(1);
radio.setPALevel(RF24_PA_MIN);
radio.setDataRate(RF24_250KBPS);
radio.setRetries(15,15);
radio.setCRCLength(RF24_CRC_8);
radio.openReadingPipe(1,rxAddr);
radio.startListening();
}
void alarme10s()
{
pinMode(pinalarme,OUTPUT);
digitalWrite(pinalarme,HIGH); // Envoie une tension interne de +3.7v pendant 10 sec. sur le pin 2
delay(10000); // pour permettre le changement d'état de la boucle de l'alarme pour son déclenchement.
digitalWrite(pinalarme,LOW);
pinMode(pinalarme,INPUT);
}
void loop()
{
//******** Lecture des paquets qui arrivent au récepteur ********
{
if (f_wdt==1) // attend la fin de la tempo du watchdog
{
f_wdt=0; // reset flag
}
reception(); // positionne le prog. en mode réception.
delay(100); // Délai pour permettre de bien se positionner.
{
radio.read(&alarme, 6);
delay(100); // On attend pour lire correctement.
}
}
//******** Lecture de l'état du pin 2 pour définir l'action suivante à mener ********
{
// val = digitalRead(declencheur); // à utiliser si nécessaire, je ne sais pas.
if (digitalRead(declencheur == HIGH))
{
digitalWrite(declencheur, 1);
}
if (digitalRead(declencheur == LOW))
{
digitalWrite(declencheur, 0);
}
}
//****************** Traitement des informations *****************/
//******** Si l'alarme est déclenchée:
if (radio.available() || declencheur==1)
delay(100);
if (radio.available() || declencheur==1) // anti-rebond.
{
{
alarme10s(); // envoie un signe + pendant 10 sec. sur la pin 2
delay(100); // fait une pause avant de passer à l'étape suivante.
{
//********** Ecriture d'un déclenchement d'alarme vers les émetteur environnants ******
emission(); // positionne le prog. en mode émission pour envoyer un signal pendant 20 sec.
delay(100); // fait une pause avant de passer à l'étape suivante.
while (compteur>0)
{
delay(250); // fait une pause
radio.write("alarme", 6);
delay(250); // fait une pause
compteur=compteur-1;
}
compteur=40;
}
//********** Le programme se positionne en Mode réception et s'endort.
reception(); // le prog. se positionne en mode réception.
delay(100); // fait une pause
system_sleep(); // l'ensemble s'endort
}
}
//********* Si l'alarme n'a pas été déclenchée: Mode réception et s'endort.
if ( !radio.available() && declencheur==0)
delay(100);
if ( !radio.available() && declencheur==0) // anti-rebond.
{
reception(); // le prog. se positionne en mode réception.
delay(100); // fait une pause
system_sleep();
}
}
/* Système de jeu dans l'état de sommeil
Système se réveille quand le watchdog est dépassée*/
void system_sleep()
{
cbi(ADCSRA,ADEN); // switch Analog to Digitalconverter OFF
power_all_disable (); // power off ADC, Timer 0 and 1, serial interfacesleep_enable();
radio.powerDown(); //arrêt de lalimentation du module nrf24l01+
set_sleep_mode(SLEEP_MODE_PWR_DOWN); // sleep mode is set here
sleep_enable();
sleep_mode(); // Système dort ici
sleep_disable(); // Système continue l'exécution ici quand chien de garde a terminé
radio.powerUp(); // réalimente le module nrf24l01+
power_all_enable(); // power everything back on
sbi(ADCSRA,ADEN); // commutateur analogique à Digitalconverter ON
}
/* 0=16ms, 1=32ms,2=64ms,3=128ms,4=250ms,5=500ms
6=1 sec,7=2 sec, 8=4 sec, 9= 8sec*/
void setup_watchdog(int ii)
{
byte bb;
int ww;
if (ii > 9 ) ii=9;
bb=ii & 7;
if (ii > 7) bb|= (1<<5);
bb|= (1<<WDCE);
ww=bb;
#if defined( __AVR_ATtinyX5__ )
MCUSR &= ~(1<<WDRF);
// commencer séquence cadencée
WDTCR |= (1<<WDCE) | (1<<WDE);
// définir une nouvelle valeur de temporisation du watchdog
WDTCR = bb;
WDTCR |= _BV(WDIE);
#endif
}
// la détection de l'émetteur est exécutée lorsque la surveillance du watchdog a expiré.
ISR(WDT_vect)
{
f_wdt=1; // reset du watchdog
} |
Partager