Simple PWM-based square wave works
This commit is contained in:
parent
a4adc0087d
commit
ea4bd872bc
4 changed files with 61 additions and 15 deletions
17
README.md
17
README.md
|
|
@ -2,12 +2,19 @@
|
|||
A low power soil moisture sensor based on the nRF52840.
|
||||
|
||||
# TODO
|
||||
* Hook square wave generator to the protoboard sensor circuit
|
||||
* Make the protoboard sensor work
|
||||
* Implement ADC; check out air/water range (using protoboard)
|
||||
* Figure out how to calibrate the ADC when running from different voltages, as the battery discharges
|
||||
* Implement deep sleep
|
||||
* Measure power consumption in deep sleep
|
||||
* Measure power consumption in transmission
|
||||
* Implement BLE advertising with moisture, battery level
|
||||
* Measure current in deep sleep
|
||||
* Measure current in operation (ADC + BLE adversiting)
|
||||
* Test with a range of 2-5V input. Disconnect from USB and monitor using a serial post. Use the bench power supply to power Vcc with variable voltage. *DO NOT CONNECT VCC FROM THE USB-TO-SERIAL BOARD!**
|
||||
* Test with a coin cell
|
||||
* Figure out a way for people to configure the device with a custom name. Idea: BLE service (this is what my [hacked xiaomi temp sensor](https://github.com/atc1441/ATC_MiThermometer) does)
|
||||
* Figure out how OTA works (if at all) over BLE
|
||||
* Design new board using the nrf52 instead of esp32
|
||||
|
||||
# Done
|
||||
* Simple PWM square wave generator
|
||||
* Simple PWM square wave generator
|
||||
* Hook square wave generator to the protoboard sensor circuit
|
||||
* Make the protoboard sensor work
|
||||
|
|
@ -22,11 +22,11 @@ void SetupSquareWave(double frequency, int pin_number) {
|
|||
const int max_count = 16e6 / frequency;
|
||||
|
||||
// Since we want a duty cycle of 0.5, we flip the PVM output when the counter
|
||||
// reaches kPWMMaxCounter / 2/;
|
||||
// reaches kPWMMaxCounter / 2;
|
||||
const int flip_at_count = max_count / 2;
|
||||
|
||||
HwPWM0.addPin(pin_number);
|
||||
HwPWM0.setClockDiv(PWM_PRESCALER_PRESCALER_DIV_1);
|
||||
HwPWM0.setClockDiv(kPWMFrequencyPrescale);
|
||||
HwPWM0.setMaxValue(max_count);
|
||||
HwPWM0.writePin(pin_number, flip_at_count);
|
||||
HwPWM0.begin();
|
||||
|
|
|
|||
|
|
@ -5,21 +5,23 @@
|
|||
constexpr int kLED1Pin = 17;
|
||||
constexpr int kLED2Pin = 18;
|
||||
constexpr int kPWMPin = 19;
|
||||
constexpr int kSensAnalogPin = 4; // AIN2
|
||||
constexpr int kDischargeEnablePin = 16;
|
||||
constexpr double kPWMFrequency = 500000;
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
pinMode(kLED1Pin, OUTPUT);
|
||||
pinMode(kLED2Pin, OUTPUT);
|
||||
pinMode(kDischargeEnablePin, OUTPUT);
|
||||
parasite::SetupSquareWave(kPWMFrequency, kPWMPin);
|
||||
digitalWrite(kDischargeEnablePin, HIGH);
|
||||
|
||||
analogReference(AR_VDD4);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
Serial.print("Hello, world\n");
|
||||
digitalWrite(kLED1Pin, LOW);
|
||||
digitalWrite(kLED2Pin, LOW);
|
||||
delay(500);
|
||||
digitalWrite(kLED1Pin, HIGH);
|
||||
digitalWrite(kLED2Pin, HIGH);
|
||||
int sens_val = analogRead(kSensAnalogPin);
|
||||
Serial.printf("Val: %d\n", sens_val);
|
||||
digitalToggle(kLED1Pin);
|
||||
delay(500);
|
||||
}
|
||||
39
resources.md
39
resources.md
|
|
@ -103,4 +103,41 @@ The [SoftDevice S132 spec](https://infocenter.nordicsemi.com/index.jsp?topic=%2F
|
|||
# PWM
|
||||
* [HardwarePWM.cpp](https://github.com/adafruit/Adafruit_nRF52_Arduino/blob/a86fd9f36c88db96f676cead1e836377a37c7b05/cores/nRF5/HardwarePWM.cpp#L112) by Adafruit is a good reference. [Servo.c](https://github.com/adafruit/Adafruit_nRF52_Arduino/blob/4d703b6f38262775863a16a603c12aa43d249f04/libraries/Servo/src/nrf52/Servo.cpp#L154) uses it.
|
||||
* [nrf52832 pwm spec](https://infocenter.nordicsemi.com/index.jsp?topic=%2Fcom.nordic.infocenter.nrf52832.ps.v1.1%2Fpwm.html)
|
||||
* [nrf5 SDK PWM reference](https://infocenter.nordicsemi.com/index.jsp?topic=%2Fcom.nordic.infocenter.sdk5.v11.0.0%2Fgroup__nrf__pwm__hal.html) HAL => Hardware Abstraction Layer?
|
||||
* [nrf5 SDK PWM reference](https://infocenter.nordicsemi.com/index.jsp?topic=%2Fcom.nordic.infocenter.sdk5.v11.0.0%2Fgroup__nrf__pwm__hal.html) HAL => Hardware Abstraction Layer?
|
||||
|
||||
# Analog to digital converter (ADC)
|
||||
* In nrf52-land, the ADC is called [SSADC](https://infocenter.nordicsemi.com/index.jsp?topic=%2Fcom.nordic.infocenter.sdk5.v15.0.0%2Fgroup__nrf__adc.html)
|
||||
* Example in the sdk: in `examples/peripheral/saadc/main.c`
|
||||
* [Docs from Adafruit](https://learn.adafruit.com/bluefruit-nrf52-feather-learning-guide/nrf52-adc). It uses Arduino's `analogRead`.
|
||||
|
||||
## Resoultion
|
||||
The default resolution is 10 bits (1024 values),
|
||||
|
||||
## Reference value
|
||||
The default reference is an internally supplied 3.6V. It seems like we woulld only be able to read values up to 3.6V. This might be enough if we're using a CR2032 coin cell, but might not if we use a LiPo (4.2V fully charged).
|
||||
|
||||
**Question**: what happens if Vcc < 3.6?
|
||||
|
||||
There is a possibility of using Vcc as a reference. Then I imagine 0 -> 0V; 1024 -> Vcc. This might be exactly what we want:
|
||||
In a PWM positive pulse, our RC_parasitic will rise to 0.63Vcc in R*C_para time. If we use Vcc as a reference for the ADC, I think we "cancel out" the Vcc factor.
|
||||
|
||||
* How adafruit uses the Vcc reference: [link](https://github.com/adafruit/Adafruit_nRF52_Arduino/blob/master/cores/nRF5/wiring_analog_nRF52.c#L76)
|
||||
* How arduino-nRF5 uses the Vcc refenrece: [link](https://github.com/sandeepmistry/arduino-nRF5/blob/master/cores/nRF5/wiring_analog_nRF52.c#L98)
|
||||
|
||||
So in Arduino land, using AR_VDD4 does all we need: use nrf's SAADC_CH_CONFIG_REFSEL_VDD1_4 (Vcc/4 ref) and a gain of 4 (SAADC_CH_CONFIG_GAIN_Gain1_4).
|
||||
While connected via USB, with:
|
||||
```
|
||||
analogReference(AR_VDD4);
|
||||
int sens_val = analogRead(kSensAnalogPin);
|
||||
```
|
||||
I'm getting ~680 when in the air; ~65 while holding the sensor. The default resolution is 10 bits, so 1024 -> 3.3V. On the scope, I'm reading the sensor output value to be 2.16V. This matches the value I'm reading: 1024/3.3 * 2.15 = 667. Nice.
|
||||
|
||||
# Battery
|
||||
* [CR2032 datasheet](https://data.energizer.com/pdfs/cr2032.pdf)
|
||||
* 235 mAh (from 3.0V to 2.0V)
|
||||
* Typical discharge current: 0.19 mA -> 1200 hours
|
||||
|
||||
# Battery monitoring
|
||||
* Good post on how to measure lipo batteries: [link](https://devzone.nordicsemi.com/nordic/nordic-blog/b/blog/posts/measuring-lithium-battery-voltage-with-nrf52#:~:text=To%20reduce%20the%20leakage%20current,of%2040%20us%2C%20see%20here.)
|
||||
|
||||
# OTA
|
||||
Loading…
Add table
Reference in a new issue