Peltier current control

Apologies. Moved from Sensor section. Topic removed.

The camera CMOS cooling project is nearing completion. Recapping, a Peltier cools a copper finger attached to the back of the CMOS. Max deltaT is 34C from ambient with no temp control. A TMP36 is located near the CMOS on the cold finger.

I want to control the temperature of the cold finger using the readings from the TMP36 using (as previously suggested) a Logic Level N-Channel MOSFET low rds(on) controlling current to the TEC (-ve to Drain).

This is working at the moment by setting a digital pin HIGH and LOW. Effectively hard banging. There is a lag in response to the TMP analog input and switching the digital pin equal to the frequency of polling the temperature. This doesn't seem ideal and using PWM is making more sense for smoother results.

As I understand PWM pulse width is related to current flow and therefore a fixed temperature for a given system. The cold finger is very sensitive to temperature deviation at minus temperatures, and a different temperature may be required for each imaging session (dew point).

I am not clear on the best approach or how to write a PWM sketch. In-fact understanding how to implement PWM is not clear to me at all. Missing something here?

Many thanks.

In-fact understanding how to implement PWM is not clear to me at all.

You just use analogWrite(pin, value); Where pin is one of the PWM capable pins, and value is between 0 (off) and 255 (fully on). For further discussion see:-

Thanks GM. Clear as day. Great instructional.

Now working. Temperature becomes readout only in the simplest form, setting a value for a given temp. There must be a way of setting PWM in response to temperature to achieve a set point. Manually a pot might do it crudely, but in a filter that would mean varying the value of the capacitor. Alternatively, I could set up some tables temp/PWM value.

You need to implement PID regulator control loop. There is a library:

I'm not completely sure that PID will do what I plan with a better understanding of PWM.

If I use two temp sensors I can read ambient temp and monitor cold finger temp and set PWM as a variable of;

ambient temp - deviation from zero * (256 / max system delta.

e.g. 20 - -5 * (256 / 35) = 182 - where 35 is the maximum demonstrated temp differential. PWM will change to keep cold finger temp constant with changes in ambient temp. Assuming that PWM is linear.

That's the concept I have in mind...? As night time temps cool power requirements reduce, while all images have the ~same EXIF temp.

During winter lower temps can be achieved by declaring new values - say -10 or 15.

I don't understand what you are trying to control by PWM: 1. Keep difference between two (ambient and finger's) temperatures constant; 2. Keep absolute finger's temperature constant. PWM is just a means to adjust power of heat pump, necessary to achieve ether task. PID is a way, to get to set-point fast, and after that keep it stable, it also works for 1 or 2.

BTW, why you are colling CMOS, decreasing a noise floor?

I'm not completely sure that PID will do what I plan with a better understanding of PWM.

Yes it is. The net effect is that when the temperature is a long way off what you want then the PWM will be on at full belt. When you get closer the PWM backs off the power. Then at the requited temperature it turns the power off. As it drifts back up it will give it a short blast of low power to gently push it down again.

Thanks GM and Magician.

I want to read ambient air temp which varies while maintaining a constant and much lower temp at the cold finger.

It occurred to me after my previous post that the temp needs to be driven down to set point quickly. What I proposed wouldn’t do that.

Apologies Magician PID is necessary. Important is a stable temp at the cold finger irrespective of ambient temp.

I have read the PID documentation beginning to end an will search around for some examples. Doesn’t look straight forward, but is more appropriate than PWM from what I can see now.

Problem is, that regardless of the ambient temperature, the system is only capable of a max differential of 35C. So at 30 C ambient the lowest possible temp is -5. At 15 degrees -20. The power requirements are very similar. Using PWM ambient temperature will be 0, and at the lowest possible temperature 255, irrespective of the ambient or set point temp. The only constants using a TMP36 are voltage and temperature reading 0-1023. So drive down temperature at full power using PID to a set point voltage and then maintain that PWM style.

For an example look at the Teapot software for 3D printers, the file that is called heater.c has what you are looking for, only it is going up and you are going down.
You need to monitor the external temperature and subtract 30 from it and put that as a target for your PID.

Thanks GM. That is Apple software I think. The only other reference that approximates what I'm doing is the coffee machine in Playground.

Methinks another learning curve coming up. I did try a basic PID script but it froze the board an older Diecimila.

Back to PWM. In the short term I will drive the temp down to within 1/2 a degree of set point and set a PWM value to maintain at or near the setpoint. Main thing is stability rather than accuracy. Not so concerned whether stable at -5, 5.5 or -6.

While still working on a PID solution, below is a PWM sketch, which is a bit noisy because of the ~0.32 error in temp reading of both sensors. At least, that’s what I think is happening. Otherwise, setting a fixed PWM value performs well with acceptable accuracy. But doesn’t account for changing ambient air temp. Consequently, the actual temp of the cold finger changes too.

EDIT: In practice the temperature is fairly stable with transient readings of +/- 0.33. Accuracy is within 0.3 of the set point temperature and in one trial 0.05.

Following this approach should I use a resistor capacitor filter to smooth the pwm out. Or is there way to smooth things with code?

//Adapted from 

/* Utilizing two TMP36 temperature sensors to read ambient air temperature and cold finger temperature, a PWM value is calculated to maintain constant cold finger temp i
 with changing ambient air temp. Includes allowance for sensor ambient readouts. Typically the cold finger sensor is lower than the ambient air sensor. */

#define setPointT 2 // target cold finger temp

#define deltaS 0.33 // sensor delta ambient air - ambient finger

#define aref_voltage 3.3

int fingerT;
int ambientT;

int tempPin = 1;
int tempPin1 = 2;

int tempReading;
int tempReading1;

void setup(void) { 

  pinMode(10, OUTPUT);




void loop(void) {

  tempReading = analogRead(tempPin);
  tempReading1 = analogRead(tempPin1);

  float voltage = tempReading * aref_voltage; 
  voltage /= 1024.0; 

  float voltage1 = tempReading1 * aref_voltage; 
  voltage1 /= 1024.0; 

  float fingerT = (voltage - 0.5) * 100;

  float ambientT = (voltage1 - 0.5) * 100; 


  /* PWM control - read ambient air temperature and apply PWM calibration (5.45) and sensor ambient delta to ambient temperature - setPoint temperature delta. 
   Read cold finger temp and PWM max power to setPoint temp. Then within standard read error of the sensor apply variable PWM for set point. Note: cold finger response is slow decreasing temp and rapid when power is removed 

  int pwmV = (ambientT - deltaS - setPointT) * 5.45; 


  if (fingerT > setPointT) {

    analogWrite(10, 255);


    if (fingerT  > (setPointT + 0.1)) {

      analogWrite(10, pwmV);
      if (fingerT < setPointT) {

        analogWrite(10, pwmV);

That is Apple software I think.

No it is for the arduino:-

should I use a resistor capacitor filter to smooth the pwm out.

If you do it on the gate side of the FET then you send it into linear mode and it will get very hot. If you do it on the load side of the FET then you will need an absolutely huge capacitor with a ginormous current ripple rating.

Thanks GM. I might leave out a filter for now. On that score the FET is getting hot without a sink, but I think this may be related to the value of the resistor, 220ohms - too much current. I’m guessing 1meg would be better.

I’m reviewing the teacup heater files as we speak. The penny will eventually drop re PID.

but I think this may be related to the value of the resistor, 220ohms - too much current.

If that is the resistor between the FET's gate and the arduino then:- No the gate FET takes hardly any current at all, you up that resistor and you will make it turn on slower and that will cause over heating. If anything drop it to 100R.

OK. I will replace the resistor.

The results of the posted code seem to be within the standard read error of the TMP36, +/-0.32C, with occasional spikes of 1 or 1.5C. I notice when removing power from the TEC that thermal inertia is about 2 or 3 seconds, so averaging the readings ignoring the outliers should be representative of actual temperature.

ignoring the outliers

Have you tried a capacitor on the analogue input from your temperature sensor? It might remove them altogether.

Depending on the current draw of the Peltier device, the temp sensor may be picking up noise when the Peltier device switches on and off. The most important thing to do to avoid this is to separate the analog and digital grounds. Use one ground pin of your Arduino solely to connect the ground side of your analog sensors (in this case, just your temperature sensor). Use the other ground pins to connect power and the ground sides of any output devices. This avoids the problem of a voltage being induced on the ground side of the temperature sensor when the Peltier device switches due to the inductance of a common ground wire. I've found that using a common ground even when the only output device is an LCD display can cause significant fluctuation in the reading obtained from a temperature sensor.

I am seeing interference lines in live view and lines in still images, plus odd readings from both temp sensors when power is applied, with temperature indications jumping up by 5 and 10 degrees, ambient temperature and camera temperature respectively.

I am also running a stepper motor and shutter release. The stepper is resonating and has little torque. I think this is all related to GND setup. Will try again tomorrow. It seems that I fix one problem to have another crop up at the moment.

Capacitors are doing there job and readings are more stable.

update: Resolved GND connection to stepper. Both anlaog temp sensors have a dedicated GND are reading correctly with caps smoothing out readings. Camera chassis is bonded to GND, which eliminated power supply connected (OFF and plugged in to mains) noise issues. All good until I turn the power on.

Noise in camera live view, which can be eliminated by coupling the temp sensor GND to power supply GND. As before temp sensor overreads by 10 - 20 degrees. Without this camera temp sensor is very erratic. I suspect this has something to do with the FET GND to the Arduino board. So the last resort before giving up in despair is to connect the FET GND to power supply GND and not the Arduino???

Short of writing code to adjust for the power on temp over reading with its GND to power supply GND I'm lost as to what to do...

The switch mode power supply to the Arduino is the culprit. No noise when Arduino is powered by a wall adapter. Not inconvenient because I would like to keep adapters / leads to a minimum.