Come collegare l'ADC HX711 a NRF52832

1. introduzione

All'ordine del giorno c'era il compito di sviluppare un protocollo di comunicazione per il microcontrollore nrf52832 con due estensimetri cinesi a mezzo ponte.

Il compito si è rivelato non facile, poiché mi sono trovato di fronte alla mancanza di informazioni comprensibili. È più probabile che la "radice del male" sia nell'SDK della stessa Nordic Semiconductor: aggiornamenti costanti della versione, alcune ridondanze e funzionalità confuse. Ho dovuto scrivere tutto da zero.

Penso che questo argomento sia abbastanza rilevante in quanto questo chip ha uno stack BLE e tutta una serie di "chicche" per la modalità di risparmio energetico. Ma non entrerò troppo nella parte tecnica, dato che sono stati scritti molti articoli su questo argomento.

2. Descrizione del progetto

Come collegare l'ADC HX711 a NRF52832

Ferro:

  • Adafruit Feather nRF52 Bluefruit LE (cosa era a portata di mano)
  • ADC HX711
  • Estensimetri cinesi 2 pz. (50x2kg)
  • Programmatore ST-LINK V2

Software:

  • CODICE VS IDE
  • SDK NRF 16
  • ApriOCD
  • Programmatore ST-LINK V2

Tutto è in un unico progetto, devi solo modificare il Makefile (specificare la posizione del tuo SDK).

3. Descrizione del codice

Utilizzeremo il modulo GPIOTE per lavorare con le periferiche in base all'associazione di compiti ed eventi, nonché il modulo PPI per trasferire dati da una periferica all'altra senza la partecipazione di un processore.

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

Configuriamo la linea di sincronizzazione PD_SCL sull'uscita per generare impulsi con una durata di 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);//включаем таймер
}
 

Configuriamo la linea dati DOUT per leggere lo stato di prontezza dell'HX711; se è presente un livello basso, viene attivato un gestore in cui disabilitiamo l'interrupt e avviamo un timer per generare impulsi di clock sull'uscita 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); 

// abilita gpiote

Successivamente, inizializziamo il modulo PPI e colleghiamo il nostro timer all'uscita PD_SCL per generare impulsi con una durata di 10 μs quando si verifica un evento di confronto e accendiamo anche il modulo 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);// срабатывает по сравнению

Inizializziamo il timer zero e il suo gestore.

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

La cosa più interessante accade nel gestore del timer. Il periodo dell'impulso è di 20 μs. Siamo interessati agli impulsi dispari (lungo il fronte di salita) e a condizione che il loro numero non sia superiore a 24 e che gli eventi siano 48. Per ogni evento dispari viene letto DOUT

Dal datasheet risulta che il numero di impulsi deve essere almeno 25, che corrisponde ad un guadagno di 128 (nel codice ho usato 25 impulsi), questo equivale a 50 eventi timer, che indica la fine del frame di dati.

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

Successivamente, disattiviamo il timer ed elaboriamo i dati (secondo la scheda tecnica) e impostiamo l'HX711 in modalità a basso consumo energetico.


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

Ci aspettiamo eventi dal timer RTC con un intervallo di 10 s (questo è a tua discrezione) e lanciamo l'HX711 nell'handler, causando un'interruzione sulla linea DOUT.

C'è un altro punto, i registri vengono emessi tramite UART (velocità di trasmissione 115200, TX - 6 pin, RX - 8 pin) tutte le impostazioni sono in sdk_config.h

Come collegare l'ADC HX711 a NRF52832

risultati

Grazie a tutti per l'attenzione, spero che questo articolo sia utile e riduca il tempo prezioso affinché gli sviluppatori trovino una soluzione. Voglio dire che l'approccio tecnico che Nordic utilizza nelle sue piattaforme è piuttosto interessante dal punto di vista dell'efficienza energetica.

PS

Il progetto è ancora in fase di sviluppo, quindi se questo argomento è di vostro interesse, nel prossimo articolo cercherò di descrivere l'algoritmo per la calibrazione dei sensori di peso, nonché il collegamento dello stack BLE.

materiale

Fonte: habr.com

Aggiungi un commento