Cómo conectar el ADC HX711 a NRF52832

1 Introduccion

En el orden del día estaba la tarea de desarrollar un protocolo de comunicación para el microcontrolador nrf52832 con dos galgas extensométricas chinas de medio puente.

La tarea resultó no ser fácil, ya que me encontré con una falta de información inteligible. Es más probable que la "raíz del mal" esté en el SDK del propio Nordic Semiconductor: actualizaciones constantes de la versión, cierta redundancia y funcionalidad confusa. Tuve que escribir todo desde cero.

Creo que este tema es bastante relevante debido al hecho de que este chip tiene una pila BLE y un conjunto completo de "beneficios" para el modo de ahorro de energía. Pero no profundizaré mucho en la parte técnica, ya que se han escrito muchos artículos sobre este tema.

2. Descripción del proyecto

Cómo conectar el ADC HX711 a NRF52832

Hierro:

  • Adafruit Feather nRF52 Bluefruit LE (lo que resultó estar a la mano)
  • ADC HX711
  • Galgas extensométricas chinas 2 uds. (50x2 kilos)
  • Programador ST-LINK V2

Suave:

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

Todo está en un proyecto, sólo tienes que modificar el Makefile (especificar la ubicación de tu SDK).

3. Descripción del código

Usaremos el módulo GPIOTE para trabajar con periféricos en función de la vinculación de tareas y eventos, así como el módulo PPI para transferir datos de un periférico a otro sin la participación de un procesador.

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 la línea de sincronización PD_SCL a la salida para generar pulsos con una duración 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 la línea de datos DOUT para leer el estado de preparación del HX711; si hay un nivel bajo, se activa un controlador en el que deshabilitamos la interrupción e iniciamos un temporizador para generar pulsos de reloj en la salida 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); 

// habilitar gpiote

Después de eso, inicializamos el módulo PPI y conectamos nuestro temporizador a la salida PD_SCL para generar pulsos con una duración de 10 μs cuando ocurre un evento de comparación, y también encendemos el 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 el temporizador cero y su controlador.

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

Lo más interesante sucede en el controlador del temporizador. El período del pulso es de 20 μs. Nos interesan los pulsos impares (a lo largo del flanco ascendente) y siempre que su número no sea más de 24 y haya 48 eventos. Para cada evento impar, se lee DOUT

De la hoja de datos se desprende que el número de pulsos debe ser al menos 25, lo que corresponde a una ganancia de 128 (en el código utilicé 25 pulsos), esto equivale a 50 eventos del temporizador, lo que indica el final del marco de datos.

 ++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
       }
   

Después de esto, apagamos el temporizador y procesamos los datos (según la hoja de datos) y cambiamos el HX711 al modo de bajo consumo de energía.


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 del temporizador RTC con un intervalo de 10 s (esto queda a su discreción) y ejecutamos el HX711 en el controlador, provocando una interrupción en la línea DOUT.

Hay un punto más, los registros se generan a través de UART (velocidad de baudios 115200, TX - 6 pines, RX - 8 pines) todas las configuraciones están en sdk_config.h

Cómo conectar el ADC HX711 a NRF52832

Hallazgos

Gracias a todos por su atención. Espero que este artículo sea útil y reduzca el valioso tiempo para que los desarrolladores encuentren una solución. Quiero decir que el enfoque técnico que utiliza Nordic en sus plataformas es bastante interesante desde el punto de vista de la eficiencia energética.

PS

El proyecto aún está en desarrollo, por lo que si este tema es de su interés, en el próximo artículo intentaré describir el algoritmo para calibrar sensores de peso, así como para conectar la pila BLE.

materiales

Fuente: habr.com

Añadir un comentario