Русский
Русский
English
Статистика
Реклама

Из песочницы Как подключить АЦП HX711 к NRF52832

1. Введение


На повестке дня стояла задача разработать протокол общения микроконтролера nrf52832 с двумя полумостовыми китайскими тензодатчиками.

Задача оказалась не простой, так как столкнулся с отсутствием какой либо внятной информации. Вероятнее, что корень зла находится в самом SDK от Nordic Semiconductor это постоянное обновления версий, некоторая избыточность и запутанность функционала. Пришлось писать все с нуля.


Я думаю эта тема довольно актуальна исходя из того, что данный чип обладает BLE стеком и целым набором вкусняшек режима энергосбережения. Но в техническую часть я сильно углубляться не буду, так как на эту тему написано немало статей.


2. Описание проекта


image

Железо:


  • Adafruit Feather nRF52 Bluefruit LE (то что оказалось под рукой)
  • АЦП HX711
  • Китайские тензодатчики 2 шт. (50х2 кг)
  • Программатор ST-LINK V2

Софт:


  • IDE VSCODE
  • NRF SDK 16
  • OpenOCD
  • Программатор ST-LINK V2


Все находится в одном проекте, придется только подшаманить Makefile (указать расположение вашего SDK).


3. Описание кода


Будем использовать GPIOTE модуль для работы с периферией исходя из привязки задач и событий, а также PPI модуль для передачи данных из одной периферии в другую без участия процессора.



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

Настраиваем линию синхронизации PD_SCL на выход для генерации импульсов длительностью 10 мкс.

   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);//включаем таймер} 

Настраиваем линию данных DOUT для считывания состояния готовности HX711, при наличии низкого уровня срабатывает обработчик в котором отключаем прерывание и запускаем таймер для генерации синхронизирующих импульсов на выходе 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

После чего инициализируем PPI модуль и коммутируем наш таймер к выходу PD_SCL, для генерирования импульсов длительность 10мкс при наступление события сравнения, а также включаем 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);// срабатывает по сравнению

Инициализируем нулевой таймер и его обработчик.



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

Самое интересное происходит в обработчике таймера. Период импульсов составляет 20 мкс. Нас интересуют нечетные импульсы (по восходящему фронту) и при условии, что их количество не более 24, а событий 48. При каждом нечетном событии происходит считывание DOUT


Из даташита следует, что количество импульсов должно быть не менее 25, что соответствует коэффициенту усиления 128 (в коде я использовал 25 импульсов), это эквивалентно 50 событиям таймера, что указывает на окончание фрейма данных.


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

После этого отключаем таймер и обрабатываем данные (по даташиту) и переводим HX711 в режим низкого энергопотребления.


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

Ожидаем события от RTC таймера с интервалом в 10 с (эту уже на ваше усмотрение) в обработчике запускаем HX711, вызывая прерывание по линии DOUT.

Есть еще один момент, логи выводятся через UART (baud rate 115200, TX 6 пин, RX 8 пин) все настройки находятся в sdk_config.h

image

Выводы


Спасибо всем за внимание, надеюсь эта статья будет полезной и сократит драгоценное время на поиск решения для разработчиков. Хочу сказать, что технический подход который использует Nordic в своих платформах довольно интересен с точки зрения энергоэффективности.


P.S.


Проект еще в процессе разработки, поэтому если будет интересна эта тема в следующей статье я постараюсь описать алгоритм калибровки датчиков веса, а также подключения BLE стека.


Материалы


Источник: habr.com
К списку статей
Опубликовано: 29.09.2020 18:09:04
0

Сейчас читают

Комментариев (0)
Имя
Электронная почта

Беспроводные технологии

Программирование микроконтроллеров

Ацп hx711

Nrf52832

Электронные весы

Тензодатчики

Интернет вещей

Cortex-m4

Категории

Последние комментарии

  • Имя: Макс
    24.08.2022 | 11:28
    Я разраб в IT компании, работаю на арбитражную команду. Мы работаем с приламы и сайтами, при работе замечаются постоянные баны и лаги. Пацаны посоветовали сервис по анализу исходного кода,https://app Подробнее..
  • Имя: 9055410337
    20.08.2022 | 17:41
    поможем пишите в телеграм Подробнее..
  • Имя: sabbat
    17.08.2022 | 20:42
    Охренеть.. это просто шикарная статья, феноменально круто. Большое спасибо за разбор! Надеюсь как-нибудь с тобой связаться для обсуждений чего-либо) Подробнее..
  • Имя: Мария
    09.08.2022 | 14:44
    Добрый день. Если обладаете такой информацией, то подскажите, пожалуйста, где можно найти много-много материала по Yggdrasil и его уязвимостях для написания диплома? Благодарю. Подробнее..
© 2006-2024, personeltest.ru