Jump to content


Arduino Sky Quality Meter - working!

Recommended Posts

The above post was delayed by over an hour due to a power cut here :(  My offer still applies I guess we should arrange by PM.  Drat the power's gone off again :(  Guess this will go when it comes back on...

Edited by Gina
Link to post
Share on other sites
  • Replies 119
  • Created
  • Last Reply

Top Posters In This Topic

Top Posters In This Topic

Popular Posts

So, finally my DIY arduino SQM is finalized, it is not calibrated yet, but hang in there, i will do so in the near future... But first i want to point out that i didn't want any scientific grade SQM b

I recently had a chance to use the Unihedron SQM and SQM-L meters and decided I wanted to build my own. A search led me to this thread, thanks for all this great info! In researching this project I di

Here’s a few preliminary sketches of my DIY SQM that I’m building. Just need my 3D Printer to show up now. I may have to revise the ‘turret’ area where the lens is to make it a bit more printer f

Posted Images

I've the code for the last SQM I made (fitted with a GPS receiver and sits on the top of my car). It's written for a PIC, but might be useful for someone writing for Arduino.
I'm sure it could be optimised, but it seems to work fine.

#define TSL237 PIN_B0;int16 timermsb=0;int16 timermsbbuf=0;int16 timerlsbbuf=0;int16 i;int8 send=0;int8 bytes[5];int8 mult;#INT_TIMER0void  TIMER0_isr(void){  //set_timer0(0);  timermsb++;}#INT_RDA HIGHvoid  RDA_isr(void){	int8 in;	in=getc(PORT1);	if(in=='S'){		if(send==1){ //ok to send			fputc(bytes[0], PORT1);			fputc(bytes[1], PORT1);			fputc(bytes[2], PORT1);			fputc(bytes[3], PORT1);			fputc(bytes[4], PORT1);		}else{ //not ok, buffer still writing			fputc(255, PORT1);			fputc(255, PORT1);			fputc(255, PORT1);			fputc(255, PORT1);			fputc(255, PORT1);		}	}}void main(){      	setup_timer_0(RTCC_INTERNAL|RTCC_DIV_2);//333ns resolution, 21.8 ms overflow	enable_interrupts(INT_TIMER0);	enable_interrupts(INT_RDA);	enable_interrupts(GLOBAL);	while(1){					restart_wdt();		enable_interrupts(INT_TIMER0);		while(input(TSL237)); //wait for falling edge        		while(!input(TSL237));//wait for rising edge		set_timer0(0);		timermsb=0;		while(input(TSL237));		while(!input(TSL237));		timermsbbuf=timermsb;		timerlsbbuf=get_timer0();		mult=1;				if(timermsbbuf==0){ //short period, repeat a few times (improves resolution in brighter conditions)			while(input(TSL237));			while(!input(TSL237));			set_timer0(0);			timermsbbuf=0;			for(i=0; i<100; i++){				while(input(TSL237));				while(!input(TSL237));				mult++;				if(timermsb>50){break;}			}			timermsbbuf=timermsb;			timerlsbbuf=get_timer0();           		}		disable_interrupts(INT_TIMER0);		send=0;		bytes[0]=mult;		bytes[1]=(timermsbbuf>>8) & 0xFF;		bytes[2]=timermsbbuf & 0xFF;		bytes[3]=(timerlsbbuf>>8) & 0xFF;		bytes[4]=timerlsbbuf & 0xFF;		send=1;	}}
Link to post
Share on other sites

ok so we have the arduino, the sensor, the uv/ir cut glass, just need a box cables, cap and lens.   would this work for a lens?

was thinking for a box this : http://www.ebay.co.uk/itm/Arduino-Enclosure-Case-Box-UNO-MEGA-R3-Ethernet-Shield-many-colours-/181418044847?pt=UK_BOI_Electrical_Components_Supplies_ET&var=&hash=item2a3d5badaf

as i want to eventually put an ethernet sheild to output to an online weatherstation eventually.

Link to post
Share on other sites

Hello guys

so im going to be buying the sensor on friday (2 days from now) if any one would like to go in shares send me a pm with how many. 

http://uk.mouser.com/ProductDetail/ams/TSL237S-LF/?qs=sGAEpiMZZMuhmhJ32%2fprP004vccwnQtD is the sensor. please make sure you check that it is the correct one as i cant be held if its not. 

also just going to the previous post would http://www.ebay.co.uk/itm/16mm-CCTV-Board-Lens-for-CCTV-Cameras-Security-Cameras-/121342651755?pt=UK_CCTV&hash=item1c4095ed6b work as a lens?  (i forgot to post it above)

Link to post
Share on other sites

I have some lenses if anyones interested, I had to buy a bag of 20. Happy to give a few away

Hi OneEyedsam,

I've seen your offer but I'm in Portugal. Is there any chance to obtain one from you by mail?

I'm thinking in build the SQM with arduino.

Thank you

Jose Fernandes

Link to post
Share on other sites

Happy to post a couple if you pay postage, but to be honest, it's probably easier and cheaper to buy locally

Thank you very much for your reply, i'll try to obtain them locally.


Link to post
Share on other sites
  • 2 weeks later...
  • 2 months later...

Is it possible for the arduino code to be posted? The code I found seems to be very much early and not sure if there have been changes due to the recent discussions? Or is the code posted somewhere else?

Many thanks


Link to post
Share on other sites
  • 5 months later...

Couldn't resist joining in this noble venture! Still at the uber-prototype stage

but a few observations and measurements... which might help someone? :)

To make the postage (vaguely) worthwhile, I bought three TSL237s from:


Since they were in stock, I bought the surface mounted variety. Same spec.

- The pins slightly shorter and spaced slightly less than 0.1", but whatever! :p

So, ONE of the above was duly soldered to a small square of Veroboard...

I decide to give Arduino lib routine: "FreqCount" a whirl (see Per above etc.) 

Doiwnloaded from: https://www.pjrc.com/teensy/td_libs_FreqCount.html

The basic functionality demonstrated by:

#include <FreqCount.h>#include <Math.h>void setup() {  Serial.begin(9600);  FreqCount.begin(1000); // Sampling period (ms)}void loop() {  if(FreqCount.available()) {    unsigned long count = FreqCount.read();    Serial.println(count); // Number of Counts!  }}

Just connect output of TL237 to Pin 5 of the Arduino and it WORKED!  :cool:

(With short leads, it didn't even have a 0.1 micro farad decoupling cap) 

I initialised the sampling period at 1000 (ms) for a start. First observations.

1. With 16MHz Arduino UNO R3 it gave a count around 60,000 on my desk

    (Ergo a frequency of 60kHz!) 

2. If I shone a BRIGHT LED light on the sensor it maxed out at 540kHz.

    (With this setup, count rate saturates, but the code doesn't bomb!) :)

3. The minimum frequency is "pretty low" (less than 1Hz)  

    so clearly a practical App needed a little more thought...

To simulate dark skies, I covered the sensor with a small lens cap and

covered the whole Arduino setup with a black plastic microwave tray! :p

To try to get a bit more accuracy at low count rate, I increased the

value of the FreqCount.begin(ms) parameter. It seemed to get "good"

(same) results for 10000 (10 sec) etc. but went "weird" above 60 sec?

I found value of 30000 (30 sec) worked and about the most useful?  ;)

A reasonably consistent value (Freq ~10Hz) at typical sky brightness.

NSec: 30 Count:292 Freq: 9.73 Msqm 19.53 Nelm: 5.17 

(Hopefully this will be about right for my approximately Mag +5 skies!)

NO PRIZES for code! I just arbitrarily used constant A = 22.0 above.

So, in the spirit of sometime Fortran Programmers of my vintage:  :D

/************************************** Sqm - Prototype Sky Quality Meter! **************************************/#include <FreqCount.h>#include <Math.h>float Msqm;float Nelm;float freq;const int nsec = 30;const float A = 22.0; void setup() {  Serial.begin(9600);  FreqCount.begin(nsec * 1000);}void loop() {  if(FreqCount.available()) {    unsigned long count = FreqCount.read();    freq = float(count) / float(nsec);    Msqm = A - 2.5 * log10 (freq);    Nelm = 7.93 - 5.0*log10((pow(10,(4.316 - (Msqm / 5.0))) + 1));    Serial.print("N Sec: ");    Serial.print(nsec);        Serial.print(" Count: ");    Serial.print(count);    Serial.print(" Freq: ");    Serial.print(freq);      Serial.print (" Msqm: ");    Serial.print(Msqm);    Serial.print (" Nelm: ");    Serial.println(Nelm);  }}

Aside: I hope to improve on the "Hardware" too! I intend to try a miniature 

M12 CCTV camera lens of about f=3.5mm. Should give about 20 deg field

across the 1mm sensor? Might usefully increase count rates? Who knows!

Some useful bits and bobs available at: http://www.stockoptics.com/

Have Fun.  :)

Edited by Macavity
  • Like 1
Link to post
Share on other sites

This is certainly something on my future project list but still a good way off.  I shall want it when I've completed my ROR automation.   Everything seems to take such a long time these days! :eek:  I already have the sensor (somwewhere :D)

Edited by Gina
  • Like 1
Link to post
Share on other sites

This is certainly something on my future project list but still a good way off.  I shall want it when I've completed my ROR automation.   Everything seems to take such a long time these days! :eek:  I already have the sensor (somwewhere :D)

Well, there are other things I could do (spend on) ... replacing... upgrading. :o

But something NEW (relatively simple!) Impetus... "Desiderata" and all that? :D

Edited by Macavity
Link to post
Share on other sites

I've made some progress now, the light sensing part seems to work pretty well. I've got a serial interface so I can send it commands, at the moment limited to sending a calibration adjustments (going to calibrate with a friends unihedron SQM)

I also have mobile phone module and thinking of having it send me text messages when the sq reaches a certain threshold. I have it sending me fixed texts at the moment, I just need to integrate the two projects/code bases. Will probably get it to take text message commands , eg for setting the threshold value.

All prototyped on a breadboard at the moment. I'm a software developer not a sparky, so it's been a fun learning experience, well it's been cloudy recently !!

Edited by OneEyedSam
Link to post
Share on other sites
  • 8 months later...


just finished my SQM (in fact - have new name SLM = Sky Luminance Meter - to not mess with original SQM from Unihedron :) )

- 16mm lens + UV/IR-cut filter

- LCD with backlight and contrast regulation

- USB - for program and data transfer to PC (working with APT as original)

- Real Time Clock with batery backup (CR3025) and EEPROM for storage.

- temperature and humidity.

Powered by 9V or UPS when connected.

Calibrated to original SQM.

Software is beta version - will be upgraded soon (more features planned)

On pictures - few units with engraved logo of Polish Astro Forum for members . More available.... (PM or e-mail me)







  • Like 1
Link to post
Share on other sites
  • 4 months later...

Just shows how long it takes me to finish some projects? :D

Herewith, the now boxed version of my SQM:
(Stuck to backing board for observatory use!)


Will resist "teaching grannies / grandads / etc. " - But for anyone interested:
I soldered the TL237 sensor to a square of veroboard and placed it inside a
small "lightproof" Maplin box (Above the Arduino R3). I drilled a hole in the
side (to allow light the in!) and added an M12 lens holder (for future use?).

With the sensor CAPPED, I get down to a count rate of less than 0.1Hz ... :)
Local skies (Surface Brightness +18 to +19?) give count rates ~20-60 Hz.
The rest is, as they say, all down to (your) software (I'll spare MY blushes)!

I decided to use an LED display. For under a Tenner, these are rather nice:
https://proto-pic.co.uk/7-segment-serial-display-red/  :cool:
(Integrated proc, Libraries for Serial, I2C, SPI etc.)

The switch on the left changes the display between Mag/sq.arc.sec and
Limiting Vis. Mag. I analog-read the "pot" (at right) for display dimming.

I think will make a second sensor box and fit an "external" socket. I am
rather interested in the variation of sky brightness across my sky. I may
even record this in the region where the telescope is actually imaging...

An interesting article in Feb 2016 "Astronomy Now" by John Rowland.
He concludes (like me) "Msqm" varies quite a lot, once you depart from
the zenith. And raises the interesting question... What figure to use. :p

Edited by Macavity
  • Like 1
Link to post
Share on other sites

Looking good Chris :)

Takes me a very long time to finish projects too - if I ever do and that's rather rare :D

Edited by Gina
  • Like 1
Link to post
Share on other sites
17 hours ago, Gina said:

Takes me a very long time to finish projects too - if I ever do and that's rather rare :D

Ain't that the truth! :D

If everyone is not completely bored yet, I do have a couple of "hot tips" 
based on what I have found out (and not without some minor effort!) ;)

There are two commonly used Arduino Libraries to measure frequency:

Freqcount: https://www.pjrc.com/teensy/td_libs_FreqCount.html

Freqmeasure: https://www.pjrc.com/teensy/td_libs_FreqMeasure.html#compare

Despite the above, I find that I can use *Freqcount* to measure the
signal from the sensor over a WIDE(!) range. In this application, the 
accuracy is mostly limited by the sample time argument (in millisec) 
to Freqcount_begin being an Arduino unsigned integer...  

#include <FreqCount.h>

void setup() {

void loop() {
  if (FreqCount.available()) {
    unsigned long count = FreqCount.read();

Thus you can happily measure the count up for upto 60s 
(or 65.535s to be exact?) before things go rather awry. :p
And this confirmed by Experiment!

THE GOOD thing about FreqCount is that it can work to
*high*  frequencies too. The counter will work in daylight!
Of course it then delivers negative magnitudes too. Thus
proving that Venus might be seen during daylight etc.  ;)

The essence of MY program - to deliver mag per sq.sec.
and limiting magnitude is contained (explicitly) within:

    if(FreqCount.available()) {
      unsigned long count = FreqCount.read();
      freq = float(count) / float(nsec);
      Msqm = A - 2.5 * log10 (freq);
      Nelm = 7.93 - 5.0*log10((pow(10,(4.316 - (Msqm / 5.0))) + 1));

Of course "A" (22.0) is the constant you will have to define? ;)

The other thing I had to revisit was  the thorny question of
converting floating point to integer! (for the display)...

Opinion is divided on WHICH routines work on the Arduino.
But I can personally vouch for *sprintf* in the following:

char tempString[10]; // Large enough for digits


if (modeVal == 0) // Swithc to Msqm or Nelm?
	sprintf(tempString, "%4d", int(Msqm*100.0));
    sprintf(tempString, "%4d", int(Nelm*100.0));
s7s.print(tempString); // Serial Write etc.

Anyway enough... enough... I might preserve some of this for
posterity? My website is mostly "Lorem Ipses" at the moment"!

IF only life were based on having great plans... :D

Edited by Macavity
  • Like 1
Link to post
Share on other sites
  • 1 month later...

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    No registered users viewing this page.

  • Similar Content

    • By HN50
      My attempts at SID monitoring have been languishing for a while due to radio problems, though I have been getting to grips with Arduino and even had a go at building my own.
      In order to move things along I went to the UKRAA stand at Astrofest and bought the VLF radio kit, their signal generator and the 15V power supply.
      Last weekend I soldered the board.  It wasn’t too difficult following their instructions which are pretty clear.  The only fiddly bit was soldering on an SMD capacitor but they also give you a through-hole one as well.  Initial tests suggest it is working but I will have a better idea when it is all connected.

      This weekend I have been working on the housing and hopefully tomorrow get the leads soldered.  From left to right will be led power, 15V in, 15V out, antenna in, then analogue -ve and +ve (can be 5V or 2.5V).  

      I am building it as-is, so the first iteration will have the radio running off mains power and in turn the radio will power the Arduino.  That seems a bit backwards but I would just like to get logging data.  For the time being it will write to an SD card, but the Arduino MKR 1010 looks rather good and comes with WiFi and encryption.
      That though, is a long way off..!  Anyway, this shows progress so far.
    • By wimvb
      Just finished work on a sky quality meter with built in wifi. The device is based on the ambient light sensor TSL2591 and the wifi board ESP32. Communication between the two boards is through I2C. The device has a 40 degrees lens.
      The light sensor is programmable, which means you can set integration time (from 100 to 600 ms) and gain (from 1 to almost 5000, in 4 steps). I implemented automatic adjustment of these parameters to allow for the highest dynamic range (600M:1 accoring to the spec sheet).
      The device shows Sky readings as a web page. It is connected to a local wifi network, although it could also create its own access point. So far I haven't been able to calibrate the sqm yet, partly due to eternal cloud cover. But it should only require one parameter to be adjusted.
      The code is available on GitHub. Sky-Quality-Meter
      Here are som pictures.
      The components:

      The parts connected:

      The finished device:

      This is how output is presented:

    • By Captain Magenta
      Last year I was given a Unihedron SQM-L, the narrow field of view version of their gadget for measuring night-sky brightness. Since then, I’ve nipped outside to take zenith readings whenever I’ve been able, often a few times per night. As a result I now have 85 data-points, all from my back garden in Sunbury on Thames which rates a 19.04 on www.lightpollutionmap.info . As it turns out, this agrees well with the data I’ve collected.
      The darkest I’ve measured at this location has been 19.13, with 4 records better than 19.05 and 10 better than 19.00.
      Plotted against Moon altitude, it looks like:

      One thing I noticed very early on was that the reading generally gets darker and darker as the night goes on. The chart below suggests the data agrees, but how strongly I’m not adept enough yet with my statistics to work out. If anyone fancies doing this for me, I’d be grateful, I’ve attached the data .csv file I think to the end of this post.

      The data itself: each record contains date, time[GMT], SQM value, Moon phase, Moon altitude . For the purposes of my analysis, I’ve converted the time value into hoursafter6pm, which allows the intercept of the regression solution to be loosely considered as the “6pm starting point” for the darkness estimation, which is OK for this dataset as my data is all from this latest Autumn/Winter.
      I’ve done an “ordinary least-squares” regression with multiple input variables. At first glance it seems to me that the SQ vs altitude chart above should not behave well with that: there’s a clear kink, intuitively obvious I guess, at the point the Moon altitude goes negative.
      To cope with that, I divided my data into two and did three separate regressions: “Moon up” data, “Moon down”, and “All data” but treating phase and altitude as zero if the Moon is below -5 degrees (I chose -5 degrees arbitrarily).
      With Moon up, I decided the SQM value will depend on Time of Night, Moon Altitude and Phase. With Moon down, it only needs to depend on time of night.
      Thus my regression model is:
      SkyQual = a + b.timeafter6pm + c.phase + d.altitude + residual
      or rearranged
      residual = a + b.timeafter6pm + c.phase + d.altitude – SkyQual
      The analysis involves minimizing the sum of (the squares of the) residuals, by hunting around for the appropriate values of a, b, c & d which yields this minimum. I used MS Excel’s built-in Solver to do the “hunting around”.
      The following table summarizes the results:

      In words, using “Moon Up” as my subject, my Sky Quality, in magnitudes per arc-second, can be estimated as
      19.28 mags/arc-sec
      plus 0.0314 /hour
      minus 0.864 /full-phase (or 0.216 /quarter)
      minus 0.0186 /degree above horizon (or 0.186 /10 degrees).
      This is a pretty simple analysis. I’m sure there’s theory and formulae available relating Moon-altitude and -phase to extra sky brightness, but I haven’t used any of that here. And the “error model” I’ve used implicitly assumes that the relationships between SQM-reading and the variables are linear.
      If anyone is curious and wishes to do their own analysis, my raw-ish data is available as a .csv file attachment at the end of this post.
      A note about the data collection: each reading is an average of a few readings at a given time, with outliers rejected. For instance, often the first press yields an outlier, and over the following few seconds subsequent ones tend to settle down. So the series of readings 19.05 (me getting excited), 18.85, 18.86, 18.86 , which is a quite typical pattern, would cause me to record 18.86. My highest recorded reading, 19.13, was indeed where it settled down.
      Other “one-on-one” charts:
    • By lenscap
      My diy Onstep GoTo controller is basically an Arduino Mega 2560 with a RAMPS 1.5 shield, rated for 12V normal, 20V max & uses about 2A max.
      It is powered from a 12V car  battery. The lead has crocodile clips at the battery & connects to 5A screw terminals on the RAMPS.
      When I "power-up" by connecting the clips there is a spark at the terminal. This is expected, but does the sparking reduce the life of my electronics?
      If so is there a cheap/simple way to reduce or prevent this?
      I know I could put a switch in the lead but I assume the sparking would then happen inside the switch, making no difference.
    • By angryowl
      This will be a thread detailing some of the changes and additions I will be doing to my ASC/Weather Station project. This is version 2.0 as I'll be making some very big changes from the initial project and I think continuing on in the existing thread would not have made much sense.
      So, I still want to use an APS size sensor as after seeing the quality and light capturing capabilities of the now defunct Opticstar DS-616C XL camera and Meike lens I simply cannot go back to using a smaller lens/sensor combination. One thing is certain, I won't be paying £400 or potentially more for another APS astro sized camera so with that in mind I plan on heavily modifying a Nikon D50 DLSR and use the same lens. I chose the D50 primarily due to it having a CCD sensor (ICX453AQ) very close in specs to the one in the Opticstar (ICX413AQ) and the fact that I got a hold of a fully working body for £25.
      Now there's a few issues with going down the DSLR route which I plan on addressing as follows:
      The oversized camera body can be stripped down to bare essentials and fitted in the existing case with some moving of parts around Uncooled, the sensor is quite noisy so to cool it I plan on using the existing Opticstar enclosure with the TEC and hopefully get it purged with Argon to avoid dew formation. Also, since the box will need to be completely sealed to achieve this, there's simply not enough room inside for the main board to which the sensor connects to. The only way around this is using an 39pin 150mm long FPC extension which I managed to find and will be arriving shortly. This means I can have the sensor completely sealed with enough slack in the connection to place the mainboard anywhere I want. The D50 uses the NEF file extension as a "RAW" file format but it's not truly RAW and a heavy median filter is applied to all long exposure images to smooth out the noise. It works great for day to day shots, but in an application such as mine it'll most probably eliminate or severely affect my stars as most of them at the FL I'll be using the camera at will be a few pixels across and the Nikon median filter is very aggressive with such small features. The way around this is what's commonly known as Mode 3 on Nikons. Nikons have a additional Noise Reduction mode which takes the long exposure light first then straight after an equal length dark with the shutter closed, then applies the dark on the light and you get a further noise reduced image which again works very well, but not so much for AP. With mode 3 you essentially have the NR feature on and take an exposure but then immediately shut down the camera after the light has finished exposing. What this does is it causes the camera to dump a REAL RAW image onto the SD card without applying the median filter OR the Noise Reduction process. This obviously results in a much noisier image as expected, but all the stars will still be there and the image in this way can then be dark-subtracted and processed to my liking. I'll post some test shots I've taken to illustrate this. The D50 uses a hybrid shutter, both the CCD electronic shutter and mechanical shutter are used depending I think on the exposure length. If a high enough exposure is used, from what I understand, one can use exclusively the electronic shutter, but for longer exposures the shutters work in conjunction. Now I know the ICX413AQ in the Opticstar is more than capable of taking long exposures solely with its electronic shutter despite the fact that in its datasheet they recommend a mechanical shutter for proper use. So, my thinking is since the D50's sensor is similar to the ICX413AQ the only thing preventing the camera from being able to take any exposure using exclusively the electronic shutter is that its mechanical shutter is in the way and I don't think that the camera would prevent the CCD electronic global shutter itself to still open and close when required. However, this is all a theory at the moment and the only way to confirm it is to test the camera with the sensor outside when the FPC cable arrives. More on this later... In terms of capture software available, the D50 is actually very poor and I could only get digiCamControl to see and control the camera via USB. But I won't be using this as when the camera is hooked up to the PC its SD card is identified as a storage drive and the camera can be used as it would normally with the images appearing on the drive after being written to the SD! Since I'm using my VB app to process the images I would just point the app to that folder and should work. That's all I can think of for now but if and when new ones come up I'll add them here.
      Next I'll be describing some of the other changes planned.
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue. By using this site, you agree to our Terms of Use.