Extracts soil reading to SoilMonitor
This commit is contained in:
parent
4c30ff3549
commit
9c2d95569d
3 changed files with 104 additions and 27 deletions
48
code/parasite/lib/parasite/parasite/adc.cpp
Normal file
48
code/parasite/lib/parasite/parasite/adc.cpp
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
#include "parasite/adc.h"
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
namespace parasite {
|
||||
namespace {
|
||||
// Resultion in bits. ADC read values will be mapped to [0, 2^reference].
|
||||
constexpr int kResolution = 10;
|
||||
|
||||
/*
|
||||
* Battery monitoring
|
||||
*/
|
||||
// Use the internal 0.6 reference with a gain of 1/2.
|
||||
// This lets us read values in the range [0, 1.2V].
|
||||
constexpr eAnalogReference kBattADCReference = AR_INTERNAL_1_2;
|
||||
constexpr double kMaxVoltage = 1.2;
|
||||
// How many samples will be averaged out.
|
||||
constexpr uint32_t kOversampling = 32;
|
||||
// Voltage divider.
|
||||
constexpr double kBattDividerR1 = 1470;
|
||||
constexpr double kBattDividerR2 = 470;
|
||||
constexpr double kBattDividerFactor =
|
||||
(kBattDividerR1 + kBattDividerR2) / kBattDividerR2;
|
||||
} // namespace
|
||||
|
||||
double BatteryMonitor::Read() {
|
||||
analogOversampling(kOversampling);
|
||||
analogReference(kBattADCReference);
|
||||
int batt_val = analogRead(pin_);
|
||||
double v_in = kMaxVoltage * batt_val / (1 << kResolution);
|
||||
return kBattDividerFactor * v_in;
|
||||
}
|
||||
|
||||
soil_reading_t SoilMonitor::Read() {
|
||||
analogOversampling(kOversampling);
|
||||
// Set up the analog reference to be VDD. This allows us to cancel out
|
||||
// the effect of the battery discharge across time, since the RC circuit
|
||||
// also depends linearly on VDD.
|
||||
analogReference(AR_VDD4);
|
||||
int raw = analogRead(pin_);
|
||||
double percentage =
|
||||
static_cast<double>(raw - air_val_) / (water_val_ - air_val_);
|
||||
return {raw, std::max(0.0, std::min(1.0, percentage))};
|
||||
}
|
||||
|
||||
} // namespace parasite
|
||||
35
code/parasite/lib/parasite/parasite/adc.h
Normal file
35
code/parasite/lib/parasite/parasite/adc.h
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
#ifndef _PARASITE_ADC_H_
|
||||
#define _PARASITE_ADC_H_
|
||||
|
||||
namespace parasite {
|
||||
|
||||
class BatteryMonitor {
|
||||
public:
|
||||
explicit BatteryMonitor(int pin) : pin_(pin) {}
|
||||
double Read();
|
||||
|
||||
private:
|
||||
const int pin_;
|
||||
};
|
||||
|
||||
struct soil_reading_t {
|
||||
int raw;
|
||||
double parcent;
|
||||
};
|
||||
|
||||
class SoilMonitor {
|
||||
public:
|
||||
explicit SoilMonitor(int air_val, int water_val, int pin)
|
||||
: air_val_(air_val), water_val_(water_val), pin_(pin) {}
|
||||
|
||||
soil_reading_t Read();
|
||||
|
||||
private:
|
||||
// Referencce values for estimating the soil moisture percentage.
|
||||
const int air_val_, water_val_;
|
||||
|
||||
// Pin the analog signal is connected to.
|
||||
const int pin_;
|
||||
};
|
||||
} // namespace parasite
|
||||
#endif // _PARASITE_ADC_H_
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
#include <Arduino.h>
|
||||
|
||||
#include <cstring>
|
||||
#include <vector>
|
||||
|
||||
#include "parasite/adc.h"
|
||||
#include "parasite/ble.h"
|
||||
#include "parasite/ble_advertisement_data.h"
|
||||
#include "parasite/pwm.h"
|
||||
|
|
@ -10,22 +10,25 @@
|
|||
constexpr int kLED1Pin = 17;
|
||||
constexpr int kLED2Pin = 18;
|
||||
constexpr int kPWMPin = 19;
|
||||
constexpr int kSensAnalogPin = 4; // AIN2
|
||||
constexpr int kSoilAnalogPin = 4; // AIN2
|
||||
constexpr int kBattAnalogPin = 3; // AIN3
|
||||
constexpr int kDischargeEnablePin = 16;
|
||||
constexpr double kPWMFrequency = 500000;
|
||||
|
||||
constexpr double kBattDividerR1 = 1470;
|
||||
constexpr double kBattDividerR2 = 470;
|
||||
constexpr double kBattDividerFactor = (kBattDividerR1 + kBattDividerR2) / kBattDividerR2;
|
||||
constexpr int kSoilMonitorAirVal = 680;
|
||||
constexpr int kSoilMonitorWaterVal = 60;
|
||||
|
||||
const parasite::MACAddr kMACAddr = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06};
|
||||
parasite::BLEAdvertiser advertiser(kMACAddr);
|
||||
|
||||
void updateAdvertisingData(parasite::BLEAdvertiser *advertiser,
|
||||
int moisture_level) {
|
||||
parasite::BatteryMonitor batt_monitor(kBattAnalogPin);
|
||||
parasite::SoilMonitor soil_monitor(kSoilMonitorAirVal, kSoilMonitorWaterVal,
|
||||
kSoilAnalogPin);
|
||||
|
||||
void updateAdvertisingData(parasite::BLEAdvertiser* advertiser,
|
||||
const parasite::soil_reading_t& soil_reading) {
|
||||
parasite::BLEAdvertisementData data;
|
||||
data.SetRawSoilMoisture(moisture_level);
|
||||
|
||||
data.SetRawSoilMoisture(soil_reading.raw);
|
||||
|
||||
advertiser->SetData(data);
|
||||
|
||||
|
|
@ -48,25 +51,16 @@ void setup() {
|
|||
}
|
||||
|
||||
void loop() {
|
||||
// With a gain of 1/2, we can read the range of [0, 1.2V].
|
||||
// I'm using a voltage divider with R1 = 1470, R2 470, so
|
||||
// We can read 0 - ~5V.
|
||||
// This seems to be working okay, but I need to investigate if making it
|
||||
// stiffer (lower R1 and R2) work better.
|
||||
analogOversampling(32);
|
||||
analogReference(AR_INTERNAL_1_2);
|
||||
int batt_val = analogRead(kBattAnalogPin);
|
||||
double v_in = 1.2 * batt_val / (1<<10);
|
||||
double batt_voltage = kBattDividerFactor * v_in;
|
||||
Serial.printf("Batt val: %d, voltage: %f\n", batt_val, batt_voltage);
|
||||
double batt_voltage = batt_monitor.Read();
|
||||
Serial.printf("Batt voltage: %f\n", batt_voltage);
|
||||
|
||||
parasite::soil_reading_t soil_reading = soil_monitor.Read();
|
||||
Serial.printf("Moisture val: %d, %f%%\n", soil_reading.raw,
|
||||
100 * soil_reading.parcent);
|
||||
|
||||
// We setup the analog reference to be VDD. This allows us to cancel out
|
||||
// the effect of the battery discharge across time, since the RC circuit
|
||||
// also depends linearly on VDD.
|
||||
analogReference(AR_VDD4);
|
||||
int sens_val = analogRead(kSensAnalogPin);
|
||||
// Serial.printf("Moisture val: %d\n", sens_val);
|
||||
digitalToggle(kLED1Pin);
|
||||
updateAdvertisingData(&advertiser, sens_val);
|
||||
|
||||
updateAdvertisingData(&advertiser, soil_reading);
|
||||
|
||||
delay(500);
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue