-
Notifications
You must be signed in to change notification settings - Fork 8
/
MailboxNotifier2_receiver.ino
164 lines (136 loc) · 5.24 KB
/
MailboxNotifier2_receiver.ino
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
// Standalone receiver with LCD Moteino based MailboxNotifier
// This is the code running on the receiving end that displays info on LCD
// LowPowerLab.com - 2013-8-25 (C) felix@lowpowerlab.com
// http://opensource.org/licenses/mit-license.php
// uses the RFM12B library found at: https://github.com/LowPowerLab/RFM12B
// the LCD libraries are found in separate ZIP file (source: https://bitbucket.org/fmalpartida/st7036-display-driver/wiki/Home)
#include <Arduino.h>
#include "ST7036.h"
#include "LCD_C0220BiZ.h"
#include <Wire.h>
#include <RFM12B.h>
#define SERIAL_BAUD 115200
#define NODEID 1 // network ID used for this unit
#define NETWORKID 100
#define FREQUENCY RF12_915MHZ //Match this with the version of your Moteino! (others: RF12_433MHZ, RF12_915MHZ)
#define KEY "ABCDABCDABCDABCD"
#define ACK_TIME 50 // # of ms to wait for an ack
#define LED 9
#define LDRPIN A0 //light sensor on pin A0 for backlight purposes
#define BACKLIGHTPIN 6
char temp[RF12_MAXDATA];
RFM12B radio;
ST7036 lcd = ST7036 (2, 20, 0x78, BACKLIGHTPIN); //row count, column count, I2C addr, pin for backlight PWM
typedef struct {
unsigned long lastOpen;
unsigned long lastClosed;
unsigned short battery;
} Payload;
Payload theData;
byte battChar[8] = {0b00000,0b01110,0b11111,0b11111,0b11111,0b11111,0b11111,0};
void setup()
{
pinMode(LED, OUTPUT);
radio.Initialize(NODEID, FREQUENCY, NETWORKID);
radio.Encrypt((byte*)KEY);
Serial.begin(SERIAL_BAUD);
char buff[50];
sprintf(buff, "Listening at %d Mhz...", FREQUENCY == RF12_433MHZ ? 433 : FREQUENCY== RF12_868MHZ ? 868 : 915);
Serial.println(buff);
lcd.init();
lcd.setContrast(10);
lcd.clear();
lcd.load_custom_character(0, battChar);
}
byte recvCount = 0;
int milliCount=0;
void loop()
{
if (radio.ReceiveComplete())
{
if (radio.CRCPass())
{
digitalWrite(LED,HIGH);
Serial.print('[');Serial.print(radio.GetSender(), DEC);Serial.print("] ");
if (*radio.DataLen != sizeof(Payload))
for (byte i = 0; i < *radio.DataLen; i++)
Serial.print((char)radio.Data[i]);
else
{
theData = *(Payload*)radio.Data; //assume radio.DATA actually contains our struct and not something else
char periodO='X', periodC='X';
long lastOpened = theData.lastOpen;
long lastClosed = theData.lastClosed;
long LO = lastOpened;
long LC = lastClosed;
char* MLOstr="LO:99d23h59m";
char* MLCstr="LC:99d23h59m";
char* BATstr="BAT:1024";
if (lastOpened <= 59) periodO = 's'; //1-59 seconds
else if (lastOpened <= 3599) { periodO = 'm'; lastOpened/=60; } //1-59 minutes
else if (lastOpened <= 259199) { periodO = 'h'; lastOpened/=3600; } // 1-71 hours
else if (lastOpened >= 259200) { periodO = 'd'; lastOpened/=86400; } // >=3 days
if (lastClosed <= 59) periodC = 's';
else if (lastClosed <= 3599) { periodC = 'm'; lastClosed/=60; }
else if (lastClosed <= 259199) { periodC = 'h'; lastClosed/=3600; }
else if (lastClosed >= 259200) { periodC = 'd'; lastClosed/=86400; }
if (periodO == 'd')
sprintf(MLOstr, "LO:%ldd%ldh", lastOpened, (LO%86400)/3600);
else if (periodO == 'h')
sprintf(MLOstr, "LO:%ldh%ldm", lastOpened, (LO%3600)/60);
else sprintf(MLOstr, "LO:%ld%c", lastOpened, periodO);
if (periodC == 'd')
sprintf(MLCstr, "LC:%ldd%ldh", lastClosed, (LC%86400)/3600);
else if (periodC == 'h')
sprintf(MLCstr, "LC:%ldh%ldm", lastClosed, (LC%3600)/60);
else sprintf(MLCstr, "LC:%ld%c", lastClosed, periodC);
sprintf(BATstr, "BAT:%i", theData.battery);
sprintf(temp, "%s %s %s", MLOstr, MLCstr, BATstr); //sprintf(sendBuf, "MLO:%ld%c MLC:%ld%c", lastOpened, periodO, lastClosed, periodC);
byte len = strlen(temp);
Serial.print(temp); Serial.print(" ("); Serial.print(len); Serial.print(")");
lcd.clear();
lcd.setCursor(0,0);
lcd.print(MLOstr);
lcd.setCursor(1,0);
lcd.print(MLCstr);
float battV = ((float)theData.battery * 3.3 * 9)/(1023*2.8776);
dtostrf(battV, 3, 2, BATstr);
Serial.print(BATstr);Serial.print("v");
//sprintf(temp, "BAT:%sv", BATstr);
//lcd.setCursor(0,11);
//lcd.print(temp);
lcd.setCursor(0,14);
lcd.print(char(0));
lcd.setCursor(0,15);
sprintf(temp, "%sv", BATstr);
lcd.print(temp);
}
if (radio.ACKRequested())
{
byte theNodeID = radio.GetSender();
radio.SendACK();
}
delay(5);
digitalWrite(LED,LOW);
}
else Serial.print("BAD-CRC");
Serial.println();
}
//update backlight every second
if (millis() - milliCount > 1000)
{
milliCount = millis();
int LDR = analogRead(LDRPIN);
lcd.setBacklight(map(LDR, 0, 1024, 0, 255));
lcd.setCursor(1,19);
}
}
// wait a few milliseconds for proper ACK to me, return true if indeed received
static bool waitForAck(byte theNodeID) {
long now = millis();
while (millis() - now <= ACK_TIME) {
if (radio.ACKReceived(theNodeID))
return true;
}
return false;
}