Hi,
I am working with ANT bpwr tx profile and trying to implement HX711 and TWI sensor to it. TWI sensor is already working, but when I add library for HX711 from Vidar Berg and start sampling HX711, the ant transmission looks like it stops transmitting, or lose all packets. I can see it in AntWare II, that when hx711_start(false) function is called, AntWare can not see any transmitting device and i can see data from hx711 printing in debug terminal, but when I comment this function and let it how it was before, AntWare II can see the device and is able to receive data, so i know, that there is some conflict between hx711 data sampling and ant+ data transmission, but the project compiles succesfull. Do somebody know, what might be the problem?
using nRF52832, SDK15.2, Segger embedded studio, and library written by Vidar
thanks in advance
/******************************************************************************/ /* */ /******************************************************************************/ #include <stdint.h> #include <string.h> #include "hx711.h" #include "nrf_drv_gpiote.h" #include "app_util_platform.h" #include "boards.h" #include "nrf_delay.h" #define NRF_LOG_MODULE_NAME hx711 #if HX711_CONFIG_LOG_ENABLED #define NRF_LOG_LEVEL HX711_CONFIG_LOG_LEVEL #define NRF_LOG_INFO_COLOR HX711_CONFIG_INFO_COLOR #define NRF_LOG_DEBUG_COLOR HX711_CONFIG_DEBUG_COLOR #else // HX711_CONFIG_LOG_ENABLED #define NRF_LOG_LEVEL 0 #endif // HX711_CONFIG_LOG_ENABLED #include "nrf_log.h" NRF_LOG_MODULE_REGISTER(); /* Defines frequency and duty cycle for clock signal - default: 1 MHz 50%*/ #define TIMER_COUNTERTOP 32 #define TIMER_COMPARE 16 // Pinout #define PD_SCK 23 #define DOUT 24 #define VDD 25 // Note: Depending on design, GPIO may not be able to source enough current for hx711 and loadcell. /* HX711 ADC resolution in bits */ #define ADC_RES 24 typedef struct { uint32_t value; // buffer for ADC read uint8_t count; // number of bitshifts. Read complete when count == ADC_RES }hx711_sample_t; static volatile hx711_sample_t m_sample; static hx711_event_handler_t m_evt_handler; static uint32_t m_mode; static bool m_continous_sampling; static int convert_sample(uint32_t sample) { return (int)(sample << 8) >> 8; } /* Clocks out HX711 result - if readout fails consistently, try to increase the clock period and/or enable compiler optimization */ static void hx711_sample() { NRF_TIMER2->TASKS_CLEAR = 1; m_sample.count = 0; m_sample.value = 0; NRF_TIMER1->TASKS_START = 1; // Starts clock signal on PD_SCK for (uint32_t i=0; i < ADC_RES; i++) { do { /* NRF_TIMER->CC[1] contains number of clock cycles.*/ NRF_TIMER2->TASKS_CAPTURE[1] = 1; if (NRF_TIMER2->CC[1] >= ADC_RES) goto EXIT; // Readout not in sync with PD_CLK. Abort and notify error. } while(NRF_TIMER1->EVENTS_COMPARE[0] == 0); NRF_TIMER1->EVENTS_COMPARE[0] = 0; m_sample.value |= (nrf_gpio_pin_read(DOUT) << (23 - i)); m_sample.count++; } EXIT: if (!m_continous_sampling) { NRF_GPIOTE->TASKS_SET[1] = 1; // HX711 power-down } NRF_LOG_INFO("Number of bits : %d", m_sample.count); NRF_LOG_INFO("ADC val: 0x%x", m_sample.value); if (m_sample.count == ADC_RES) { // Send notification with raw ADC value m_evt_handler(DATA_READY, convert_sample(m_sample.value)); } else { // Notify readout error m_evt_handler(DATA_ERROR, m_sample.value); } } static void gpiote_evt_handler(nrf_drv_gpiote_pin_t pin, nrf_gpiote_polarity_t action) { nrf_drv_gpiote_in_event_disable(DOUT); hx711_sample(); if (m_continous_sampling) { nrf_drv_gpiote_in_event_enable(DOUT, true); } } void hx711_init(hx711_mode_t mode, hx711_event_handler_t evt_handler) { ret_code_t ret_code; nrf_drv_gpiote_in_config_t gpiote_config = GPIOTE_CONFIG_IN_SENSE_HITOLO(false); m_evt_handler = evt_handler; m_mode = mode; nrf_gpio_cfg_output(PD_SCK); nrf_gpio_pin_set(PD_SCK); nrf_gpio_cfg(VDD, NRF_GPIO_PIN_DIR_OUTPUT, NRF_GPIO_PIN_INPUT_DISCONNECT, NRF_GPIO_PIN_PULLUP, NRF_GPIO_PIN_S0H1, NRF_GPIO_PIN_NOSENSE); nrf_gpio_pin_set(VDD); nrf_gpio_cfg_input(DOUT, NRF_GPIO_PIN_NOPULL); if (!nrf_drv_gpiote_is_init()) { ret_code = nrf_drv_gpiote_init(); APP_ERROR_CHECK(ret_code); } ret_code = nrf_drv_gpiote_in_init(DOUT, &gpiote_config, gpiote_evt_handler); APP_ERROR_CHECK(ret_code); /* Set up timers, gpiote, and ppi for clock signal generation*/ NRF_TIMER1->CC[0] = 1; NRF_TIMER1->CC[1] = TIMER_COMPARE; NRF_TIMER1->CC[2] = TIMER_COUNTERTOP; NRF_TIMER1->SHORTS = (uint32_t) (1 << 2); //COMPARE2_CLEAR NRF_TIMER1->PRESCALER = 0; NRF_TIMER2->CC[0] = m_mode; NRF_TIMER2->MODE = 2; NRF_GPIOTE->CONFIG[1] = (uint32_t) (3 | (PD_SCK << 8) | (1 << 16) | (1 << 20)); NRF_PPI->CH[0].EEP = (uint32_t) &NRF_TIMER1->EVENTS_COMPARE[0]; NRF_PPI->CH[0].TEP = (uint32_t) &NRF_GPIOTE->TASKS_SET[1]; NRF_PPI->CH[1].EEP = (uint32_t) &NRF_TIMER1->EVENTS_COMPARE[1]; NRF_PPI->CH[1].TEP = (uint32_t) &NRF_GPIOTE->TASKS_CLR[1]; NRF_PPI->FORK[1].TEP = (uint32_t) &NRF_TIMER2->TASKS_COUNT; // Increment on falling edge NRF_PPI->CH[2].EEP = (uint32_t) &NRF_TIMER2->EVENTS_COMPARE[0]; NRF_PPI->CH[2].TEP = (uint32_t) &NRF_TIMER1->TASKS_SHUTDOWN; NRF_PPI->CHEN = 7; } void hx711_power_down() { nrf_gpio_cfg_default(VDD); nrf_gpio_cfg_default(PD_SCK); nrf_gpio_cfg_default(DOUT); } void hx711_start(bool single) { m_continous_sampling = !single; NRF_LOG_INFO("Start sampling"); NRF_GPIOTE->TASKS_CLR[1] = 1; // Generates interrupt when new sampling is available. nrf_drv_gpiote_in_event_enable(DOUT, true); } void hx711_stop() { nrf_drv_gpiote_in_event_disable(DOUT); NRF_GPIOTE->TASKS_SET[1] = 1; // Must be kept high for >60 us to power down HX711 }