پروژه اخیر آردوینو من ساخت دوربین حرارتی ارزان با استفاده از حسگر IR و مقداری سختافزار پان/تیلت بود. اگر به تصویر دستگاه در سمت چپ نگاه کنید، محدوده یاب آکوستیک نیز در بالا نصب شده است.
این دستگاه با جارو کردن شبکه ای از نقاط کار می کند و تصویر را به صورت تکه ای جمع می کند. خروجی از دو تصویر تشکیل شده است: 1) تصاویر آکوستیک که فاصله اشیاء در دید را نشان می دهد و 2) تصویر حرارتی که دمای اجسام در دید را نشان می دهد. من از gnuplot برای جمع آوری تصاویر استفاده می کنم. اسکریپت های زیر را ببینید.
من قصد دارم از فاصله یاب برای تعیین اندازه نقطه خوان IR استفاده کنم. اندازه نقطه با dh_o/dL=2sin(5) مقیاس می شود. جایی که dh_o تغییر قطر نقطه و dL تغییر فاصله سنسور تا جسم است. پنج بر اساس زاویه دید 5 درجه سنسور IR ثابت است.
من ایده پروژه را از این سایت گرفتم: http://www.cheap-thermocam.tk/
پیشرفت مونتاژ:
- Pan/Tilt را با سرووها جمع کنید. از سرووهای متوسط استفاده کنید زیرا کوچک برای عمل شیب کمی بیش از حد تحت گشتاور بود (به پرش در ویدیو توجه کنید). سرووها به 5 ولت نیاز دارند.
- مبدل اولتراسونیک را با قرار دادن یک سیم از سوراخ ها و لحیم کاری در دو طرف به یک برد پروتویی وصل کرد. (سوراخ ها باید روی هر دو برد هماهنگ باشند) حسگر اولتراسونیک را در وسط برد اصلی قرار دهید تا سنسور ir با مرکز سنسور اولتراسونیک هم تراز شود.
- پایه لیزری به سخت افزار Pan/Tilt متصل شده است به طوری که دو سوراخ نصب با زاویه راست در سمت بالا برای اتصال برد قرار دارند. من از پیچ های سمت چپ سروو برای اتصال پایه لیزری استفاده کردم. من ابتدا سوراخی ایجاد کردم که کمی کوچکتر از قطر رزوه پیچ بود.
- لیزر را تا انتها به پایه لیزر فشار دهید. توقف کنید و با لیزر و برنامه ساده سروو کار کنید.
- اکنون یک خط برق 3 ولت و خط GND را اجرا کنید و مقداری سیم اضافی برای بازی باقی بگذارید. مبدل اولتراسونیک می تواند 3 ولت یا 5 ولت (رزولوشن 5 ولت بهتر) مصرف کند. سنسور مادون قرمز فقط 3 ولت می تواند مصرف کند. ساخت من فقط از 3 ولت برای IR و سونار استفاده می کند.
- حالا سنسور ir را با احتیاط داخل آن قرار دهید و فقط لحیم کاری کنید که لیدها بریده نشوند. سپس مقاومت های 4.7K اهم خود را از برق به سمت مخالف برد بالای سنسور ir اجرا کنید.
- حالا اتصالات را روی تخته تشکیل دهید.
- برای رفتن از برد به آردوینو سه سیم اضافه کنید. یکی برای سنسور اولتراسوند و دو تا برای سنسور ir وجود دارد.
- سنسور را روی پایه لیزری نصب کنید. از سوراخ های ارائه شده روی پایه لیزری استفاده کنید. من همچنین از پیچهای اضافی سرووها استفاده کردم و سوراخهای منطبق بر روی برد سنسور را دریل کردم. بسیار مهم است که همه چیز مربع باشد.
- سیم های لیزر را به برق 3 ولت (سیم قرمز) و GND (سفید) وصل کنید.
- حالا اتصالات را روی تخته تشکیل دهید.
- برای رفتن از برد به آردوینو سه سیم اضافه کنید. یکی برای سنسور اولتراسوند و دو تا برای سنسور ir وجود دارد.
- سنسور را روی پایه لیزری نصب کنید. از سوراخ های ارائه شده روی پایه لیزری استفاده کنید. من همچنین از پیچهای اضافی سرووها استفاده کردم و سوراخهای منطبق بر روی برد سنسور را دریل کردم. بسیار مهم است که همه چیز مربع باشد.
- سیم های لیزر را به برق 3 ولت (سیم قرمز) و GND (سفید) وصل کنید.
- دو سیم برق و سه خط دیتا را به یک برد میانی وصل کنید (یکی را از رادیو شاک دریافت کرده و با اره کاپینگ از وسط نصف کنید). این برد میانی به شما امکان انتقال به پین های آردوینو را می دهد. من هدرهای نر (3 پین) را به این برد میانی اضافه می کنم تا کانکتورهای سروو را بپذیرم. بنابراین، اگر من یک سروو را باد کنم، مجبور نیستم دوباره لحیم کنم.
- هنگام استفاده از تخته میانی می توانید یک زمینه مشترک ایجاد کنید.
- اکنون، جعبه تصویر پلاستیکی را تغییر دهید تا سروو در بالا و سیمها از بالای آن عبور کنند. وسط قسمت بالا را پیدا کردم و بعد سروو را در قسمت بالا ترسیم کردم و سوراخ هایی ایجاد کردم و از سوراخ خارج شدم. سپس با استفاده از سخت افزاری که برای نصب روی سروو ارائه شده است، سوراخ هایی ایجاد کردم تا آن را روی پلاستیک محکم کنم. علاوه بر این، من یک بخش مستطیلی از کناره بریدم تا USB و پاور را قبول کند. من آردوینو را در محفظه قرار دادم و شکل کلی را ترسیم کردم و دوباره از یک اره برای ایجاد دهانه استفاده کردم.
- من پایه های پایه را به پایین آردوینو اضافه کردم و پایه های پایه را به محفظه و پایین آردوینو چسباندم.
- اکنون سیم ها را از حسگرها از طریق سوراخ ها به برد میانی و لحیم کاری وارد کنید. همچنین برای اتصال به آردوینو سیم هایی را روی برد میانی اضافه کنید.
- به سیم های آردوینو چسب حرارتی اضافه کردم تا از بیرون نکشیدن آن ها مطمئن شوم.
- حالا همه چیز را ببندید و مقداری چسب حرارتی به لبه محفظه اضافه کنید تا همه چیز کنار هم بماند.
- USB و برق را وصل کنید و کد زیر را آپلود کنید.
کد آردوینو:
تا زمانی که یک اتصال سریال را باز نکنید و دکمه "1" و Enter را فشار دهید، برنامه شروع نمی شود. سپس منطقه مورد علاقه را مشخص می کند. برای ادامه روی "1" ضربه بزنید و دوباره Enter کنید. آردوینو شروع به جمعآوری دادهها در یک آرایه دو بعدی میکند که پس از تکمیل به صفحه نمایش خروجی میدهد.
//Arduino Thermal Camera
#include <i2cmaster.h>
#include <Servo.h>
Servo mvert;
Servo mhorz;
// Pins: 7=sonar; 4&5=ir sensor; 8=vert servo; 9=horz servo
//
//
//
const int pwPin = 7;
const int dev = 0x5A<<1;
long count = 0;
///Servo Ranges
int home_p = 0;
int j_done = 0;
int even = 0;
int xskip = 1;
int yskip = 1;
int xstart = 60;
int xstop = 75;
int ystart = 80;
int ystop = 70;
const int xnum = abs(xstart-xstop)+1;
const int ynum = abs(ystart-ystop)+1;
double therm[16][11];
double acous[16][11];
void setup(){
//sonar pin
pinMode(pwPin, INPUT);
//Servo pins
mvert.attach(8);
mhorz.attach(9);
//Home position servos
mvert.write(xstart); //1485
mhorz.write(ystart); //1530
Serial.begin(9600);
Serial.println("Setup...");
i2c_init(); //Initialise the i2c bus
PORTC = (1 << PORTC4) | (1 << PORTC5);//enable pullups
}
void loop(){
int i,j,jt;
int hpos,vpos,hpos2,vpos2;
double tempData1 = 0x0000; // zero out the data
double sonrData1 = 0x0000;
if(Serial.available()){
if(home_p == 0){
i = 0;
Serial.flush();
Serial.println("Sweeping Viewing Space");
Serial.println("Enter 1 to confirm space");
mvert.write(ystart);
mhorz.write(xstart);
delay(30);
do
{
//This will sweep through window of view
for(int hpos=xstart;hpos<=xstop;hpos++){
mvert.write(ystart);
mhorz.write(hpos);
delay(20);
}
for(int vpos=ystart;vpos>=ystop;vpos--){
mvert.write(vpos);
mhorz.write(xstop);
delay(20);
}
for(int hpos=xstop;hpos>=xstart;hpos--){
mvert.write(ystop);
mhorz.write(hpos);
delay(20);
}
for(int vpos=ystop;vpos<=ystart;vpos++){
mvert.write(vpos);
mhorz.write(xstart);
delay(20);
}
i=Serial.read();
}while (i<=0);
Serial.println("Starting Calculation");
home_p=1;
}
if(j_done == 0){
for(int i=ystart;i>=ystop;i-=yskip){
for(int j=xstart;j<=xstop;j+=xskip){
if(even == 0){
jt = j;
mhorz.write(j);
delay(20);
}
else{
jt=xstop-(j-xstart);
mhorz.write(jt);
delay(20);
}
sonrData1 = readSonar(1);
tempData1 = readMLX(1);
//58uS per cm
double cm = sonrData1;
double celcius = tempData1 - 273.15;
//double fahrenheit = (celcius*1.8) + 32;
//Serial.print("temp,dist,i,j: ");
//Serial.print(celcius);
//Serial.print(", ");
//Serial.print(cm);
//Serial.print(", ");
//Serial.print(ystart-i);
//Serial.print(", ");
//Serial.println(xstop-jt);
//Serial.print("Fahrenheit,inches: ");
//Serial.println(fahrenheit,inches);
therm[xstop-jt][ystart-i] = celcius;
acous[xstop-jt][ystart-i] = cm;
delay(400); // wait a second before printing again
}
mvert.write(i);
delay(20);
if(even == 0){
even = 1;
}else{
even = 0;
}
}
//Output data
Serial.println("Outputting Data");
for(int j=0;j<ynum;j++){
for(int i=0;i<xnum;i++){
Serial.print(therm[i][j]);
Serial.print(", ");
Serial.print(acous[i][j]);
Serial.print(", ");
Serial.print(i);
Serial.print(", ");
Serial.println(j);
Serial.flush();
}
Serial.println(" ");
}
j_done = 1;
}
}}
double readMLX(int Tt) {
int data_low = 0;
int data_high = 0;
int pec = 0;
i2c_start_wait(dev+I2C_WRITE);
i2c_write(0x07);
// read
i2c_rep_start(dev+I2C_READ);
data_low = i2c_readAck(); //Read 1 byte and then send ack
data_high = i2c_readAck(); //Read 1 byte and then send ack
pec = i2c_readNak();
i2c_stop();
//This converts high and low bytes together and processes temperature, MSB is a error bit and is ignored for temps
double tempFactor = 0.02; // 0.02 degrees per LSB (measurement resolution of the MLX90614)
double tempData = 0x0000; // zero out the data
int frac; // data past the decimal point
// This masks off the error bit of the high byte, then moves it left 8 bits and adds the low byte.
tempData = (double)(((data_high & 0x007F) << 8) + data_low);
tempData = (tempData * tempFactor)-0.228;
return tempData;
}
double readSonar(int St) {
long pulse;
//Used to read in the pulse that is being sent by the MaxSonar device.
//Pulse Width representation with a scale factor of 147 uS per Inch.
pulse = pulseIn(pwPin, HIGH);
double sonrData = (double) ((pulse)/58.0);
return sonrData;
}
کد Gnuplot:
من این مشکل را برطرف میکنم اما در حال حاضر دادههای خروجی را روی صفحه از کد بالا در فایلی به نام data.txt کپی و پیست کنید. دما بر حسب سلسیوس، فاصله بر حسب سانتی متر و مختصات xy است. حالا یک فایل دیگر با نام _plot.gnu ایجاد کنید و کد زیر را در آن فایل قرار دهید. سپس اسکریپت gnuplot را با تایپ gnuplot ./_plot.gnu اجرا کنید. مطمئن شوید data.txt و _plot.gnu در یک پوشه هستند.
اجزای اصلی پروژه
لیست مواد:
- آردوینو ( http://www.sparkfun.com/products/9950 )
- سخت افزار Pan/Tilt ( http://www.sparkfun.com/products/10335 )
- 2x سروو، متوسط ( http://www.sparkfun.com/products/10333 )
- تخته مدار مربعی 1 اینچی (sparkfun)
- لیزر ( http://www.sparkfun.com/products/594 )
- پایه لیزری ( http://www.sparkfun.com/products/8674 )
- محدوده یاب اولتراسونیک – XL-Maxsonar EZ2 ( http://www.sparkfun.com/products/9493)
- سنسور IR، 5FOV (http://www.futureelectronics.com/en/Technologies/Product.aspx?ProductID=MLX90614ESFDCIMELEXIS3003055 )
- سیم سیم جامد (رادیوشاک)
- 2 x مقاومت 4.7k اهم (رادیوشاک)
- تخته سنجاق (Radioshack)
- جعبه عکس پلاستیکی (Hobbylobby)
منبع: چگونه دوربین حرارتی آردوینو بسازیم
در ادامه، متن انگلیسی این مطلب را میتوانید مشاهده نمایید:
My recent arduino project was to build thermal camera on the cheap using an ir sensor and some pan/tilt hardware. If you look at the device picture to the left there is also acoustic range finder mounted to the top.