Cum se conectează HX711 ADC la NRF52832

1. Introducere

Pe ordinea de zi a fost sarcina de a dezvolta un protocol de comunicație pentru microcontrolerul nrf52832 cu două detensometre chinezești cu jumătate de punte.

Sarcina s-a dovedit a fi deloc ușoară, deoarece mă confruntam cu o lipsă de informații inteligibile. Este mai probabil ca „rădăcina răului” să fie în SDK-ul de la Nordic Semiconductor însuși - actualizări constante ale versiunii, oarecare redundanță și funcționalitate confuză. A trebuit să scriu totul de la zero.

Cred că acest subiect este destul de relevant pe baza faptului că acest cip are o stivă BLE și un întreg set de „bunătăți” pentru modul de economisire a energiei. Dar nu voi intra prea adânc în partea tehnică, deoarece s-au scris multe articole pe această temă.

2. Descrierea proiectului

Cum se conectează HX711 ADC la NRF52832

Fier:

  • Adafruit Feather nRF52 Bluefruit LE (ce s-a întâmplat să fie la îndemână)
  • HX711 ADC
  • Tensometre chinezești 2 buc. (50x2 kg)
  • Programator ST-LINK V2

Software:

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

Totul este într-un singur proiect, trebuie doar să modificați Makefile (specificați locația SDK-ului).

3. Descrierea codului

Vom folosi modulul GPIOTE pentru a lucra cu periferice bazate pe legarea sarcinilor și evenimentelor, precum și modulul PPI pentru a transfera date de la un periferic la altul fără participarea unui procesor.

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

Configuram linia de sincronizare PD_SCL la ieșire pentru a genera impulsuri cu o durată 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);//включаем таймер
}
 

Configuram linia de date DOUT pentru a citi starea de pregătire a HX711; dacă există un nivel scăzut, este declanșat un handler în care dezactivăm întreruperea și pornim un temporizator pentru a genera impulsuri de ceas la ieșirea 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); 

// activați gpiote

După aceea, inițializam modulul PPI și conectăm cronometrul la ieșirea PD_SCL pentru a genera impulsuri cu o durată de 10 μs atunci când are loc un eveniment de comparație și, de asemenea, pornim modulul 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);// срабатывает по сравнению

Inițializam cronometrul zero și handlerul acestuia.

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

Cel mai interesant lucru se întâmplă în gestionarea temporizatorului. Perioada pulsului este de 20 μs. Suntem interesați de impulsuri impare (de-a lungul muchiei crescătoare) și cu condiția ca numărul lor să nu fie mai mare de 24 și să existe 48 de evenimente. Pentru fiecare eveniment impar, se citește DOUT

Din fișa tehnică rezultă că numărul de impulsuri trebuie să fie de cel puțin 25, ceea ce corespunde unui câștig de 128 (în codul am folosit 25 de impulsuri), acesta echivalent cu 50 de evenimente timer, ceea ce indică sfârșitul cadrului de date.

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

După aceasta, oprim cronometrul și procesăm datele (conform fișei de date) și comutăm HX711 în modul de consum redus de energie.


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

Ne așteptăm la evenimente de la temporizatorul RTC cu un interval de 10 s (acesta este la discreția dvs.) și lansăm HX711 în handler, provocând o întrerupere pe linia DOUT.

Mai există un punct, jurnalele sunt scoase prin UART (rată de transmisie 115200, TX - 6 pini, RX - 8 pini) toate setările sunt în sdk_config.h

Cum se conectează HX711 ADC la NRF52832

Constatări

Vă mulțumim tuturor pentru atenție, sper că acest articol va fi util și va reduce timpul prețios pentru dezvoltatori pentru a găsi o soluție. Vreau să spun că abordarea tehnică pe care Nordic o folosește în platformele sale este destul de interesantă din punct de vedere al eficienței energetice.

PS

Proiectul este încă în dezvoltare, așa că dacă acest subiect este de interes, în articolul următor voi încerca să descriu algoritmul de calibrare a senzorilor de greutate, precum și conectarea stivei BLE.

Materiale

Sursa: www.habr.com

Adauga un comentariu