Thermoscanner

Thermography was never so easy/cheap 
Take the hardware of the 3d Scanner, and just replacing the distance sensor with a thermopile. Thats it, and there it goes, the Thermoscanner!
Whats needed:
Hardware:
This time im using tape, as i was running out of zip ties 

Just combine the 2 RC Servos and stick the TPA81 onto it.
Theorie:
The TPA81 provides 1x8 Pixels with 5.12° by 6°. The Sensor is mounted verticaly.
To Increase the resolution its stepping 1° horizontal and about 2° verticaly.
This makes is possible to get a real nice resolution, as can be seen in the top picture showing the candle.
The Thermal resolution from the TPA81 is 1°, but its jumping +-1° so measuring a human in a room is tricky...
(Pictrue from me on the couch)
Software:
The Software is splitted, on part Arduino Code, and the other is Processing.
The Arduino is only listening to the Processing Application, and this is then drawing a nice picture from it.
Processing makes the picture above, below is it processed in false color:

This is me on a couch wearing a tshirt and shorts, my face/arms/legs are hotter as they are not covered by clothing.
Taking this picture took about 30seconds with the code provided below.
Arduino Code:
//test by d2k2 24.09.2009
#include <AFSoftSerial.h>
#include <Wire.h> #define TPA81ADDR (0xd0>>1)
#include Servo myServoPan; // create servo object to control a servo Servo myServoTilt; // create servo object to control a servo
AFSoftSerial mySerial = AFSoftSerial(3, 2);
char CurrentServo; int value;
int valueA; //Storage int valueB;
int fresh = 0;
int Read = 0; int runVal = 0;
void setup() { Wire.begin(); // join i2c bus (address optional for master) myServoPan.attach(9); // attaches the servo on pin 9 to the servo object myServoTilt.attach(10); // attaches the servo on pin 10 to the servo object
pinMode(13, OUTPUT); Serial.begin(57600); Serial.println("Scanturm V0.1"); }
void loop() // run over and over again { get_keyboard_commands(); }
void get_keyboard_commands() {
myServoPan.write(valueA); myServoTilt.write(valueB); if ( Serial.available()) { // read in a string Read = Serial.read(); if (Read == 200){ runVal = 0; // Serial.println("Reset"); }; switch (runVal) { case 0: runVal = 1; break; case 1: valueA = Read; runVal = 2; break; case 2: valueB = Read; runVal = 3; case 3:
SendTPA();
/* Serial.print(": "); Serial.print(val); Serial.println("$"); */ //runVal = 1; break; } } }
void SendTPA(){ //Send the TPA81 Data back to the PC: byte b; int i; for (i=1; i<=9; i++) { Wire.beginTransmission(TPA81ADDR); Wire.send(i); Wire.endTransmission(); Wire.requestFrom(TPA81ADDR, (int) 1); while(Wire.available() < 1) { ; }
b = Wire.receive(); // receive a byte as character
Serial.print(b, DEC); Serial.print(";"); } Serial.println(""); }
Processing Code:
//d2k2 24.09.2009 shows values from the TPA81 //prestage for putting the sensor on the scan turrent
import processing.serial.*;
Serial myPort; // Create object from Serial class int lf = 10; // Linefeed in ASCII String myString; int[] val = {1,1,1,1,1,1,1,1,1}; int MaxT=100; int MinT=20; int pan = 40; int tilt = 80; String[] list = null;
int MaxT2 = 0; int MinT2 = 255;
boolean result = false; boolean run = false;
long time; long lastrun = 0; long runT;
void setup() { size(400, 400);
String portName = Serial.list()[1]; myPort = new Serial(this, portName, 57600); myPort.buffer(1);
}
void draw() { time = millis(); runT = lastrun - time;
String myTest = ""; if ( myPort.available() > 0) { // If data is available, myString = myPort.readStringUntil(lf); if (myString != null) { list = split(myString, ';'); myTest = list[0]; if(int(myTest)>0) {
result = true; val[1] = int(list[8]); val[2] = int(list[7]); val[3] = int(list[6]); val[4] = int(list[5]); val[5] = int(list[4]); val[6] = int(list[3]); val[7] = int(list[2]); val[8] = int(list[1]); val[0] = int(list[0]); //check for new max/min events if(MaxT2<max(val)) { MaxT2 = max(val); } if(MinT2>min(val)) { MinT2 = min(val); } //Draw another Line, right at the Pan Position
//Pan is about everywhere from 10 to 170 //so i need to update every Pan Pixel and just try it like that now float Col = 0;
for(int i = 1;i<9; i = i+1){ Col = map(val[i],MinT,MaxT,0,255); color drp = color(Col,Col,Col); for(int i2 = 1; i2 < 5; i2 = i2+1){ set(pan+pan, (i*4)+75+i2+tilt+tilt+4*i-100,drp); } for(int i2 = 1; i2 < 5; i2 = i2+1){ set(pan+1+pan,(i*4)+75+i2+tilt+tilt+4*i-100,drp); }
} } }
//background(255); // Set background to white
//Draw them 9 Pixels in a line: /* int Size = 45; float Col = 0; for (int i = 1; i < 9; i = i+1) { rect((Size*i)-Size+5, 5, Size, Size); Col = map(val[i],MinT,MaxT,0,255); fill(0,0,Col); } */ }
if(millis()>lastrun) { if(run == true) { //Now i need to check if i got a result: if(result == true) { //Now i need to check if im at the end of my motion: if(pan < 150) { //Now i can move :) pan = pan + 1; SetServo(); lastrun = millis()+100; } else { run = false; } } } } }
void keyPressed() { if( key == '6'){ pan = pan+1; SetServo(); println("Pan: " + pan); println("Tilt: " + tilt); } if( key == '4'){ pan = pan-1; SetServo(); println("Pan: " + pan); println("Tilt: " + tilt); } if( key == '8'){ tilt = tilt-2; SetServo(); println("Pan: " + pan); println("Tilt: " + tilt); } if( key == '2'){ tilt = tilt+2; SetServo(); println("Pan: " + pan); println("Tilt: " + tilt); } if( key == '5'){ SetServo(); println("Pan: " + pan); println("Tilt: " + tilt); } if( key == '1'){ pan = 40; SetServo(); println("Pan: " + pan); println("Tilt: " + tilt); } if( key == '3'){ run = true; }
}
void SetServo(){ result = false; myPort.write(200); //init myPort.write(tilt); //tilt myPort.write(pan); //pan delay(100); myPort.write(80); //trigger read }
Links related to this:Arduino Forum: http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1253898939/0#0 Hack a Day: http://hackaday.com/2009/09/25/arduino-thermoscanner/ Make: http://blog.makezine.com/archive/2009/09/thermal_imaging_on_the_cheap.html
|