#include <RFM69.h> //Library 1.4.0 https://github.com/LowPowerLab/RFM69
#include <SPI.h>
#include <LowPower.h> //Library 1.2.1
#include <Servo.h> //Library 1.1.6
// Uncomment the appropriate frequency for your hardware
#define FREQUENCY RF69_915MHZ
//ENCRYPT_KEY must match gateway value and must be exactly 16 characters
//#define ENCRYPT_KEY "mysecretmysecret"
#define NODEID 1 //This is the right blind
//#define NODEID 2 //This is the left blind
#define NETWORKID 100
#define GATEWAYID 1
#define BLINDS_1 0b00000001 //This is the right blind
//#define BLINDS_2 0b00000010 //This is the left blind
#define MY_NODE_FLAG BLINDS_1 //This is the right blind
//#define MY_NODE_FLAG BLINDS_2 //This is the left blind
struct PACKET {
int16_t percent;
int16_t voltage1;
int16_t voltage2;
char charger;
} packetOut;
struct inPACKET {
uint8_t
group,
value;
} packetIn;
RFM69 radio;
const int wakeUpPin = 3;
const int moveUpPin = 4;
const int servoPowerPin = 5;
const int moveDownPin = 7;
const int servoPin = 6;
const int okStatus = 16;
const int chStatus = 15;
int currentAngle = 0;
Servo blindServo;
void setup() {
Serial.begin(115200);
radio.initialize(FREQUENCY, NODEID, NETWORKID);
// radio.encrypt(ENCRYPT_KEY);
char buff[50];
sprintf(buff, "\nTransmitting at %d Mhz...", FREQUENCY==RF69_433MHZ ? 433 : FREQUENCY==RF69_868MHZ ? 868 : 915);
Serial.println(buff);
radio.listenModeEnd();
Serial.print("Network ID: ");
Serial.print(NETWORKID);
Serial.print(", Node ID: ");
Serial.println(NODEID);
pinMode(wakeUpPin, INPUT);
pinMode(moveUpPin, INPUT);
pinMode(moveDownPin, INPUT);
pinMode(servoPowerPin, OUTPUT);
pinMode(A0, INPUT);
pinMode(okStatus, INPUT_PULLUP);
pinMode(chStatus, INPUT_PULLUP);
blindServo.attach(servoPin, 500, 2500); //This is the right blind
// blindServo.attach(servoPin, 400, 2400); //This is the left blind
blindServo.write(currentAngle); //Sets the starting angle at 0
// Serial.println(blindServo.read());
}
void loop() {
int angle;
//This section is for the manual switch
attachInterrupt(1, wakeUpSwitch, HIGH);
if (digitalRead(moveUpPin) == HIGH) {
while(digitalRead(moveUpPin) == HIGH) {
digitalWrite(servoPowerPin, HIGH);
delay(75);
currentAngle = blindServo.read();
if (currentAngle < 175) {
currentAngle += 5;
blindServo.write(currentAngle);
delay(50);
// Serial.print("Opening, Setting servo angle to: ");
// Serial.println(blindServo.read());
}
else if (currentAngle < 180 && currentAngle > 175) {
currentAngle += 1;
blindServo.write(currentAngle);
delay(50);
// Serial.print("Opening, Setting servo angle to: ");
// Serial.println(blindServo.read());
}
else {
blindServo.write(180);
// Serial.println("Setting servo angle to: 180");
}
}
}
else if (digitalRead(moveDownPin) == HIGH) {
while(digitalRead(moveDownPin) == HIGH){
digitalWrite(servoPowerPin, HIGH);
delay(75);
currentAngle = blindServo.read();
if (currentAngle > 5) {
currentAngle -= 5;
blindServo.write(currentAngle);
delay(50);
// Serial.print("Closing, Setting servo angle to: ");
// Serial.println(blindServo.read());
}
else if (currentAngle > 0 && currentAngle < 5) {
currentAngle -= 1;
blindServo.write(currentAngle);
delay(50);
// Serial.print("Closing, Setting servo angle to: ");
// Serial.println(blindServo.read());
}
else {
blindServo.write(0);
// Serial.println("Closing, Setting servo angle to: 0");
}
}
}
//End of the manual switch section
else {
if (radio.receiveDone()) {
// Serial.print('[');Serial.print(radio.SENDERID, DEC);Serial.print("] ");
// Serial.print("[RX_RSSI:");Serial.print(radio.readRSSI());Serial.println("]");
// Serial.print("Payload Size: ");Serial.println(sizeof(inPACKET));//Serial.print(" ");
// Serial.print("DataLen Size: ");Serial.println(radio.DATALEN);//Serial.print(" ");
if (radio.ACKRequested()) {
radio.sendACK();
}
Serial.println("Received a normal message");
Serial.println((char*)radio.DATA);
Serial.flush();
}
radio.listenModeStart();
if (digitalRead(wakeUpPin) == LOW) {
digitalWrite(servoPowerPin, LOW);
delay(5);
// Serial.println("Entering low-power listen mode...");
Serial.flush();
LowPower.powerDown(SLEEP_60MS, ADC_OFF, BOD_OFF);
// LowPower.powerDown(SLEEP_FOREVER, ADC_OFF, BOD_OFF);
// Woke up, check for a message
// delay(2000);
// Serial.println("Woke up!");
// delay(25);
// detachInterrupt(1);
}
int sensorValue = analogRead(A0);
delay(1);
sensorValue = analogRead(A0);
// Convert the analog reading (which goes from 0 - 1023) to a voltage (0 - 5V):
float voltage = ((sensorValue * (3.3 / 1023.0)) * 2);
uint8_t percent = ((voltage - 3.3) / 0.9125) * 100;
packetOut.percent = percent;
packetOut.voltage1 = voltage;
// packetOut.voltage1 = (voltage * 100);
packetOut.voltage2 = (voltage * 100);
// Serial.println(sensorValue);
// Serial.print("Battery Percent: ");
// Serial.println(packetOut.percent);
// Serial.print("Battery Voltage: ");
// Serial.println(voltage);
// Serial.print("Battery Voltage1: ");
// Serial.println(packetOut.voltage1);
// Serial.print("Battery Voltage2: ");
// Serial.println(packetOut.voltage2);
// Check the status of the solar charger
if (digitalRead(okStatus) == LOW && digitalRead(chStatus) == HIGH) {
// packetOut.charger = 'O';
packetOut.charger = 79; //Converted output to ASCII
// Serial.println(digitalRead(okStatus));
// Serial.println(digitalRead(chStatus));
// Serial.println("Solar: Fully Charged");
}
else if (digitalRead(okStatus) == HIGH && digitalRead(chStatus) == LOW) {
// packetOut.charger = 'C';
packetOut.charger = 67;
// Serial.println(digitalRead(okStatus));
// Serial.println(digitalRead(chStatus));
// Serial.println("Solar: Charging");
}
else if (digitalRead(okStatus) == LOW && digitalRead(chStatus) == LOW) {
// packetOut.charger = 'E';
packetOut.charger = 69;
// Serial.println(digitalRead(okStatus));
// Serial.println(digitalRead(chStatus));
// Serial.println("Solar: ERROR");
}
else {
// packetOut.charger = 'N';
packetOut.charger = 78;
// Serial.println(digitalRead(okStatus));
// Serial.println(digitalRead(chStatus));
// Serial.println("Solar: Not Charging");
}
int initialPosition = blindServo.read();
uint8_t from = 0;
long burstRemaining = 0;
if (radio.DATALEN > 0) {
// Serial.println("Received a message in listen mode");
// Serial.println((char*)radio.DATA);
if (radio.TARGETID == 255) {
// Entire section commented out for now
// struct inPACKET
// *myPacket = (struct inPACKET *)radio.DATA;
// angle = (myPacket->value);
// if (myPacket->group & MY_NODE_FLAG)
// {
// digitalWrite(servoPowerPin, HIGH);
// delay(75);
// currentAngle = blindServo.read();
// //Serial.print("Angle: ");
// //Serial.println(angle);
// while (currentAngle != angle) {
// if (currentAngle > angle) {
// currentAngle -= 1;
// blindServo.write(currentAngle);
// delay(15);
// }
//
// else if (currentAngle < angle) {
// currentAngle += 1;
// blindServo.write(currentAngle);
// delay(15);
// }
// }
// }
}
else if ( radio.DATA != null && radio.TARGETID == NODEID) {
struct inPACKET
*myPacket = (struct inPACKET *)radio.DATA;
angle = (myPacket->value);
if ( angle != 0 ) {
digitalWrite(servoPowerPin, HIGH);
delay(75);
currentAngle = blindServo.read();
// Serial.print("Angle: ");
// Serial.println(angle);
while (currentAngle != angle) {
if (currentAngle > angle) {
currentAngle -= 1;
blindServo.write(currentAngle);
delay(15);
}
else if (currentAngle < angle) {
// Serial.println(blindServo.read());
currentAngle += 1;
blindServo.write(currentAngle);
delay(15);
}
}
}
}
delay(125);
Serial.flush();
from = radio.SENDERID;
burstRemaining = radio.RF69_LISTEN_BURST_REMAINING_MS;
}
// Radio goes back to standby, ready for normal operations
radio.listenModeEnd();
if (from) {
while (burstRemaining > 0) {
// LowPower.powerDown(SLEEP_60MS, ADC_OFF, BOD_OFF);
burstRemaining -= 60;
}
// LowPower.powerDown(SLEEP_30MS, ADC_OFF, BOD_OFF);
radio.send(from, &packetOut, sizeof(packetOut));
}
}
}
void wakeUpSwitch() {
// Serial.println("Waking up due to switch.");
}