kopia lustrzana https://github.com/mikaelnousiainen/RS41ng
Add support for RadSens I2C radiation sensor. Improve BMP280 sensor configuration.
rodzic
82a181c520
commit
b5b10dad80
|
@ -3,7 +3,7 @@
|
|||
**NOTE:** This firmware is a work in progress and some features might not work as expected yet!
|
||||
|
||||
This is a custom, amateur radio-oriented firmware for [Vaisala RS41 radiosondes](https://www.vaisala.com/en/products/instruments-sensors-and-other-measurement-devices/soundings-products/rs41).
|
||||
Some of the code is based on an earlier RS41 firmware project called [RS41HUP](https://github.com/df8oe/RS41HUP),
|
||||
Some code is based on an earlier RS41 firmware project called [RS41HUP](https://github.com/df8oe/RS41HUP),
|
||||
but most of it has been rewritten from scratch. The Horus 4FSK code has been adapted from
|
||||
the [darksidelemm fork of RS41HUP](https://github.com/darksidelemm/RS41HUP).
|
||||
|
||||
|
@ -109,6 +109,9 @@ The following sensors are currently supported:
|
|||
|
||||
* Bosch BMP280/BME280 barometric pressure / temperature / humidity sensor
|
||||
* Note that only BME280 sensors will report humidity. For BMP280 humidity readings will be zero.
|
||||
* RadSens universal dosimeter-radiometer module for measuring radiation
|
||||
* https://www.tindie.com/stores/climateguard/
|
||||
* https://github.com/climateguard/RadSens
|
||||
|
||||
Sensor driver code contributions are welcome!
|
||||
|
||||
|
|
|
@ -1,5 +1,14 @@
|
|||
project(RS41ng C CXX)
|
||||
|
||||
set(CMAKE_FIND_ROOT_PATH /usr/arm-none-eabi)
|
||||
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
|
||||
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
|
||||
|
||||
set(COLLECT_GCC ${TOOLCHAIN_PATH}/arm-none-eabi-gcc)
|
||||
|
||||
if (UNIX)
|
||||
set(TOOLCHAIN_PATH /usr/bin)
|
||||
set(CMAKE_C_COMPILER ${TOOLCHAIN_PATH}/arm-none-eabi-gcc)
|
||||
|
@ -19,7 +28,7 @@ add_definitions(-DSUPPORT_CPLUSPLUS)
|
|||
add_definitions(-D__ASSEMBLY__)
|
||||
|
||||
SET(LINKER_SCRIPT arm-gcc-link.ld)
|
||||
SET(COMMON_FLAGS " -mcpu=cortex-m3 -mthumb -Wall -ffunction-sections -fdata-sections -g -O3 -nostartfiles")
|
||||
SET(COMMON_FLAGS " -mcpu=cortex-m3 -mthumb -Wall -ffunction-sections -fdata-sections -O3 -nostartfiles")
|
||||
SET(CMAKE_CXX_FLAGS "${COMMON_FLAGS} -std=c++11")
|
||||
SET(CMAKE_C_FLAGS "${COMMON_FLAGS} -std=gnu99")
|
||||
SET(CMAKE_EXE_LINKER_FLAGS "-Wl,-Map=${CMAKE_BINARY_DIR}/${PROJECT_NAME}.map -lstdc++ -O3 -mcpu=cortex-m3 -mthumb -Wl,--gc-sections --specs=nano.specs -T ${LINKER_SCRIPT}")
|
||||
|
|
|
@ -9,7 +9,7 @@ static bool bmp280_initialization_required = true;
|
|||
bool bmp280_handler_init()
|
||||
{
|
||||
bmp280_dev.port = &DEFAULT_I2C_PORT;
|
||||
bmp280_dev.addr = BMP280_I2C_ADDRESS_1;
|
||||
bmp280_dev.addr = SENSOR_BMP280_I2C_ADDRESS;
|
||||
|
||||
bmp280_params_t bmp280_params = {
|
||||
.mode = BMP280_MODE_NORMAL,
|
||||
|
|
|
@ -49,10 +49,17 @@ size_t horus_packet_v2_create(uint8_t *payload, size_t length, telemetry_data *d
|
|||
|
||||
uint8_t *custom_data_pointer = horus_packet.CustomData;
|
||||
|
||||
// Unit: cm/s
|
||||
int16_t gps_climb_cm_per_second = (int16_t) gps_data->climb_cm_per_second;
|
||||
memcpy(custom_data_pointer, &gps_climb_cm_per_second, sizeof(gps_climb_cm_per_second));
|
||||
custom_data_pointer += sizeof(gps_climb_cm_per_second);
|
||||
if (radsens_enabled) {
|
||||
// Unit: µR/h
|
||||
uint16_t ext_radiation_intensity_uR_h = (uint16_t) data->radiation_intensity_uR_h;
|
||||
memcpy(custom_data_pointer, &ext_radiation_intensity_uR_h, sizeof(ext_radiation_intensity_uR_h));
|
||||
custom_data_pointer += sizeof(ext_radiation_intensity_uR_h);
|
||||
} else {
|
||||
// Unit: cm/s
|
||||
int16_t gps_climb_cm_per_second = (int16_t) gps_data->climb_cm_per_second;
|
||||
memcpy(custom_data_pointer, &gps_climb_cm_per_second, sizeof(gps_climb_cm_per_second));
|
||||
custom_data_pointer += sizeof(gps_climb_cm_per_second);
|
||||
}
|
||||
|
||||
// Unit: Celsius * 10
|
||||
int16_t ext_temp_celsius_10 = (int16_t) (data->temperature_celsius_100 / 10.0f);
|
||||
|
@ -68,7 +75,7 @@ size_t horus_packet_v2_create(uint8_t *payload, size_t length, telemetry_data *d
|
|||
uint16_t ext_pressure_mbar = (uint16_t) (data->pressure_mbar_100 / 10.0f);
|
||||
memcpy(custom_data_pointer, &ext_pressure_mbar, sizeof(ext_pressure_mbar));
|
||||
|
||||
if (pulse_counter_enabled) {
|
||||
if (pulse_counter_enabled || radsens_enabled) {
|
||||
// Unit: pulse count
|
||||
custom_data_pointer += sizeof(ext_pressure_mbar);
|
||||
uint16_t ext_pulse_count = (uint16_t) data->pulse_count;
|
||||
|
|
12
src/config.c
12
src/config.c
|
@ -26,6 +26,7 @@
|
|||
* $cl - Climb in m/s (up to 2 chars)
|
||||
* $he - Heading in degrees (up to 3 chars)
|
||||
* $pc - Pulse counter value (wraps to zero at 65535, 16-bit unsigned value)
|
||||
* $ri - Radiation intensity in µR/h (up to 5 chars)
|
||||
*
|
||||
* Allowed message lengths:
|
||||
*
|
||||
|
@ -43,6 +44,7 @@
|
|||
|
||||
bool leds_enabled = LEDS_ENABLE;
|
||||
bool bmp280_enabled = SENSOR_BMP280_ENABLE;
|
||||
bool radsens_enabled = SENSOR_RADSENS_ENABLE;
|
||||
bool si5351_enabled = RADIO_SI5351_ENABLE;
|
||||
bool gps_nmea_output_enabled = GPS_NMEA_OUTPUT_VIA_SERIAL_PORT_ENABLE;
|
||||
bool pulse_counter_enabled = PULSE_COUNTER_ENABLE;
|
||||
|
@ -54,7 +56,10 @@ volatile bool system_initialized = false;
|
|||
* Maximum length: 64 characters.
|
||||
*/
|
||||
char *cw_message_templates[] = {
|
||||
"$cs $loc6 $altm $gs km/h $tiC",
|
||||
// "$cs $loc6 $altm $gs km/h $tiC",
|
||||
// "$cs $loc6",
|
||||
// "$alt m",
|
||||
// "$gs km/h $ti C",
|
||||
NULL
|
||||
};
|
||||
|
||||
|
@ -76,7 +81,8 @@ char *aprs_comment_templates[] = {
|
|||
// " B$bu $teC $hu% $prmb $hh:$mm:$ss @ $tow ms - " APRS_COMMENT,
|
||||
// " B$bu $teC $hu% $prmb - " APRS_COMMENT,
|
||||
// " B$bu $loc12 $hh:$mm:$ss - " APRS_COMMENT,
|
||||
" $loc12 - " APRS_COMMENT,
|
||||
// " $loc12 - " APRS_COMMENT,
|
||||
// " $teC $hu% $prmb PC $pc RI $ri uR/h - " APRS_COMMENT,
|
||||
// " " APRS_COMMENT,
|
||||
NULL
|
||||
};
|
||||
|
@ -86,7 +92,7 @@ char *aprs_comment_templates[] = {
|
|||
* Maximum length: 130 characters.
|
||||
*/
|
||||
char *fsq_comment_templates[] = {
|
||||
"TEST $loc6 $altm $tiC",
|
||||
// "TEST $loc6 $altm $tiC",
|
||||
// " $lat $lon, $alt m, $cl m/s, $gs km/h, $he deg - " FSQ_COMMENT,
|
||||
// " $loc12, $teC $hu% $prmb $hh:$mm:$ss @ $tow ms - " FSQ_COMMENT,
|
||||
NULL
|
||||
|
|
12
src/config.h
12
src/config.h
|
@ -32,6 +32,18 @@
|
|||
// Enable use of an externally connected I²C BMP280/BME280 atmospheric sensor
|
||||
// NOTE: Only BME280 sensors will report humidity. For BMP280 humidity readings will be zero.
|
||||
#define SENSOR_BMP280_ENABLE false
|
||||
// BMP280/BME280 I²C device address is usually 0x76 or 0x77.
|
||||
#define SENSOR_BMP280_I2C_ADDRESS 0x77
|
||||
|
||||
// Enable use of an externally connected I²C RadSens radiation sensor
|
||||
#define SENSOR_RADSENS_ENABLE false
|
||||
// Expected RadSens chip ID to verify initialization of the sensor, default is 0x7D.
|
||||
#define SENSOR_RADSENS_CHIP_ID 0x7D
|
||||
// RadSens I²C device address, default is 0x66.
|
||||
#define SENSOR_RADSENS_I2C_ADDRESS 0x66
|
||||
// Uncomment to set RadSens sensor sensitivity (imp/MKR). The default value is 105 imp/MKR.
|
||||
// The value is stored in the non-volatile memory of the microcontroller.
|
||||
#define SENSOR_RADSENS_SENSITIVITY 105
|
||||
|
||||
// Enable use of an externally connected I²C Si5351 clock generator chip for HF radio transmissions
|
||||
#define RADIO_SI5351_ENABLE false
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
extern bool leds_enabled;
|
||||
extern bool gps_nmea_output_enabled;
|
||||
extern bool bmp280_enabled;
|
||||
extern bool radsens_enabled;
|
||||
extern bool si5351_enabled;
|
||||
extern bool pulse_counter_enabled;
|
||||
|
||||
|
|
|
@ -1,5 +1,10 @@
|
|||
#ifndef __PULSE_COUNTER_H
|
||||
#define __PULSE_COUNTER_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
void pulse_counter_init(int pin_mode, int edge);
|
||||
uint16_t pulse_counter_get_count();
|
||||
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,212 @@
|
|||
/**
|
||||
* RadSens - universal dosimeter-radiometer module
|
||||
*
|
||||
* Driver code adapted from https://github.com/climateguard/RadSens
|
||||
* Original license GPL 3.0.
|
||||
*/
|
||||
|
||||
#include "radsens.h"
|
||||
#include "../../hal/delay.h"
|
||||
|
||||
RadSens::RadSens(i2c_port *port, uint8_t sensor_address)
|
||||
{
|
||||
_port = port;
|
||||
_sensor_address = sensor_address;
|
||||
}
|
||||
|
||||
RadSens::~RadSens()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialization function and sensor connection. Returns false if the sensor is not connected to the I2C bus.
|
||||
*/
|
||||
bool RadSens::init()
|
||||
{
|
||||
uint8_t res[2];
|
||||
if (!i2c_read(RS_REG_DEVICE_ID, res, 2)) {
|
||||
return false;
|
||||
}
|
||||
_chip_id = res[0];
|
||||
_firmware_ver = res[1];
|
||||
updatePulses();
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get chip id, default value: 0x7D.
|
||||
*/
|
||||
uint8_t RadSens::getChipId()
|
||||
{
|
||||
return _chip_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get firmware version.
|
||||
*/
|
||||
uint8_t RadSens::getFirmwareVersion()
|
||||
{
|
||||
return _firmware_ver;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get radiation intensity (dynamic period T < 123 sec).
|
||||
*/
|
||||
float RadSens::getRadIntensityDynamic()
|
||||
{
|
||||
// It seems any I²C command will reset the pulse counter, so it must be read first
|
||||
updatePulses();
|
||||
uint8_t res[3];
|
||||
if (!i2c_read(RS_REG_RAD_INTENSITY_DYNAMIC, res, 3)) {
|
||||
return -1;
|
||||
}
|
||||
return (((uint32_t) res[0] << 16) | ((uint16_t) res[1] << 8) | res[2]) / 10.0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get radiation intensity (static period T = 500 sec).
|
||||
*/
|
||||
float RadSens::getRadIntensityStatic()
|
||||
{
|
||||
// It seems any I²C command will reset the pulse counter, so it must be read first
|
||||
updatePulses();
|
||||
uint8_t res[3];
|
||||
if (!i2c_read(RS_REG_RAD_INTENSITY_STATIC, res, 3)) {
|
||||
return -1;
|
||||
}
|
||||
return (((uint32_t) res[0] << 16) | ((uint16_t) res[1] << 8) | res[2]) / 10.0;
|
||||
}
|
||||
|
||||
bool RadSens::updatePulses()
|
||||
{
|
||||
uint8_t res[2];
|
||||
if (!i2c_read(RS_REG_PULSE_COUNTER, res, 2)) {
|
||||
return false;
|
||||
}
|
||||
_pulse_count += (res[0] << 8) | res[1];
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the accumulated number of pulses registered by the module since the last I2C data reading.
|
||||
*/
|
||||
int32_t RadSens::getNumberOfPulses()
|
||||
{
|
||||
if (!updatePulses()) {
|
||||
return -1;
|
||||
}
|
||||
return _pulse_count;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get sensor address.
|
||||
*/
|
||||
uint8_t RadSens::getSensorAddress()
|
||||
{
|
||||
uint8_t res;
|
||||
if (!i2c_read(RS_REG_DEVICE_ADDRESS, &res, 1)) {
|
||||
return 0;
|
||||
}
|
||||
_sensor_address = res;
|
||||
return _sensor_address;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get state of high-voltage voltage Converter.
|
||||
*/
|
||||
bool RadSens::getHVGeneratorState()
|
||||
{
|
||||
uint8_t res;
|
||||
if (!i2c_read(RS_REG_HV_GENERATOR, &res, 1)) {
|
||||
return false;
|
||||
}
|
||||
return res == 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value coefficient used for calculating the radiation intensity.
|
||||
*/
|
||||
int16_t RadSens::getSensitivity()
|
||||
{
|
||||
uint8_t res[2];
|
||||
if (!i2c_read(RS_REG_SENSITIVITY, res, 2)) {
|
||||
return -1;
|
||||
}
|
||||
return res[1] * 256 + res[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Control register for a high-voltage voltage Converter. By default, it is in the enabled state.
|
||||
* To enable the HV generator, write 1 to the register, and 0 to disable it. If you try to write other
|
||||
* values, the command is ignored.
|
||||
* @param state true - generator on / false - generator off
|
||||
*/
|
||||
bool RadSens::setHVGeneratorState(bool state)
|
||||
{
|
||||
return i2c_write(RS_REG_HV_GENERATOR, state ? 1 : 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Contains the value coefficient used for calculating the radiation intensity.
|
||||
* If necessary (for example, when installing a different type of counter), the necessary sensitivity value in
|
||||
* Imp / uR is entered in the register. The default value is 105 Imp / uR. At the end of
|
||||
* recording, the new value is stored in the non-volatile memory of the microcontroller.
|
||||
* @param sens sensitivity coefficient in Impulse / uR
|
||||
*/
|
||||
bool RadSens::setSensitivity(uint16_t sens)
|
||||
{
|
||||
if (!i2c_write(RS_REG_SENSITIVITY, (uint8_t)(sens & 0xFF))) {
|
||||
return false;
|
||||
}
|
||||
delay_ms(15);
|
||||
|
||||
if (!i2c_write(RS_REG_SENSITIVITY + 1, (uint8_t)(sens >> 8))) {
|
||||
return false;
|
||||
}
|
||||
delay_ms(15);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Control register for an indication diode. By default, it is in the enabled state. To enable the indication,
|
||||
* write 1 to the register, and 0 to disable it. If you try to write other values, the command is ignored.
|
||||
* @param state true - diode on / false - diode off
|
||||
*/
|
||||
bool RadSens::setLedState(bool state)
|
||||
{
|
||||
bool result = i2c_write(RS_REG_LED_CONTROL, state ? 1 : 0);
|
||||
delay_ms(15);
|
||||
return result;
|
||||
}
|
||||
|
||||
/*Get state of led indication.*/
|
||||
bool RadSens::getLedState()
|
||||
{
|
||||
uint8_t res;
|
||||
if (!i2c_read(RS_REG_LED_CONTROL, &res, 1)) {
|
||||
return false;
|
||||
}
|
||||
return res == 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read block of data
|
||||
* @param reg - address of starting register
|
||||
* @param dest - destination array
|
||||
* @param num - number of bytes to read
|
||||
*/
|
||||
bool RadSens::i2c_read(uint8_t reg, uint8_t *dest, uint8_t num)
|
||||
{
|
||||
return i2c_read_bytes(_port, _sensor_address, reg, num, dest) == HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write a byte of data
|
||||
* @param reg - address of starting register
|
||||
* @param data - byte of data to write
|
||||
*/
|
||||
bool RadSens::i2c_write(uint8_t reg, uint8_t data)
|
||||
{
|
||||
return i2c_write_byte(_port, _sensor_address, reg, data) == HAL_OK;
|
||||
}
|
|
@ -0,0 +1,103 @@
|
|||
/**
|
||||
* RadSens - universal dosimeter-radiometer module
|
||||
*
|
||||
* Driver code adapted from https://github.com/climateguard/RadSens
|
||||
* Original license GPL 3.0.
|
||||
*/
|
||||
|
||||
#ifndef __RADSENS_H
|
||||
#define __RADSENS_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "hal/i2c.h"
|
||||
|
||||
#define RS_REG_COUNT 21
|
||||
|
||||
// Default RadSens I2C device address
|
||||
#define RS_DEFAULT_I2C_ADDRESS 0x66
|
||||
|
||||
// Device id, default value: 0x7D
|
||||
// Size: 8 bit
|
||||
#define RS_REG_DEVICE_ID 0x00
|
||||
|
||||
// Firmware version
|
||||
// Size: 8 bit
|
||||
#define RS_REG_FIRMWARE_VER 0x01
|
||||
|
||||
// Radiation intensity (dynamic period T < 123 sec)
|
||||
// Size: 24 bit
|
||||
#define RS_REG_RAD_INTENSITY_DYNAMIC 0x03
|
||||
|
||||
// Radiation intensity (static period T = 500 sec)
|
||||
// Size: 24 bit
|
||||
#define RS_REG_RAD_INTENSITY_STATIC 0x06
|
||||
|
||||
// Contains the accumulated number of pulses registered by the module since the last I2C data reading.
|
||||
// The value is reset each time it is read. Allows you to process directly the pulses from the Geiger counter
|
||||
// and implement other algorithms. The value is updated when each pulse is registered.
|
||||
// Size: 16 bit
|
||||
#define RS_REG_PULSE_COUNTER 0x09
|
||||
|
||||
// This register is used to change the device address when multiple devices need to be connected
|
||||
// to the same line at the same time. By default, it contains the value 0x66. At the end of recording, the new
|
||||
// value is stored in the non-volatile memory of the microcontroller.
|
||||
// Size: 8 bit
|
||||
// Access: R/W
|
||||
#define RS_REG_DEVICE_ADDRESS 0x10
|
||||
|
||||
// Control register for a high-voltage voltage Converter. By default, it is in the enabled state.
|
||||
// To enable the HV generator, write 1 to the register, and 0 to disable it. If you try to write other
|
||||
// values, the command is ignored.
|
||||
// Size: 8 bit
|
||||
// Access: R/W
|
||||
#define RS_REG_HV_GENERATOR 0x11
|
||||
|
||||
// Contains the value coefficient used for calculating the radiation intensity.
|
||||
// If necessary (for example, when installing a different type of counter), the necessary sensitivity value in
|
||||
// imp/MKR is entered in the register. The default value is 105 imp/MKR. At the end of
|
||||
// recording, the new value is stored in the non-volatile memory of the microcontroller.
|
||||
// Size: 16 bit
|
||||
// Access: R/W
|
||||
#define RS_REG_SENSITIVITY 0x12
|
||||
|
||||
// Control register for an indication diode. By default, it is in the enabled state. To enable the indication,
|
||||
// write 1 to the register, and 0 to disable it. If you try to write other values, the command is ignored.
|
||||
// Size: 8 bit
|
||||
// Access: R/W
|
||||
#define RS_REG_LED_CONTROL 0x14
|
||||
|
||||
class RadSens {
|
||||
private:
|
||||
i2c_port *_port;
|
||||
uint8_t _sensor_address;
|
||||
uint8_t _chip_id = 0;
|
||||
uint8_t _firmware_ver = 0;
|
||||
uint32_t _pulse_count = 0;
|
||||
|
||||
bool i2c_read(uint8_t addr, uint8_t *dest, uint8_t num);
|
||||
bool i2c_write(uint8_t reg, uint8_t data);
|
||||
|
||||
bool updatePulses();
|
||||
|
||||
public:
|
||||
RadSens(i2c_port *port, uint8_t sensor_address);
|
||||
|
||||
~RadSens();
|
||||
|
||||
bool init();
|
||||
uint8_t getChipId();
|
||||
uint8_t getFirmwareVersion();
|
||||
float getRadIntensityDynamic();
|
||||
float getRadIntensityStatic();
|
||||
int32_t getNumberOfPulses();
|
||||
uint8_t getSensorAddress();
|
||||
bool getHVGeneratorState();
|
||||
bool getLedState();
|
||||
int16_t getSensitivity();
|
||||
bool setHVGeneratorState(bool state);
|
||||
bool setSensitivity(uint16_t sens);
|
||||
bool setLedState(bool state);
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,5 +1,5 @@
|
|||
#ifndef __SI4032_H
|
||||
#define __SI4032_h
|
||||
#define __SI4032_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
|
12
src/main.c
12
src/main.c
|
@ -9,6 +9,7 @@
|
|||
#include "drivers/si4032/si4032.h"
|
||||
#include "drivers/pulse_counter/pulse_counter.h"
|
||||
#include "bmp280_handler.h"
|
||||
#include "radsens_handler.h"
|
||||
#include "si5351_handler.h"
|
||||
#include "radio.h"
|
||||
#include "config.h"
|
||||
|
@ -118,6 +119,17 @@ int main(void)
|
|||
}
|
||||
}
|
||||
|
||||
if (radsens_enabled) {
|
||||
for (int i = 0; i < 3; i++) {
|
||||
log_info("RadSens init\n");
|
||||
success = radsens_handler_init();
|
||||
if (success) {
|
||||
break;
|
||||
}
|
||||
log_error("RadSens init failed, retrying...");
|
||||
}
|
||||
}
|
||||
|
||||
if (si5351_enabled) {
|
||||
for (int i = 0; i < 3; i++) {
|
||||
log_info("Si5351 init\n");
|
||||
|
|
|
@ -849,6 +849,8 @@ void radio_init()
|
|||
|
||||
memset(¤t_telemetry_data, 0, sizeof(current_telemetry_data));
|
||||
|
||||
telemetry_collect(¤t_telemetry_data);
|
||||
|
||||
for (uint8_t i = 0; i < radio_transmit_entry_count; i++) {
|
||||
radio_transmit_entry *entry = &radio_transmit_schedule[i];
|
||||
switch (entry->data_mode) {
|
||||
|
|
|
@ -0,0 +1,175 @@
|
|||
#include <stdio.h>
|
||||
#include "drivers/radsens/radsens.h"
|
||||
#include "radsens_handler.h"
|
||||
#include "hal/delay.h"
|
||||
#include "log.h"
|
||||
|
||||
RadSens *radsens = NULL;
|
||||
|
||||
static bool radsens_initialization_required = true;
|
||||
|
||||
static bool radsens_handler_init_sensor();
|
||||
|
||||
bool radsens_handler_init()
|
||||
{
|
||||
if (radsens == NULL) {
|
||||
radsens = new RadSens(&DEFAULT_I2C_PORT, SENSOR_RADSENS_I2C_ADDRESS);
|
||||
}
|
||||
return radsens_handler_init_sensor();
|
||||
}
|
||||
|
||||
static bool radsens_handler_init_sensor()
|
||||
{
|
||||
uint16_t sensitivity;
|
||||
|
||||
bool success = radsens->init();
|
||||
radsens_initialization_required = !success;
|
||||
if (!success) {
|
||||
log_error("RadSens init failed\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
success = radsens->getChipId() == SENSOR_RADSENS_CHIP_ID;
|
||||
radsens_initialization_required = !success;
|
||||
if (!success) {
|
||||
log_error("RadSens invalid chip ID\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
sensitivity = radsens->getSensitivity();
|
||||
success = sensitivity > 0;
|
||||
radsens_initialization_required = !success;
|
||||
if (!success) {
|
||||
log_error("RadSens get sensitivity failed\n");
|
||||
return false;
|
||||
}
|
||||
log_info("RadSens initial sensitivity: %d\n", sensitivity);
|
||||
|
||||
// Give the sensor some time to start up
|
||||
delay_ms(50);
|
||||
|
||||
success = radsens->setLedState(true);
|
||||
radsens_initialization_required = !success;
|
||||
if (!success) {
|
||||
log_error("RadSens enable LED failed\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
delay_ms(200);
|
||||
|
||||
#if defined(SENSOR_RADSENS_SENSITIVITY)
|
||||
success = radsens->setSensitivity(SENSOR_RADSENS_SENSITIVITY);
|
||||
radsens_initialization_required = !success;
|
||||
if (!success) {
|
||||
log_error("RadSens set sensitivity failed\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
sensitivity = radsens->getSensitivity();
|
||||
success = sensitivity > 0;
|
||||
radsens_initialization_required = !success;
|
||||
if (!success) {
|
||||
log_error("RadSens get sensitivity failed\n");
|
||||
return false;
|
||||
}
|
||||
log_info("RadSens final sensitivity: %d\n", sensitivity);
|
||||
#endif
|
||||
|
||||
success = radsens->setHVGeneratorState(true);
|
||||
radsens_initialization_required = !success;
|
||||
if (!success) {
|
||||
log_error("RadSens HV generator enable failed\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
delay_ms(50);
|
||||
|
||||
bool enabled = radsens->getHVGeneratorState();
|
||||
radsens_initialization_required = !enabled;
|
||||
if (!enabled) {
|
||||
log_error("RadSens HV generator is not enabled\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
delay_ms(50);
|
||||
|
||||
radsens->getNumberOfPulses();
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
bool radsens_read(uint16_t *pulse_count, float *dynamic_intensity, float *static_intensity)
|
||||
{
|
||||
float radiation_intensity_static;
|
||||
float radiation_intensity_dynamic;
|
||||
uint32_t radiation_pulse_counter;
|
||||
|
||||
if (static_intensity) {
|
||||
radiation_intensity_static = radsens->getRadIntensityStatic();
|
||||
if (radiation_intensity_static < 0) {
|
||||
radsens_initialization_required = true;
|
||||
log_error("Failed to read RadSens static radiation intensity\n");
|
||||
return false;
|
||||
}
|
||||
*static_intensity = radiation_intensity_static;
|
||||
}
|
||||
|
||||
if (dynamic_intensity) {
|
||||
radiation_intensity_dynamic = radsens->getRadIntensityDynamic();
|
||||
if (radiation_intensity_dynamic < 0) {
|
||||
radsens_initialization_required = true;
|
||||
log_error("Failed to read RadSens dynamic radiation intensity\n");
|
||||
return false;
|
||||
}
|
||||
*dynamic_intensity = radiation_intensity_dynamic;
|
||||
}
|
||||
|
||||
if (pulse_count) {
|
||||
radiation_pulse_counter = radsens->getNumberOfPulses();
|
||||
if (radiation_pulse_counter < 0) {
|
||||
radsens_initialization_required = true;
|
||||
log_error("Failed to read RadSens pulse counter\n");
|
||||
return false;
|
||||
}
|
||||
*pulse_count = (uint16_t) (radiation_pulse_counter % 0x10000);
|
||||
}
|
||||
|
||||
// log_info("PC: %d RI: %d\n", radiation_pulse_counter, (int) radiation_intensity_dynamic);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool radsens_read_telemetry(telemetry_data *data)
|
||||
{
|
||||
bool success;
|
||||
|
||||
if (radsens_initialization_required) {
|
||||
log_info("RadSens re-init\n");
|
||||
success = radsens_handler_init_sensor();
|
||||
log_info("RadSens re-init: %d\n", success);
|
||||
if (!success) {
|
||||
// Pulse counter does not need to be zeroed
|
||||
data->radiation_intensity_uR_h = 0;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
success = radsens_read(&data->pulse_count, &data->radiation_intensity_uR_h, NULL);
|
||||
|
||||
if (!success) {
|
||||
log_info("RadSens re-init\n");
|
||||
success = radsens_handler_init_sensor();
|
||||
log_info("RadSens re-init: %d\n", success);
|
||||
|
||||
if (success) {
|
||||
success = radsens_read(&data->pulse_count, &data->radiation_intensity_uR_h, NULL);
|
||||
} else {
|
||||
// Pulse counter does not need to be zeroed
|
||||
data->radiation_intensity_uR_h = 0;
|
||||
}
|
||||
}
|
||||
|
||||
radsens_initialization_required = !success;
|
||||
|
||||
return success;
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
#ifndef __RADSENS_HANDLER_H
|
||||
#define __RADSENS_HANDLER_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include "telemetry.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
bool radsens_handler_init();
|
||||
bool radsens_read(uint16_t *pulse_count, float *dynamic_intensity, float *static_intensity);
|
||||
bool radsens_read_telemetry(telemetry_data *data);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -4,6 +4,7 @@
|
|||
#include "drivers/ubxg6010/ubxg6010.h"
|
||||
#include "drivers/pulse_counter/pulse_counter.h"
|
||||
#include "bmp280_handler.h"
|
||||
#include "radsens_handler.h"
|
||||
#include "locator.h"
|
||||
#include "config.h"
|
||||
#include "log.h"
|
||||
|
@ -20,6 +21,10 @@ void telemetry_collect(telemetry_data *data)
|
|||
bmp280_read_telemetry(data);
|
||||
}
|
||||
|
||||
if (radsens_enabled) {
|
||||
radsens_read_telemetry(data);
|
||||
}
|
||||
|
||||
if (pulse_counter_enabled) {
|
||||
data->pulse_count = pulse_counter_get_count();
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@ typedef struct _telemetry_data {
|
|||
uint32_t pressure_mbar_100;
|
||||
uint32_t humidity_percentage_100;
|
||||
uint16_t pulse_count;
|
||||
float radiation_intensity_uR_h;
|
||||
|
||||
gps_data gps;
|
||||
|
||||
|
|
|
@ -106,6 +106,10 @@ size_t template_replace(char *dest, size_t dest_len, char *src, telemetry_data *
|
|||
strlcpy(temp, dest, dest_len);
|
||||
str_replace(dest, dest_len, temp, "$pc", replacement);
|
||||
|
||||
snprintf(replacement, sizeof(replacement), "%d", (int) data->radiation_intensity_uR_h);
|
||||
strlcpy(temp, dest, dest_len);
|
||||
str_replace(dest, dest_len, temp, "$ri", replacement);
|
||||
|
||||
free(temp);
|
||||
|
||||
return len;
|
||||
|
|
Ładowanie…
Reference in New Issue