1. Inleiding
Op de agenda stond de taak om een communicatieprotocol te ontwikkelen voor de microcontroller nrf52832 met twee halfbruggen Chinese tenso-sensoren.
De taak bleek niet eenvoudig te zijn, aangezien ik te maken kreeg met het ontbreken van enige duidelijke informatie. Het lijkt erop dat de 'wortel van het kwaad' zich in de SDK van Nordic Semiconductor bevindt — de constante versies updates, enige overbodigheid en verwarring over de functionaliteit. Ik moest alles vanaf nul schrijven.
Ik denk dat dit onderwerp vrij relevant is, gezien het feit dat deze chip over een BLE-stack beschikt en een hele reeks 'snufjes' voor energiebesparingsmodus heeft. Maar ik ga niet diep op de technische details in, aangezien er al veel artikelen over dit onderwerp zijn geschreven.
2. Projectbeschrijving

Hardware:
- Adafruit Feather nRF52 Bluefruit LE (hetgeen dat voorhanden was)
- ADC HX711
- Chinese tenso-sensoren 2 st. (50x2 kg)
- Programmer ST-LINK V2
Software:
- IDE VSCODE
- NRF SDK 16
- OpenOCD
- Programmer ST-LINK V2
Alles is in één project, ik zal alleen de Makefile moeten aanpassen (de locatie van uw SDK opgeven).
3. Codebeschrijving
We zullen de GPIOTE-module gebruiken om met de randapparatuur te werken, op basis van de binding van taken en gebeurtenissen, evenals de PPI-module om gegevens van de ene randapparatuur naar de andere te verzenden zonder tussenkomst van de processor.
ret_code_t err_code;
err_code = nrf_drv_gpiote_out_init(PD_SCK, &config); // instellen op uitgang
nrf_drv_gpiote_out_config_t config = GPIOTE_CONFIG_OUT_TASK_TOGGLE(false); // we gaan de pin omwisselen voor een impuls
err_code = nrf_drv_gpiote_out_init(PD_SCK, &config); // instellen op uitgang
We stellen de synchronisatielijn PD_SCL in als uitgang voor het genereren van impulsen van 10 μs.
nrf_drv_gpiote_in_config_t gpiote_config = GPIOTE_CONFIG_IN_SENSE_HITOLO(false); // overgang van hoog naar laag
nrf_gpio_cfg_input(DOUT, NRF_GPIO_PIN_NOPULL); // ingang zonder pull-up
err_code = nrf_drv_gpiote_in_init(DOUT, &gpiote_config, gpiote_evt_handler); static void gpiote_evt_handler(nrf_drv_gpiote_pin_t pin, nrf_gpiote_polarity_t action)
{
nrf_drv_gpiote_in_event_disable(DOUT); // interrupt uitschakelen
nrf_drv_timer_enable(&m_timer0); // timer inschakelen
}
We stellen de gegevenslijn DOUT in voor het uitlezen van de status van de gereedheid van de HX711; bij een laag niveau wordt de handler geactiveerd, waarin we de interrupt uitschakelen en de timer starten voor het genereren van synchroniserende impulsen op de uitgang PD_SCL.
err_code = nrf_drv_ppi_channel_alloc(&m_ppi_channel1);
APP_ERROR_CHECK(err_code);
err_code = nrf_drv_ppi_channel_assign(m_ppi_channel1, nrf_drv_timer_event_address_get(&m_timer0, NRF_TIMER_EVENT_COMPARE0), nrf_drv_gpiote_out_task_addr_get(PD_SCK)); // we connect the timer to the output
APP_ERROR_CHECK(err_code);
err_code = nrf_drv_ppi_channel_enable(m_ppi_channel1); // we enable the channel
APP_ERROR_CHECK(err_code);
nrf_drv_gpiote_out_task_enable(PD_SCK); // включаем gpiote
Daarna initialiseren we de PPI-module en verbinden we onze timer met de uitgang PD_SCL om impulsen van 10 μs te genereren bij een vergelijkingsgebeurtenis, en schakelen we ook de GPIOTE-module in.
nrf_drv_timer_config_t timer_cfg = NRF_DRV_TIMER_DEFAULT_CONFIG; // default
timer_cfg.frequency = NRF_TIMER_FREQ_1MHz; // we clock at 1 MHz
ret_code_t err_code = nrf_drv_timer_init(&m_timer0, &timer_cfg, timer0_event_handler);
APP_ERROR_CHECK(err_code);
nrf_drv_timer_extended_compare(&m_timer0,
NRF_TIMER_CC_CHANNEL0,
nrf_drv_timer_us_to_ticks(&m_timer0,
10),
NRF_TIMER_SHORT_COMPARE0_CLEAR_MASK,
true); // triggers on compareWe initialiseren de nul-timer en zijn handler.
if(m_counter%2 != 0 && m_counter<=48){
buffer <<= 1; // variable for read data
c_counter++; // counter for positive impulses
if(nrf_gpio_pin_read(DOUT))buffer++; //read the state of the input
}
Het interessantste gebeurt in de timer-handler. De periode van de impulsen bedraagt 20 μs. We zijn geïnteresseerd in oneven impulsen (bij de opgaande flanken) onder de voorwaarde dat hun aantal niet meer dan 24 is, en dat van de gebeurtenissen - 48. Bij elke oneven gebeurtenis wordt DOUT weergegeven.
Uit de datasheet blijkt dat het aantal impulsen minimaal 25 moet zijn, wat overeenkomt met een versterkingsfactor van 128 (in de code heb ik 25 impulsen gebruikt), dit is equivalent aan 50 timergebeurtenissen, wat aangeeft dat het gegevensframe is afgelopen.
++m_counter; // event counter
if(m_counter==50){
nrf_drv_timer_disable(&m_timer0); // we disable the timer
m_simple_timer_state = SIMPLE_TIMER_STATE_STOPPED; //
buffer = buffer ^ 0x800000;
hx711_stop(); // we disable hx711
}
Daarna schakelen we de timer uit en verwerken we de gegevens (volgens de datasheet) en zetten we de HX711 in de laag-energiebesparingsmodus.
static void repeated_timer_handler(void * p_context)
{
nrf_drv_gpiote_out_toggle(LED_2);
if(m_simple_timer_state == SIMPLE_TIMER_STATE_STOPPED){
hx711_start();// starten van hx711
nrf_drv_gpiote_out_toggle(LED_1);
m_simple_timer_state = SIMPLE_TIMER_STATE_STARTED;
}
}
/**@brief Timer aanmaken.
*\/
static void create_timers()
{
ret_code_t err_code;
// Timer aanmaken
err_code = app_timer_create(&m_repeated_timer_id,
APP_TIMER_MODE_REPEATED,
repeated_timer_handler);
APP_ERROR_CHECK(err_code);
}
We wachten op een gebeurtenis van de RTC-timer met een interval van 10 s (dit is aan uw eigen discretion). In de handler starten we de HX711 door een onderbreking op de DOUT-lijn te activeren.
Er is nog een ander punt, de logs worden weergegeven via UART (baudrate 115200, TX - pin 6, RX - pin 8) alle instellingen bevinden zich in sdk_config.h.

Conclusies
Bedankt iedereen voor uw aandacht, ik hoop dat dit artikel nuttig zal zijn en waardevolle tijd zal besparen voor ontwikkelaars die naar een oplossing zoeken. Ik wil zeggen dat de technische aanpak die Nordic gebruikt in zijn platforms interessant is vanuit het oogpunt van energie-efficiëntie.
P.S.
Het project is nog in ontwikkeling, dus als dit onderwerp u interesseert, zal ik in het volgende artikel proberen het algoritme voor het kalibreren van gewichtssensoren en het aansluiten van de BLE-stack te beschrijven.
Materialen
Bron: habr.com
