Arduino controlled chemistry lab build log (or building a smart hood)

Hopefully this is the proper forum to post a log.

I am beginning work on automating my chemistry experiments. I am an amateur chemist majoring in biology and minoring in chemistry. I have a home lab that I have been building, and I find that it takes a lot of my time and attention to run even simple procedures. I feel like a lot of the processes can be automated, and as data is collected, processes can be improved to the point that minimal human interaction would be necessary. In an ideal world, reaction automation files could be shared with others with similar systems to help run first time reactions efficiently.

The goals of the project fall into a number of categories:

  • Reaction temperature control, monitoring, logging, and optimization from the data.

  • Reagent addition including gas flow control for gas additions, liquid addition, and powder addition.

  • Distillation temperature control and drip monitoring for completion

  • Controlling my hood fan, monitoring the efficiency of the hood. Also, setting reminders to replace the hood filter (which gets forgotten unless reminded).

  • Controlling and monitoring my refrigerated cooling system

  • Controlling my vacuum pump

  • Alarms for events that fall outside of set parameters, including fire or runaway reactions, gas evolution, equipment failures, etc.

  • Melting point apparatus control. Set it and forget it, with a camera that records the melting point range for viewing later.

  • Automated dry vacuum chromatography. Solvent system mixing, monitoring solvent levels, monitoring each elution, and automatically changing the collection vessel once the a solvent mix has finished passing through the column.

Obviously each of these are big tasks in their own right. I am new to micro-controllers, but not to programming. I have learned and produced in Visual Basic. The concepts in the programming are the same so far, just different syntax. My downfall right now is no real electronics knowledge (but that is why I am here).

I will ask questions as I go. I just wanted to have a place to post results and show off my work, and see if anyone has suggestions on improvements. I have no problems sharing code with others interested in the systems, as long as none of it is used to develop commercial applications unless you bring me in on it :).

Look forward to growing and learning here. Thanks for looking.

I think the answer you're looking for is 42.

But seriously, you need to break this down into manageable separate projects.

Agreed.

I will start with what I think is the easiest and work to the most difficult. I have a tendency to loose interest in projects if they are not progressing after long periods of work. Again, the purpose of this specific post is to log progress.

First order of business is turning on the hood. Lights and fan. Should be fairly straight forward.

The fan draws a fair amount of amps, so I will be using a solid state relay triggered by the Arduino. If I feel crazy I will try and air add flow monitoring to it and a way to control the variable speed of the fan. I haven't purchased the lights yet, but I am looking at an LED strip that draws about 3w, which a breakout relay should have no problem managing.

I am going to sketch out the flow of the system so I have a good idea of what I want it to do and post it to see if others agree. From what I have seen so far, the Arduino does not have a lot of room for code, so I will probably group functions into sub-controllers, and those sub controllers will be controlled by a master controller (unless there is a way to expand program memory, like an SD card, I haven't looked into it yet...). Ideally, the program I write for communicating what I want with the Arduino will be modular, so that if someone wants to use a specific piece, they can just download or copy the code for it.

More to come.

On and off of the lights and fan is done, it was pretty easy. Fan speed control is not a priority right now so i'll leave it for later if it is something I see that I need.

I have been dealing the past few nights with serial communications. I program in VB, and prefer to do so if possible. C languages are similar, but not similar enough that the programming is intuitive yet. As I get into Arduino programming more I am sure I will get the hang of it.

The serial communications so far have just been sending and getting the status of pins. It has been a bit of a learning curve. I am using FirmataVB with Visual Studio 2013, and I haven't found much documentation about using the code (I am used to having sources like the MSDN that give examples of how to use the code when I have a question).

The plan for the next part is to make essentially a PID controller for the oil bath I use for distillations. I have a PID controller now controlling the bath and I would like to mimic its functionality with Arduino. After that, I want to add a some way to measure the drip rate on the receiving flask as a way to monitor the distillation progress (infrared beam or motion sensor possibly).

The plan is to have a program on my desktop that transfers whatever parameters I want to run on the Arduino, and then for the Arduino to run and log onto an SD card, or log to the program through wireless or USB.

More to follow.

For drip detection I'd imagine a laser pointing directly at a photo transistor could work quite well. If this were setup so that it's beam passes just off centre of the drips path, then as the drip passes through the beam, it will be deflected by the lensing effect of the drip. Thus causing a negative pulse. Also by being offset from the centre of the drip, it would also allow the second smaller drip (there's always 2) to pass unnoticed. Thereby effectively debouncing the signal.

The sad thing about robotic processes is that , even at an elementary level... you, the person... are a hell of a lot better at pattern recognition and change detection than anything you can do with an Arduino. it sounds simple... but it ain't

Your laundry list of things that you want to control is so extensive, that you will be spending most of your time writing/debugging code and soldering connections, rather than doing chemistry or biology.

You say it takes a lot of your time monitoring "simple" processes. It will take even more of your time designing robust code to monitor those processes. I am a retired chemist who has worked for years designing and coding hardware and software for chemical instruments and believe me, even seemingly simple operations can require a lot of code to make sure your hardware is fail-safe.

your first item "Reaction temperature control, monitoring, logging, and optimization from the data." will probably require several months of coding and debugging to get even close to a system that is trustworthy.... if you are an experienced coder.

The second item will take even longer.

Some of the others (chromatography apps) I have worked on as part of a development team of expert chemists and software engineers who took several years to come up with something that does what you propose.

I don't want to rain on your parade tbaggins , but some of what you are tying to do is unrealistic. Start out real easy. Start with one sensor and an on/off output. log the sensor data to an ASCII file and learn as you go.

Next, try a simple control loop... maybe ramping a temperature... and see how fast the if/then/else and do/while statements begin piling up in your code, as you add logic to make the ramp fool proof.

You have the right idea... learn chem and biology... but also learn electronics and software engineering. In this world, that is where the jobs are. the disciplines are now linked together and if you are familiar with all, you are in demand.

I also believe you should learn to code in JAVA and C++ rather than VB. This will give you much more flexibility in the future. It's a little harder, but in the end it will pay off. Plus you will not be at the mercy of Microsoft.

One of the companies I worked for wrote a user interface in VB 6 and then Microsoft pulled the plug and we ended up re-working 150K plus lines of code... we switched to JAVA.

Good luck in whatever you do but please take care and try not to go to fast and get discouraged. robotics and process control are the hot careers of the 21st century and you are learning just what is needed to be part of it.

RPCoyle,

First thank you for the reply. I realize that the project is large, and as you point out larger than I realize. But I have a lot of time outside of my studies (which means maybe I should be taking on a higher credit load lol), and all of this will eventually lead somewhere. Even if I solve a few of my problems, it is better than the place I am in now.

My hope is to release something that is open source and usable to novice chemists, and professionals alike. In my O-chem lab, there was a day where the a grad student walked in during the middle of lab and informed the professor that the reaction he was running had failed, due to him no watching it, even though he didn't really admit it. The professor was understandably upset, and it was probably because of the time and steps it took to make the precursors to that specific reagent used in the process. My reactions are so much simpler, and it is time consuming to babysit, even though my hood is literally right next to my desk.

For the VB issue, I agree. I want to learn C++, and other languages based on it. They really are not that different fundamentally, it is just syntax. It is hard to beat my head against the computer when I get stuck at something and know how to code what I am thinking of in VB, but dealing with programming the arduino to communicate with my desktop app is helping a lot. As the prototype is for my own use currently, it is not an issue per say, but I would like to release something more universal eventually, such as an app that is web based. Once I iron out what it is that I want the app to do in VB, I think I would be motivated to transfer the code to another platform, or release my VB code for other to translate. If it is something that people want, I think think that others will help adapt the code (if you build it, they will come). If not, then at least I have solved the problem for me and possibly for my university. I can write a paper on it and be done.

For both RPCoyle and KenF. Thanks for the input, really. Critique and ideas are good and help me.

For KenF, that is basically how i had planned to do it. I was playing with the IR sender and receiver last night, I think it will work. I am going to 3D print a black coupling to house the emitter and receiver to reduce noise, and make it easier to attach to the neck of a flask. A beam will shoot through the path of the drip and (hopefully) the drop will break the beam enough to allow a measurement of some kind. After a few runs, I should be able to determine how much volume an average drop in my distillation system represents, and use that to estimate the volume collected.

Attached is a screen shot of the distillation menu that I made today. I haven't done any coding so far. If anyone sees anything that they think should be added let me know. I am about to start coding the form functions and communication with Arduino tonight.

Target name allows for multiple temperature ranges based on expected components of a mix.
High point/low point is the distillation range
Out of range high/low is what to do if the temperature falls out of the range once, say a certain point of the range is reached (Alarm, alarm and go to temp, go temp, do nothing, etc).
Ramp to target is the aggressiveness of the temperature increase (slow, moderate, fast)
Heat lag will be calculated from the characteristics of my oil bath. An equation that allows the ramp to understand where it is and what it should expect to do in the process (calculated from datalogged graph, and refined each time the reaction is run)
log a point x times per x number of seconds.
listbox is an easy way to record the information from the arudio to save to an external file later.

Each value in the form is saved in an multidimensional array with the target name as the index. I don't really want to be messing with a SQL database for saved reaction files. Point logging will have to be optimized and explained to keep log files down. I can sort that out once I get it going to find the best system.

Any ideas are welcome.

RPCoyle:
robotics and process control are the hot careers of the 21st century

....which is exactly why my daughter starts her BSc(Eng) in Mechatronics in the new year.

I have been trying to wrap my head around how the hardware side of this program will run.

Ideally, the arduino runs predefined loops, directed by the values on this form. It will run independent of the PC, logging to an SD card if the computer is not communicating with it. The log files on the SD card can be imported into this program for optimization or viewing (ideally).

Drip rate will be added to the form after I sort distillation temperature control out.

Cooling is basically the same as this module, with less complexity, as it is just maintaining a single set point. I may work on this before drip rate measurement.

Vacuum is similar to cooling, just a different sensor and process, but basically the same idea (on/off at certain conditions).

Fan on off are done. Lights on off are done.

Melting point is difficult, but not impossible, due to the camera and no way that I can think of right now to reliably see when something is crystal vs liquid (change in transmittance?).

Reagent and reaction control stuff is a dream, it would be awesome but we will see what happens with distillation first. The distillation control lays the foundation for reaction control. Addition of liquid, solid, and gas reagents is a big, big task to get right. I can't even do it right manually some times lol. It will have to proceed step wise, ironing out kinks as I go, if I do it.

Chromatography I have no idea what it will need, as I haven't actually done a dry vacuum chromatography run yet. The main benefits of the dry vacuum method are that each fraction is passed completely through the column before the next eluent is added, which allows for changing of collection vessels between each(vs a typical chromatography setup where the column is never allowed to run dry). It is the lowest of my goals, as I really have not had a need for chromatography yet. It would be a combination of vacuum control, drip rate, reagent mixing and addition (if I can automate it), and then movement of stage with the vessels in it. All but the reagent mixing I think I can do right now with some time and effort.

Honestly, if I can get distillation down, that would be awesome in my opinion and totally worth my effort. Babysitting a fractional distillation sucks.

I have been trying to wrap my head around how the hardware side of this program will run.

Ideally, the arduino runs predefined loops, directed by the values on this form. It will run independent of the PC, logging to an SD card if the computer is not communicating with it. The log files on the SD card can be imported into this program for optimization or viewing (ideally).

You have your choices.

Well the arduino itself, as well as monitoring the process should also monitor user input. If the user is sitting at a computer with the controls, then that computer needs to be able to communicate with the arduino. So it's simply a matter of defining some kind of protocol between the computer and the arduino.

What I meant by my comment was more how detailed does the code in the arduino get. I have been debating stand alone vs relying on a computer's input.

I would like for the arduino to be able to accept user commands without a computer input. But it adds a level of complexity to the entire program that allows for more issues. At the simplest level, the arduino is set up to only execute what the computer tells it to do. At the most complex level, there are user inputs hooked directly to the ardunio that allow a user to plug in an SD card with a set of parameters on it, or allows a user to input parameters into the arduino from a user interface on a TFT Screen or LCD.

What is likely is that I will write the code on the computer targeting the simple(r) process, get it sorted out, and then expand to user controls that are independent of a computer. If the log files and input files are written in a simple, universal way, others can adapt their own code to read and write to/from the Arduino via SD card, wifi, etc. to control the system.

My internal dilemma comes from my feeling that I keep putting the cart before the horse while debating options. In some cases I convince myself that it is easier to code what I want from the get go rather than adding modules incrementally, but then I see fallacy in the idea. That is what I mean by wrapping my head around the hardware side. Simplicity vs complexity, and how complex should I start.

I have a question though on best practices for sending information to the arduino...

What should the message to the arduino look like? I was thinking of sending a series as a string or whatever with something that identifies the current target number and 2. splits all of the user defined parameters to parse into the arduino routines.

Example of a string sent to arduino to be parsed: 01,100,200,F,0,3,0, etc., string can be split by commas and parsed to variables or routines based on position.

Example explained:
computer sends >Target number, low temp,high temp, scale, alert low, alert high, ramp speed logic, etc.
then Arduino > echo back each value attached to its respective routine for the program to verify.

Any suggestions on this idea?

Second issue:
Each "target" on the form is basically a user defined temperature range. The form gives the ability to name each target with a string in a combo box. The rest of the components on the form are bound to this target combo box, so when the combo box value changes, if settings have been saved for the target they are populated in their respective fields based on the target.

Theoretically, right now, there can be 1 - infinite targets. Should I limit this number to say 10 or so, and send all of the user defined targets to the arduino at once? Or should I send one target at a time, and have the computer send the next target once the arduino sends a message that the current target it done?

Thoughts?

I just found an interesting paper on fuzzy logic temperature control for anyone that is interested in a good read.

http://engagedscholarship.csuohio.edu/cgi/viewcontent.cgi?article=1047&context=enece_facpub

computer sends >Target number, low temp,high temp, scale, alert low, alert high, ramp speed logic, etc.
then Arduino > echo back each value attached to its respective routine for the program to verify.

The amount of memory in the Arduino may cause you to hit a wall if your code gets to very complex. In most major applications of this type the majority of the logic is on the computer side. Having the same or similar code on both sides, so that it can be controlled both at the device and at the computer, seem to me redundant, and not worth the effort.

I built a ceramics kiln controller that ramps temperature up and down at a given rate. I enclosed the code that is used on the Arduino.... real simple... the code on the computer runs about 8K lines, including all control logic and a complete computer interface plus live data output and printing of graphs.

#include <MAX31855.h>

float tempOut = 0;
int command = 0;
int value;
// Adruino 1.0 pre-defines these variables
//int SCk = 13;
//int MISO = 12;//SO
//int SS = 11;//CS

// Setup the variables we are going to use.
double tempTC, tempCJC;
bool faultOpen, faultShortGND, faultShortVCC, x;
bool temp_unit = 0; // 0 = Celsius, 1 = Fahrenheit
//temp(SCk,CS,SO)
MAX31855 temp(11, 12, 13);

void setup() {
  
  pinMode(2, OUTPUT);      // SSR relay pin out  
  pinMode(9, OUTPUT);      // alarm
 
  Serial.begin(9600);

}

void Average10() { // average 10 readings
 
  float Ave;
  int AveCt ;
  AveCt =0;
  Ave = 0;
  delay(50);
  do {
  
      temp.readMAX31855(&tempTC, &tempCJC, &faultOpen, &faultShortGND, &faultShortVCC, temp_unit);
      Ave = Ave +  tempTC ; // tempTC ; 
      AveCt = AveCt + 1;
      delay(10); 
     } while  (AveCt < 10 ) ; 
 
    tempOut = (Ave/10);
 }

void loop() {
   if ( analogRead(0)> 1021) {          // it's too high turn it off
          digitalWrite(2,LOW);
      }
     value = 0;
     Serial.flush();
     if (Serial.available()) {      // Look for char in serial que and process if found
       command = Serial.read();
     }
      switch (command) {
      case 84 : {                  // If command = "T" turn it on (unless to high)
          digitalWrite(2,HIGH);
       }
      case 67 : {                 // If command = "C" turn it off
          digitalWrite(2,LOW);
      }
      case 68 : {                 //if command ="D" sound tone
        tone(9,220);
      }
      case 69 : {                 //if command ="E" end tone
        noTone(9);
      }
     } 
      command = 0;                 // reset command 

    
    delay(50);
    Average10(); // take averaged sample
    delay(50);
    Serial.flush();
  
    Serial.print("@- "); 
    Serial.print(tempOut);       // output to computer USB port
    Serial.println(" -Tmp ");
 
 }

Awesome reply, that's what I was looking for. Scanning through your code, it looks like you are printing a string to the serial from your program, and using the Arduino to see which ASCII character it is. Basically, the computer does all of the logic and the Arduino turns on or off the SSR, and/or sounds a tone. I like it, it is a simple solution to what I was going to make overly complex.

I have a PID controller that I am using now to control my oil bath (it was sort of my inspiration for the project), and really like it. I also have a controller on my cooling system, but it basically switches the compressor on until it reaches the set point, and then I have to manually turn everything off because the fan to the condenser will keep running (don't like the system as it is).

After reading the paper I posted, I like the idea of fuzzy logic, and I think in essence that is what I will be shooting for in this portion of the program. I have been mulling over what you have said to me about how much work this is going to take, and I see your point. BUT, I think it is worth it. As it is, the lab is just a hobby lab. This project is not really taking me away from anything per se. The goal of everything I am doing is to learn concepts and to experiment with life. Therefore, all of this is worth it, and like you said, the more I know about all of these processes the better. Plus, if it works, it would be an interesting paper to write and try and get published (open source lab control with arduino).

It appears from your code that your using an ADAfruit thermocouple shield, no? It only supports K type thermocouples correct? What hardware are you using to measure temperature? I have two PT100 theromcouples, and I haven't tried attaching them yet. From what I understand, I don't need a shield to use them. Also, what is the general logic scheme for the control (PID?).

Thanks again for the input, I am listening and trying to integrate your suggestions :). You obviously know much more about this than me.

After reading the paper I posted, I like the idea of fuzzy logic, and I think in essence that is what I will be shooting for in this portion of the program

AAAAHHHGGG!!!! ??? Please save this until you learn how to program UNFUZZY logic... believe me, you have a hard enough time doing this at the start.

The MAX thermocouple chips come in a variety of flavors, depending on the thermocouple you are looking for. I got my shield on e-bay. If you get one, make sure it has an on-board voltage divider to drop the logic from 5 volts to 3.3 V of so, otherwise you burn up the chip. I don't know what is on a PT100

here is a code fragment from my ancient VB6 program that contains most of the logic for the temperature ramp.

Sub Gradiant(StartTemp As Single, StopTemp As Single, Delta As Single, holdtime As Single, MaxPts As Single)
Dim n As Integer

On Error GoTo errx
Ping ' test to see it the connection is alive
StatusLBL.Caption = "Ramp " & RampIdx + 1 & " Running"
' incrament the gradiant array if it is out of bounds and put the last value into it.
 If (RmpCt + RampTimes(RampIdx, 0) > UBound(GradArr)) Then
   ReDim Preserve GradArr(UBound(GradArr) + 1)
   GradArr(UBound(GradArr)) = GradArr(UBound(GradArr) - 1)
 End If
 'if it is way to low or high then the signal may be lost
 If (CurrentTemp < GradArr((RmpCt + RampTimes(RampIdx, 0))) - 50 Or CurrentTemp > MaxRamp + 30) Then
   ToneOn
   PinOutOff 'make sure it's off
   AbortRun ("Temperature out of range ")
 End If
If RunHold = True Then GoTo TestMax

If LastIdx < RampIdx Then
 HighLiteRamp (RampIdx)
 loadRampParams (RampIdx)
 LastIdx = RampIdx
 RmpCt = 0
End If
'********************************** trouble statement ********************************

If RunHold = False And RmpCt + RampTimes(RampIdx, 0) <= UBound(GradArr) Then
'RampTimes...  (0)= ct at start (1)= ct at end (2)ct hold start (3) ct hold end
 TargetTxt = Round(GradArr(RmpCt + (RampTimes(RampIdx, 0))), 0) & " deg"
ElseIf RunHold = False Then
  TargetTxt = Round(GradArr(UBound(GradArr)), 0) & " deg"
End If
'*************************************************************************************
If RampPositive = True Then
   
    If CurrentTemp < StopTemp And (RmpCt) > RampTimes(RampIdx, 1) Then
       PinOutON
        Exit Sub
    End If
 
    If (RmpCt) < UBound(GradArr) - 1 Then
        If CurrentTemp < GradArr((RmpCt + RampTimes(RampIdx, 0))) Then
          PinOutON
        Else
          PinOutOff
        End If
    End If
    If (RmpCt) > UBound(GradArr) Then
       If CurrentTemp < StopTemp Then
          PinOutON
       Else
          PinOutOff
      End If
    End If
    ' the temperature must be over the max for three counts
    If CurrentTemp >= StopTemp Then OverCt = OverCt + 1
      If OverCt >= 3 Then
        HoldStartTime = Val(DurationTBX.Text)
        RunHold = True
        RunRamp = False
        OverCt = 0
       End If
 
 ElseIf RampPositive = False Then
    'If CurrentTemp > MaxRamp + 30 Then AbortRun
    If (ct) < UBound(GradArr) - 1 Then
       If CurrentTemp < GradArr((RmpCt + RampTimes(RampIdx, 0))) Then
           PinOutON
       Else
           PinOutOff
       End If
    End If
    If (ct) > UBound(GradArr) Then
      If CurrentTemp < StopTemp Then
        PinOutON
      Else
        PinOutOff
      End If
    End If
   If CurrentTemp < StopTemp Then OverCt = OverCt + 1
      If OverCt > 1 Then
        HoldStartTime = Val(DurationTBX.Text)
        RunHold = True
        RunRamp = False
        OverCt = 0
      End If
   
 End If
TestMax:
Exit Sub
errx:
 FailErr = True
 PinOutOff
 PinOutOff
 ToneOn
 AbortRun (Err.Description)
 StatusLBL.Caption = Err.Description & " Rct " & RmpCt & " Ubd " & UBound(GradArr) & " sum " & RmpCt + RampTimes(RampIdx, 0)
End Sub

Sub PinOutON()
Dim n As Integer
On Error GoTo e1
If MSComm1.PortOpen = True Then
 Sleep 50 ' try to prevent switch bounce
 MSComm1.Output = "T" & Chr$(13)
 PinOnLBL.Caption = "Elements ON"
 PinOnSHP.FillColor = vbRed
 KWH = KWH + (Amps * Volts * 0.001) / 3600
 KWHtxt.Text = Round(KWH, 2)
End If
Exit Sub
e1:
MSComm1.PortOpen = False
AbortRun ("lost communications")
End Sub

Sub PinOutOff()
Dim n As Integer
Dim str As String
On Error GoTo e1
 If MSComm1.PortOpen = True Then
 Sleep 50 ' try to prevent switch bounce
  MSComm1.Output = "C" & Chr$(13)
  PinOnLBL.Caption = "Elements OFF"
  PinOnSHP.FillColor = &H80808
End If
Exit Sub
e1:
MSComm1.PortOpen = False
AbortRun ("lost communications")
End Sub

First, thanks again for the code. I just browsed through it a second ago, i'll have a better look at it in Visual Studio in a bit.

Do you mid elaborating on your comment about fuzzy logic?

Also, I was asking specifically about your thermocouple as well. You are running a kiln, which is probably pretty hot right? What type of probe are you using? The PT100 is a 3 wire Platinum thermocouple, and from what I understand, doesn't need a shield to run it on the arduino. It is good from -something to 400C. I am using it with my current PID setup and its great.

I haven't really given a lot of thought until now of the dynamics of the distillation procedure. Really, it doesn't matter if the bath is too hot (within reason), because a given component will distill within a set range, all the extra energy will do is to distill the product faster, or possibly blend some components together if their boiling points are close enough (or azeotropes). Once a drip starts, the temperature of the distillate can be used to adjust the temperature of the bath (with it set a certain percentage above (like 10-15C), which is how my bath seems to need to be set from using the PID).

The fuzzy logic is not hard to grasp conceptually, so I am curious to see what you have to say about it. Even though I post on here with big ideas, all of the work I do is done incrementally like I feel you are trying to get me to do. The next steps of my program is just as you suggested, making sure that I can use my probe with arduino, which means testing output against a known temperature, figuring out difference, etc. Then testing communication of the values with the program, then of the program initiating control of the arduino. Then testing of how to optimize bath ramps, and figuring out how to deal commanded vs. actual (error). I just don't post much about these in between steps because they seem like obvious obstacles and don't seem important to log (unless I do something that I think is cool). I hope it doesn't seem like I am not seeing them.

I have no problem with fuzzy logic, but for the relatively simple things you are trying to do, it seems like an over kill. Also, most people on the forum are not using it, so if you hit a snag, you will limit the amount of help you will get. Learn it by all means if it interests you. Your incremental approach (with LOTS of testing) is really the only valid way to go, especially with potentially flammable and corrosive chemicals.

I use a K thermocouple and the kiln gets up to 1300 C. I have also used a AD 595 and a voltage divider to drop the output to the Arduino down to within 5 volts. If you don't need great accuracy in the temperature, you can just use the output of the thermocouple and run it through an op amp to boost the gain, and then imbed a lookup table in the setup of the Arduino code.

thirty cent op amp and a couple of resistors would be all you need to set this up. here is some code I found that I incorporated into another controller that I have used.

#include <stdio.h>
#define POINTS_COUNT 65
int command = 0;  
double temp = 0;
void setup() {
 
  Serial.begin(9600);
}

typedef	struct {
	long temp;
	unsigned long microvolts;
} temp_point;

static temp_point thermocouplePoints[] = {
{ 0 , 0 },
{ 10000 , 397 },
{ 20000 , 798 },
{ 30000 , 1203 },
{ 40000 , 1612 },
{ 50000 , 2023 },
{ 60000 , 2436 },
{ 79000 , 3225 },
{ 98000 , 4013 },
{ 116000 , 4756 },
{ 134000 , 5491 },
{ 139000 , 5694 },
{ 155000 , 6339 },
{ 172000 , 7021 },
{ 193000 , 7859 },
{ 212000 , 8619 },
{ 231000 , 9383 },
{ 250000 , 10153 },
{ 269000 , 10930 },
{ 288000 , 11712 },
{ 307000 , 12499 },
{ 326000 , 13290 },
{ 345000 , 14084 },
{ 364000 , 14881 },
{ 383000 , 15680 },
{ 402000 , 16482 },
{ 421000 , 17285 },
{ 440000 , 18091 },
{ 459000 , 18898 },
{ 478000 , 19707 },
{ 497000 , 20516 },
{ 516000 , 21326 },
{ 535000 , 22137 },
{ 554000 , 22947 },
{ 573000 , 23757 },
{ 592000 , 24565 },
{ 611000 , 25373 },
{ 630000 , 26179 },
{ 649000 , 26983 },
{ 668000 , 27784 },
{ 687000 , 28584 },
{ 706000 , 29380 },
{ 725000 , 30174 },
{ 744000 , 30964 },
{ 763000 , 31752 },
{ 782000 , 32536 },
{ 801000 , 33316 },
{ 820000 , 34093 },
{ 839000 , 34867 },
{ 858000 , 35637 },
{ 877000 , 36403 },
{ 896000 , 37166 },
{ 915000 , 37925 },
{ 934000 , 38680 },
{ 953000 , 39432 },
{ 972000 , 40180 },
{ 991000 , 40924 },
{ 1010000 , 41665 },
{ 1029000 , 42402 },
{ 1048000 , 43134 },
{ 1067000 , 43863 },
{ 1086000 , 44588 },
{ 1105000 , 45308 },
{ 1124000 , 46024 },
{ 1143000 , 46735 },
{ 1200000 , 48838 }
};

static inline unsigned long interpolate(unsigned long val, unsigned long rangeStart, unsigned long rangeEnd, unsigned long valStart, unsigned long valEnd) {
    return rangeStart + (rangeEnd - rangeStart) * (val - valStart) / (valEnd - valStart);
}

static inline unsigned long interpolateVoltage(unsigned long temp, unsigned char i){
    return interpolate(temp, thermocouplePoints[i-1].microvolts, thermocouplePoints[i].microvolts, thermocouplePoints[i-1].temp, thermocouplePoints[i].temp);
}

static inline unsigned long interpolateTemperature(unsigned long microvolts, unsigned char i){
    return interpolate(microvolts, thermocouplePoints[i-1].temp, thermocouplePoints[i].temp, thermocouplePoints[i-1].microvolts, thermocouplePoints[i].microvolts);
}

/**
 * Returns the index of the first point whose temperature value is greater than argument
 **/
static inline unsigned char searchTemp(unsigned long temp) {
	unsigned char i;
	for(i = 0; i < POINTS_COUNT; i++) {
		if(thermocouplePoints[i].temp > temp) {
			return i;
		}
	}
	return POINTS_COUNT-1;
}

/**
 * Returns the index of the first point whose microvolts value is greater than argument
 **/
static inline unsigned char searchMicrovolts(unsigned long microvolts) {
	unsigned char i;
	for(i = 0; i < POINTS_COUNT; i++) {
		if(thermocouplePoints[i].microvolts > microvolts) {
			return i;
		}
	}
	return POINTS_COUNT-1;
}

/**
 * Returns temperature as a function of the ambient temperature and measured thermocouple voltage.
 * Currently only positive ambient temperature is supported
 **/
long thermocoupleConvertWithCJCompensation(unsigned long microvoltsMeasured, unsigned long ambient) {
	//convert ambient temp to microvolts
	//and add them to the thermocouple measured microvolts 
	unsigned long microvolts = microvoltsMeasured + interpolateVoltage(ambient, searchTemp(ambient));
	//look up microvolts in The Table and interpolate
	return interpolateTemperature(microvolts, searchMicrovolts(microvolts));
}

/**
 * Returns temperature, equivalent to the voltage provided in microvolts
 */
long thermocoupleMvToC(unsigned long microvolts) {
	return interpolateTemperature(microvolts, searchMicrovolts(microvolts));
}

/******************************************************************************
 * Additional info
 * ****************************************************************************
 * Changelog:
 * - v. 1.0 (initial release) 2014-04-24 by Albertas MickÄ—nas mic@wemakethings.net
 *
 * ****************************************************************************
 * Bugs, feedback, questions and modifications can be posted on the github page
 * on https://github.com/Miceuz/k-thermocouple-lib/
 * ****************************************************************************
 * - LICENSE -
 * GNU GPL v2 (http://www.gnu.org/licenses/gpl.txt)
 * This program is free software. You can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as published
 * by the Free Software Foundation.
 * ****************************************************************************
 */




void loop() {
  unsigned long x;
   int sensorValue = analogRead(A0);
  // Convert the analog reading (which goes from 0 - 1023) to a voltage (0 - 5V):
  float voltage = sensorValue * (5.0 / 1023.0);
  voltage =10.1744*voltage - 0.8191;
   if ( analogRead(0)> 1021) {          // it's too high turn it off
          digitalWrite(13,LOW);
      }
    
     Serial.flush();
     if (Serial.available()) {      // Look for char in serial que and process if found
      command = Serial.read();
      if (command == 84 & analogRead(0)< 1021) { // If command = "T" turn it on (unless to high)
          digitalWrite(13,HIGH);
         // delay (500); // keep it on for at least half a sec to prevent bounce
      }
      if (command == 67) {          // If command = "C" turn it off
          digitalWrite(13,LOW);
         // delay(500); // keep it off for at least half a second to prevent bounce
      }
      if (command==68){                 //if command ="D" sound tone
        tone(9,220);
      }
      if (command==69){                 //if command ="E" end tone
        noTone(9);
      }
          command = 0;                 // reset command 
   }
    delay(100);
    
    Serial.flush();
    
    delay(100);
    temp= thermocoupleMvToC(voltage);
    if (temp <=0)  {temp = 0;} // if it goes negative just utput 0
    Serial.print("@- ");  // output to computer USB port
    Serial.print(temp);
    Serial.println(" -Tmp ");
  }