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
//
// 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 를 구매가 이루어 지니, 이런 프로젝트도 가능해 졌네요.
동일한 제작자가 조금 더 작은 도플러 센서를 가지고 가속도계를 만든 것이 있으니, 다음 포스팅에 소개해 보도록 하겠습니다.
PCB 여분이 4개가 있어, 배송료만 받고 분양합니다. 필요하신 분이 계시면 메시지 남겨 주세요.
답글삭제