ASCOM focuser temperature incorrectly reported in SGPro


I recently added a temperature capability to my DIY focuser (AAF2, ASCOM compliant). The focuser has been working fine with SGP so far, but now the reported temperature behaves weirdly.
Below are the focuser log and SGP log (Shortened to the relevant parts).
When the focuser is first connected the temperature is correctly read (21.75 at 16:10:05.287).
I do a few moves to check everything is working well.
Then at 16:10:45.762 the focuser reports a new value of 23.75 C, but in SGP it displays 22.42. I don’t know where this value is coming from (the focuser outputs temperature in multiples of 0.25).

Any idea what the problem could be?

Edit: After further test, it seems SGP applies some weighted average on the temperatures it receives, most likely to smooth out short fluctuations. It could be a good idea to mention it in the user manual (along with the sampling rate ~20s).

16:10:01.975 AAF2 Constructed
16:10:04.010 AAF2.setInitialPosition Sending: I5000#
16:10:04.011 AAF2.CommandString ------------------ Start -----------------------
16:10:04.011 AAF2.CommandString Command = I5000#
16:10:04.011 AAF2.CommandString Clearing Buffers
16:10:04.012 AAF2.CommandString Transmitting:I5000#
16:10:04.265 AAF2.CommandString Getting Return Message
16:10:04.267 AAF2.CommandString Return Message = I5000:OK#
16:10:04.267 AAF2.CommandString ------------------ Finish ----------------------
16:10:04.268 AAF2.setInitialPosition Received: I5000:OK#
16:10:04.269 AAF2.getPosition Sending: P#
16:10:04.269 AAF2.CommandString ------------------ Start -----------------------
16:10:04.269 AAF2.CommandString Command = P#
16:10:04.269 AAF2.CommandString Clearing Buffers
16:10:04.269 AAF2.CommandString Transmitting:P#
16:10:04.520 AAF2.CommandString Getting Return Message
16:10:04.521 AAF2.CommandString Return Message = P5000:OK#
16:10:04.521 AAF2.CommandString ------------------ Finish ----------------------
16:10:04.521 AAF2.getPosition Received: P5000:OK#
16:10:04.521 AAF2.getPosition Position = 5000
16:10:04.525 AAF2.halt Sending: H#
16:10:04.526 AAF2.CommandString ------------------ Start -----------------------
16:10:04.526 AAF2.CommandString Command = H#
16:10:04.526 AAF2.CommandString Clearing Buffers
16:10:04.526 AAF2.CommandString Transmitting:H#
16:10:04.777 AAF2.CommandString Getting Return Message
16:10:04.778 AAF2.CommandString Return Message = H5000:OK#
16:10:04.778 AAF2.CommandString ------------------ Finish ----------------------
16:10:04.778 AAF2.halt Received: H5000:OK#
16:10:04.778 AAF2.halt Focuser has stopped
16:10:04.778 AAF2.getPosition Sending: P#
16:10:04.778 AAF2.CommandString ------------------ Start -----------------------
16:10:04.778 AAF2.CommandString Command = P#
16:10:04.778 AAF2.CommandString Clearing Buffers
16:10:04.778 AAF2.CommandString Transmitting:P#
16:10:05.030 AAF2.CommandString Getting Return Message
16:10:05.031 AAF2.CommandString Return Message = P5000:OK#
16:10:05.031 AAF2.CommandString ------------------ Finish ----------------------
16:10:05.031 AAF2.getPosition Received: P5000:OK#
16:10:05.031 AAF2.getPosition Position = 5000
16:10:05.033 AAF2.getTemperature Sending: C#
16:10:05.033 AAF2.CommandString ------------------ Start -----------------------
16:10:05.033 AAF2.CommandString Command = C#
16:10:05.033 AAF2.CommandString Clearing Buffers
16:10:05.033 AAF2.CommandString Transmitting:C#
16:10:05.285 AAF2.CommandString Getting Return Message
16:10:05.286 AAF2.CommandString Return Message = C2175:OK#
16:10:05.287 AAF2.CommandString ------------------ Finish ----------------------
16:10:05.287 AAF2.getTemperature Received: C2175:OK#
16:10:05.287 AAF2.getTemperature Temperature = 2175
16:10:05.340 AAF2.getTemperature Sending: C#
16:10:05.340 AAF2.CommandString ------------------ Start -----------------------
16:10:05.340 AAF2.CommandString Command = C#
16:10:05.340 AAF2.CommandString Clearing Buffers
16:10:05.340 AAF2.CommandString Transmitting:C#
16:10:05.377 AAF2.isMoving Sending: M#
16:10:05.377 AAF2.CommandString ------------------ Start -----------------------
16:10:05.377 AAF2.CommandString Command = M#
16:10:05.377 AAF2.CommandString Clearing Buffers
16:10:05.378 AAF2.CommandString Transmitting:M#
16:10:05.591 AAF2.CommandString Getting Return Message
16:10:05.592 AAF2.CommandString Return Message = C2175:OK#
16:10:05.592 AAF2.CommandString ------------------ Finish ----------------------
16:10:05.592 AAF2.getTemperature Received: C2175:OK#
16:10:05.593 AAF2.getTemperature Temperature = 2175
16:10:05.628 AAF2.CommandString Getting Return Message
16:10:05.629 AAF2.CommandString Return Message = M0:OK#
16:10:05.629 AAF2.CommandString ------------------ Finish ----------------------
16:10:05.629 AAF2.isMoving Received: M0:OK#
16:10:05.629 AAF2.isMoving Focuser is Not Moving
16:10:10.882 AAF2.isMoving Sending: M#
16:10:10.882 AAF2.CommandString ------------------ Start -----------------------
16:10:10.882 AAF2.CommandString Command = M#
16:10:10.882 AAF2.CommandString Clearing Buffers
16:10:10.882 AAF2.CommandString Transmitting:M#
16:10:11.133 AAF2.CommandString Getting Return Message
16:10:11.133 AAF2.CommandString Return Message = M0:OK#
16:10:11.133 AAF2.CommandString ------------------ Finish ----------------------
16:10:11.133 AAF2.isMoving Received: M0:OK#
16:10:11.133 AAF2.isMoving Focuser is Not Moving
16:10:11.135 AAF2.isMoving Sending: M#
16:10:11.135 AAF2.CommandString ------------------ Start -----------------------
16:10:11.136 AAF2.CommandString Command = M#
16:10:11.136 AAF2.CommandString Clearing Buffers
16:10:11.136 AAF2.CommandString Transmitting:M#
16:10:11.387 AAF2.CommandString Getting Return Message
16:10:11.387 AAF2.CommandString Return Message = M0:OK#
16:10:11.387 AAF2.CommandString ------------------ Finish ----------------------
16:10:11.387 AAF2.isMoving Received: M0:OK#
16:10:11.387 AAF2.isMoving Focuser is Not Moving
16:10:11.387 AAF2.setPosition Sending: T5050#
16:10:11.388 AAF2.CommandString ------------------ Start -----------------------
16:10:11.388 AAF2.CommandString Command = T5050#
16:10:11.388 AAF2.CommandString Clearing Buffers
16:10:11.388 AAF2.CommandString Transmitting:T5050#
16:10:11.638 AAF2.CommandString Getting Return Message
16:10:11.640 AAF2.CommandString Return Message = T5050:OK#
16:10:11.640 AAF2.CommandString ------------------ Finish ----------------------
16:10:11.640 AAF2.setPosition Received: T5050:OK#
16:10:11.967 AAF2.isMoving Sending: M#
16:10:11.967 AAF2.CommandString ------------------ Start -----------------------
16:10:11.967 AAF2.CommandString Command = M#
16:10:11.967 AAF2.CommandString Clearing Buffers
16:10:11.968 AAF2.CommandString Transmitting:M#
16:10:12.219 AAF2.CommandString Getting Return Message
16:10:12.220 AAF2.CommandString Return Message = M1:OK#
16:10:12.220 AAF2.CommandString ------------------ Finish ----------------------
16:10:12.220 AAF2.isMoving Received: M1:OK#
16:10:12.220 AAF2.isMoving Focuser is Moving
16:10:12.976 AAF2.isMoving Sending: M#
16:10:12.976 AAF2.CommandString ------------------ Start -----------------------
16:10:12.976 AAF2.CommandString Command = M#
16:10:12.976 AAF2.CommandString Clearing Buffers
16:10:12.976 AAF2.CommandString Transmitting:M#
16:10:13.228 AAF2.CommandString Getting Return Message
16:10:13.229 AAF2.CommandString Return Message = M0:OK#
16:10:13.229 AAF2.CommandString ------------------ Finish ----------------------
16:10:13.229 AAF2.isMoving Received: M0:OK#
16:10:13.229 AAF2.isMoving Focuser is Not Moving
16:10:14.170 AAF2.isMoving Sending: M#
16:10:14.170 AAF2.CommandString ------------------ Start -----------------------
16:10:14.170 AAF2.CommandString Command = M#
16:10:14.170 AAF2.CommandString Clearing Buffers
16:10:14.170 AAF2.CommandString Transmitting:M#
16:10:14.421 AAF2.CommandString Getting Return Message
16:10:14.422 AAF2.CommandString Return Message = M0:OK#
16:10:14.422 AAF2.CommandString ------------------ Finish ----------------------
16:10:14.422 AAF2.isMoving Received: M0:OK#
16:10:14.422 AAF2.isMoving Focuser is Not Moving
16:10:14.422 AAF2.isMoving Sending: M#
16:10:14.422 AAF2.CommandString ------------------ Start -----------------------
16:10:14.422 AAF2.CommandString Command = M#
16:10:14.422 AAF2.CommandString Clearing Buffers
16:10:14.422 AAF2.CommandString Transmitting:M#
16:10:14.674 AAF2.CommandString Getting Return Message
16:10:14.675 AAF2.CommandString Return Message = M0:OK#
16:10:14.675 AAF2.CommandString ------------------ Finish ----------------------
16:10:14.675 AAF2.isMoving Received: M0:OK#
16:10:14.675 AAF2.isMoving Focuser is Not Moving
16:10:14.675 AAF2.setPosition Sending: T5000#
16:10:14.675 AAF2.CommandString ------------------ Start -----------------------
16:10:14.675 AAF2.CommandString Command = T5000#
16:10:14.675 AAF2.CommandString Clearing Buffers
16:10:14.676 AAF2.CommandString Transmitting:T5000#
16:10:14.927 AAF2.CommandString Getting Return Message
16:10:14.929 AAF2.CommandString Return Message = T5000:OK#
16:10:14.929 AAF2.CommandString ------------------ Finish ----------------------
16:10:14.929 AAF2.setPosition Received: T5000:OK#
16:10:15.243 AAF2.isMoving Sending: M#
16:10:15.243 AAF2.CommandString ------------------ Start -----------------------
16:10:15.243 AAF2.CommandString Command = M#
16:10:15.243 AAF2.CommandString Clearing Buffers
16:10:15.243 AAF2.CommandString Transmitting:M#
16:10:15.494 AAF2.CommandString Getting Return Message
16:10:15.494 AAF2.CommandString Return Message = M1:OK#
16:10:15.495 AAF2.CommandString ------------------ Finish ----------------------
16:10:15.495 AAF2.isMoving Received: M1:OK#
16:10:15.495 AAF2.isMoving Focuser is Moving
16:10:16.248 AAF2.isMoving Sending: M#
16:10:16.248 AAF2.CommandString ------------------ Start -----------------------
16:10:16.248 AAF2.CommandString Command = M#
16:10:16.248 AAF2.CommandString Clearing Buffers
16:10:16.248 AAF2.CommandString Transmitting:M#
16:10:16.500 AAF2.CommandString Getting Return Message
16:10:16.501 AAF2.CommandString Return Message = M0:OK#
16:10:16.501 AAF2.CommandString ------------------ Finish ----------------------
16:10:16.501 AAF2.isMoving Received: M0:OK#
16:10:16.501 AAF2.isMoving Focuser is Not Moving
16:10:25.416 AAF2.getTemperature Sending: C#
16:10:25.416 AAF2.CommandString ------------------ Start -----------------------
16:10:25.416 AAF2.CommandString Command = C#
16:10:25.416 AAF2.CommandString Clearing Buffers
16:10:25.417 AAF2.CommandString Transmitting:C#
16:10:25.668 AAF2.CommandString Getting Return Message
16:10:25.669 AAF2.CommandString Return Message = C2175:OK#
16:10:25.669 AAF2.CommandString ------------------ Finish ----------------------
16:10:25.669 AAF2.getTemperature Received: C2175:OK#
16:10:25.669 AAF2.getTemperature Temperature = 2175
16:10:45.508 AAF2.getTemperature Sending: C#
16:10:45.508 AAF2.CommandString ------------------ Start -----------------------
16:10:45.508 AAF2.CommandString Command = C#
16:10:45.508 AAF2.CommandString Clearing Buffers
16:10:45.508 AAF2.CommandString Transmitting:C#
16:10:45.760 AAF2.CommandString Getting Return Message
16:10:45.761 AAF2.CommandString Return Message = C2375:OK#
16:10:45.762 AAF2.CommandString ------------------ Finish ----------------------
16:10:45.762 AAF2.getTemperature Received: C2375:OK#
16:10:45.762 AAF2.getTemperature Temperature = 2375
16:10:48.343 AAF2.isMoving Sending: M#
16:10:48.343 AAF2.CommandString ------------------ Start -----------------------
16:10:48.343 AAF2.C4ommandString Command = M#
16:10:48.343 AAF2.CommandString Clearing Buffers
16:10:48.343 AAF2.CommandString Transmitting:M#
16:10:48.595 AAF2.CommandString Getting Return Message
16:10:48.595 AAF2.CommandString Return Message = M0:OK#
16:10:48.595 AAF2.CommandString ------------------ Finish ----------------------
16:10:48.595 AAF2.isMoving Received: M0:OK#
16:10:48.595 AAF2.isMoving Focuser is Not Moving
16:10:48.595 AAF2.isMoving Sending: M#
16:10:48.595 AAF2.CommandString ------------------ Start -----------------------
16:10:48.595 AAF2.CommandString Command = M#
16:10:48.595 AAF2.CommandString Clearing Buffers
16:10:48.595 AAF2.CommandString Transmitting:M#
16:10:48.848 AAF2.CommandString Getting Return Message
16:10:48.848 AAF2.CommandString Return Message = M0:OK#
16:10:48.848 AAF2.CommandString ------------------ Finish ----------------------
16:10:48.848 AAF2.isMoving Received: M0:OK#
16:10:48.848 AAF2.isMoving Focuser is Not Moving
16:10:48.848 AAF2.setPosition Sending: T5010#
16:10:48.848 AAF2.CommandString ------------------ Start -----------------------
16:10:48.848 AAF2.CommandString Command = T5010#
16:10:48.848 AAF2.CommandString Clearing Buffers
16:10:48.848 AAF2.CommandString Transmitting:T5010#
16:10:49.100 AAF2.CommandString Getting Return Message
16:10:49.101 AAF2.CommandString Return Message = T5010:OK#
16:10:49.101 AAF2.CommandString ------------------ Finish ----------------------
16:10:49.101 AAF2.setPosition Received: T5010:OK#
16:10:49.392 AAF2.isMoving Sending: M#
16:10:49.392 AAF2.CommandString ------------------ Start -----------------------
16:10:49.392 AAF2.CommandString Command = M#
16:10:49.392 AAF2.CommandString Clearing Buffers
16:10:49.392 AAF2.CommandString Transmitting:M#
16:10:49.644 AAF2.CommandString Getting Return Message
16:10:49.645 AAF2.CommandString Return Message = M0:OK#
16:10:49.645 AAF2.CommandString ------------------ Finish ----------------------
16:10:49.645 AAF2.isMoving Received: M0:OK#
16:10:49.645 AAF2.isMoving Focuser is Not Moving

And SGP:
[07/05/19 16:09:51.888][DEBUG] [Main Thread] ===== S E Q U E N C E G E N E R A T O R (v3.1.0.198) =====
[07/05/19 16:09:51.931][DEBUG] [Main Thread] OS: Microsoft Windows 10 Home

[07/05/19 16:10:01.968][DEBUG] [Main Thread] Connecting ASCOM focuser…
[07/05/19 16:10:05.287][DEBUG] [Main Thread] Focuser supports temperature
[07/05/19 16:10:05.287][DEBUG] [Main Thread] Current temperature reports: 21.75
[07/05/19 16:10:05.288][DEBUG] [Main Thread] Focuser reports Max Increment as: 10000
[07/05/19 16:10:05.289][DEBUG] [Main Thread] Focuser reports max steps as: 10000
[07/05/19 16:10:10.882][DEBUG] [Focuser Thread] SGM_FOCUSER_MOVE_REL message received…
[07/05/19 16:10:11.135][DEBUG] [Focuser Thread] Focuser moving to 4950
[07/05/19 16:10:11.640][DEBUG] [Focuser Thread] Focuser move call complete
[07/05/19 16:10:13.329][DEBUG] [Focuser Thread] SGM_FOCUSER_MOVE_REL complete…
[07/05/19 16:10:14.170][DEBUG] [Focuser Thread] SGM_FOCUSER_MOVE_REL message received…
[07/05/19 16:10:14.422][DEBUG] [Focuser Thread] Focuser moving to 5000
[07/05/19 16:10:14.929][DEBUG] [Focuser Thread] Focuser move call complete
[07/05/19 16:10:16.602][DEBUG] [Focuser Thread] SGM_FOCUSER_MOVE_REL complete…
[07/05/19 16:10:48.343][DEBUG] [Focuser Thread] SGM_FOCUSER_MOVE_REL message received…
[07/05/19 16:10:48.595][DEBUG] [Focuser Thread] Focuser moving to 4990
[07/05/19 16:10:49.101][DEBUG] [Focuser Thread] Focuser move call complete
[07/05/19 16:10:49.753][DEBUG] [Focuser Thread] SGM_FOCUSER_MOVE_REL complete…
[07/05/19 16:10:56.562][DEBUG] [Main Thread] Disconnecting ASCOM Focuser: ASCOM.AAF2.Focuser

Interesting. I would also like to hear from the developers a comment on this finding (sampling interval and smoothing algorithm).


We poll ever 20 seconds. Last 15 reads are averaged as to prevent a single erroneous temperature reading throwing focus compensation into a whirlwind.


Thanks for clarifying. Good to know everything is working as expected.

Jared, this approach may be working well for the focuser and temperature sensor that you are using, but I am not convinced that this is a good approach.

In my case (Seletek Armadillo2 focuser controller), the focuser software reads temperature data 4 times per second and the last 16 readings are averaged. When SGP does a second smoothing (reading every 20 s and averaging the last 15 readings), this will have a considerable delaying effect on both the temperature trend and the temperature compensation.

I am aware that thermal transfer processes are slow. For achieving a correct temperature compensation it would be wrong to use the ambient air temperature. In case of a refractor, we would like to measure the temperature of the objektive lens. In case of a pure reflector, we would like to measure the temperature of the tube. However, this goal can be achieved only by positioning an external temperature sensor reasonably, i.e. in close contact to the tube (for refractors: near the objective cell). The temperature sensor has also to be protected from direct contact to air in order to prevent that the reading is influenced by rapid temperature change of the ambient air in windy conditions. When these precautions are met, i.e. when the temperature sensor is positioned reasonably, there is no need for extensive smoothing of the data that delayes the measurement: smoothing is then only necessary for reducing the noise of the temperature readings. In my view, this required smoothing has to be achieved by the focuser software, and NOT by the acquisition software.

I had an email exchange about this topic with Jaime Alemany (Lunatico) who informed me about the temperature reading and averaging that the Armadillo2 focuser software performs. His statement was:
“Two smoothings is a tad overkill. I honestly think SGPro should not (theoretically!) - it should trust the data provided by each respective driver.”

I am curious about your assessment.


We added the smoothing precisely because we could NOT trust the data coming from other focusers. The Lunatico focuser may handle this better but the vast majority of focusers out there just read data from a temperature probe and pass it along. This was especially bad when using temperature compensation as a single bad read could end up pushing focus out quite a bit.

5 minutes of average time should not be enough for the temperature to drop considerably and for your tube to react to the temperature change.

I can see how this might be confusing if you’re developing your own driver (as the OP is and expecting to see those values from his driver immediately in SGP). However, if you’re just using SGP “as is” then there should be no issue.

Have you actually seen issues and have evidence that this smoothing is causing issues? Other than the initial confusion of the OP?


I am aware that my point is different from what the OP believed to see. I already gave reasons for my request that smoothing should ONLY be applied in order to reduce the noise of the temperature readings, and not in order to damp real temperature change. The smoothing performed in SGP (moving average of the last 5 minutes) delays considerably the reaction of temperature compensation to a temperature change, this period is too large.

This is not the point at all. In my previous post I gave reasons that the temperature sensor has to be positioned reasonably in order to measure the temperature of the telescope tube (for refractors: near the objective cell), protected from direct contact to air in order to prevent that the reading is influenced by rapid temperature change of the ambient air in windy conditions. If this requirement is met, we are not measuring ambient temperature, but the slowly changing temperature of the telescope. Therefore, we don’t want to delay the reaction of temperature compensation even more by applying a moving average of the last 5 minutes to the measured values: temperature compensation would always drag behind. This is especially unfavorable when the temperature sequence exhibits inflection points.

You are asking for too much: I cannot prove that temperature compensation would be improved by disabling the smoothing in SGP because this is currently not achievable. My simple conclusion: I would like to have the possibility to disable the smoothing in SGP (a switch in the focuser settings). Shall I put a feature request?


Yes, you can create a feature request. But it is unlikely that we would address it without actual evidence of it being an issue. Every feature and code change comes at some cost, so it’s difficult to pick a feature that has no known benefit associated with it when we can work on something that has known benefits.

We added the smoothing as it was needed and prefer not to add additional options to the UI if we can get around it as it just causes additional confusion about if a user should enable a feature or not.

Thank you,

1 Like

Yes, it’s a pity. With this argument you can block every feature request.

My suggestion would only require a switch that effects the skipping of some particular code.

This option would either work or not (depending on how the focuser driver handles temperature readings), and this could be commented on with a short help text - creating no confusion of the user at all.


Hi Bernd,

I agree with Jared that the averaging of the temperature over 15 cycles @ 20 seconds for each read is a very good smoothing. I have my autofocus to run once an hour or every 1 degree in temperature change, which ever comes first. I have the 1 hour setting to cover for any possible mirror flop in my SCT that may effect focus. I live in Northeast Ohio where the summers are hot and winters are cold. I have never seen an issue with these settings even under changing conditions when the sun was out during the day but the nights cool down quickly, early spring or late fall, and never experienced such a rapid temperature change in a 5 minute period that my my focus would be a concern. I have both SCT and Refractor scopes and the mass of these scope would make it difficult for them to react that quickly to such a rapid temperature change. I would not be in favor of yet another setting I need to check on when programming a sequence or setting up a new equipment profile.

Have you actually experience such a situation that within 5 minutes your temperature changed so much that your focus was affected?


Indeed, I guess that I have such data. However, it turns out to be quite time-consuming to extract the relevant data of the FITS files and present them, it takes some more time. I will report back.


I chose a capturing session with varying temperatures during the night, extracted the scope temperatures (smoothed by SGP) from the FITS files and plotted the values versus time. The appended plot (Temperature.JPG) shows time segments with steep temperature changes dT/dt, e.g. from 02:06 to 02:40. In this period, dT/dt was 0.11 K/min.

Generally the application of a moving average using a period of p causes a delay of

tau = p/2

So for the smoothing of temperature values by SGP, tau = 2.5 min

The maximum temperature deviation d between the true and the smoothed value is:

d = tau * dT/dt

Inserting the above value of dT/dt yields e.g. a maximum temperature deviation of 0.28 K. For my refractor, this temperature deviation translates into a focus deviation of 0.28 K * 53 µm/K = 15 µm.

This value has to be compared to the Critical Focus Deviation (in one direction from the best focus). According to the article of Don Goldman, Barry Megdal, “Get Focused!” Sky & Telescope Aug. 2010, the CFD is:

CFD = 0.8 * F^2 * lambda

For my refractor (F = 5) and blue light (450 nm), this formula yields a CFD of 9 µm.

The implication of this finding is clear: the period used for smoothing by SGP (5 min) is too large. When dT/dt exceeds certain limits, the result of the temperature compensation will be wrong.

Unfortunately it is not possible for me to separate the influence of focus and variable seeing conditions on the FWHM of the stars in the subframes for lack of having measured the seeing conditions concurrently. So I cannot present here a quantitative treatment with comparison to the FWHM values of the subframes.

I want to stress again: the application of smoothing of temperature readings is necessary in order to remove noise. Preferably this necessary smoothing is performed by the focuser driver (as in the case of the Seletek focuser controller: moving average of 16 readings every 0.25 s). However, this smoothing must not be done over a too large period because that will lead to temperature deviation and subsequently wrong focuser temperature compensation.


Something you don’t seem to be considering is the differing thermal inertia of different parts of your scope. For example the lens and the telescope tube will respond to temperature changes at different rates. Both of these will change the focus but will respond to temperature changes at different rates.

One way to get quantitative data would be to use an artificial star. This should eliminate, or at least reduce the effects of seeing on focus. Ths will allow you to collect data on focus position as a function of temperature and the rate of temperature change.

Also what caused the sudden step change in temperature? 2K in about 30 minutes with relatively small temperature changes on either side seems strange, could there be something other than the environment changing the temperature?

I’m also not sure about your estimate of 0.11K/min. Your graph seems to show a 2K change in 30 to 40 minutes which is 0.066 to 0.05 K/min, about half what you suggest.

I think the philosophy behind the 5 min smoothing is to be (too?) conservative and avoid incessant focuser motion. Maybe changing this to a 2 min average with more frequent poling (10 s) could mitigate the issue.

Alternatively, can your focuser take care of the temperature compensation on its own?

Hi Bernd,

Was there an attachment, What I’m looking at is very small to be able to read accurately but it appears the biggest change in temperature looks to occur between approximately 1:45 and 2:35. During that time the temperature dropped from approximately 18 to 14.75 giving a delta of 3.25 degrees per hour. during that time SGP smoothing would had updated the temperature 12 times during that one hour time period. So if I divide the 3.25 degrees by 12 would give me a 0.27 temperature change on average every 5 minutes. So if you set your tolerance to something less then 0.27 degrees your focuser would run every 5 minutes. Are you saying your scope comes out of focus even with a 0.27 degrees of temperature change?

Maybe I’m miss reading the graph or misunderstand the issue.


My scope is a refractor (Takahashi FSQ106, non-ED). Yes, I am aware of that there are two effects: 1) the contraction of the aluminum tube with decreasing temperature, and 2) the refractive index of the glass utilized for the objective. However, effect 1) is irrelevant here: it is strongly overcompensated by effect 2). The resulting temperature coefficient is negative, i.e. when temperature decreases, the focus has to be corrected INWARDS (see ).

I have enough data from capturing sessions not suffering from large temperature changes. The effect of temperature on best focus position for my scope is as I indicated above: 53 µm/K.

The change in temperature in that very night was caused by special meteorological conditions. The rapid temperature changes occurred only in certain time segments.

The temperature curve in that specific period (02:06 to 02:40) is S-shaped. I evaluated its maximum slope by placing a tangent to the curve. The result was 0.11 K/min.


Your suggestions are constructive, I thank you for that.

Yes, I think even a reduction of the averaging period from 5 to 2 minutes (with more frequent polling) would actually eliminate any issue.

Yes, my focuser controller has a temperature compensation of its own. Unfortunately, its focuser backlash compensation doesn’t work like SGP’s one (which I really like!). I did not get along with it. It was not possible to combine SGP’s backlash compensation with Seletek’s temperature compensation - it’s a pity.



It is how it is with this scope: the temperature coefficient is 53 µm/K, and the CFD (according to Goldman & Megdal) is 9 µm. My calculation is as follows, the result even more painful: if there was no focusing temperature compensation and I started with optimal focus, I would have to refocus every (9 µm / 53 µm/K = 0.17 K).

That’s the reason why I (have to) use temperature compensation.

I want to clarify though that SGP’s focuser temperature compensation is working well for me when the temperature changes are more slowly. The too large period of averaging the temperature data will do damage only when rapid temperature changes occur. However, this is something that I cannot control.


5 minutes probably is too conservative. I have no issue reducing this. Really we only need a handful of reads for this to properly smooth.

Unfortunately most focusers don’t have any type of internal smoothing in them. So this is something we still need to handle in SGP. But I would think a 1 minute moving window would be more than adequate for this. I’ll make that change.

Have you tried this recently? We made some changes around how/when we toggle Temperature Compensation a while back that should better work with backlash enabled in SGP.

Thanks for the thoroughness and providing some backing data,


Thanks for the feedback completely makes sense. However, given your scope sensitivity, if you can’t get the temperature compensation to correctly run and Jared changes the smoothing you’re going to be spending all of your time doing nothing but focusing runs. will not be much time between focusing for much imaging.