Author Topic: DIY Scanning Thermal Camera  (Read 22229 times)

0 Members and 3 Guests are viewing this topic.

Offline Kaptein QK

  • Regular Contributor
  • *
  • Posts: 61
DIY Scanning Thermal Camera
« on: January 25, 2013, 05:59:37 AM »
Hi, here is some details about my thermal cam project:

Scanning Thermal Camera


I used this IR temperature gun: http://www.ebay.com/itm/150969162727?ssPageName=STRK:MEWNX:IT&_trksid=p3984.m1497.l2649

It has a TPS334 thermopile, Op-amp and a ADS1110 AD converter with I2C bus.   I use a Arduino Nano to interface the AD converter and pan/tilt servos.

On the PC side a Processing program displays the result.

See pictures for connections.

Arduino code:
Code: [Select]
#include <Wire.h>
#include <Servo.h>

Servo pan;
Servo tilt;

int angle;

char charInput;

String command, temp;

void setup()
{
  pan.attach(2);
  tilt.attach(3);
 
  Wire.begin();
  Serial.begin(9600);
 

  pinMode(13, OUTPUT);
 
  Wire.beginTransmission(0x49);    // thermosensor init
  Wire.write(0b10001110);
  if (Wire.endTransmission()) Serial.println("Error 1");
}


void loop() {
 
  command="";
 
  while (1) {
    charInput = Serial.read();
    if (charInput == '\r') break;
    if (charInput != -1 && charInput != '\n') command += charInput;   
  }

  if (command.length() == 8) {
   
    temp = command.substring(0,4);
    angle = temp.toInt();
    angle = constrain(angle, 1000, 2000);
    pan.writeMicroseconds(angle);
   
    temp = command.substring(4,8);
    angle = temp.toInt();
    angle = constrain(angle, 1000, 2000);
    tilt.writeMicroseconds(angle);
   
    digitalWrite(13,1);
    delay(50);
    digitalWrite(13,0);
    Serial.println(getTemperature());
  }
  else Serial.println(command);
}



void debug() {
  digitalWrite(13,1);
  delay(100);
  digitalWrite(13,0);
  delay(100);
}


int getTemperature() {
  byte byteLow, byteHigh;
  Wire.requestFrom(0x49, 2);
  if (Wire.available() != 2) Serial.println("Error 2");
  byteHigh = Wire.read();
  byteLow = Wire.read();
  return byteHigh<<8 | byteLow;
}


Processing code:
Code: [Select]
final int xSize = 150;
final int ySize = 150;

import processing.serial.*;

Serial myPort;  // Create object from Serial class

int xPos, yPos, angle, state, temperature, minimum, maximum;

String serialInput;
char charInput;

int[][] temperatureMap = new int[xSize][ySize];


void setup()
{
  size(xSize*4, ySize*4);

  for (yPos = 0 ; yPos < ySize ; yPos++) {
    for (xPos = 0 ; xPos < xSize ; xPos++) {
      temperatureMap[xPos][yPos] = 0;
    }
  }

  xPos=0;
  yPos=0;
  state=1;
  minimum = 0x7fff;
  maximum = 0x0000;

  myPort = new Serial(this, Serial.list()[1], 9600);
  delay(2000);

  background(0);
}

void draw() {

  if (state==1) {
   
    print(xPos);
    print(", ");
    println(yPos);
   
    angle = 1500 - (-xSize / 2 + xPos ) * 5;  //horizontal FOV
    myPort.write(str(angle));
    angle = 1500 - (-ySize / 2 + yPos ) * 5;  //vertical FOV
    myPort.write(str(angle));
    myPort.write('\r');
   
    if (xPos==0) delay(400);
    drawMap();
   
    serialInput = "";
    while (true) {
      charInput = myPort.readChar();
      if (charInput == '\r') break;
      if (charInput != 65535 && charInput != '\n') serialInput += charInput;   
    }
     
   
    temperature = parseInt(serialInput);
    println(temperature);
   
    temperatureMap[xPos][yPos] = temperature;
   
    if (temperature > maximum) maximum = temperature;
    if (temperature < minimum) minimum = temperature;
    println(minimum);
    println(maximum);

   
    xPos++;
    if (xPos==xSize) {
      xPos=0;
      yPos++;
      if (yPos==ySize) state=0;
    } 
  }
}
 
 
void drawMap() {
  int x, y, temp;
  float gain, colour;
  color c;
 
 
  gain = 256.0 / (float)(maximum - minimum + 1);
 
  println(gain);
 
  for (y = 0 ; y < ySize ; y++) {
    for (x = 0 ; x < xSize ; x++) {
      temp = temperatureMap[x][y];
      if (temp != 0) {
        colour = (float)(temp - minimum) * gain;
        stroke(colour);
        fill(colour);
        rect(x*4,y*4,3,3);
      }
    }
  } 
}

 
« Last Edit: January 25, 2013, 06:09:45 AM by Kaptein QK »

Offline Psi

  • Super Contributor
  • ***
  • Posts: 4805
  • Country: nz
Re: DIY Scanning Thermal Camera
« Reply #1 on: January 25, 2013, 08:37:45 AM »
Cool.

You could probably speed it up if you used one of those new sensor arrays. Like the 4x16 MLX90620.
They're a bit expensive ($30-100) but still affordable.

That way you'd get more pixels per sample and require less servo movement.
You'd probably need an extra lens, the FOV of those sensors is a bit wide to build a detailed image.

« Last Edit: January 25, 2013, 08:42:17 AM by Psi »
Greek letter 'Psi' (not Pounds per Square Inch)

Offline ftransform

  • Frequent Contributor
  • **
  • Posts: 728
  • Country: 00
Re: DIY Scanning Thermal Camera
« Reply #2 on: January 25, 2013, 07:51:15 PM »
Can you post some more details? I want to make one.

Offline Kaptein QK

  • Regular Contributor
  • *
  • Posts: 61
Re: DIY Scanning Thermal Camera
« Reply #3 on: January 26, 2013, 03:36:56 AM »
Cool.

You could probably speed it up if you used one of those new sensor arrays. Like the 4x16 MLX90620.
They're a bit expensive ($30-100) but still affordable.

That way you'd get more pixels per sample and require less servo movement.
You'd probably need an extra lens, the FOV of those sensors is a bit wide to build a detailed image.

I have already speed up the servo movements, so I am quite happy with it.  :)
It is still very slow, but I have good time and it gives a good image, the best I have seen by similar projects on the net.

Offline Kaptein QK

  • Regular Contributor
  • *
  • Posts: 61
Re: DIY Scanning Thermal Camera
« Reply #4 on: January 26, 2013, 03:39:44 AM »
Can you post some more details? I want to make one.

Ok, what details do you need?

Offline codeboy2k

  • Super Contributor
  • ***
  • Posts: 1138
  • Country: ca
Re: DIY Scanning Thermal Camera
« Reply #5 on: January 26, 2013, 05:53:33 AM »
Cool job.. I thought about something like this years ago, but I didn't start anything yet. Maybe you would like to give my idea a try.. basically I thought about using a scanning mirror like a laser printer... a hexagon mirror on a rotating motor, and you can servo it vertically.  If you use it with a line array it might work pretty well.


Offline bombledmonk

  • Regular Contributor
  • *
  • Posts: 51
  • Country: us
Re: DIY Scanning Thermal Camera
« Reply #6 on: January 26, 2013, 06:16:25 AM »
Have you taken a look at the Panasonic grid-eye?  I've been meaning to pick one up, but just haven't had time to work on something new.  It might not be quite suitable for your setup, but it's interesting.
http://www.digikey.com/product-search/en?x=0&y=0&lang=en&site=us&KeyWords=panasonic+grid

http://pewa.panasonic.com/components/built-in-sensors/infrared-array-sensors/grid-eye/

Offline KD0CAC John

  • Frequent Contributor
  • **
  • Posts: 325
  • Country: us
Re: DIY Scanning Thermal Camera
« Reply #7 on: January 26, 2013, 06:24:09 AM »
Just in it was missed by some , I did not get in before the deadline but I caught the link .
http://www.kickstarter.com/projects/andyrawson/ir-blue-thermal-imaging-smartphone-accessory?ref=card

Offline svofski

  • Regular Contributor
  • *
  • Posts: 56
  • Country: ru
    • svo's interactive persuasion vehicle
Re: DIY Scanning Thermal Camera
« Reply #8 on: January 26, 2013, 01:16:12 PM »
Really cool, something I've been wanting to build myself for a long time. I also thought about making a mirror system to make it quieter (probably no use to try to make it faster? What's the update speed of the thermopile you're using?)

A little optimization idea: why make a rough turn to the beginning of the next scan line if you can scan in a meander pattern?
The dark boxes are coming

Offline Kaptein QK

  • Regular Contributor
  • *
  • Posts: 61
Re: DIY Scanning Thermal Camera
« Reply #9 on: January 26, 2013, 09:43:14 PM »
Really cool, something I've been wanting to build myself for a long time. I also thought about making a mirror system to make it quieter (probably no use to try to make it faster? What's the update speed of the thermopile you're using?)
I have not measured it, but is seems reasonably fast. The limiting factor seems to be the slow AD converter.
Quote
A little optimization idea: why make a rough turn to the beginning of the next scan line if you can scan in a meander pattern?
Good idea, I will try that.
« Last Edit: January 26, 2013, 09:46:31 PM by Kaptein QK »

Offline mikeselectricstuff

  • Super Contributor
  • ***
  • Posts: 5547
  • Country: gb
    • Mike's Electric Stuff
Re: DIY Scanning Thermal Camera
« Reply #10 on: January 26, 2013, 10:06:03 PM »
Really cool, something I've been wanting to build myself for a long time. I also thought about making a mirror system to make it quieter (probably no use to try to make it faster? What's the update speed of the thermopile you're using?)
I have not measured it, but is seems reasonably fast. The limiting factor seems to be the slow AD converter.
Quote
A little optimization idea: why make a rough turn to the beginning of the next scan line if you can scan in a meander pattern?
Good idea, I will try that.
Further optimisation - dynamically adjust scan speed according to rate of change, so flat areas are scanned faster.
Mike's Electric Stuff: High voltage, vintage electronics, electrical curiosities
Day Job: UFOs, LEDs etc.
Versatronics & other low-end pick & place forum

Offline Kaptein QK

  • Regular Contributor
  • *
  • Posts: 61
Re: DIY Scanning Thermal Camera
« Reply #11 on: January 28, 2013, 09:24:16 AM »
Further optimisation - dynamically adjust scan speed according to rate of change, so flat areas are scanned faster.


I do not know how well that will work here. Already the scanning rate is close to the speed of the AD-converter ( 15 conversions/second )



Offline Kaptein QK

  • Regular Contributor
  • *
  • Posts: 61
Re: DIY Scanning Thermal Camera
« Reply #12 on: January 28, 2013, 09:32:26 AM »
A little optimization idea: why make a rough turn to the beginning of the next scan line if you can scan in a meander pattern?

I tested this and it did not work well.  The alternating lines where shifted about 3-4 pixels.


I have a new version of the PC-side software that reduces the load on the PC and the scan time. 150x150 pixels take about 30 minutes.

Code: [Select]
final int xSize = 150;
final int ySize = 150;

import processing.serial.*;

Serial myPort;  // Create object from Serial class

int xPos, yPos, angle, state, temperature, minimum, maximum;

String serialInput;
char charInput;

float gain, previousGain;

int[][] temperatureMap = new int[xSize][ySize];


void setup()
{
  size(xSize*4, ySize*4);

  for (yPos = 0 ; yPos < ySize ; yPos++) {
    for (xPos = 0 ; xPos < xSize ; xPos++) {
      temperatureMap[xPos][yPos] = 0;
    }
  }

  xPos=0;
  yPos=0;
  state=1;
  minimum = 0x7fff;
  maximum = 0x0000;
  previousGain = 0;

  myPort = new Serial(this, Serial.list()[1], 9600);
  delay(2000);

  background(0);
}

void draw() {

  if (state==1) {
   
    print(xPos);
    print(", ");
    println(yPos);
   
    angle = 1500 - (-xSize / 2 + xPos ) * 5;  //horizontal FOV
    myPort.write(str(angle));
    angle = 1500 - (-ySize / 2 + yPos ) * 5;  //vertical FOV
    myPort.write(str(angle));
    myPort.write('\r');
   
    if (xPos==0) delay(400);
   
    serialInput = "";
    while (true) {
      charInput = myPort.readChar();
      if (charInput == '\r') break;
      if (charInput != 65535 && charInput != '\n') serialInput += charInput;   
    }
     
   
    temperature = parseInt(serialInput);
    println(temperature);
   
    temperatureMap[xPos][yPos] = temperature;
   
    if (temperature > maximum) maximum = temperature;
    if (temperature < minimum) minimum = temperature;
    println(minimum);
    println(maximum);


    gain = 256.0 / (float)(maximum - minimum + 1);
 
    println(gain);

    if (gain != previousGain) {
      previousGain = gain;
      drawMap();
    }
    else {
      drawPixel(xPos, yPos, temperature);
    }
   
    xPos++;
    if (xPos==xSize) {
      xPos=0;
      yPos++;
      if (yPos==ySize) {
        state=0;
        myPort.write("15001500\r");
      }
    } 
  }
  else {
    drawMap();
  }
}
 
 
void drawMap() {
  int x, y, temp;
 
  for (y = 0 ; y < ySize ; y++) {
    for (x = 0 ; x < xSize ; x++) {
      temp = temperatureMap[x][y];
      if (temp != 0) {
        drawPixel(x, y, temp);
      }
    }
  } 
}


void drawPixel(int x, int y, int temp) {
  float colour;
 
  colour = (float)(temp - minimum) * gain;
  stroke(colour);
  fill(colour);
  rect(x*4,y*4,3,3);
}
 

Offline svofski

  • Regular Contributor
  • *
  • Posts: 56
  • Country: ru
    • svo's interactive persuasion vehicle
Re: DIY Scanning Thermal Camera
« Reply #13 on: January 28, 2013, 11:38:58 PM »
A little optimization idea: why make a rough turn to the beginning of the next scan line if you can scan in a meander pattern?

I tested this and it did not work well.  The alternating lines where shifted about 3-4 pixels.
Yeah, RC servos usually have a lot of play, ~2 degrees is nothing special even in the expensive ones. You can try preloading it by pulling it to one side with a spring or a rubber band.
The dark boxes are coming

Offline Kaptein QK

  • Regular Contributor
  • *
  • Posts: 61
Re: DIY Scanning Thermal Camera
« Reply #14 on: January 30, 2013, 09:37:23 AM »
I think backlash is only a part of the problem. There is not that much hysteresis in the servo. The sensors time constant and other processing delay also play a role. I either have to slow down the scan (it is now much faster than in the video, about 10 pixels/second) or apply some more processing.

 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf