Come collegare l'ADC HX711 al NRF52832

1. Introduzione

L'argomento all'ordine del giorno era sviluppare un protocollo di comunicazione per il microcontrollore nrf52832 con due sensori di pressione cinesi a mezzo ponte.

Il compito si è rivelato complesso, in quanto mi sono trovato di fronte all'assenza di informazioni chiare. È probabile che «la radice del male» risieda nel SDK stesso di Nordic Semiconductor: gli aggiornamenti costanti delle versioni, alcune ridondanze e la confusione della funzionalità. Ho dovuto scrivere tutto da zero.

Penso che questo argomento sia piuttosto attuale, considerando che questo chipset possiede uno stack BLE e un intero insieme di “delizie” per la modalità di risparmio energetico. Tuttavia, non entrerò troppo nei dettagli tecnici, poiché su questo tema sono stati scritti numerosi articoli.

2. Descrizione del progetto

Come collegare l'ADC HX711 al NRF52832

Hardware:

  • Adafruit Feather nRF52 Bluefruit LE (quello che avevo a disposizione)
  • ADC HX711
  • Sensori di pressione cinesi 2 pz. (50x2 kg)
  • Programmatore ST-LINK V2

Software:

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

Tutto è all'interno di un unico progetto, dovrò solo sistemare il Makefile (indicare la posizione del proprio SDK).

3. Descrizione del codice

Utilizzeremo il modulo GPIOTE per lavorare con la periferica, in base all'associazione di compiti ed eventi, e il modulo PPI per trasferire dati da una periferica all'altra senza l'intervento del processore.

ret_code_t err_code;
   err_code = nrf_drv_gpiote_out_init(PD_SCK, &config); // impostiamo per l'uscita
   nrf_drv_gpiote_out_config_t config = GPIOTE_CONFIG_OUT_TASK_TOGGLE(false); // cambieremo il pin per l'impulso
   err_code = nrf_drv_gpiote_out_init(PD_SCK, &config); // impostiamo per l'uscita

Impostiamo il pin di sincronizzazione PD_SCL come uscita per generare impulsi di durata 10 µs.

   nrf_drv_gpiote_in_config_t gpiote_config = GPIOTE_CONFIG_IN_SENSE_HITOLO(false); // transizione di livello da alto a basso
   nrf_gpio_cfg_input(DOUT, NRF_GPIO_PIN_NOPULL); // impostato come input senza resistenza di 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); // disabilitiamo l'interruzione
    nrf_drv_timer_enable(&m_timer0); // attiviamo il timer
}
 

Impostiamo la linea dati DOUT per leggere lo stato di prontezza dell'HX711; in presenza di un livello basso, si attiva il gestore, nel quale disattiviamo l'interruzione e avviamo un timer per generare impulsi di sincronizzazione all'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); 

// включаем gpiote

Dopo di che, inizializziamo il modulo PPI e colleghiamo il nostro timer all'uscita PD_SCL, per generare impulsi della durata di 10 µs all'occorrenza dell'evento di confronto, e attiviamo anche il modulo GPIOTE.


nrf_drv_timer_config_t timer_cfg = NRF_DRV_TIMER_DEFAULT_CONFIG;
   timer_cfg.frequency = NRF_TIMER_FREQ_1MHz;
   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++;
   }

Le cose più interessanti accadono nel gestore del timer. La durata degli impulsi è di 20 µs. Siamo interessati agli impulsi dispari (sul fronte di salita) e a condizione che il loro numero non superi 24, mentre gli eventi — 48. Ad ogni evento dispari avviene la lettura di DOUT.

Dal datasheet si evince che il numero di impulsi deve essere di almeno 25, il che corrisponde a un guadagno di 128 (nel codice ho usato 25 impulsi), equivalente a 50 eventi del timer, che indica la fine del frame 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();
       }
   

Dopo di che, disattiviamo il timer e trattiamo i dati (secondo il datasheet) e mettiamo 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();// accendiamo hx711
       nrf_drv_gpiote_out_toggle(LED_1);
       m_simple_timer_state = SIMPLE_TIMER_STATE_STARTED;
   }
  
}
/**@brief Crea timer.
*/*
static void create_timers()
{
   ret_code_t err_code;
 
   // Crea timer
   err_code = app_timer_create(&m_repeated_timer_id,
                               APP_TIMER_MODE_REPEATED,
                               repeated_timer_handler);
   APP_ERROR_CHECK(err_code);
}

Aspettiamo un evento dal timer RTC con un intervallo di 10 secondi (questo lo lasciamo a vostra scelta) nell'handler avviamo HX711, chiamando l'interruzione sulla linea DOUT.

C'è un altro punto, i log vengono visualizzati tramite UART (baud rate 115200, TX — pin 6, RX — pin 8) tutte le impostazioni si trovano in sdk_config.h

Come collegare l'ADC HX711 al NRF52832

Conclusioni

Grazie a tutti per l'attenzione, spero che questo articolo sia utile e riduca il tempo prezioso nella ricerca di soluzioni per gli sviluppatori. Vorrei dire che l'approccio tecnico utilizzato da Nordic nelle sue piattaforme è piuttosto interessante dal punto di vista dell'efficienza energetica.

P.S.

Il progetto è ancora in fase di sviluppo, quindi se questo tema vi interessa nella prossima articolo cercherò di descrivere l'algoritmo di calibrazione dei sensori di peso, così come il collegamento allo stack BLE.

Materiali

Fonte: habr.com

Acquista hosting affidabile per siti web con protezione DDoS, VPS VDS server 🔥 Acquista hosting affidabile per siti web con protezione DDoS, VPS VDS server | ProHoster