Hardware | HB100 도플러 속도센서 DIY 해보기

Arduino 와 센서 놀이를 하던 중, 도플러 효과를 이용한 가속도 센서가 있다는 것을 아래 글에서 보게 됩니다.


1. HB100

* Making the electronics for a $7 USD doppler motion sensor
  - https://www.limpkin.fr/index.php?post/2013/08/09/Making-the-electronics-for-a-%247-USD-doppler-motion-sensor

HB100 이라는 센서 인데, 이 것을 그대로 Arduino 와 연결하여 사용할 수는 없고, breakout board 를 통해서 simple 한 코드로 데이터를 처리할 수 있습니다.

이걸 가능하게 해주는 breakout board 를 스웨덴의 어떤 개인이 만들었더군요.

HB100 센서와 일체형으로 보드를 만들어, V_out 을 통하여 변하는 값을 확인 할 수 있게 되어 있습니다.

구성 component 들은 아래 사진 처럼, 아주 간단 합니다.

이것을 개인들이 판매할 수 있는 Tindie 에 등록되어 있습니다. Breakout 자체는 2만 5천원 정도인데, 배송비가 35 USD... 6만원이나 들여서 만들기는 조금 부담스럽습니다.

* HB100 Doppler Speed Sensor - Arduino Compatible
  - https://www.tindie.com/products/limpkin/hb100-doppler-speed-sensor-arduino-compatible/


2. Components - AliExpress

개발자가 부품과 회로도를 공개 했습니다.

* Bill of Materials
  - HB100_BoM.xlsm

* Production files
  - doppler_backpack.rar

* HB100 application note
  - HB100_Microwave_Sensor_Application_Note.pdf

* HB100 datasheet
  - HB100_Microwave_Sensor_Module_Datasheet.pdf

한참, 고민만 하다 위의 정보를 가지고, breakout board 까지 자체 준비를 해보기로 합니다.

우선 HB100 센서를 AliExpress 에서 저렴하게 구입합니다. 약 3천원 정도.

* HB100 microwave doppler wireless radar detector probe sensor 10.525GHz
  - https://www.aliexpress.com/item/32727607058.html

이걸 2017년에 구입하고, 오랜 동안 멈춰 있었습니다. 이거 하나 때문에 PCB 주문을 하기에도 부담스러워, 깨작깨작 component 들만 구입해 놓습니다. 필요한 SMD 부품들을 정리하면 아래와 같습니다.


----------------------------------------------------------------------------------
|           name         | value          | type                                 |
----------------------------------------------------------------------------------
| C1, C10                | 0.1uF          | 50V 10% X7R 0805 SMD                 |
| C6, C7                 | 2200pF         | 50V 10% X7R 0805 SMD                 |
| C4, C5, C8             | 4.7uF          | 25V 10% X5R 0805 SMD                 |
| C11, C2, C3, C9        | 10uF           | 10V 10% X5R 0805 SMD                 |
----------------------------------------------------------------------------------
| R8, R11                | 8.2K Ohm       | 1/8W 1% 0805 SMD                     |
| R1, R2, R5, R9, R10    | 10K Ohm        | 1/8W 1% 0805 SMD                     |
| R3                     | 12K Ohm        | 1/8W 1% 0805 SMD                     |
| R4                     | 330K Ohm       | 1/8W 1% 0805 SMD                     |
| R6, R7                 | 1M Ohm         | 1/8W 1% 0805 SMD                     |
----------------------------------------------------------------------------------
| U1                     | OPA2365AIDR    | IC OPAmp 50MHZ Dual 8SOIC            |
| U2                     | MAX9031AUK+T   | IC Comparator Volt SGL SOT23-5       |
| D1                     | STPS1L30A      | Diode Schottky 30V 1A                |
| FB1                    | HZ0805D102R-10 | Ferrite Chip Signal 1000 Ohm SMD     |
----------------------------------------------------------------------------------
| P1, P2, P3, P4         | 2              | double row male 2.54mm pitch pinhead |
----------------------------------------------------------------------------------


하나씩 구입합니다.

* 0805 SMD Capacitor assorted kit ,36values*20pcs=720pcs 1pF~10uF Samples Kit electronic diy kit
  https://www.aliexpress.com/item/32816237877.html

오랜 동안 하나씩 구입하다 보니, Capacitor 들은 두 번이나 중복 구입을 하게 되었네요.

나중에 많이 쓸 일이 있을 것이니, 부담 가지지 않고 구입합니다.

저항도 필요한데, 1M Ohm 등이 필요하므로, 이참에 뭉텅이로 구입합니다.

* New 0805 SMD Resistor Sample Book 1% Tolerance 170valuesx25pcs=4250pcs Resistor Kit 0R~10M
  - https://www.aliexpress.com/item/32369567530.html

거의 모든 저항들이 들어 있어서, 당분간은 저항 구매할 일이 없겠네요. 가장 많이 사용하는 10K Ohm 도 많이 있기도 하고.

값의 순서대로 책처럼 펼쳐서 찾을 수 있도록 편하게 되어 있습니다.


3. Components - Digi-Key

비범용적인 부품은, 전자부품 전문 회사인 Digi-Key 를 통해 구입 했습니다. 물론 배송 이벤트 적용 되도록 50 USD 이상 마아서 한꺼번에 주문 할 때 같이 끼워서 했습니다.

* Digi-Key
  - https://www.digikey.com/

역시 전자부품 전문 회사답게, 수량과 관계 없이 정전기 플라스틱 백에 넣어서 보내 줬습니다.

8OSCI 인 OPAMP.

SOT23-5 타입의 Comparator.

윗면 사진.

아랫면 사진.

Schottky Diode 입니다.

용량 큰 다른 제품으로 대체해도 되나, 가능한 제작자와 같은 부품을 사용하기로 합니다.

1K Ohm 특성을 가지는 Ferrite Bead 입니다. 전기적 잡음을 잡아주는 페라이트 코어죠.


4. PCB

저번에 만들고 싶은 커스텀 PCB 를 한꺼번에 주문 할 때, 같이 주문 했습니다.

* Hardware | JLCPCB 에서 PCB 주문을 해보자
  - https://chocoball.tistory.com/entry/Hardware-JLCPCB-PCB-order

멀리 중국 업체인 JLCPCB 에 주문한 것인데, 펀칭 홀도 잘 뚫려 있고, 완성도가 높아 매우 만족스럽습니다.

5장이 한 묶음이라 나머지는 어디에? 마무리가 잘 되어 있습니다. 주문 제작 PCB 업계는 경쟁이 치열 할 듯 합니다.


5. 실장

우선, 플럭스 페이스트를 실장면에 찍어 줍니다.

아래 회로 완성도를 확인 하면서 부품 실장을 시작해 봅니다.

몇 번 해본거지만, 플럭스 페이스트를 너무 많이 도포한 느낌이 드네요.

전기 오븐으로 약 8분 정도 구워줍니다. 플럭스 페이스트 들이, 쪼륵~ 하면서 납을 형상하는 시점에 전기를 꺼주도록 완전 메뉴얼로 작업 합니다 :-D


6. HB100 과 연결

Breakout 보드가 완성 되었으니, HB100 과 연결해 줍니다.

원제작자가 잘 만들어서 그런지, 딱 들어 맞네요.

한 부분만 빼구요. 네 귀퉁이가 모두 동일한 형상이다 보니, 실제 HB100 은 한 귀퉁이가 살짝 안쪽으로 들어가 있습니다. 동일하게 연결될 수 있도록 male pin hader 를 꺾어 줍니다.

나머지는 이쁘게 잘 되었습니다. 확실한 pin header 고정을 위해, 플라스틱 밑 부분에도 납을 따로 먹여 지지가 확실하게 되었습니다.

꺾인 pin header 를 땜 해주면 끝.

Pin header 가 너무 튀어나오면 어디에 걸릴 까봐, 납땜 부위를 뭉퉁한 모양으로 만들어 지도록 띄워서 납땜 하였습니다. 이렇게 해야 breakout board 와 HB100 사이 간격도 조금 여유 있어지구요.


7. Source

공개되어 있는 소스는 다음과 같습니다.


// Below: pin number for FOUT
#define PIN_NUMBER 4
 
// Below: number of samples for averaging
#define AVERAGE 4
 
// Below: define to use serial output with python script
//#define PYTHON_OUTPUT
 
unsigned int doppler_div = 19;
unsigned int samples[AVERAGE];
unsigned int x;
  
void setup() {
    Serial.begin(115200);
    pinMode(PIN_NUMBER, INPUT);
}
 
void loop() {
    noInterrupts();
    pulseIn(PIN_NUMBER, HIGH);
    unsigned int pulse_length = 0;
     
    for (x = 0; x < AVERAGE; x++) {
        pulse_length = pulseIn(PIN_NUMBER, HIGH);
        pulse_length += pulseIn(PIN_NUMBER, LOW);  
        samples[x] =  pulse_length;
    }
    interrupts();
     
    // Check for consistency
    bool samples_ok = true;
    unsigned int nbPulsesTime = samples[0];
     
    for (x = 1; x < AVERAGE; x++) {
        nbPulsesTime += samples[x];
        if ((samples[x] > samples[0] * 2) || (samples[x] < samples[0] / 2)) {
            samples_ok = false;
        }
    }
}
 
if (samples_ok) {
    unsigned int Ttime = nbPulsesTime / AVERAGE;
    unsigned int Freq = 1000000 / Ttime;
     
    #ifdef PYTHON_OUTPUT
        Serial.write(Freq/doppler_div);
    #else
        //Serial.print(Ttime);
        Serial.print("\r\n");
        Serial.print(Freq);
        Serial.print("Hz : ");
        Serial.print(Freq/doppler_div);
        Serial.print("km/h\r\n");
    #endif
} else {
    #ifndef PYTHON_OUTPUT
        Serial.print(".");
    #endif
}


소스와 아래 그림처럼, digital pin 4 에 V_out 을 연결만 하면 끝 입니다.

소스를 올리고, 손바닥으로 측정을 해주면, 아래와 같이 감지되는 주파수와 그에 맞는 속도를 표시해 줍니다.

동영상 올립니다.


8. Another Source

Youtube 에서 검색해 보면, 소스를 여러가지로 만든 분들이 계십니다.

* HB100 Doppler Radar, Limpkin’s Amplifier and Arduino MCU – The Details (3/3)
  - https://www.youtube.com/watch?v=ZIRCv6hNd8I

* HB100 Doppler Radar, Limpkin’s Amplifier and Arduino MCU – The Details (2/3)
  - https://www.youtube.com/watch?v=4hkwILBBegE

* HB100 Doppler Radar, Limpkin’s Amplifier and Arduino MCU – The Details (1/3)
  - https://www.youtube.com/watch?v=MpVRHEUV3Xo

* Mini Mailbag: Breakout PCBs for HB100 Doppler Radar and MAX31855K Module
  - https://www.youtube.com/watch?v=EbrPqeHiWdY

이 소스는, V_out 뿐만 아니라, F_out 도 입력받도록 고안 되어 있습니다.


//
// HB100 Doppler Radar + Limpkin's Amplifier
// Robert's Smorgasbord 2020
// www.robertssmorgasbord.net
//
// This is work in progress!
//
 
// Change ADC sample
// http://yaab-arduino.blogspot.com/2015/02/fast-sampling-from-analog-input.html
 
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
 
const byte          hb100_fout_pin      =   2;     // interrupt capable pin (2 or 3 for Nano)
const byte          hb100_vout_pin      =  A0;     // analog input pin
const unsigned long analysis_every      = 500;     // ms
const float         period_to_frequency =  70.235; // Hz/m/s
const byte          level_minimum       = 120;     // minimum signal level for analysis
const float         frequency_lower     =   4.0;   // Hz
const float         frequency_upper     =  70.0;   // Hz
const byte          average_pulses      =   4;     // min 1
 
volatile unsigned long pulse_times[256];  // pulses start times, 256 element ringbuffer, use with counter of type byte (!)
volatile byte          pulse_levels[256]; // pulses signal levels, 256 element ringbuffer, use with counter of type byte (!)
volatile byte          pulse_last;        // last pulse written in pulse_times ring buffer
 
void setup()
{
   unsigned int i;
 
   for (i = 0; i < 256; i++) // initialize pulse_times ring buffer
   {
       pulse_times[i] = 0;
   }
    
   pulse_last = 255; // initialize pulse_last
 
   // Increase ADC sample rate from 10kS/sec (100us/S) to 1MS/s (1us/S)
   // http://yaab-arduino.blogspot.com/2015/02/fast-sampling-from-analog-input.html
   sbi(ADCSRA, ADPS2);
   cbi(ADCSRA, ADPS1);
   cbi(ADCSRA, ADPS0);
    
   Serial.begin(1000000L); // 1MBaud
   pinMode(hb100_fout_pin, INPUT);
   pinMode(hb100_vout_pin, INPUT);
   attachInterrupt(digitalPinToInterrupt(hb100_fout_pin), hb100InterruptFoutPin, RISING);
}
 
void loop()
{
   static unsigned long analysis_next = millis();
 
   byte          pulse_current;
   byte          pulse_previouse;      
   unsigned long time_current;
   unsigned long time_previouse;
   byte          level_current;
   byte          level_previouse;
   long          period;
   float         frequency;
   float         velocity;
    
   if (millis() >= analysis_next)
   {
      pulse_current   = pulse_last;  // copy volatile variable
      pulse_previouse = pulse_current;
      pulse_previouse = pulse_previouse - average_pulses;
 
      time_current    = pulse_times[pulse_current];  
      time_previouse  = pulse_times[pulse_previouse];
      level_current   = pulse_levels[pulse_current];
      level_previouse = pulse_levels[pulse_current];
       
      period         = (time_current - time_previouse) / average_pulses;
 
      if (time_current / 1000 > millis() - analysis_every &&
          period              > 0                         &&
          level_current       > level_minimum             &&
          level_previouse     > level_minimum               )
      {
         frequency = 1000000.0 / period;
 
         //if (frequency > frequency_upper || frequency < frequency_lower)
         //{
         //   frequency = 0.0;
         //}
          
         velocity = frequency / period_to_frequency;
      }
      else
      {
         frequency = 0.0;
         velocity  = 0.0;
      }
       
      /*Serial.print(frequency, 2);*/
      /*Serial.print("\t");*/
      Serial.print(velocity * 100, 3);
      Serial.print("\t");
      Serial.print(level_current / 2, DEC);
      Serial.println("");
          
      analysis_next = millis() + analysis_every;
   }
}
 
void hb100InterruptFoutPin()
{
   pulse_last++;
   pulse_times[pulse_last] = micros();
   pulse_levels[pulse_last] = analogRead(hb100_vout_pin) / 4;
}


연결은 다음과 같습니다.


+-------------------------+
|   HB100  | Arduino Nano |
+-------------------------+
|    VCC   |      5V      |
|    GND   |      GND     |
| FREQ OUT |      D2      |
|   V OUT  |      A0      |
+-------------------------+


실제 구성은 다음과 같습니다. FREQ OUT 이 하나 더 추가된 것 뿐, 다른건 없습니다.

실제 frequency 와 전류량 (current) 까지 표현해 줍니다.

전류량은 127 이 max 인 듯 합니다. 더 이상은 올라가지 않는군요.

Serial Monitor 의 속도를 민감하게 하기 위해, 기준을 1000000 baud 로 맞추는 것이 필요합니다.


FIN

매우 오래 걸렸지만, PCB 부터 전용 SMD component 를 구매가 이루어 지니, 이런 프로젝트도 가능해 졌네요.

동일한 제작자가 조금 더 작은 도플러 센서를 가지고 가속도계를 만든 것이 있으니, 다음 포스팅에 소개해 보도록 하겠습니다.


댓글

  1. PCB 여분이 4개가 있어, 배송료만 받고 분양합니다. 필요하신 분이 계시면 메시지 남겨 주세요.

    답글삭제

댓글 쓰기