Comment connecter l'ADC HX711 au NRF52832

1. Introduction

À l'ordre du jour figurait la tâche de développer un protocole de communication pour le microcontrôleur nrf52832 avec deux jauges de contrainte chinoises en demi-pont.

La tâche s’est avérée difficile, car je me trouvais confronté à un manque d’informations intelligibles. Il est plus probable que la « racine du mal » se trouve dans le SDK de Nordic Semiconductor lui-même : mises à jour constantes des versions, certaines redondances et fonctionnalités déroutantes. J'ai dû tout écrire à partir de zéro.

Je pense que ce sujet est tout à fait pertinent étant donné que cette puce possède une pile BLE et tout un ensemble de « goodies » pour le mode économie d'énergie. Mais je n’entrerai pas trop dans la partie technique, puisque de nombreux articles ont été écrits sur ce sujet.

2. Descriptif du projet

Comment connecter l'ADC HX711 au NRF52832

Fer:

  • Adafruit Feather nRF52 Bluefruit LE (ce qui se trouvait à portée de main)
  • CAN HX711
  • Jauges de contrainte chinoises 2 pcs. (50x2kg)
  • Programmeur ST-LINK V2

Doux:

  • VSCODE IDE
  • Kit de développement logiciel (SDK) NRF 16
  • OuvrirOCD
  • Programmeur ST-LINK V2

Tout est dans un seul projet, il vous suffit de modifier le Makefile (précisez l'emplacement de votre SDK).

3. Description du code

Nous utiliserons le module GPIOTE pour travailler avec des périphériques basés sur la liaison de tâches et d'événements, ainsi que le module PPI pour transférer des données d'un périphérique à un autre sans la participation d'un processeur.

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);//настраеваем на выход

Nous configurons la ligne de synchronisation PD_SCL vers la sortie pour générer des impulsions d'une durée 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);//включаем таймер
}
 

Nous configurons la ligne de données DOUT pour lire l'état de préparation du HX711 ; s'il y a un niveau bas, un gestionnaire est déclenché dans lequel nous désactivons l'interruption et démarrons une minuterie pour générer des impulsions d'horloge à la sortie 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); 

// active gpiote

Après cela, nous initialisons le module PPI et connectons notre minuterie à la sortie PD_SCL pour générer des impulsions d'une durée de 10 μs lorsqu'un événement de comparaison se produit, et activons également le module 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);// срабатывает по сравнению

Nous initialisons le timer zéro et son gestionnaire.

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

La chose la plus intéressante se produit dans le gestionnaire de minuterie. La période d'impulsion est de 20 µs. On s'intéresse aux impulsions impaires (le long du front montant) et à condition que leur nombre ne soit pas supérieur à 24, et qu'il y ait 48 événements. Pour chaque événement impair, DOUT est lu

De la fiche technique, il s'ensuit que le nombre d'impulsions doit être d'au moins 25, ce qui correspond à un gain de 128 (dans le code j'ai utilisé 25 impulsions), cela équivaut à 50 événements de minuterie, ce qui indique la fin de la trame de données.

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

Après cela, nous éteignons la minuterie, traitons les données (selon la fiche technique) et passons le HX711 en mode faible consommation d'énergie.


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);
}

Nous attendons des événements du temporisateur RTC avec un intervalle de 10 s (c'est à votre discrétion) et lançons le HX711 dans le gestionnaire, provoquant une interruption sur la ligne DOUT.

Il y a encore un point, les journaux sont sortis via UART (débit en bauds 115200, TX - 6 broches, RX - 8 broches) tous les paramètres sont dans sdk_config.h

Comment connecter l'ADC HX711 au NRF52832

résultats

Merci à tous pour votre attention, j'espère que cet article sera utile et réduira un temps précieux aux développeurs pour trouver une solution. Je tiens à dire que l'approche technique utilisée par Nordic dans ses plateformes est assez intéressante du point de vue de l'efficacité énergétique.

PS

Le projet est encore en développement, donc si ce sujet vous intéresse, dans le prochain article j'essaierai de décrire l'algorithme de calibrage des capteurs de poids, ainsi que de connexion de la pile BLE.

matériels

Source: habr.com

Ajouter un commentaire