Created
July 27, 2021 18:50
-
-
Save apricat/f3203a864fbbe0e7ef8f2a0a110bd38c to your computer and use it in GitHub Desktop.
sleepypouding2021.ino
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <Adafruit_SleepyDog.h> | |
#include <RadioHead.h> | |
#include <SPI.h> | |
#include <RH_RF95.h> | |
#include <Adafruit_SleepyDog.h> | |
#include <Wire.h> | |
#include "SparkFun_Qwiic_Scale_NAU7802_Arduino_Library.h" // Click here to get the library: http://librarymanager/All#SparkFun_NAU7802 | |
/** Adafruit Feather M0 RFM9x **/ | |
#define VBATPIN A7 // battery pin | |
#define RFM95_CS 8 | |
#define RFM95_RST 4 | |
#define RFM95_INT 3 | |
#define RFM95_FREQ 915.0 | |
RH_RF95 rf95(RFM95_CS, RFM95_INT); | |
long id = 1; // Node id. Change this value depending on which board this code is uploaded to. | |
long weightSensorId = 1; | |
long batterySensorId = 2; | |
int sleepCycles = 4; | |
NAU7802 scale; //Create instance of the NAU7802 class | |
void setup() | |
{ | |
setupSerial(); | |
print("Waiting on boot for new code before starting sleep cycle..."); | |
delay(100000); // on boot, give time to upload new script (if needed) before starting loop where usb is disconnected | |
pinMode(LED_BUILTIN, OUTPUT); | |
digitalWrite(LED_BUILTIN, HIGH); // Show we're awake | |
setupRFM95(); | |
setupWeightSensor(); | |
Watchdog.enable(); | |
} | |
void loop() | |
{ | |
print("Awake: starting readings."); | |
scale.powerUp(); //Power up scale. This scale takes ~600ms to boot and take reading. | |
while(scale.available() == false) | |
delay(1); | |
sendPacket(weightSensorId, scale.getAverage(25)*(-1)); | |
scale.powerDown(); //Power down to ~200nA | |
delay(200); | |
sleep(); | |
sendPacket(batterySensorId, measureBatteryMillivoltage()); | |
print("Ended readings, going to sleep."); | |
sleep(); | |
} | |
void setupSerial() { | |
while (!Serial); | |
Serial.begin(9600); | |
delay(100); | |
} | |
void setupWeightSensor() { | |
Wire.begin(); | |
if (scale.begin() == false) | |
{ | |
print("Scale not detected. Please check wiring. Freezing..."); | |
while (1); | |
} | |
print("Scale detected"); | |
} | |
/** | |
Pouding can only sleep for 16000ms. Combine sleeps in loop for maximum efficiency. | |
*/ | |
void sleep() { | |
delay(1000); | |
digitalWrite(LED_BUILTIN, LOW); // Asleep | |
//rf95.sleep(); // Put radio back to sleep until woken up by `send()` method | |
int sleepMS = 0; | |
for (int x = 0; x < sleepCycles; x++) { | |
sleepMS += Watchdog.sleep(); | |
} | |
#if defined(USBCON) && !defined(USE_TINYUSB) | |
USBDevice.attach(); | |
#endif | |
digitalWrite(LED_BUILTIN, HIGH); // Awake | |
delay(1000); | |
} | |
/** | |
Note that USB connection deconnects during sleep. | |
To see Serial messages, reopen COM monitor window after wakeup. | |
*/ | |
void print(String msg) { | |
Serial.print(msg); | |
Serial.println(); | |
} | |
void setupRFM95() { | |
pinMode(RFM95_RST, OUTPUT); | |
digitalWrite(RFM95_RST, HIGH); | |
delay(100); | |
digitalWrite(RFM95_RST, LOW); | |
delay(10); | |
digitalWrite(RFM95_RST, HIGH); | |
delay(10); | |
while (!rf95.init()) { | |
print("LoRa radio init failed"); | |
while (1); | |
} | |
print("LoRa radio init OK!"); | |
if (!rf95.setFrequency(RFM95_FREQ)) { | |
print("setFrequency failed"); | |
while (1); | |
} | |
rf95.setTxPower(23, false); | |
} | |
void sendPacket(long sensorId, long val) { | |
char radiopacket[20]; | |
String d = decToHex(id, 2) + " " + decToHex(sensorId, 2) + " " + decToHex(val, 2); | |
d.toCharArray(radiopacket, 20); | |
delay(10); | |
rf95.send((uint8_t *)radiopacket, strlen(radiopacket)); | |
print("Sent packet: " + String(radiopacket)); | |
} | |
String decToHex(long val, byte desiredStringLength) { | |
String hash = String(val, HEX); /** works **/ | |
if (hash.length() & 1 != 0) { | |
hash = "0" + hash; | |
} | |
String padded_hash = ""; | |
for (int i = 0; i < hash.length(); i++) { | |
padded_hash += hash[i]; | |
if (i & 1 != 0 && i != hash.length()-1) { | |
padded_hash += " "; | |
} | |
} | |
return padded_hash; | |
} | |
/** | |
Lipoly batteries are 'maxed out' at 4.2V and stick around 3.7V for much of the battery life, | |
then slowly sink down to 3.2V or so before the protection circuitry cuts it off. | |
By measuring the voltage you can quickly tell when you're heading below 3.7V | |
*/ | |
float measureBatteryMillivoltage() { | |
float measuredvbat = analogRead(VBATPIN); | |
measuredvbat *= 2; // we divided by 2, so multiply back | |
measuredvbat *= 3.3; // Multiply by 3.3V, our reference voltage | |
measuredvbat /= 1024; // convert to voltage | |
measuredvbat *= 1000; // convert to mv | |
print("v: " + String(measuredvbat)); | |
return measuredvbat; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment