Skip to content

Instantly share code, notes, and snippets.

@apricat
Created July 27, 2021 18:50
Show Gist options
  • Save apricat/f3203a864fbbe0e7ef8f2a0a110bd38c to your computer and use it in GitHub Desktop.
Save apricat/f3203a864fbbe0e7ef8f2a0a110bd38c to your computer and use it in GitHub Desktop.
sleepypouding2021.ino
#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