这个项目在我把好友放入搜索空间后不久就开始了。现在,在您开始吓唬并呼吁执法之前,我的“Crawlspace Buddy”在室外有4个温度传感器--1个关键位置的爬网空间。当温度变得太低时,用这些读数来控制辅助加热器,以防止我110岁的房子里冻住管子。还有一个安装在托梁上的超声波距离传感器,用于测量发生淹水时的水位。那个项目重新点燃了建立我自己的气象站的长期梦想。现在它已经变得相当复杂的系统,有3个独立的微控制器进行通信,并最终将数据发送到互联网。 我开始使用我现有的DHT22温度/湿度传感器和Arduino Nano(我记录中,我并不是DHT传感器的忠实粉丝,并且最终会升级)。然后我制作了一个“tipping斗“雨量计,紧接着一个风速计。风速计和雨量计都使用霍尔效应传感器和磁铁进行检测。我还增加了气压模块和实时时钟。接下来,我制作了一个通风箱,以容纳DHT和气象站电路,并将其全部安装在离我家大约100英尺的围栏上。所有数据仅在此阶段通过蓝牙发送到我的手机,所以我还添加了一个RF发射器(433Mhz)。
气象站传感器
气象站电路 - 纳米,RTC模块,气压模块安装在原板上。
“倾翻斗”雨量计机制
然后我建立了数据接收器。我使用了超外差射频接收器模块,为它建了一个抛物面天线,并将它连接到我桌上已有的Arduino MEGA类型的板上,监控我的“Crawlspace Buddy”,并解析/处理数据。我在那时决定,MEGA将成为我计划的几个家庭监测项目的数据/控制中心。MEGA在下面的照片中,埋在MEGA原始屏蔽下,以及安装在UNO屏蔽上的LCD。
显示Crawlspace Buddy Temps-室外,炉子,杂物间和厨房的MEGA
所示的抛物面天线板不是我目前使用的超外差射频接收器
最后,我需要实施项目链中的最后一环 - 将其连接到互联网,这样我就可以在世界任何地方监视我家的天气,因为......好的,谁不需要这种能力?在用ESP8266模块和分线板几个无用的时间后,我咨询了Arduino论坛,并决定寻找一个单独的基于ESP8266的开发板。根据我读过的几篇文章,我决定NodeMCU制作的一块电路板听起来就像是我的最佳选择,并且在亚马逊的搜索中发现了一个包含NodeMCU ESP8266电路板,DHT11温度/湿度传感器以及a.96的“气象站工具包” “OLED显示屏,它将从”Weather Underground“中检索天气和预报数据,从时间服务器获取正确时间,然后将温度和湿度读数从DHT发送到” 并将必要的代码添加到NodeMCU程序中。每10分钟一次,它从MEGA收到一份数据摘要,并将其提交到“Thingspeak”网站。这里是我的公共频道与我的实时天气数据的链接。 https://thingspeak.com/channels/463187
Weatherpeak上显示天气数据
NodeMCU ESP8266物联网天气设备/气象站网络接口
正如任何复杂项目的典型情况一样,在开发过程中必须解决一些问题。对于这个项目项目来说,室外电台的电源是一个主要问题。我正在使用3.7v 18650型电池(2)为监控站供电。我最终希望纳入太阳能充电,但那会晚一些。目前,我只是监测电压,并在需要时更换电池。我有几套,所以我总是保持一套收费。这些电池已被证明具有大致线性的工作范围,用于在满充电时施加8.4伏的电压,以7.4伏放电,电压以更快的速率开始下降。我使用降压转换器将其降至系统调节的5v,并且这5伏也通过OptoMOS继电器连接到升压调节器的输入端以输出9。6v到发射机。此供应仅在每分钟实际传输一次数据包期间打开。(每个数据包发送2次以防止数据丢失,因为这只是单向RF链路。)为了最大限度地延长电池寿命,我还实现了睡眠/节能,将电阻器与Nano上的LED断开连接并消除板上监管机构,因为我正在向董事会交付受监管的5。这使得我的功耗在节电模式下降至约11毫安,正常工作时降至16毫安,在射频传输期间降至约24毫安。由于风速和雨量读数都是由中断产生的,为了保持风速测量的准确性,Nano只有在风速计没有输入脉冲10秒的情况下才进入省电模式。有了这个当前的设置,在我必须更换它们之前,我会在充满电的电池组上使用约48-60小时。风对潜在的电池寿命有显着的影响,因此范围很广。 这个项目已经用了大约3个月的时间,并且可能还需要几个月才能完全实施。我想添加一个风向标来监测风向。时间允许时发布原理图和代码。哦,还有“Rube Goldberg”头衔的原因?我的儿子称这个气象站为“疯狂的装置”,它确实是一个电路/设备的大杂烩,所以这个名字似乎很适合。另一个“功能”,虽然我很少打开由于大量电流消耗,是一套紫外线LED。他们照在风速计上,一杯风速计涂上绿色荧光漆。晚上打开时,你会看到一个绿色的光球来回摆动。这样做的目的是为了给邻居和路人一些想法!
Arduino的数据接收器代码
#include
#include
#include
#include
#include
#include
#define TIMEOUT 5000
// SoftwareSerial dataSerial(39,38); // RX,TX const int rs = 2 ,en = 3 ,d4 = 4 ,d5 = 5 ,d6 = 6 ,d7 = 7 ; const String THINGSPEAK_API_WRITE_KEY = “PWLOULJXD5GO8RWP” ; LiquidCrystal lcd (rs ,en ,d4 ,d5 ,d6 ,d7 ); INT
alarmLevel = 7000 ;
int devCount ;
int swPin = 11 ;
int RlyPin = 8 ;
const int receive_pin = 9 ; //针对来自发射器在
天井中的
天气数据的RF接收器的引脚// bool OKtoPost;
bool HeatControl ; // ON状态表示温度控制处于活动状态
bool SuspendData ;
浮动 t1 , t2 , t3 , t4 ;
/ ******************* ******************* /
//数据线插入到Arduino的引脚12
#define ONE_WIRE_BUS 12
/ ************* ************************************************** ***** / /
设置一个oneWire实例与任何OneWire设备进行通信
//(不仅仅是Maxim / Dallas温度IC)
OneWire oneWire (ONE_WIRE_BUS );
/ ******************* ******************* /
//将我们的oneWire参考传递给Dallas Temperature。
DallasTemperature 传感器(&oneWire );
/ ******************* ******************* /
DeviceAddress Probe01 = { 0x28, 0xFF, 0x67, 0x18, 0x23, 0x17, 0x04, 0xBF }; //Outdoor Sensor
DeviceAddress Probe02 = { 0x28, 0xFF, 0xF5, 0x22, 0x23, 0x17, 0x04, 0xD8 }; //Under Stairs Sensor
DeviceAddress Probe03 = { 0x28, 0xFF, 0xA9, 0xE7, 0x22, 0x17, 0x04, 0x7F }; // Utility Room
DeviceAddress Probe04 = { 0x28, 0xFF, 0x7D, 0x18, 0x23, 0x17, 0x04, 0x7E };// Under Kitchen
long delayMS;
long OutdoorTrig = 25; // Trigger Relay if outdoor temp is below
long OutdoorCut = 26; // Cutoff Relay if outdoor temp is above
long SinkTrig = 35;
long SinkCut = 38;
struct package
{
float temperature = 0;
float humidity = 0;
float barometer = 0;
byte wind = 0;
byte maxWind = 0;
byte windPacketPeak = 0;
float rain = 0;
float rainRate = 0;
float randDate = 0;
float randTime = 0;
float battery = 0;
long packetID = 0;
float CKSum = 1;
};
typedef struct package Package;
Package data;
Package lastData;
struct postingPackage{
float temperature = 0;
float barometer = 0;
float humidity = 0;
uint8_t avgWind = 0;
uint8_t peakWindThisRead = 0;
float rainThisRead = 0;
float rainRate = 0;
float battV = 0;
};
typedef struct postingPackage PostingPackage;
PostingPackage dataToPost;
bool wxMode;
void setup() {
pinMode(13, OUTPUT);
pinMode(RlyPin, OUTPUT);
pinMode(swPin, INPUT);
Serial.begin(115200);
Serial1.begin(57600);
HeatControl = false;
SuspendData = false;
//OKtoPost = false;// becomes true after first temperature readings
//Serial.println("Dallas Temperature IC Control Library Demo");
// Start up the library
sensors.begin();
lcd.begin(16, 2);
// Print a message to the LCD.
lcd.print("Pipe Protector 2");
lcd.setCursor(0, 1);
devCount = sensors.getDeviceCount();
Serial.print("Device Count: ");
Serial.println(devCount);
delayMS = 60000;// WIll increase to 60000 ms when finished. One reading per minute is plenty
randomSeed(analogRead(0));
vw_set_rx_pin(receive_pin);
vw_setup(2000); // Bits per sec
vw_rx_start(); // Start the receiver PLL running
wxMode = true;// for now, we'll start in weather mode
//lastData.
//sensors.requestTemperatures();
}// End Setup
void stateSwitch(void) {
/* if(delayMS >=50000){
delayMS=10000;
}
else{
delayMS=60000;
}*/
}
bool SuspendToggle(void) {
SuspendData = !SuspendData;
return (SuspendData);
}
void sendStatus(void) {
String myStr;// Variable to hold all values as text string for sending over serial port
myStr = OutdoorTrig;
myStr.concat(",");
myStr.concat(OutdoorCut);
myStr.concat(",");
myStr.concat(SinkTrig);
myStr.concat(",");
myStr.concat(SinkCut);
myStr.concat(",");
myStr.concat(delayMS);
myStr.concat(",");
myStr.concat(HeatControl);
myStr.concat(",");
myStr.concat(SuspendData);
Serial.println(myStr);
}
int HighestTemp() {
int retVal;
for (int cnt = 0; cnt < devCount; cnt++) {
//int trVal = GetFTempDec(cnt);
int trVal = sensors.getTempFByIndex(cnt);
if (cnt == 0) {
retVal = trVal;
}
//Serial.println(sensors.getTempFByIndex(cnt));
if (retVal < trVal) {
retVal = trVal;
}
}
// checkRange(retVal);
return (retVal);
}
float LowestTemp() {
float retVal;
for (int cnt = 0; cnt < devCount; cnt++) {
//int trVal = GetFTempDec(cnt);
int trVal = sensors.getTempFByIndex(cnt);
if (cnt == 0) {
retVal = trVal;
}
//Serial.println(sensors.getTempFByIndex(cnt));
if (retVal > trVal) {
retVal = trVal;
}
}
// checkRange(retVal);
return (retVal);
}
float printTemperature(DeviceAddress deviceAddress)
{
float retVal = sensors.getTempF(deviceAddress);
if (retVal == -196.60)
{
Serial.print(F(""));
}
else
{
Serial.print(retVal);
Serial.print(F(" F "));
return (retVal);
//Serial.print(DallasTemperature::toFahrenheit(tempC));
}
}// End printTemperature
void serial1Check(){
String myCmd;
if(Serial1.available() > 0){
Serial.println("You are there");
myCmd = Serial1.readString();
Serial.println(myCmd);
}
Serial.println("You ARE LEAVING!!");
}
void serialCheck(){
if (Serial.available() >> 0) {
String NewVal = Serial.readString();
lcd.clear();
if (NewVal == "+") {
//lcd.print("HEAT ON");
// delay( 2000);
HeatControl = true;
}
else if (NewVal == "-") {
lcd.print(F("HEAT OFF"));
HeatControl = false;
//delay (2000);
}
else if (NewVal == "S") {
sendStatus;
//delay (2000);
}
else {
long secs = NewVal.toInt();
delayMS = secs * 1000;
//lcd.clear();
//lcd.print(delayMS);
//delay (2000);
}
// digitalWrite(13,HeatControl);
}
}
void pipeProtect(){
sensors.requestTemperatures(); // Send the command to get temperature readings
/********************************************************************/
bool RelayOn;
RelayOn = digitalRead(RlyPin);
digitalWrite(13, HeatControl); // Board LED indicates Heat Control Status
if (HeatControl == true) {
//if (!(t1> OutdoorTrig && t4>SinkTrig)){
//if (digitalRead(RlyPin)==false){// Heat status is OFF
if (t1 > OutdoorCut) {
RelayOn = false;
}
if (t4 > SinkCut) {
RelayOn = false;
}
if (t1 < OutdoorTrig) {
RelayOn = true;
}
if (t4 > 41) { //Absolute cutoff if temp at sink is above 41. No need to heat more that?
RelayOn = false;
}
if (t4 < SinkTrig) {
RelayOn = true;
}
digitalWrite(RlyPin, RelayOn);
// }
}
else {
digitalWrite(RlyPin, false);
}
if (SuspendData == false) {
Serial.println(F(" ** Temperatures Read **"));
Serial.print(F("Outdoor temp. is: "));
t1 = printTemperature(Probe01);
Serial.println();
Serial.print(F("Near Furnace temp. is: "));
t2 = printTemperature(Probe02);
Serial.println();
Serial.print(F("Under Utility Room temp. is: "));
t3 = printTemperature(Probe03);
Serial.println();
Serial.print(F("Under Sink temp. is: "));
t4 = printTemperature(Probe04);
String OutLogic;
OutLogic = "*&*";
if (digitalRead(RlyPin) == HIGH) {
OutLogic.concat("+");
}
else {
OutLogic.concat("-");
}
Serial.println();
Serial.println();
Serial.println(OutLogic);
Serial.println();
}
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(F("O="));
lcd.print(t1);
lcd.print(F(" F="));
lcd.print(t2);
lcd.setCursor(0, 1);
lcd.print(F("U="));
lcd.print(t3);
lcd.print(F(" K="));
lcd.print(t4);
}
void loop(void)
{
static bool notFirstIteration;
static long nextOneWireMillis;
if (!notFirstIteration) {// Occurs on first run.
nextOneWireMillis = millis() + delayMS;
pipeProtect();
notFirstIteration = true;
}
if (wxMode == true) {// If monitoring weather station
//Serial.println("WXMODE TRUE");
rxSubLoop();
delay(100);
if(Serial1.available()>0){
Serial.println("Something Returned I think");
while(Serial1.available()){
char c = Serial1.read();
Serial.print(c);
}
Serial.println("nDDDDn");
}
}
// call sensors.requestTemperatures() to issue a global temperature
// request to all devices on the bus
/********************************************************************/
//Serial.print("**Requesting temperatures...");
serialCheck();//检查传入命令的串行端口
// serial1Check(); //Serial.println("Out of Serial1Check“); if (nextOneWireMillis <= millis ()){ //这段是程序管道保护部分nextOneWireMillis = millis ()+ delayMS ; pipeProtect (); //你可以在同一条总线上有多个DS18B20。// 0表示线上的第一个IC // delay(delayMS + 200); } }
Arduino Mega的数据接收器代码
bool CheckData () {
float CkVal = data 。湿度+ 数据。温度+ 数据。晴雨表+ 数据。风+ 数据。雨+ 数据。maxWind + 数据。rainRate + 数据。packetID + 数据。windPacketPeak + 数据。randDate + 数据。randTime +
数据。电池;
布尔CKB = ((CkVal == 数据。CKSUM )&& (数据。CKSUM > 30000 )); if (ckB == false ){ data 。温度= 0 ; 数据。湿度= 0 ; 数据。气压计= 0 ; 数据。风= 0 ; 数据
。雨 = 0 ;
数据。CKSum = 1 ; } return (ckB ); } float rainFallRate (){ } // END rainFallRate()********************** float windChill (float mTempF ,float mMPH ){ //计算风寒如果温度<50,风力> 3 浮动Twc ; 如果((mTempF < 50.0 )&& (mMPH > 3.0 ))
{
Twc = 35.74 + 0.6215 * mTempF - 35.75 * pow(mMPH, 0.16) + 0.4275 * mTempF * pow(mMPH, 0.16);
}
else
{
Twc = mTempF;// return temp unchanged if no wind chill
}
return (Twc);
}// End windChill()---------------------------------------------
float RandianDate(byte dayOfMonth, byte month, byte year) { // Date to integer format - 01-01-1980 becomes 111180
String myStr;
byte myDay = dayOfMonth + 10;// Adding 10 to values to make all 2 digit. No need to do the years.
byte myMonth = month + 10;
byte myYear = year + 10;
//month += 10;
myStr.concat(myMonth);
myStr.concat(myDay);
myStr.concat(myYear);
return (myStr.toFloat());
//return(0);
}
float RandianTime(byte hours, byte minutes, byte seconds) { // Time to integer format - 14:56:03 becomes 145603
String myStr;
hours += 10; // Adding 10 to these values to ensure all are 2 digits.
minutes += 10; // Will subtract 10 again when decoded
seconds += 10;
myStr.concat(hours);
myStr.concat(minutes);
myStr.concat(seconds);
return (myStr.toFloat());
//return(0);
}
String RandianToDate(float RandDate) {
String msg = "";
msg.concat(RandDate);
String token;
String myDt;
int trans;
for ( int cnt = 0; cnt < 6 ; cnt++) {
token.concat(msg.charAt(cnt));
if ((cnt == 1) || (cnt == 3)) {
trans = token.toInt() - 10;
if (trans < 10) {
myDt.concat("0");
}
myDt.concat(trans);
myDt.concat("-");
token = "";
}
else if (cnt == 5) {
trans = token.toInt() - 10;
myDt.concat("20");
myDt.concat(trans);
}
}
return (myDt);
}
String RandianToTime(float RandTime) {
String msg = "";
msg.concat(RandTime);
String token;
String myDt;
int trans;
for ( int cnt = 0; cnt < 6 ; cnt++) {
token.concat(msg.charAt(cnt));
if ((cnt == 1) || (cnt == 3) || (cnt == 5)) {
trans = token.toInt() - 10;
if (trans < 10) {
myDt.concat("0");
}
myDt.concat(trans);
if (cnt < 5) {
myDt.concat(":");
}
token = "";
}
}
return (myDt);
}
void showReport(void) {
Serial.print(F("nTemperature: "));
Serial.print(data.temperature);
Serial.print(F(" Degrees FnHumidity: "));
Serial.print(data.humidity);
Serial.print(F("% nBarometer: "));
Serial.print(data.barometer);
Serial.print(F(" Inches Hg nWind (current): "));
Serial.print(data.wind);
Serial.print(F(" Mphn Feels like "));
Serial.print(windChill(data.temperature, data.wind));
Serial.print(F(" Wind ChillnPeak Wind this Read: "));
Serial.print(data.windPacketPeak);
Serial.print(F(" MphnPeak Wind Today: "));
Serial.print(data.maxWind);
Serial.print(F(" MphnRainfall: "));
Serial.print(data.rain);
Serial.print(F(" InchesnRain Rate: "));
Serial.print(data.rainRate);
Serial.print(F(" Inches per HournnPacket ID: "));
Serial.print(data.packetID);
//Serial.print("nCheck Sum: ");
//Serial.println(data.CKSum);
Serial.print(F("nDate: "));
Serial.println(RandianToDate(data.randDate));
Serial.print(F("Time: "));
Serial.println(RandianToTime(data.randTime));
Serial.println("");
Serial.print(F("Battery: "));
Serial.print(data.battery);
Serial.println(F(" Voltsnn****************************************n"));
}
void dataPrep() { // Process incoming data, prepare dataToPost for transmission to network interface. Average some values
//static bool firstSeries;
static int avgCounter;
static float tempAvg;
static int windAvg;
static int windPeak;
static int windRing[10];
static float tempRing[10];// the "Ring arrays keep the last 10 readings for averaging, constatly rotating through
static float rainVals[10];
static float barVals[10];
static float humVals[10];
float tempTot;
float batt;
float rainfallRate;
static int clearCount;
if (avgCounter == 0) { // Reset some vals for next post
windPeak = 0;
for (int ct; ct < 10 ; ct++) {
rainVals[ct] = 0;
tempRing[ct] = 0;
tempTot = 0;
}
}
windRing[avgCounter] = data.wind;
if (data.windPacketPeak > windPeak) {
windPeak = data.windPacketPeak;
}
tempRing[avgCounter] = data.temperature;
humVals[avgCounter] = data.humidity;
barVals[avgCounter] = data.barometer;
rainVals[avgCounter] = data.rain;// - lastData.rain;// Rain measurement from station is a daily total-we need to calculate rain per package
String trTime = RandianToTime(data.randTime);
bool saveNOW = (trTime.charAt(4) == '0') && (avgCounter > 0);// will cause update at least every 10 packets, but should keep it at 00 minutes
if ((avgCounter == 9)|| (saveNOW)) { //Last of data packets. Prepare values, insert into dataToPost, then send to Network Interface
float rainTot;
float windTot;
float humTot;
float barTot;
// int tempTot;
for (int ct = 0; ct < avgCounter+1 ; ct++) {
rainTot = rainVals[ct];// for rain, just use last reading sent. No need to average, will send as total for day
windTot += windRing[ct];
tempTot += tempRing[ct];
barTot += barVals[ct]-28.00;// Subtracting out lowest likely reading. Averaging difference to increase accuracy in the event of errors
humTot += humVals[ct];
/* Serial.println();
Serial.print(tempRing[ct]);
Serial.print(" ");
Serial.println(tempTot);
//Serial.println();
*/
}
avgCounter ++;// increment for calculating averages (due to zero based array counter)
dataToPost.battV = data.battery;
dataToPost.temperature = tempTot / float(avgCounter);
dataToPost.barometer = (barTot / float(avgCounter))+28.00;
dataToPost.humidity = humTot / float(avgCounter);
dataToPost.avgWind = windTot / (avgCounter);
dataToPost.peakWindThisRead = windPeak;
dataToPost.rainThisRead = rainTot;
dataToPost.rainRate = data.rainRate;
Serial.println(F("n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"));
Serial.print(F("nData to Post:n"));
Serial.println(dataToPost.temperature);
Serial.println(dataToPost.barometer);
Serial.println(dataToPost.humidity);
Serial.println(dataToPost.avgWind);
Serial.println(dataToPost.peakWindThisRead);
Serial.println(dataToPost.rainThisRead);
Serial.println(F("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~n"));
delay (2000);
String url = "@";// add start character
url += String(dataToPost.temperature);
url += ",2=";
url += String(dataToPost.humidity);
url += ",3=";
url += String(dataToPost.avgWind);
url += ",4=";
url += String(dataToPost.peakWindThisRead);
url += ",5=";
url += String(dataToPost.rainThisRead);
url += ",6=";
url += String(dataToPost.barometer);
url += ",7=";
url += String(dataToPost.rainRate);
url += ",8=";
url += String(dataToPost.battV);
url += "~";// add end character
String datStr;
datStr.concat(dataToPost.temperature);
datStr.concat(",");
datStr.concat(dataToPost.humidity);
datStr.concat(",");
datStr.concat(dataToPost.avgWind);
datStr.concat(",");
datStr.concat(dataToPost.peakWindThisRead);
datStr.concat(",");
datStr.concat(dataToPost.rainThisRead);
datStr.concat(",");
datStr.concat(dataToPost.barometer);
Serial.println (datStr);
Serial1.print(url);// This line is where data is submitted to Network Interface (NodeMCU)
delay(10000); // Lets wait a little while then
Serial1.print(url);// Send again to minimize data gaps due to errors in transmission
avgCounter = -1;
// Serial.print("IN the Test");
}
avgCounter ++;
if (avgCounter > 9) {
avgCounter = 0;
}
}
void simulateData() {
static long cnt;
data.temperature = t1;
data.humidity = t2;
data.barometer = t3;
data.wind = random(t4);
data.maxWind = t4 + random(0, 21);
data.windPacketPeak = t4 + random(0, 21);
data.rain = t1;
data.rainRate = t2;
data.randDate = 101218;
data.randTime = 131313;
data.packetID = cnt;
cnt ++;
}
void rxSubLoop(void) {
// Serial.println("In the rxSubLoop");
uint8_t buf[sizeof(data)];
uint8_t buflen = sizeof(data);
//Serial.println("in Loop");
//vw_wait_message();
if (vw_have_message()) // Is there a packet for us?
{
vw_get_message(buf, &buflen);
memcpy(&data, &buf, buflen);
// delay(500);
bool myCkV = CheckData();// Check for valid Packet-return true if valid
if (myCkV == true) {
if (data.packetID != lastData.packetID) {
dataPrep();
showReport();
lastData = data;
}
}
else {
Serial.print(F("Bad Packet"));
Serial.print(F("nn****************************************nn"));
}
}
/*else{//A place to add a line for data simlation-for devel purposes
// This ELSE clause will be commented out after new transmitter comes in
simulateData();
dataPrep();
showReport();
lastData = data; 延迟(30000); //希望每隔1分钟模拟一次数据包 //Serial.println("Exiting RX_Lib“); } * / }
Arduino的气象站传感器/变送器代码
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #define DS3231_I2C_ADDRESS 0x68
- #define OFF false
- #define ON true
- #define TOGGLE 2 //如果您想切换一个值而不是ON / OFF / TRUE / FALSE,则使用此选项以获得无线电功能
- dht myDHT ; //创建DHT传感器实例
- Adafruit_MPL3115A2 baro = Adafruit_MPL3115A2 (); //创建气压传感器的实例
- time_t myTime ; //是系统时间对象time_t upTime ; //包含时间系统定时器被设置为const uint8_t ledPin = 13 ; const uint8_t transmit_pin =
-
-
-
- 11;
- const uint8_t rainPin = 2;// Wind and rain readings handled by interrupts
- const uint8_t windPin = 3; // Wind and rain readings handled by interrupts
- const uint8_t dhtPin = 4;
- const uint8_t rfPower = 5;// control line for RF Power Relay
- const float rainPerTip = .0202;// Specific to dimensions of rain gauge built
- const int timeComp = -1516;// Value for periodic time compensation. After this many seconds,
- // 1 second adjustment is added or subtracted for on the fly Sys Clock a Correction
- // Value was computed after 24 hours running, to determine approximate adjustment value.
- // This may be further refined as I use unit for longer periods of time.
- float rainInches;
- volatile long rainLastMillis; // Millis of previous rain "tip"
- volatile long rainMillis; // Millis of current rain tip
- float windAdj = 9.5; //default value for wind speed (Anemometer) adjustment
- volatile long windLastMillis; // last millis reading from anemometer
- volatile long revTime; // time in millis of current anemometer revolution
- volatile int f_wdt = 1;
- volatile long nextSleepMillis;
- volatile long wokeUpMillis;
- long xmitRate = 60000; // xmitRate is how often packets will be transmitted, in milliseconds.
- int tipCount; // Rain gauge bucket "tips", .0202 inch per tip for my gauge. Resets at midnight
- float tempDHT; // Temperature from DHT
- float humDHT; // Humidity from DHT
- float curWindMPH; // Calculated wind speed
- float topWind;
- bool needsReset; // Set to true at 11:59 PM, to trigger reset at midnight
- bool baroSensorPresent; // Set to true if barometric pressure sensor is detected at startup
- long timeCompTrigger;// value of next time compensation in millis
- bool serialDump;
- bool testMode;
- byte testMinutes = 2;
- byte ckHour;// ckHour and ckMinute are used to see if time to reset (at midnight)
- byte ckMinute;
- byte ckSecond;
- volatile bool beenAsleep;
- struct package
- {
- float temperature ;
- float humidity ;
- float barometer ;
- byte wind ;
- byte maxWind;
- byte windPacketPeak;
- float rain ;
- float rainRate;
- float randDate;
- float randTime;
- float battery;
- long packetID;
- float CKSum ;
- };
- typedef struct package Package;
- Package data;
- //DHT dht(DHTPIN, DHTTYPE);
- void setup()
- {
- testMode = true; // Will start in test mode, this will time out in 5 minutes. Helps aim antenna
- beenAsleep = false;
- serialDump = testMode;
- // Initialise the IO and ISR
- vw_set_tx_pin(transmit_pin);
- vw_set_ptt_inverted(true); // Required for DR3100
- vw_setup(2000); // Bits per sec
- Serial.begin(9600);
- Serial.println(F("Working to setup"));
- Wire.begin();
- //serialDump = false;
- //serialDump = true;
- baroSensorPresent = true;
- if (! baro.begin()) {
- Serial.println(F("Couldnt find sensor"));
- baroSensorPresent = false;
- //return;
- }
- else {
- baro.write8(0x2D, 0x23);// calibration for altitude
- }
- pinMode (rainPin, INPUT_PULLUP);
- pinMode (dhtPin, INPUT);
- pinMode(ledPin, OUTPUT);
- pinMode (windPin, INPUT_PULLUP);
- pinMode(rfPower, OUTPUT);
- attachInterrupt(0, rain_Count, FALLING);// Define interrupt pins and processes required
- attachInterrupt(1, wind_Count, FALLING);
- //needsReset = true;// used in testing only
- tipCount = 0;// Initial value 0 "tips", 0 inches of rain
- rainInches = 0;
- revTime = 0;
- readDHT();
- /*** Setup the WDT ***/
- /* Clear the reset flag. */
- MCUSR &= ~(1 << WDRF);
- /* In order to change WDE or the prescaler, we need to
- set WDCE (This will allow updates for 4 clock cycles).
- */
- WDTCSR |= (1 << WDCE) | (1 << WDE);
- /* set new watchdog timeout prescaler value */
- WDTCSR = 1 << WDP0 | 1 << WDP3; /* 8.0 seconds */
- /* Enable the WD interrupt (note no reset). */
- WDTCSR |= _BV(WDIE);
- delay(2000);// Delay to prevent re-read of DHT prematurely after startup
- radio(OFF);
- } // END Setup() *******************
- //!!!!!!!!!!!!!!!!!! The following 3 functions are used by RTC. DO NOT CHANGE !!!!!!!!!!!!!!!!!!!
- byte decToBcd(byte val)
- {
- return ( (val / 10 * 16) + (val % 10) );
- }
- // Convert binary coded decimal to normal decimal numbers
- byte bcdToDec(byte val)
- {
- return ( (val / 16 * 10) + (val % 16) );
- }
- void readRTCTime(byte *second,
- byte *minute,
- byte *hour,
- byte *dayOfWeek,
- byte *dayOfMonth,
- byte *month,
- byte *year)
- {
- Wire.beginTransmission(DS3231_I2C_ADDRESS);
- Wire.write(0); // set DS3231 register pointer to 00h
- Wire.endTransmission();
- Wire.requestFrom(DS3231_I2C_ADDRESS, 7);
- // request seven bytes of data from DS3231 starting from register 00h
- *second = bcdToDec(Wire.read() & 0x7f);
- *minute = bcdToDec(Wire.read());
- *hour = bcdToDec(Wire.read() & 0x3f);
- *dayOfWeek = bcdToDec(Wire.read());
- *dayOfMonth = bcdToDec(Wire.read());
- *month = bcdToDec(Wire.read());
- *year = bcdToDec(Wire.read());
- }
- // !!!!!!!!!!!!!!!! END OF DO NOT CHANGE SECTION !!!!!!!!!!!!!!!!!!!!!!!!!!!
- // ** INTERRUPT PROCESSOR SECTION **
- //*************************************************************
- void rain_Count() { // Interrupt Process for Rain Gauge Tip Counting
- rainLastMillis = rainMillis;
- rainMillis = millis();
- tipCount ++; // All we aneed to do here is increment the tip counter
- } // END of Interrupt Processor rain_Count --------------------
- // ************************************************************
- //*************************************************************
- void wind_Count() { // Interrupt Process for Wind measuring
- if (beenAsleep) {
- /*
- nextSleepMillis = millis() + 10000;// wait 10 seconds to see if another wind pulse comes in before sleeping again.
- windLastMillis = nextSleepMillis - 10000;
- */
- //long adj = 15;
- long myVal = millis();
- //long newRevTime = myVal - windLastMillis;
- nextSleepMillis = myVal + 9000;// stay awake for a little while to wait for more wind pulses.
- if (1) { //(((curWindMPH > 8) && (newRevTime < revTime/2)) || ((curWindMPH <8) && (newRevTime < revTime/3))) {// Probably Noise-ignore pulse
- }
- else {
- revTime = myVal - windLastMillis;
- windLastMillis = myVal;
- nextSleepMillis = myVal + 12000;
- }
- }
- else {
- long myVal = millis();
- long newRevTime = myVal - windLastMillis;
- if (((curWindMPH > 8) && (newRevTime < revTime/2)) || ((curWindMPH <8) && (newRevTime < revTime/3))) {// Probably Noise-ignore pulse
- }
- else {
- revTime = myVal - windLastMillis;
- windLastMillis = myVal;
- }
- }
- //Serial.println("TRIGGERED");
- //}
- } // END of Interrupt Processor wind_Count
- ISR(WDT_vect)// Watchdog timer interrupt routine
- {
- if (f_wdt == 0)
- {
- f_wdt = 1;
- }
- else
- {
- //Serial.println("WDT Overrun!!!");
- }
- }
- // ************************************************************
- void sleepNow()
- {
- Serial.println(F("Going to sleep now"));
- // Choose our preferred sleep mode:
- set_sleep_mode(SLEEP_MODE_IDLE);
- // Set sleep enable (SE) bit:
- sleep_enable();
- power_adc_disable();
- power_spi_disable();
- power_timer0_disable();
- power_timer2_disable();
- power_twi_disable();
- // Put the device to sleep:
- sleep_mode();
- // Upon waking up, sketch continues from this point.
- sleep_disable();
- Serial.println(F("GOOD MORNING VIET NAM!"));
- power_all_enable();
- }
- void radio(uint8_t action) {
- int pwrOnDly = 500;
- if (action < 2) {
- digitalWrite(rfPower, action); // If action = ON or OFF, comply
- if (action == ON) {
- delay(pwrOnDly);// Give radio a moment to power up before using0
- }
- }
- else {
- digitalWrite(rfPower, !digitalRead(rfPower)); // Otherwise Toggle
- delay(pwrOnDly);// see above
- }
- }
- float readBattery(void) {
- float chipVoltage = 5.096;// Set this value to the measured voltage on 5 v pin on Arduino, USING EXPECTED POWER SUPPLY!!
- int sum = 0; // sum of samples taken
- unsigned char sample_count = 0; // current sample number
- // take a number of analog samples and add them up
- while (sample_count < 10) {
- sum += analogRead(A1);
- sample_count++;
- delay(10);
- }
- float voltage = ((float)sum / 10.0 * chipVoltage ) / 1024.0;
- // Serial.println(voltage * 1.922);
- return (voltage * 2);
- }
- void readDHT() {
- static long nextReadMillis;
- if (millis() >= nextReadMillis) {
- int readData = myDHT.read22(dhtPin);
- tempDHT = myDHT.temperature * 1.8 + 32;
- humDHT = myDHT.humidity;
- nextReadMillis = millis() + 2000;// DHT can only be read every 2 seconds. This variable prevents premature readings
- }
- }// END of readDHT()-------------------------------------------
- void rain_Set(float myVal) {// Set rain to a specific value, used if restarting during day with rain
- rainInches = myVal;
- tipCount = rainInches / rainPerTip;
- rainLastMillis = 0;
- Serial.println("");
- Serial.print(F("Rainfall Measurement SET to "));
- Serial.print(myVal);
- Serial.println(F(" Imchesn"));
- }// END of rain_Set()-----------------------------------------
- void rain_Reset() {
- tipCount = 0;
- rainInches = 0;
- rainLastMillis = 0;
- Serial.println("");
- Serial.println(F("Rainfall Measurement RESET!n"));
- Serial.println(F(""));
- }// END of rain_Reset()-----------------------------------------
- void wind_Reset() {
- topWind = 0;
- Serial.println();
- Serial.println(F("Maximum Wind RESET!n"));
- Serial.println();
- }// END of wind_Reset()-----------------------------------------
- void all_Reset() {
- wind_Reset();
- rain_Reset();
- }// END of all()-----------------------------------------
- float RandianDate(byte dayOfMonth, byte month, byte year) { // Date to integer format - 01-01-1980 becomes 111180
- String myStr;
- byte myDay = dayOfMonth + 10;// Adding 10 to values to make all 2 digit. No need to do the years.
- byte myMonth = month + 10;
- byte myYear = year + 10;
- //month += 10;
- myStr.concat(myMonth);
- myStr.concat(myDay);
- myStr.concat(myYear);
- return (myStr.toFloat());
- //return(0);
- }
- float RandianTime(byte hours, byte minutes, byte seconds) { // Time to integer format - 14:56:03 becomes 145603
- String myStr;
- hours += 10; // Adding 10 to these values to ensure all are 2 digits.
- minutes += 10; // Will subtract 10 again when decoded
- seconds += 10;
- myStr.concat(hours);
- myStr.concat(minutes);
- myStr.concat(seconds);
- return (myStr.toFloat());
- //return(0);
- }
- String RandianToDate(float RandDate) {
- String msg = "";
- msg.concat(RandDate);
- String token;
- String myDt;
- int trans;
- for ( int cnt = 0; cnt < 6 ; cnt++) {
- token.concat(msg.charAt(cnt));
- if ((cnt == 1) || (cnt == 3)) {
- trans = token.toInt() - 10;
- if (trans < 10) {
- myDt.concat("0");
- }
- myDt.concat(trans);
- myDt.concat("-");
- token = "";
- }
- else if (cnt == 5) {
- trans = token.toInt() - 10;
- myDt.concat("20");
- myDt.concat(trans);
- }
- }
- return (myDt);
- }
- String RandianToTime(float RandTime) {
- String msg = "";
- msg.concat(RandTime);
- String token;
- String myDt;
- int trans;
- for ( int cnt = 0; cnt < 6 ; cnt++) {
- token.concat(msg.charAt(cnt));
- if ((cnt == 1) || (cnt == 3) || (cnt == 5)) {
- trans = token.toInt() - 10;
- if (trans < 10) {
- myDt.concat("0");
- }
- myDt.concat(trans);
- if (cnt < 5) {
- myDt.concat(":");
- }
- token = "";
- }
- }
- return (myDt);
- }
- void stampTime(void) {
- String dateStr;
- String timeStr;
- byte second;
- byte minute;
- byte hour;
- byte dayOfWeek;
- byte dayOfMonth;
- byte month;
- byte year;
- readRTCTime(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month,
- &year);
- ckMinute = minute;
- ckHour = hour;
- ckSecond = second;
- data.randDate = RandianDate(dayOfMonth, month, year);
- data.randTime = RandianTime(hour, minute, second);
- /*
- Serial.print("Hour: ");
- Serial.print(hour);
- Serial.print(" Minute: ");
- Serial.print(minute);
- Serial.print(" Second ");
- Serial.print(second);
- Serial.print("nn");
- Serial.println(data.randTime);
- //Serial.println(data.randTime);
- Serial.println(data.randDate);
- */
- }
- void serialReport(void) {
- Serial.print("Temperature: ");
- Serial.print(data.temperature);
- Serial.print(F(" Degrees FnHumidity: "));
- Serial.print(data.humidity);
- Serial.print(F("% nBarometer: "));
- Serial.print(data.barometer);
- Serial.print(F(" Inches Hg nWind (current): "));
- Serial.print(data.wind);
- Serial.print(F(" MphnPeak Wind this Read: "));
- Serial.print(data.windPacketPeak);
- Serial.print(F(" MphnPeak Wind Today: "));
- Serial.print(data.maxWind);
- Serial.print(F(" MphnRainfall: "));
- Serial.print(data.rain);
- Serial.print(F(" InchesnRain Rate: "));
- Serial.print(data.rainRate);
- Serial.print(F(" Inches per HournPacket ID: "));
- Serial.print(data.packetID);
- Serial.print(F("nCheck Sum: "));
- Serial.println(data.CKSum);
- Serial.print(F("Date: "));
- Serial.print(RandianToDate(data.randDate));
- Serial.print(F("nTime: "));
- Serial.println(RandianToTime(data.randTime));
- Serial.print(F("Battery Voltage: "));
- Serial.print(data.battery);
- Serial.print(F(" Vdcnn"));
- if (testMode == true) {
- Serial.print(F("** TEST MODE ** TEST MODE **nn"));
- }
- }
- float CheckSum() { // A Check to ensure valid packet received. Basic Check Sum (Sum of all fields-all are numeric)
- return (data.temperature + data.humidity + data.barometer + data.wind + data.rain + data.rainRate + data.maxWind + data.packetID + data.windPacketPeak + data.randDate + data.randTime + data.battery);
- } // END CheckSum **************************
- void setDS3231time(byte second, byte minute, byte hour, byte dayOfWeek, byte
- dayOfMonth, byte month, byte year)
- {
- // sets time and date data to DS3231
- Wire.beginTransmission(DS3231_I2C_ADDRESS);
- Wire.write(0); // set next input to start at the seconds register
- Wire.write(decToBcd(second)); // set seconds
- Wire.write(decToBcd(minute)); // set minutes
- Wire.write(decToBcd(hour)); // set hours
- Wire.write(decToBcd(dayOfWeek)); // set day of week (1=Sunday, 7=Saturday)
- Wire.write(decToBcd(dayOfMonth)); // set date (1 to 31)
- Wire.write(decToBcd(month)); // set month
- Wire.write(decToBcd(year)); // set year (0 to 99)
- Wire.endTransmission();
- }
- void sendData() { // Send data packet by RF transmitter
- radio(ON);
- digitalWrite(ledPin, HIGH); // Flash a light to show transmitting
- //readSensors(); now doing in loop, not here - prevents differences in "same" packet sends
- vw_send((uint8_t *)&data, sizeof(data));
- vw_wait_tx(); // Wait until the whole message is gone
- digitalWrite(ledPin, LOW);
- // delay(2000);
- radio(OFF);
- }// END sendData *******************
- void readSensors()// Read all sensors and build data package
- {
- readDHT();
- data.humidity = humDHT;
- data.temperature = tempDHT;
- data.barometer = baroReading();
- data.wind = Wind_Speed();
-
- data.maxWind = topWind;
- data.rainRate = rainFallRate();
- data.rain = rainInches;
- data.battery = readBattery();
- data.CKSum = CheckSum();
- } // END readSensors() ******************************
- float rainFallRate() {
- if (tipCount > 0) {
- float tipDuration = rainMillis - rainLastMillis;
- if (millis() > rainMillis + 600000) {// no new tips in last 10 minutes
- tipDuration = millis() - rainLastMillis;
- }
- if (tipDuration > 120 * 60000) { // tip takes over 2 hour2, effective rate 0 for our purposes
- return (0);
- }
- else {
- float tipSeconds = tipDuration / 1000.00;
- float tipsPerHour = 3600.00 / tipSeconds;
- return ( rainPerTip * tipsPerHour);
- }
- }
- else {
- return (0);
- }
- }
- float baroReading() {
- if (baroSensorPresent == true) {
- float pascals = baro.getPressure();
- // Our weather page presents pressure in Inches (Hg)
- // Use http://www.onlineconversion.com/pressure.htm for other units
- // Serial.print(pascals/3377); Serial.println(" Inches (Hg)");
- return ((pascals / 3377.00) + 0.87); // 0.87 is barometric adjustment
- }
- else {
- return (99.99); // bogus reading if sensor not detected.
- }
- }// End baroReading() ----------------------------------------------
- /*
- float rainfallRate() {
- float tipDuration = rainMillis - rainLastMillis;
- float tipSeconds = tipDuration / 1000;
- float tipsPerHour = 3600 / tipSeconds;
- float myRainRate = rainPerTip * tipsPerHour;
- return (myRainRate);
- }// END of RainfallRate() ************************
- */
- int Wind_Speed() {
- float retValF = 717.00 * windAdj / (revTime);
- if (millis() >= windLastMillis + 10000) { // No wind pulses in 10 seconds, wind is effectively 0
- retValF = 0.00;
- }
- curWindMPH = retValF;
- if (data.windPacketPeak < retValF){
- data.windPacketPeak = retValF;
- }
- if (topWind
- topWind = data.wind;
- }
- return retValF;
- }// END of Wind_Speed() ---------------------------------------------
- float baroTempReading() {
- float tempF = baro.getTemperature() * 1.8 + 32;
- //Serial.println(tempF);
- //Serial.println(tempF);
- return (tempF);
- // Serial.print(tempC); Serial.println("*C");
- }// End baroTempReading() -----------------------------------------
- void showHelp() {
- Serial.println(F("- Valid Serial Commands -"));
- Serial.println(F("W ## - Sets Max Wind to ##"));
- Serial.println(F("I ## - Interval in seconds - Sets Packet Interval"));
- Serial.println(F("R ## - Sets Rainfall"));
- Serial.println(F("+ Wind Adj up 1"));
- Serial.println(F("- Wind Adj down 1"));
- Serial.println(F("XW - Max Wind Reset"));
- Serial.println(F("XR - Rainfall Reset"));
- Serial.println(F("XX - ALL Reset"));
- Serial.println(F("S - Toggle Serial Dump Mode"));
- Serial.println(F("n** ? - Shows This Help Screen **"));
- }// END showHelp()------------------------------------------------
- void checkSerial(void) {
- if (Serial.available() > 0) { // Check for and Begin Processing of incoming Serial commands
- String myCmd = Serial.readString();
- char myChr = myCmd.charAt(0);
- if ((myChr == 'W') || (myChr == 'w')) { // "w" should be followed by a number to set max wind to
- myCmd.replace("w", "");
- myCmd.replace("W", "");
- myCmd.replace(",", "");
- myCmd.replace(" ", "");
- float newWind = myCmd.toFloat();
- data.maxWind = newWind;
- topWind = newWind;
- }
- if ((myChr == 'I') || (myChr == 'i')) { // "I" should be followed by a number to set data transmission interval
- myCmd.replace("i", "");
- myCmd.replace("I", "");
- myCmd.replace(",", "");
- myCmd.replace(" ", "");
- float newInterval = myCmd.toFloat();
- xmitRate = newInterval * 1000;// entry will be in seconds, converting to millis()
- }
- if ((myChr == 'R') || (myChr == 'r')) { // "R" should be followed by a number to set rainfall
- myCmd.replace("r", "");
- myCmd.replace("R", "");
- myCmd.replace(",", "");
- myCmd.replace(" ", "");
- float rcmd = myCmd.toFloat();
- if (rcmd > 0) { // If number is entered, set rainfall to that, else add 1 tip
- rain_Set(rcmd);
- }
- else {
- rain_Count();
- }
- }
- if ((myChr == 'S') || (myChr == 's')) { // toggles Serial Dump mode
- serialDump = !serialDump;
- }
- if (myChr == '+') {
- windAdj ++;
- Serial.print(F("Wind Adj = "));
- Serial.println(windAdj);
- }
- if (myChr == '-') {
- windAdj --;
- Serial.print(F("Wind Adj = "));
- Serial.println(windAdj);
- }
- if (myChr == '!') { // Toggle Test Mode
- testMode = !testMode;
- serialDump = testMode;
- Serial.print(F("Toggling Test Mode - Mode="));
- Serial.println(testMode);
- }
- if (myChr == '?') {
- showHelp();
- }
- }
- }// END checkSerial() *****************************************
- void enterSleep(void)
- {
- set_sleep_mode(SLEEP_MODE_PWR_SAVE);
- wdt_reset();
- sleep_enable();
- /* Disable all of the unused peripherals. This will reduce power
- consumption further and, more importantly, some of these
- peripherals may generate interrupts that will wake our Arduino from
- sleep!
- */
- power_adc_disable();
- power_spi_disable();
- power_timer0_disable();
- power_timer2_disable();
- power_twi_disable();
- beenAsleep = true;
- /* Now enter sleep mode. */
- sleep_mode();
- /* The program will continue from here after the timer timeout*/
- sleep_disable(); /* First thing to do is disable sleep. */
- power_all_enable();
- //wokeUpMillis = millis()-10;
- /* Re-enable the peripherals. */
- }
- void loop()
- {
- static int oldTipCount;//Use to check if a Rain "Tip" has generated an Interrupt response
- static long nextSendMillis;
- static byte nextSendSecond;
- static byte nextSendMinute;
- static long packetCount;
- static float maxWindThisPkt;
- long initTestEnd = long(60000 * testMinutes);
- static bool doneFirstLoop;
- // Serial.println("SofarSOgood");
- //initTestEnd = 0;// Testing line-to be removfed
- stampTime();// called here to check time for reset at midnight. stampTime updates values in ckHour, ckMinute, ckSecond
- if (!doneFirstLoop) { // first iteration. Set up a few things for future iterations
- if (xmitRate >= 60000) {
- nextSendMinute = ckMinute + (xmitRate / 60000);
- nextSendSecond = 00;//ckSecond;
- }
- else if (xmitRate < 60000) {
- nextSendMinute = ckMinute;
- nextSendSecond = ckSecond + xmitRate / 1000;
- }
- doneFirstLoop = true;
- }
- if ((millis() >= initTestEnd) && (millis() <= initTestEnd + 60000)) {
- testMode = false;
- }
- if ((needsReset == false) && (ckHour == 23) && (ckMinute == 59)) {
- needsReset = true;
- //rain_Reset();
- }
- if ((needsReset == true) && (ckMinute < 5)) {
- all_Reset();// Resets Rain, wind Counter, stores todays values as yesterday at midnight, ready for a brand new day!
- needsReset = false;
- // *********************************************************************************
- }
- checkSerial();
- //serialReport;
- if (xmitRate < 5000) { // Don't allow less than 5 second interval.
- xmitRate = 5000;
- }
- rainInches = tipCount * rainPerTip;
- readSensors();
- if (maxWindThisPkt <= data.wind) {
- maxWindThisPkt = data.wind;
- if ((data.maxWind < maxWindThisPkt) && (maxWindThisPkt < 120)) { // if maxWindThisPkt >120, either data is corrupted, *OR*
- data.maxWind = maxWindThisPkt;// Weather Station is being destroyed by tornado
- topWind = data.maxWind;
- }
- }
- /*
- Serial.println("---");
- Serial.println(ckMinute);
- Serial.println(nextSendMinute);
- Serial.println(ckSecond);
- Serial.println(nextSendSecond);
- Serial.println("---");
- */
- if (((ckMinute >= nextSendMinute) && (ckSecond >= nextSendSecond)) || (testMode == true)) { // Time to send data packet.
- if ((ckMinute == 59) && (nextSendMinute == 0)) { //Problem condition-need to skip
- }
- else {
- data.windPacketPeak = maxWindThisPkt;
- maxWindThisPkt = 0;
- packetCount ++;
- nextSendMillis = millis() + xmitRate;
- stampTime();
- data.packetID = packetCount;
- readSensors();
- for (int cnt = 0; cnt < 2 ; cnt++) { // Send each packet 3 times, to hopefully eliminate/minimize lost packets.
- sendData();
- //d+elay(500);// NO longer needed, delays built into SendData for turning radio on.
- }
- if (serialDump == true) {
- serialReport();
- }
- if (xmitRate >= 60000) {
- nextSendMinute = (xmitRate / 60000) + ckMinute;
- //nextSendSecond = ckSecond;
- if (nextSendMinute > 59) {
- nextSendMinute -= 60;
- }
- }
- else if (xmitRate < 60000) {
- //nextSendMinute = ckMinute;
- nextSendSecond = ckSecond + xmitRate / 1000;
- if (nextSendSecond > 59) {
- nextSendSecond -= 60;
- }
- }
- }
- }//*******
- if ((!testMode) && (millis() > nextSleepMillis)) {
- Serial 。println (“睡觉” ); 延迟(300 ); beenAsleep = true ; enterSleep (); beenAsleep = false ; 串行。println (“回到生活” ); } // * / // } ///结束循环!!!!
复制代码
1
|
|
|
|