HX711 ADC рдХреЛ NRF52832 рд╕реЗ рдХреИрд╕реЗ рдХрдиреЗрдХреНрдЯ рдХрд░реЗрдВ

1ред рдкрд░рд┐рдЪрдп

рдПрдЬреЗрдВрдбреЗ рдореЗрдВ рджреЛ рдЖрдзреЗ-рдкреБрд▓ рдЪреАрдиреА рд╕реНрдЯреНрд░реЗрди рдЧреЗрдЬ рдХреЗ рд╕рд╛рде nrf52832 рдорд╛рдЗрдХреНрд░реЛрдХрдВрдЯреНрд░реЛрд▓рд░ рдХреЗ рд▓рд┐рдП рдПрдХ рд╕рдВрдЪрд╛рд░ рдкреНрд░реЛрдЯреЛрдХреЙрд▓ рд╡рд┐рдХрд╕рд┐рдд рдХрд░рдиреЗ рдХрд╛ рдХрд╛рд░реНрдп рдерд╛ред

рдпрд╣ рдХрд╛рд░реНрдп рдЖрд╕рд╛рди рдирд╣реАрдВ рдерд╛, рдХреНрдпреЛрдВрдХрд┐ рдореЗрд░реЗ рд╕рд╛рдордиреЗ рдХрд┐рд╕реА рднреА рд╕рдордЭрджрд╛рд░ рдЬрд╛рдирдХрд╛рд░реА рдХрд╛ рдЕрднрд╛рд╡ рдерд╛ред рдЗрд╕рдХреА рдЕрдзрд┐рдХ рд╕рдВрднрд╛рд╡рдирд╛ рд╣реИ рдХрд┐ "рдмреБрд░рд╛рдИ рдХреА рдЬрдбрд╝" рдиреЙрд░реНрдбрд┐рдХ рд╕реЗрдореАрдХрдВрдбрдХреНрдЯрд░ рдХреЗ рдПрд╕рдбреАрдХреЗ рдореЗрдВ рд╣реА рд╣реИ - рдирд┐рд░рдВрддрд░ рд╕рдВрд╕реНрдХрд░рдг рдЕрдкрдбреЗрдЯ, рдХреБрдЫ рдЕрддрд┐рд░реЗрдХ рдФрд░ рднреНрд░рдорд┐рдд рдХрд░рдиреЗ рд╡рд╛рд▓реА рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ред рдореБрдЭреЗ рд╕рдм рдХреБрдЫ рдирдпреЗ рд╕рд┐рд░реЗ рд╕реЗ рд▓рд┐рдЦрдирд╛ рдкрдбрд╝рд╛ред

рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рд╡рд┐рд╖рдп рдЗрд╕ рддрдереНрдп рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдХрд╛рдлреА рдкреНрд░рд╛рд╕рдВрдЧрд┐рдХ рд╣реИ рдХрд┐ рдЗрд╕ рдЪрд┐рдк рдореЗрдВ рдмреАрдПрд▓рдИ рд╕реНрдЯреИрдХ рдФрд░ рдКрд░реНрдЬрд╛ рдмрдЪрдд рдореЛрдб рдХреЗ рд▓рд┐рдП "рдЙрдкрд╣рд╛рд░реЛрдВ" рдХрд╛ рдПрдХ рдкреВрд░рд╛ рд╕реЗрдЯ рд╣реИред рд▓реЗрдХрд┐рди рдореИрдВ рддрдХрдиреАрдХреА рднрд╛рдЧ рдореЗрдВ рдмрд╣реБрдд рдЧрд╣рд░рд╛рдИ рддрдХ рдирд╣реАрдВ рдЬрд╛рдКрдВрдЧрд╛, рдХреНрдпреЛрдВрдХрд┐ рдЗрд╕ рд╡рд┐рд╖рдп рдкрд░ рдХрдИ рд▓реЗрдЦ рд▓рд┐рдЦреЗ рдЬрд╛ рдЪреБрдХреЗ рд╣реИрдВред

2. рдкрд░рд┐рдпреЛрдЬрдирд╛ рд╡рд┐рд╡рд░рдг

HX711 ADC рдХреЛ NRF52832 рд╕реЗ рдХреИрд╕реЗ рдХрдиреЗрдХреНрдЯ рдХрд░реЗрдВ

рд▓реМрд╣:

  • рдПрдбрдлреНрд░реВрдЯ рдлреЗрджрд░ рдПрдирдЖрд░рдПрдл52 рдмреНрд▓реВрдлреНрд░реВрдЯ рдПрд▓рдИ (рд╣рд╛рде рдореЗрдВ рдХреНрдпрд╛ рд╣реБрдЖ)
  • HX711 рдПрдбреАрд╕реА
  • рдЪреАрдиреА рд╕реНрдЯреНрд░реЗрди рдЧреЗрдЬ 2 рдкреАрд╕реАред (50x2 рдХрд┐рдЧреНрд░рд╛)
  • рдкреНрд░реЛрдЧреНрд░рд╛рдорд░ ST-рд▓рд┐рдВрдХ V2

рдореБрд▓рд╛рдпрдо:

  • рдЖрдИрдбреАрдИ рд╡реАрдПрд╕рд╕реАрдУрдбреАрдИ
  • рдПрдирдЖрд░рдПрдл рдПрд╕рдбреАрдХреЗ 16
  • рдУрдкрдирдУрд╕реАрдбреА
  • рдкреНрд░реЛрдЧреНрд░рд╛рдорд░ ST-рд▓рд┐рдВрдХ V2

рд╕рдмрдХреБрдЫ рдПрдХ рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдореЗрдВ рд╣реИ, рдЖрдкрдХреЛ рдмрд╕ рдореЗрдХрдлрд╝рд╛рдЗрд▓ рдХреЛ рдЯреНрд╡рд┐рдХ рдХрд░рдирд╛ рд╣реЛрдЧрд╛ (рдЕрдкрдиреЗ рдПрд╕рдбреАрдХреЗ рдХрд╛ рд╕реНрдерд╛рди рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░реЗрдВ)ред

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);//╨╜╨░╤Б╤В╤А╨░╨╡╨▓╨░╨╡╨╝ ╨╜╨░ ╨▓╤Л╤Е╨╛╨┤

рд╣рдо 10 ╬╝s рдХреА рдЕрд╡рдзрд┐ рдХреЗ рд╕рд╛рде рджрд╛рд▓реЗрдВ рдЙрддреНрдкрдиреНрди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЖрдЙрдЯрдкреБрдЯ рдореЗрдВ PD_SCL рд╕рд┐рдВрдХреНрд░рдирд╛рдЗрдЬрд╝реЗрд╢рди рд▓рд╛рдЗрди рдХреЛ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд░рддреЗ рд╣реИрдВред

   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);//╨▓╨║╨╗╤О╤З╨░╨╡╨╝ ╤В╨░╨╣╨╝╨╡╤А
}
 

рд╣рдо HX711 рдХреА рддрддреНрдкрд░рддрд╛ рд╕реНрдерд┐рддрд┐ рдХреЛ рдкрдврд╝рдиреЗ рдХреЗ рд▓рд┐рдП DOUT рдбреЗрдЯрд╛ рд▓рд╛рдЗрди рдХреЛ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд░рддреЗ рд╣реИрдВ; рдпрджрд┐ рдирд┐рдореНрди рд╕реНрддрд░ рд╣реИ, рддреЛ рдПрдХ рд╣реИрдВрдбрд▓рд░ рдЪрд╛рд▓реВ рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ рдЬрд┐рд╕рдореЗрдВ рд╣рдо рд╡реНрдпрд╡рдзрд╛рди рдХреЛ рдЕрдХреНрд╖рдо рдХрд░рддреЗ рд╣реИрдВ рдФрд░ 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 рд╕рдХреНрд╖рдо рдХрд░реЗрдВ

рдЙрд╕рдХреЗ рдмрд╛рдж, рд╣рдо рдкреАрдкреАрдЖрдИ рдореЙрдбреНрдпреВрд▓ рдХреЛ рдЗрдирд┐рд╢рд┐рдпрд▓рд╛рдЗрдЬрд╝ рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рддреБрд▓рдирд╛рддреНрдордХ рдШрдЯрдирд╛ рд╣реЛрдиреЗ рдкрд░ 10 ╬╝s рдХреА рдЕрд╡рдзрд┐ рдХреЗ рд╕рд╛рде рдкрд▓реНрд╕ рдЙрддреНрдкрдиреНрди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЕрдкрдиреЗ рдЯрд╛рдЗрдорд░ рдХреЛ PD_SCL рдЖрдЙрдЯрдкреБрдЯ рд╕реЗ рдХрдиреЗрдХреНрдЯ рдХрд░рддреЗ рд╣реИрдВ, рдФрд░ 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 ╬╝s рд╣реИред рд╣рдо рд╡рд┐рд╖рдо рджрд╛рд▓реЛрдВ (рдмрдврд╝рддреЗ рдХрд┐рдирд╛рд░реЗ рдХреЗ рд╕рд╛рде) рдореЗрдВ рд░реБрдЪрд┐ рд░рдЦрддреЗ рд╣реИрдВ рдФрд░ рдмрд╢рд░реНрддреЗ рдХрд┐ рдЙрдирдХреА рд╕рдВрдЦреНрдпрд╛ 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);
}

рд╣рдо 10 рд╕реЗрдХрдВрдб рдХреЗ рдЕрдВрддрд░рд╛рд▓ рдХреЗ рд╕рд╛рде рдЖрд░рдЯреАрд╕реА рдЯрд╛рдЗрдорд░ рд╕реЗ рдШрдЯрдирд╛рдУрдВ рдХреА рдЙрдореНрдореАрдж рдХрд░рддреЗ рд╣реИрдВ (рдпрд╣ рдЖрдкрдХреЗ рд╡рд┐рд╡реЗрдХ рдкрд░ рд╣реИ) рдФрд░ рд╣реИрдВрдбрд▓рд░ рдореЗрдВ рдПрдЪрдПрдХреНрд╕711 рд▓реЙрдиреНрдЪ рдХрд░рддреЗ рд╣реИрдВ, рдЬрд┐рд╕рд╕реЗ рдбреАрдУрдпреВрдЯреА рд▓рд╛рдЗрди рдкрд░ рд░реБрдХрд╛рд╡рдЯ рдЖрддреА рд╣реИред

рдПрдХ рдФрд░ рдмрд╛рдд рд╣реИ, рд▓реЙрдЧ UART рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдЖрдЙрдЯрдкреБрдЯ рд╣реЛрддреЗ рд╣реИрдВ (рдмреЙрдб рджрд░ 115200, TX - 6 рдкрд┐рди, RX - 8 рдкрд┐рди) рд╕рднреА рд╕реЗрдЯрд┐рдВрдЧреНрд╕ sdk_config.h рдореЗрдВ рд╣реИрдВ

HX711 ADC рдХреЛ NRF52832 рд╕реЗ рдХреИрд╕реЗ рдХрдиреЗрдХреНрдЯ рдХрд░реЗрдВ

рдирд┐рд╖реНрдХрд░реНрд╖

рдЖрдкрдХрд╛ рдзреНрдпрд╛рди рджреЗрдиреЗ рдХреЗ рд▓рд┐рдП рдЖрдк рд╕рднреА рдХрд╛ рдзрдиреНрдпрд╡рд╛рдж, рдореБрдЭреЗ рдЖрд╢рд╛ рд╣реИ рдХрд┐ рдпрд╣ рд▓реЗрдЦ рдЙрдкрдпреЛрдЧреА рд╣реЛрдЧрд╛ рдФрд░ рд╕рдорд╛рдзрд╛рди рдЦреЛрдЬрдиреЗ рдореЗрдВ рдбреЗрд╡рд▓рдкрд░реНрд╕ рдХреЗ рд▓рд┐рдП рдореВрд▓реНрдпрд╡рд╛рди рд╕рдордп рдХрдо рд╣реЛ рдЬрд╛рдПрдЧрд╛ред рдореИрдВ рдХрд╣рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВ рдХрд┐ рдиреЙрд░реНрдбрд┐рдХ рдЕрдкрдиреЗ рдкреНрд▓реЗрдЯрдлрд╛рд░реНрдореЛрдВ рдореЗрдВ рдЬрд┐рд╕ рддрдХрдиреАрдХреА рджреГрд╖реНрдЯрд┐рдХреЛрдг рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ рд╡рд╣ рдКрд░реНрдЬрд╛ рджрдХреНрд╖рддрд╛ рдХреЗ рджреГрд╖реНрдЯрд┐рдХреЛрдг рд╕реЗ рдХрд╛рдлреА рджрд┐рд▓рдЪрд╕реНрдк рд╣реИред

рдкреБрдирд╢реНрдЪ

рдкрд░рд┐рдпреЛрдЬрдирд╛ рдЕрднреА рднреА рд╡рд┐рдХрд╛рд╕ рдХреЗ рдЕрдзреАрди рд╣реИ, рдЗрд╕рд▓рд┐рдП рдпрджрд┐ рдпрд╣ рд╡рд┐рд╖рдп рд░реБрдЪрд┐ рдХрд╛ рд╣реИ, рддреЛ рдЕрдЧрд▓реЗ рд▓реЗрдЦ рдореЗрдВ рдореИрдВ рд╡рдЬрди рд╕реЗрдВрд╕рд░ рдХреЛ рдХреИрд▓рд┐рдмреНрд░реЗрдЯ рдХрд░рдиреЗ рдХреЗ рд╕рд╛рде-рд╕рд╛рде рдмреАрдПрд▓рдИ рд╕реНрдЯреИрдХ рдХреЛ рдЬреЛрдбрд╝рдиреЗ рдХреЗ рд▓рд┐рдП рдПрд▓реНрдЧреЛрд░рд┐рджрдо рдХрд╛ рд╡рд░реНрдгрди рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░реВрдВрдЧрд╛ред

рд╕рд╛рдордЧреНрд░реА

рд╕реНрд░реЛрдд: www.habr.com

рдПрдХ рдЯрд┐рдкреНрдкрдгреА рдЬреЛрдбрд╝реЗрдВ