Como conectar HX711 ADC a NRF52832

1. 1. Introdução

Em pauta estava a tarefa de desenvolver um protocolo de comunicação para o microcontrolador nrf52832 com dois extensômetros chineses de meia ponte.

A tarefa acabou por não ser fácil, pois me deparei com a falta de informações inteligíveis. É mais provável que a “raiz do mal” esteja no SDK da própria Nordic Semiconductor – atualizações constantes de versão, alguma redundância e funcionalidades confusas. Tive que escrever tudo do zero.

Acho que este tópico é bastante relevante pelo fato de este chip possuir uma pilha BLE e todo um conjunto de “guloseimas” para o modo de economia de energia. Mas não vou me aprofundar muito na parte técnica, já que muitos artigos foram escritos sobre esse tema.

2. Descrição do projeto

Como conectar HX711 ADC a NRF52832

Ferro:

  • Adafruit Feather nRF52 Bluefruit LE (o que estava em mãos)
  • ADC HX711
  • Medidores de tensão chineses 2 unid. (50x2kg)
  • Programador ST-LINK V2

Programas:

  • IDE VSCODE
  • SDK NRF 16
  • OpenOCD
  • Programador ST-LINK V2

Tudo está em um projeto, basta ajustar o Makefile (especificar a localização do seu SDK).

3. Descrição do código

Utilizaremos o módulo GPIOTE para trabalhar com periféricos baseado na vinculação de tarefas e eventos, bem como o módulo PPI para transferir dados de um periférico para outro sem a participação de um processador.

ret_code_t err_code;
   err_code = nrf_drv_gpiote_out_init(PD_SCK, &config);//настраеваем на выход
   nrf_drv_gpiote_out_config_t config = GPIOTE_CONFIG_OUT_TASK_TOGGLE(false);//будем передергивать пин для импульса
   err_code = nrf_drv_gpiote_out_init(PD_SCK, &config);//настраеваем на выход

Configuramos a linha de sincronização PD_SCL para a saída para gerar pulsos com duração de 10 μs.

   nrf_drv_gpiote_in_config_t  gpiote_config = GPIOTE_CONFIG_IN_SENSE_HITOLO(false);// переход уровня с высокого на низкий
   nrf_gpio_cfg_input(DOUT, NRF_GPIO_PIN_NOPULL);// на вход без подтяжки
   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);//отключаем прерывание
    nrf_drv_timer_enable(&m_timer0);//включаем таймер
}
 

Configuramos a linha de dados DOUT para ler o estado de prontidão do HX711; se houver nível baixo, é acionado um manipulador no qual desabilitamos a interrupção e iniciamos um timer para gerar pulsos de clock na saída 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));// подключаем таймер к выходу
   APP_ERROR_CHECK(err_code);
   err_code = nrf_drv_ppi_channel_enable(m_ppi_channel1);// включаем канал
   APP_ERROR_CHECK(err_code);
   nrf_drv_gpiote_out_task_enable(PD_SCK); 

// habilita o gpiote

Em seguida, inicializamos o módulo PPI e conectamos nosso temporizador à saída PD_SCL para gerar pulsos com duração de 10 μs quando ocorrer um evento de comparação, e também ligamos o módulo GPIOTE.


nrf_drv_timer_config_t timer_cfg = NRF_DRV_TIMER_DEFAULT_CONFIG;// по умолчанию
   timer_cfg.frequency = NRF_TIMER_FREQ_1MHz;// тактируем на частоте 1Мгц
   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);// срабатывает по сравнению

Inicializamos o temporizador zero e seu manipulador.

  if(m_counter%2 != 0 && m_counter<=48){
       buffer <<= 1;// переменная считанных даных
        c_counter++;// счетчик положительных  импульсов
           if(nrf_gpio_pin_read(DOUT))buffer++;//считываем состояние входа
   }

O mais interessante acontece no manipulador do timer. O período de pulso é de 20 μs. Estamos interessados ​​​​em pulsos ímpares (ao longo da borda ascendente) e desde que seu número não seja superior a 24 e haja 48 eventos. Para cada evento ímpar, DOUT é lido

Segue-se da ficha técnica que o número de pulsos deve ser no mínimo 25, o que corresponde a um ganho de 128 (no código usei 25 pulsos), isso equivale a 50 eventos temporizadores, o que indica o fim do quadro de dados.

 ++m_counter;// счетчик событий
if(m_counter==50){
      nrf_drv_timer_disable(&m_timer0);// отключаем таймер
       m_simple_timer_state = SIMPLE_TIMER_STATE_STOPPED;//
       buffer = buffer ^ 0x800000;
       hx711_stop();//jотключаем hx711
       }
   

Depois disso, desligamos o timer e processamos os dados (conforme ficha técnica) e colocamos o HX711 em modo de baixo consumo de energia.


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();// включаем hx711
       nrf_drv_gpiote_out_toggle(LED_1);
       m_simple_timer_state = SIMPLE_TIMER_STATE_STARTED;
   }
  
}
/**@brief Create timers.
*/
static void create_timers()
{
   ret_code_t err_code;
 
   // Create timers
   err_code = app_timer_create(&m_repeated_timer_id,
                               APP_TIMER_MODE_REPEATED,
                               repeated_timer_handler);
   APP_ERROR_CHECK(err_code);
}

Esperamos eventos do temporizador RTC com intervalo de 10 s (a seu critério) e lançamos o HX711 no manipulador, causando uma interrupção na linha DOUT.

Há mais um ponto, os logs são gerados via UART (taxa de transmissão 115200, TX - 6 pinos, RX - 8 pinos) todas as configurações estão em sdk_config.h

Como conectar HX711 ADC a NRF52832

Descobertas

Obrigado a todos pela atenção, espero que este artigo seja útil e reduza o tempo valioso para os desenvolvedores encontrarem uma solução. Quero dizer que a abordagem técnica que a Nordic utiliza nas suas plataformas é bastante interessante do ponto de vista da eficiência energética.

PS

O projeto ainda está em desenvolvimento, então se este tópico for de interesse, no próximo artigo tentarei descrever o algoritmo para calibração de sensores de peso, bem como conexão da pilha BLE.

materiais

Fonte: habr.com

Adicionar um comentário