1. Cyflwyniad
Ar yr agenda oedd y dasg o ddatblygu protocol cyfathrebu ar gyfer y microreolydd nrf52832 gyda dau fesurydd straen Tsieineaidd hanner pont.
Nid oedd y dasg yn un hawdd, gan fy mod yn wynebu diffyg unrhyw wybodaeth ddealladwy. Mae'n fwy tebygol bod “gwreiddyn drygioni” yn y SDK o Nordic Semiconductor ei hun - diweddariadau fersiwn cyson, rhywfaint o ddiswyddiad ac ymarferoldeb dryslyd. Roedd yn rhaid i mi ysgrifennu popeth o'r dechrau.
Rwy'n credu bod y pwnc hwn yn eithaf perthnasol yn seiliedig ar y ffaith bod gan y sglodyn hwn bentwr BLE a set gyfan o “nwyddau” ar gyfer modd arbed ynni. Ond nid af yn rhy ddwfn i'r rhan dechnegol, gan fod llawer o erthyglau wedi'u hysgrifennu ar y pwnc hwn.
2. Disgrifiad o'r prosiect
Haearn:
- Adafruit Feather nRF52 Bluefruit LE (beth ddigwyddodd i fod wrth law)
- HX711 ADC
- Mesuryddion straen Tsieineaidd 2 pcs. (50x2 kg)
- Rhaglennydd ST-LINK V2
Meddal:
- IDE VSCODE
- NRF SDK 16
- AgoredOCD
- Rhaglennydd ST-LINK V2
Mae popeth mewn un prosiect, mae'n rhaid i chi newid y Makefile (nodwch leoliad eich SDK).
3. Disgrifiad o'r cod
Byddwn yn defnyddio'r modiwl GPIOTE i weithio gyda perifferolion yn seiliedig ar rwymo tasgau a digwyddiadau, yn ogystal â'r modiwl PPI i drosglwyddo data o un ymylol i'r llall heb gyfranogiad prosesydd.
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);//настраеваем на выход
Rydym yn ffurfweddu'r llinell gydamseru PD_SCL i'r allbwn i gynhyrchu corbys sy'n para 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);//включаем таймер
}
Rydyn ni'n ffurfweddu llinell ddata DOUT i ddarllen cyflwr parodrwydd yr HX711; os oes lefel isel, mae triniwr yn cael ei sbarduno lle rydyn ni'n analluogi'r ymyriad ac yn cychwyn amserydd i gynhyrchu curiadau cloc yn yr allbwn 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);
// galluogi gpiote
Ar ôl hynny, rydym yn cychwyn y modiwl PPI ac yn cysylltu ein hamserydd â'r allbwn PD_SCL i gynhyrchu corbys sy'n para 10 μs pan fydd digwyddiad cymharu yn digwydd, a hefyd yn troi'r modiwl GPIOTE ymlaen.
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);// срабатывает по сравнению
Rydym yn cychwyn yr amserydd sero a'i driniwr.
if(m_counter%2 != 0 && m_counter<=48){
buffer <<= 1;// переменная считанных даных
c_counter++;// счетчик положительных импульсов
if(nrf_gpio_pin_read(DOUT))buffer++;//считываем состояние входа
}
Mae'r peth mwyaf diddorol yn digwydd yn y triniwr amserydd. Y cyfnod pwls yw 20 μs. Mae gennym ddiddordeb mewn corbys od (ar hyd yr ymyl codi) ac ar yr amod nad yw eu nifer yn fwy na 24, a bod digwyddiadau 48. Ar gyfer pob digwyddiad od, darllenir DOUT
O'r daflen ddata mae'n dilyn bod yn rhaid i nifer y corbys fod o leiaf 25, sy'n cyfateb i gynnydd o 128 (yn y cod defnyddiais 25 corbys), mae hyn yn cyfateb i 50 o ddigwyddiadau amserydd, sy'n nodi diwedd y ffrâm ddata.
++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
}
Ar ôl hyn, rydyn ni'n diffodd yr amserydd ac yn prosesu'r data (yn ôl y daflen ddata) ac yn newid yr HX711 i fodd defnydd pŵer isel.
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);
}
Disgwyliwn ddigwyddiadau o'r amserydd RTC gydag egwyl o 10 s (mae hyn yn ôl eich disgresiwn) a lansio'r HX711 yn y triniwr, gan achosi ymyrraeth ar y llinell DOUT.
Mae un pwynt arall, mae'r logiau'n cael eu hallbynnu trwy UART (cyfradd baud 115200, TX - 6 pin, RX - 8 pin) mae'r holl leoliadau yn sdk_config.h
Canfyddiadau
Diolch i chi i gyd am eich sylw, rwy'n gobeithio y bydd yr erthygl hon yn ddefnyddiol ac yn lleihau amser gwerthfawr i ddatblygwyr ddod o hyd i ateb. Rwyf am ddweud bod y dull technegol y mae Nordig yn ei ddefnyddio yn ei lwyfannau yn eithaf diddorol o safbwynt effeithlonrwydd ynni.
PS
Mae'r prosiect yn dal i gael ei ddatblygu, felly os yw'r pwnc hwn o ddiddordeb, yn yr erthygl nesaf byddaf yn ceisio disgrifio'r algorithm ar gyfer calibro synwyryddion pwysau, yn ogystal â chysylltu'r pentwr BLE.
Deunyddiau
Ffynhonnell: hab.com