تا به امروز پروژه های متعددی بر پایه ماژول های فاصله سنج srf منتشر شده که هر کدام دارای جذابیت های مختلفی بودهاند، در این پروژه قصد دارم به روش متفاوتی و هوشمندی این پروژه را اجرا کنم، به این صورت که با تغییر فاصله تشخیص داده شده توسط سنسور التراسونیک، مقادیر اندازه گیری شده به کمک یک بلندگو کتصل شده با آردوینو اعلام میشوند. در ادامه ساخت دستگاه فاصله سنج سخنگو با استفاده از آردوینو و SRF04 با مرجع تخصصی آردوینو به زبان فارسی، دیجی اسپارک همراه باشید.
ماژول فاصله سنج SRF
این نوع از ماژولهای فاصله سنج در انواع مختلفی تولید می شوند، که از محبوب ترین آن ها میتوان SRF-04 و SRF-05 را نام برد. نحوه کارکرد این ماژول ها با استفاده از دو نوع قطعه آلتراسونیک است که بر روی ماژول قرار دارد. یکی فرستنده امواج فراصوت و دیگری گیرنده امواج است. امواج التراسونیک بر اساس زمان ارسال بازخورد امواج، قادر به محاسبه فاصله تا جسم خواهد بود. همان طور که ذکر شد در این ماژول دو نوع قطعه التراسونیک وجود دارد که یکی از آن ها از نوع T یا فرستنده و دیگری از نوع R یا دریافت کننده است. پس ماژول به این صورت کار می کند که با ارسال و دریافت امواج التراسونیک فاصله با اجسام را در نهایت قابل محاسبه می کند.
برد آردوینو Nano
مجموعه برد های آردوینو از جمله برد های توسعه پرطرفدار بین مهندسین امبدد هستند که در مدل های مختلفی از جمله Micro , proMini , Nano , Uno و همچنین Mega قابل تهیه هستند. هسته مرکزی این بردهای محبوب از سری AtMega328 است. آردوینو پلتفرم سختافزاری و نرمافزاری متنباز است. همان طور که قبل تر اشاره کردیم، پلتفرم آردوینو شامل یک میکروکنترلر تکبردی متنباز است که قسمت سخت افزار آردوینو را تشکیل میدهد. علاوه بر این، پلتفرم آردوینو یک نرمافزار آردوینو IDE که به منظور برنامهنویسی برای بردهای آردوینو طراحی شدهاست و یک بوت لودر نرمافزاری که بر روی میکروکنترلر بارگذاری میشود را در بر میگیرد.
وسایل مورد نیاز
شرح پروژه فاصله سنج سخنگو
در این پروژه با استفاده از سنسور التراسونیک و کتابخانه Talkie قادر خواهیم بود مقادیر اندازه گیری شده را به واسطه بلندگو متصل شده به آردوینو به کاربر اعلام کنیم، در این پروژه از سنسور التراسونیک مدل srf04 و آردوینو مدل نانو استفاده خواهیم کرد که همچنین قابل جایگزینی با آردوینو مدل UNO خواهد بود. در ادامه درصورتی که نیاز به افزایش صوت قابل پخش از بلنگو باشیم با استفاده از یک آمپلی فایر این مورد قابل رفع خواهد بود.
اتصالات فاصله سنج سخنگو
این پروژه از یک سنسور التراسونیک و یک عدد بلند استفاده میکند، در صورتی که از سنسور التراسونیک SFR05 استفاده میکنید پین OUT نیاز به اتصال ندارد. در این مورد من پین Trig و Echo در سنسور التراسونیک را به پین های ۴ و ۵ از پین های دیجیتال متصل کردهام، همچنین به منظور تغذیه ماژول از پین ۵v در آرئینود استفاده کردم.
- در ادامه برای اتصال بلندگو به آردوینو تنها کافی از پین مثبت به پین دیجیتال ۲ در آردوینو متصل و پین منفی به GND متصل شود.
کتابخانه های مورد نیاز
برای اجرای پروژه ابتدا در نرم افزار Arduino IDE اقدام به نصب کتابخانه مرجع Talkie می پردازیم. مراحل زیر را دنبال کنید.
- این مسیر را دنبال کنید Sketch > Include Library > Manage Libraries
- کلمه Talkie را جستجو کنید.
- کتابخانه را نصب کنید.
کدهای پروژه فاصله سنج سخنگو
در کدهای این پروژه در ابتدا قادر خواهیم بود پین های مربوط به سنسور التراسونیک و بلندگو را تغییر دهیم. کد های این پروژه دارای سه بخش هستند که ابتدا کد زیر در بخش اصلی یک پروژه جدید در نرمافزار Arduino IDE ذخیره و سپس دو عدد فایل دیگر با پسوند های h. و cpp. در کنار این کد ایجاد و کنارهم اجرا خواهند شد که وظیفه راهاندازی سنسور التراسونیک و بلندگو برای اعلام فاصله را دارند.
- ابتدا در نرمافزار Arduino IDE کد های زیر را در وارد کنید.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
#include <Arduino.h> #include "TalkieUtils.h" #include "Vocab_US_Large.h" #include "Vocab_Special.h" #include "HCSR04.h" Talkie Voice; const uint8_t ECHO_IN_PIN = 4; const uint8_t TRIGGER_OUT_PIN = 5; void setup() { pinMode(LED_BUILTIN, OUTPUT); Serial.begin(115200); #if defined(__AVR_ATmega32U4__) || defined(SERIAL_USB) || defined(SERIAL_PORT_USBVIRTUAL) || defined(ARDUINO_attiny3217) delay(4000); // To be able to connect Serial monitor after reset or power up and before first print out. Do not wait for an attached Serial Monitor! #endif Serial.println(F("START " __FILE__ " from " __DATE__ "\r\nUsing library version " VERSION_TALKIE)); initUSDistancePins(TRIGGER_OUT_PIN, ECHO_IN_PIN); #if defined(TEENSYDUINO) pinMode(5, OUTPUT); digitalWrite(5, HIGH); #endif Serial.print("Voice queue size is: "); Serial.println(Voice.sayQ(spPAUSE1)); } void loop() { int tCentimeter = getUSDistanceAsCentiMeterWithCentimeterTimeout(300); if (tCentimeter >= 300) { Serial.println("timeout"); sayQTimeout(&Voice); Voice.sayQ(sp2_OUT); } else { Serial.print("cm="); Serial.println(tCentimeter); float tDistanceMeter = tCentimeter / 100.0; sayQFloat(&Voice, tDistanceMeter, 2, true, true); Voice.sayQ(sp2_METER); } Voice.sayQ(spPAUSE1); while (Voice.isTalking()) { ; } } |
- در ادامه کد های زیر را با پسوند و نام HCSR04.cpp در Arduino IDE وارد کنید.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 |
#include <Arduino.h> #include "HCSR04.h" uint8_t sTriggerOutPin; uint8_t sEchoInPin; uint8_t sHCSR04Mode = HCSR04_MODE_UNITITIALIZED; void initUSDistancePins(uint8_t aTriggerOutPin, uint8_t aEchoInPin) { sTriggerOutPin = aTriggerOutPin; if (aEchoInPin == 0) { sHCSR04Mode = HCSR04_MODE_USE_1_PIN; } else { sEchoInPin = aEchoInPin; pinMode(aTriggerOutPin, OUTPUT); pinMode(sEchoInPin, INPUT); sHCSR04Mode = HCSR04_MODE_USE_2_PINS; } } void initUSDistancePin(uint8_t aTriggerOutEchoInPin) { sTriggerOutPin = aTriggerOutEchoInPin; sHCSR04Mode = HCSR04_MODE_USE_1_PIN; } unsigned int getUSDistance(unsigned int aTimeoutMicros) { if (sHCSR04Mode == HCSR04_MODE_UNITITIALIZED) { return 0; } digitalWrite(sTriggerOutPin, HIGH); if (sHCSR04Mode == HCSR04_MODE_USE_1_PIN) { pinMode(sTriggerOutPin, OUTPUT); } #ifdef DEBUG delayMicroseconds(100); #else delayMicroseconds(10); #endif digitalWrite(sTriggerOutPin, LOW); uint8_t tEchoInPin; if (sHCSR04Mode == HCSR04_MODE_USE_1_PIN) { delayMicroseconds(20); pinMode(sTriggerOutPin, INPUT); tEchoInPin = sTriggerOutPin; } else { tEchoInPin = sEchoInPin; } #if ! defined(__AVR__) || defined(TEENSYDUINO) || defined(__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__) || defined(__AVR_ATtiny87__) || defined(__AVR_ATtiny167__) noInterrupts(); unsigned long tUSPulseMicros = pulseIn(tEchoInPin, HIGH, aTimeoutMicros); interrupts(); #else unsigned long tUSPulseMicros = pulseInLong(tEchoInPin, HIGH, aTimeoutMicros); #endif return tUSPulseMicros; } unsigned int getCentimeterFromUSMicroSeconds(unsigned int aDistanceMicros) { return (aDistanceMicros * 100L) / 5825; } unsigned int getUSDistanceAsCentiMeter(unsigned int aTimeoutMicros) { return (getCentimeterFromUSMicroSeconds(getUSDistance(aTimeoutMicros))); } unsigned int getUSDistanceAsCentiMeterWithCentimeterTimeout(unsigned int aTimeoutCentimeter) { unsigned int tTimeoutMicros = ((aTimeoutCentimeter * 233L) + 2) / 4; return getUSDistanceAsCentiMeter(tTimeoutMicros); } void testUSSensor(uint16_t aSecondsToTest) { for (long i = 0; i < aSecondsToTest * 50; ++i) { digitalWrite(sTriggerOutPin, HIGH); delayMicroseconds(582); digitalWrite(sTriggerOutPin, LOW); delay(20); } } #if (defined(USE_PIN_CHANGE_INTERRUPT_D0_TO_D7) | defined(USE_PIN_CHANGE_INTERRUPT_D8_TO_D13) | defined(USE_PIN_CHANGE_INTERRUPT_A0_TO_A5)) unsigned int sUSDistanceCentimeter; volatile unsigned long sUSPulseMicros; volatile bool sUSValueIsValid = false; volatile unsigned long sMicrosAtStartOfPulse; unsigned int sTimeoutMicros; void handlePCInterrupt(uint8_t aPortState) { if (aPortState > 0) { sMicrosAtStartOfPulse = micros(); } else { sUSPulseMicros = micros() - sMicrosAtStartOfPulse; sUSValueIsValid = true; } #ifdef DEBUG #endif } #endif #if defined(USE_PIN_CHANGE_INTERRUPT_D0_TO_D7) ISR (PCINT2_vect) { uint8_t tPortState = (*portInputRegister(digitalPinToPort(sEchoInPin))) & bit((digitalPinToPCMSKbit(sEchoInPin))); handlePCInterrupt(tPortState); } #endif #if defined(USE_PIN_CHANGE_INTERRUPT_D8_TO_D13) /* * pin change interrupt for D8 to D13 here. * state of pin is echoed to output 13 for debugging purpose */ ISR (PCINT0_vect) { // check pin uint8_t tPortState = (*portInputRegister(digitalPinToPort(sEchoInPin))) & bit((digitalPinToPCMSKbit(sEchoInPin))); handlePCInterrupt(tPortState); } #endif #if defined(USE_PIN_CHANGE_INTERRUPT_A0_TO_A5) /* * pin change interrupt for A0 to A5 here. * state of pin is echoed to output 13 for debugging purpose */ ISR (PCINT1_vect) { // check pin uint8_t tPortState = (*portInputRegister(digitalPinToPort(sEchoInPin))) & bit((digitalPinToPCMSKbit(sEchoInPin))); handlePCInterrupt(tPortState); } #endif #if (defined(USE_PIN_CHANGE_INTERRUPT_D0_TO_D7) | defined(USE_PIN_CHANGE_INTERRUPT_D8_TO_D13) | defined(USE_PIN_CHANGE_INTERRUPT_A0_TO_A5)) void startUSDistanceAsCentiMeterWithCentimeterTimeoutNonBlocking(unsigned int aTimeoutCentimeter) { // need minimum 10 usec Trigger Pulse digitalWrite(sTriggerOutPin, HIGH); sUSValueIsValid = false; sTimeoutMicros = ((aTimeoutCentimeter * 233) + 2) / 4; // = * 58.25 (rounded by using +1) *digitalPinToPCMSK(sEchoInPin) |= bit(digitalPinToPCMSKbit(sEchoInPin));// enable pin for pin change interrupt // the 2 registers exists only once! PCICR |= bit(digitalPinToPCICRbit(sEchoInPin));// enable interrupt for the group PCIFR |= bit(digitalPinToPCICRbit(sEchoInPin));// clear any outstanding interrupt sUSPulseMicros = 0; sMicrosAtStartOfPulse = 0; #ifdef DEBUG delay(2); // to see it on scope #else delayMicroseconds(10); #endif digitalWrite(sTriggerOutPin, LOW); } bool isUSDistanceMeasureFinished() { if (sUSValueIsValid) { sUSDistanceCentimeter = getCentimeterFromUSMicroSeconds(sUSPulseMicros); return true; } if (sMicrosAtStartOfPulse != 0) { if ((micros() - sMicrosAtStartOfPulse) >= sTimeoutMicros) { *digitalPinToPCMSK(sEchoInPin) &= ~(bit(digitalPinToPCMSKbit(sEchoInPin)));// disable pin for pin change interrupt return true; } } return false; } #endif |
- در نهایت نیاز دارید کد های مشخص شده یزر را با پسوند و نام HCSR04.h در نرمافزار مربوط ذخیره کنید.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
#ifndef HCSR04_H_ #define HCSR04_H_ #include <stdint.h> #define US_DISTANCE_DEFAULT_TIMEOUT_MICROS 20000 #define US_DISTANCE_DEFAULT_TIMEOUT_CENTIMETER 343 // Timeout of 20000L is 3.43 meter #define US_DISTANCE_TIMEOUT_MICROS_FOR_1_METER 5825 // Timeout of 5825 is 1 meter #define US_DISTANCE_TIMEOUT_MICROS_FOR_2_METER 11650 // Timeout of 11650 is 2 meter #define US_DISTANCE_TIMEOUT_MICROS_FOR_3_METER 17475 // Timeout of 17475 is 3 meter void initUSDistancePins(uint8_t aTriggerOutPin, uint8_t aEchoInPin = 0); void initUSDistancePin(uint8_t aTriggerOutEchoInPin); // Using this determines one pin mode unsigned int getUSDistance(unsigned int aTimeoutMicros = US_DISTANCE_DEFAULT_TIMEOUT_MICROS); unsigned int getCentimeterFromUSMicroSeconds(unsigned int aDistanceMicros); unsigned int getUSDistanceAsCentiMeter(unsigned int aTimeoutMicros = US_DISTANCE_DEFAULT_TIMEOUT_MICROS); unsigned int getUSDistanceAsCentiMeterWithCentimeterTimeout(unsigned int aTimeoutCentimeter); void testUSSensor(uint16_t aSecondsToTest); #if (defined(USE_PIN_CHANGE_INTERRUPT_D0_TO_D7) | defined(USE_PIN_CHANGE_INTERRUPT_D8_TO_D13) | defined(USE_PIN_CHANGE_INTERRUPT_A0_TO_A5)) void startUSDistanceAsCentiMeterWithCentimeterTimeoutNonBlocking(unsigned int aTimeoutCentimeter); bool isUSDistanceMeasureFinished(); extern unsigned int sUSDistanceCentimeter; extern volatile unsigned long sUSPulseMicros; #endif #define HCSR04_MODE_UNITITIALIZED 0 #define HCSR04_MODE_USE_1_PIN 1 #define HCSR04_MODE_USE_2_PINS 2 extern uint8_t sHCSR04Mode; #endif // HCSR04_H_ #pragma once |
- در ادامه قادر خواهید بود بدون دریافت ارور کد های مدنظر را در برد خود آپلود کنیدو همچنین نحوه اضافه کردن فایل به نرافزار آردوینو به شکل زیر خواهد بود. ابتدا از قسمت مشخص شده گزینه New Tab را انتخاب کنید.
- در ادامه در پایین صفحه نام و پسوند فایل مورد نظر را وارد کنید.
نتیجه نهایی فاصله سنج سخنگو
در نهایت پس از برقراری اتصالات و آپلود کد ها، در صورتی که تمام موارد به درستی انجام شده باشد، سنسور التراسونیک هر چند ثانیه یک بار مقادیر اندازه گیری شده را در سریال مانیتور نمایش میدهد و در همین بین مقادیر از طریق بلندگو متصل شده به آردوینو پخش خواهند شد.
کلام آخر با سایفر
چنانچه در مراحل راه اندازی و انجام این پروژه با مشکل مواجه شدید، بدون هیچ نگرانی در انتهای همین پست، به صورت ثبت نظر سوالتان را مطرح کنید. من در سریعترین زمان ممکن پاسخ رفع مشکل شما را خواهم داد. همچنین اگر ایرادی در کدها و یا مراحل اجرایی وجود دارند میتوانید از همین طریق اطلاع رسانی کنید.
در پایان نظرات و پیشنهادات خود را با ما درمیان بگذارید و با اشتراک گذاری این آموزش در شبکه های اجتماعی , از وبسایت دیجی اسپارک حمایت کنید.
سلام وقتتون بخیر
مرتبط با رشته ی مهندسی پزشکی پروژه ای سراغ ندارین؟
لطفا اگر ممکنه کمکم کنید
با سلام
لینک های زیر را بررسی کنید.
کیت آردوینو ضربان قلب AD8232 ECG
کیت پرتابل پالس اکسی متر با قابلیت اندازه گیری دمای بدن