Elephant Memory

4 Channel Data Logger

Johann Wyss

Issue 31, February 2020

This article includes additional downloadable resources.
Please log in to access.

Log in

This Arduino-based four channel data logger can be customised to your sensor needs and log data to an SD card, which you can analyse later.


The analogue read function of the Arduino development language is quite possibly one of the most powerful functions in the Arduino lineup. It allows us to easily access the Atmel microcontroller’s analogue to digital converter (ADC) and read values from analogue sensors that are used to take readings of the physical world. These sensors are incredibly diverse, ranging from sensing light and sound levels all the way to temperature and even detecting the presence of dangerous gases.

As such, we find ourselves quite regularly creating the same basic devices to read these sensors. We would usually record the readings at regular intervals, such as when we are monitoring the temperature of a device’s heatsink, as we did in the Dummy Load project from Issue 022. Therefore, we decided that we should create a standalone piece of benchtop test equipment that we can use for this task rather than rebuild it each time.

Furthermore, we wanted to automate the process to avoid the need to physically take each reading. This frees us up for more important maker tasks.


We have designed our data logger to have four channels, which enables us to read and record up to four different sensor values simultaneously. Data is saved to an SD card, which the user can analyse on their computer.

Keeping our maker audience in mind, we have designed the project to be as user customisable as possible. Suitably skilled users can build the logger specifically tailored to their needs. To do this, we have designed a PCB that has the ability to suit different components. The user can add or substitute the power supply components to suit their needs.


This project uses the 10-bit ADC built into the ATmega328P microcontroller used in the Arduino Uno microcontroller development board. For the vast majority of sensors, the 10-bit resolution which provides an output range between 0 and 1023 or about 5mV per increment, is more than adequate. This means the project is relatively straightforward in design. Essentially, all we need to do for this project is to read the voltages on four analogue pins and record the result to an SD card. From there, the user can import the raw CSV data into their spreadsheet program of choice and perform the mathematical processes needed to create graphs, etc. Doing the math in the spreadsheet program allows us to make the device useable for the maximum number of sensors as possible, without the user needing to upload new programs to the microcontroller.


To better understand how this device works, it’s necessary to understand how the analogue read process works. In essence, when we call the AnalogRead() function in the Arduino programming language, we initiate the microcontrollers analogue to digital converter. This uses a hardware conversion technique called successive approximation to measure the voltage on the specified analogue pin.

This conversion process takes quite a bit of time to produce a result. The input voltage first goes through a sample and hold process, which holds the input voltage at the sampled state long enough for the conversion process to be performed. This is about (260μS) on the ATmega328P. This voltage then enters a comparator circuit, which compares the sample against a reference voltage produced by the Successive Approximation Register (SAR) and Digital to Analogue converter (DAC). The result of this comparison is fed into the SAR control logic.

The SAR outputs a binary code to the DAC, which sets the output voltage of the DAC to a specified voltage depending on the bit currently being approximated and the previously measured bit. The comparator is used to indicate if the current measured bit is higher or lower than the reference voltage currently being produced by the SAR and DAC. This process is repeated ten times, producing the 10-bit resolution.

NOTE: This is, of course, a very simplified explanation. The actual process requires very precise timing for the SAR, a precision input reference voltage (Vref) and other complex supporting circuitry.

After this conversion process, the microcontroller returns a value between 0 and 1023 which represents a voltage between 0V and 5V, with each increment being about 4.88mV. Normally, we would convert this value inside the program to a voltage representation using the following in program math:

voltage = (analogRead(A0) * (5.0 / 1023.0)); 

This reads the voltage on analogue pin A0 and multiplies the result by 5 volts divided by the total maximum number 1023 or simply the 4.88mV (5v / 1023 = 4.88 mV).

We would normally then take this reading and perform any number of mathematical operations required by the specific sensor to calculate the measured result. For example, in the case of the LM335 linear temperature sensor, the output voltage is equal to 1° Kelvin for every 10mV output from the sensor.

Therefore, to get the result in the desired unit, we first convert the voltage to °K using the code:

Kelvin = (voltage / 10);

Then convert the temperature from Kelvin to °C with the code:

Celsius = (kelvin – 273.15); 

If you want the result in °F, you use the code:

Farenheit = ((Celsius * 1.8) + 32); 

You would normally find the math needed for this conversion in the datasheet for the sensor you’re using. Note that we are intentionally using a simple linear sensor for this explanation. Many sensors do not produce a linear response and can require significantly more complex math. These sensors can still be used with this device. Presumably even very complex industrial sensors, like the PT100 range of temperature sensors that require Wheatstone bridges etc., can still be used with this device. Albeit, they will require the use of two channels when used with the bridge configuration.

The Prototype:

Parts Required:JaycarAltronicsCore Electronics
1 x Arduino Nano or Compatible BoardXC4414Z6372CE05101
1 x RTC ModuleXC4450--
1 x SD card ModuleXC4386Z6353CE05113
1 x 1602 LCDQP5521Z7000ADFR0063
1 x I²C LCD BackpackXC3706-018-LCD1602-I2C
3 x Tactile SwitchesSP0608S1125ADA1010
1 x SD Memory CardXC4989D0328CE04628
4 x LDRsRD3485Z1621SEN-09088
4 x 10KΩ Resistors*RR0596R7058PRT-14491

Parts Required:

* Quantity required, may only be sold in packs.

† Sold as a mixed pack

For the prototype, we followed our usual method of designing and testing the basic circuit on a breadboard using the Arduino Nano microcontroller development board as the microcontroller. This allows us to easily program the device and test the design, making changes to the hardware and software as needed.


We settled for a 1602 LCD with the I²C adaptor to reduce the number of pins required to control the LCD. This did mean, however, that we had to assign the I²C address for the LCD, as both the RTC and LCD are using the I²C protocol, and it’s possible to have an address conflict. The easiest way we found to do this is to use the I2C scanner program that you can find here:

With the hardware connected, you simply need to run this sketch and view the serial monitor, which will identify which address the connected I²C devices are operating on.

You then use the line to set the address for the LCD:

LiquidCrystal_I2C lcd = LiquidCrystal I2C(0x27, 20, 4);

Note, in our case, the address was 0x27, therefore just replace this hex value with the value for your LCD.

The RTC address for us did not need to be changed, as it seems they are designed to all run on the same 0x68 address.

For the prototype, we opted to test by using four Light Dependent Resistors (LDRs). These very basic and inexpensive sensors adjust their output linearly with respect to the light entering them. By creating a voltage divider with a 10KΩ resistor, we get an analogue voltage that varies with the amount of light on the sensor. This is a very simple and effective way to ensure that the device was functioning correctly.

The Realtime Clock was the standard DS1307 based I²C RTC module that you can find at most electronics stores. This module, whilst not incredibly precise (losing a few seconds every day), is more than sufficient for such a basic measuring task. Its low cost and fantastic library and support makes it ideal for this project. If you’re wanting something more precise, consider a variant based on the DS3231 IC, as they are many times more accurate albeit also many times more expensive.

Ideally, we wanted to use an SD card reader that used the I²C protocol so that we could downgrade the microcontroller to a smaller and more inexpensive option, like the ATtiny84. However, it seems the only options available use the SPI protocol. This is likely due to the speed benefits afforded by SPI over I²C. Since an I²C option wasn’t available, we went with the common MH-SD SD card module. This is an affordable and easily obtainable module with fantastic library support, so it works with little trouble.


The code for this project has been made incredibly easy thanks to the Arduino platform and the community creating and sharing the awesome libraries available today. We created the code by analysing and modifying the provided example code for each of the component libraries.

To get started with this project, you need to make sure that you have the correct libraries installed on your computer. The wire.h, SD.h and SPI.h libraries are now standard in the Arduino IDE so you can ignore them. Therefore, you need to download and install the following libraries.


You can download this library here:

We were a huge fan of this library. It allowed us to write our code using the same structure and syntax as the standard Liquid Crystal library, whilst providing the benefits of an I²C interface. If your project involving the standard LiquidCrystal.h library is running low on I/O pins, we thoroughly recommend you take a look at the I²C LCD expansion module and this library. It allows you to go from needing seven I/O pins to only two, albeit at a slower refresh rate, which is perfectly fine for displays, like the 1602, that is usually only used to display alphanumeric characters.


You can download the RTC library here:

This library was originally written by Jeelabs, which has been modified by Adafruit Industries. We picked this particular library as it implements a very clever and unique way of setting the time. Traditionally, to use a real time clock you would first need to use a program to set the current time, which is then stored in the onboard memory of the RTC IC and then upload your code. Jeelabs created a way around this by using the computer time when uploading the sketch to set the current time. This makes this library so much quicker and easier to use and you completely remove a step.

NOTE: This module is incredibly inexpensive and simple to use but it isn’t very accurate. On average, it loses a few seconds a day. We wouldn’t advise you use this sensor for time critical applications but for general hobby level projects, it’s low cost makes it ideal.

The code for this project is fairly long and as such we will refrain from printing it in the magazine. You can find the entire code on our website. We will, however, attempt to explain a few sections of the code that may help you understand how it functions and perhaps helps you modify and adapt the code for your own projects.

In the main loop, we use while loops to create a very basic menu structure. The user can change the sample selection from seconds to minutes, and then set the number of each unit, which allows the user to set the sample interval. It would be trivial to extend this menu system to include a duration setting, in which the user can set how many samples they require.

We have attempted to keep the code as simple as practical with the main loop, essentially being little more than a counter.

  while (menu == 3) {
    if ((millis()- prev) >= pos) {
      prev = millis();

Because we use the Millis function for this, in conjunction with an unsigned long, the device will be able to run for a maximum of about 50 days before the millis and prev variables overflow. Unsigned long is a 32 bit register that can hold a maximum value of about 4.3 billion.

232 = 4,294,967,296

To convert this into days, we simply divide the maximum number possible by the number of milliseconds in a day, which is 86,400,000ms per day.

4.3 x 109 / 86,400,000 = 49.7 days

We have not created a means to counteract this rollover, and as such, the maximum duration on a single power cycle will be about 50 days. If you’re wanting a device to last longer than this, you could simply add some code that will reset the prev variable when you’re expecting the millis variable to overflow. Since we are not explicitly designing the device to last for such long periods, we didn’t initially see this as an issue. It’s certainly worth mentioning as it is indeed a hard limit to the current project. Once the millis variable overflows, the device will simply cease to take new readings.

The take sample function is where the bulk of the code lays. We needed to use the sprintf() function to force the date and time figures into a 12 digit array, while simultaneously keeping the leading zeros. Without this, the date and time format would become nonsensical and convert a date and time such as;

01/01/2020 10:06:03


11/20/2010/ 63:xx:xx (where xx = NaN or not a number).

Naturally, this data is completely unusable without keeping the relevant formatting of 2 digits for each value.

After this, we write the time and the values on the analogue pins to the SD card with the following block.

File dataFile ="log.txt", FILE_WRITE);
  for (int i = 0; i < 4; i++) {
    dataFile.print(" , ");
  dataFile.println(" ");

In this block, we open up or create a file on the SD card called log.txt. We then write the date and time to it. After this, we use a for loop to read each of the four analogue pins and record the values with a comma separator to the SD card. Next, we simply carriage return and close the file, which saves the data.

Note: Upon reflection, we actually read the analogue pins on two separate occasions. Once for the LCD screen and once for the SD card. This would slow down the program and possibly take up much more room than needed. If space is an issue for you, consider using the Read in the SD card loop to write the values recorded into an array where you can then use them to also write to the LCD.


Testing the prototype is fairly straightforward for this project. We have added some basic error messages to help identify potential faults. Below are the potential errors and how to rectify them.

Blank LCD: If there is no information displayed on the LCD your first action should be to adjust the potentiometer on the back of the I²C expansion module. This potentiometer adjusts the contrast of the display and should make the display visible.

If this does not rectify the display issues, double check the connections. Make sure the SDA, SCL and power and ground connections are correct. If this does not rectify the fault, ensure that the code has been correctly uploaded to the microcontroller.

This blue trimpot adjusts the contrast.

Note: Ideally this module would be soldered directly to the back of the 1602 LCD. We have soldered it in this orientation as we will keep this setup for prototyping future projects.

RTC Failure! This error message will be displayed on the LCD if there is an issue with communication between the microcontroller/Arduino and the RTC module. This would normally occur if the SCL and SDA connections are connected incorrectly or insufficient power is being delivered to the module.

Double check all connections and rectify any potential issues. If this error persists, consider switching the module to ensure it is functioning correctly.

Card Failure: If you see card failure on the LCD, the likely culprit is that the SD card has not been inserted or is the wrong format. Make sure that the SD card is correctly inserted and that the formatting is in the FAT16 or FAT32 (file allocation table) format. Most SD cards come supplied from the factory in this format, however, if the SD card has been used in other devices such as a camera or media player etc., you may need to reformat it.

On a Windows system, formatting is a very basic task. Simply insert the SD card into your PC’s card reader. Press the Windows key and type “this pc” and press enter. You should see the SD card shown, along with your other drives.

In our example here, our SD card has already been formatted and is labelled ARDUINO. Shown as E: (E drive).

Note: Make sure that you are formatting the correct drive as this process will destroy the data on the particular drive you choose. It is very difficult and potentially expensive to recover the data from a formatted drive.

To make sure you’re formatting the correct drive, remove any other potential USB drives. This will significantly reduce the chances of formatting the incorrect drive. Furthermore, make sure the size of the drive matches the drive you’re expecting. In our case, the SD card was a 16GB card, which after formatting will provide 14.4GB of storage or 14.9GB ideally.

You may find the chart below helpful in identifying approximately how much storage a storage device will register in a Windows computer.

Once you’re sure you have the correct drive, right click it and select Format.

For the file system, our options were NTFS, FAT32 or exFAT. Make sure you select either FAT32 or FAT16 if both options are offered select FAT16. You can create a volume label if you like, but we will keep ours as ARDUINO. Select the quick format option and press start.

Reinsert your SD card into the project and repower the device. If you’re still receiving the message you should verify the SPI and power connections are correct. If this does not solve the issue, test with a separate SD card and or SD card module.

The Main Build:

The final design is, in essence, identical to the prototype build. The only real difference is we swap the Arduino Nano with an ATmega328P microcontroller. This will significantly reduce the cost of the device, however, this also means that we need to add a voltage regulator.

This got us wondering about what type of sensors people are likely to use with this device. This prompted us to go back over our previous projects to see what sensors we have used in the past. The vast majority of sensors use very little current with the only exception being the LPG sensor we used in the LPG leak detector from Issue 017.

That sensor used quite a bit more current than most sensors, topping in at about 150mA to run the internal heater. Whereas, most sensors use tens of milliamps. This prompted us to design the main project with a few power supply options built in.

We have designed the circuit and PCB so that each of the sensors can be powered independently via a TO-92 linear voltage regulator, via a TO-220 linear regulator, or you could power them all or any combination of them.

Parts Required:JaycarAltronicsCore Electronics
1 x ATmega328PZZ8727Z5126CE04547
1 x 16MHz CrystalSupplied with ZZ8727V1289ACOM-00536
2 x 22pf Ceramic Capacitors*RC5316R2814CE05206
1 x 28 Pin IC SocketPI6510P0571-
1 x Piezo BuzzerAB3459S6104ADA1536
1 x Male Pin Header StripHM3211P5430POLOLU-965
1 x Female Header StripHM3230P5390PRT-00116
4 x 3 Pin Screw Terminal SocketsHM3103--
4 x 3 Pin Screw Terminal PlugsHM3123--
5 x 78L05 Linear Voltage RegulatorsZV1539Z0460-
11 x 0.1μF Ceramic Capacitors*RC5360R2865COM-08375
5 x 100μF Electrolytic CapacitorsRE6140R4825CE05258
3 x Momentary N/O Pushbutton SwitchesSP0716S1080-
4 x No.4 6mm Screws*HP0550--
6 x No4 x 9mm Screws*HP0565--
1 x DC Power Panel Mount SocketPS0524P0623-
4 x M3 x 15mm Screws*HP0407H3130AFIT0273
8 x M3 Nuts*HP0425H3175POLOLU-1069
1 x 1N4004 Diode (or equivalent)*ZR1004Z0109COM-14884

Parts Required:

OPTIONAL:JaycarAltronicsCore Electronics
1 x 2.5mm DC Power Socket †PS0520P0621APRT-00119
1 x LM7805 Voltage RegulatorZV1505Z0505ADA2164
2 x 100μF Electrolytic CapacitorsRE6140R4825CE05258
2 x 0.1μF Ceramic Capacitors*RC5360R2865COM-08375


* Quantity required, may only be sold in packs.

† May be useful if you don't intend on using this project in an enclosure.

If you want to power the sensor via the T0-92 regulator, you simply populate that sensor’s regulator. However, if you want more current, you can leave the T0-92 regulator for that sensor unpopulated, and rather, populate the footprint for the T0-220. You then simply short out the solder bridge for that sensor.

This system is beneficial for several reasons.

Having each sensor independently regulated means the analogue reads will be more stable, because the voltage does not sag due to the other sensors. This should, in turn, provide a more rigid supply.

It allows the user to populate each channel with a voltage regulator suitable for their needs. For instance, you can use a 12V regulator in place of a 5V one to power an operational amplifier, which amplifies a much smaller sensor voltage.

A faulty sensor will not cause the other sensors to return incorrect readings due to voltage sagging.

Finally, the user can customise the circuit to suit their needs. For example, if all of the sensors they intend to use draw less than 100mA, they can simply power them all from one T0-92 regulator.

There is, of course, an increase in cost due to the higher component count, however, this is negligible given the potential benefits.


To aid in the construction of this project, we have opted to design a PCB that we had professionally manufactured. Naturally, you can find the files for this design on our website, which will allow you to manufacture the boards at home or send them off to your chosen board supplier.

The PCB was designed in EagleCAD, which is freely available to the maker community. We have supplied the working file, if you plan to modify the design for your needs.

Please now refer to the main schematic diagram. We have compartmentalised the schematic for clarity, due to the customisable power delivery circuitry. This section remains constant, regardless of the power supply options you choose to utilise.


If you want to create the project using just one voltage regulator, then you will need to populate IC1 with a TO-220 LM7805 voltage regulator, along with C25, C26, C27 and C28 with their respective capacitors. You then need to create a solder bridge across SJ1, SJ2, SJ3, SJ4 and SJ5, which will connect all of the 5V lines to that single voltage regulator.

In this application, the input voltage comes in via the DC jack or the pin header, through the reverse polarity protection diode, and into Vin of the regulator. By shorting out the solder jumpers SJ1 – SJ5, you connect the output of this regulator directly to the 5V for each of the sensor inputs and the microcontroller.

If you do this, you must not have the T0-92 voltage regulators soldered to the board for any of the shorted jumpers. Doing so could damage either or both voltage regulators.


If you’re wanting to have each sensor independently powered via its own T0-92 regulator you simply populate all of the TO-92 regulators and leave the T0-220 unpopulated.

You leave the jumpers open in this application, as each regulator can work independently. This will allow you to use a higher voltage regulator and create conditioning circuits etc., for use with your sensors, without impacting on other sensors connected to the device.

We simply used the 78L05, but the range of 78Lxx regulators share the same pinout, which allows you to use the regulator of your choice for the voltage you require.

Note: The signal to the microcontroller MUST not exceed 5V. Doing so will likely damage the microcontroller.


If you want to use a combination of voltages to power the sensors, the jumpers allow you to easily do that.

You can populate the TO-220 with a 5V voltage regulator of your choice to power one or more of the sensors. You then need to select which of the sensors will be powered by this regulator by creating a solder short across the respective jumper. This can be useful when using a sensor such as the MQ6 LPG sensor that requires currents higher than the 78LO5 can comfortably produce, or even if you want to use a 9V regulator for some sensors to create an Op-amp conditioning circuit, etc.

Populating the components of the PCB should be fairly straightforward. The footprints all match the device orientation.

With components like the regulators, the device packages all match the footprint in the soldermask, meaning it’s unlikely you will have any issues with them. However, the electrolytic capacitors and the reverse polarity protection diode are polarity sensitive and must be installed correctly.

For the electrolytic capacitors, the PCB soldermask shows the positive pin this corresponds to the long leg of the capacitor.

For the diode, the PCB is marked showing the diode cathode connection. Make sure the diode cathode maker band aligns with this mark as shown here.

Note: D1 adds another 0.7V to the voltage regulator overhead which may require a higher raw voltage supply.

We recommend that you solder some female pin headers to the PCB to attach the RTC with the CR2032 battery facing up.

This will make it easier to replace the battery.

The SD card is mounted to the bottom of the PCB without using headers. We originally wanted to have the device mount to the front of the PCB with the electronics facing up, however, removing and inverting the dual line headers proved problematic without lifting tracks and damaging the device. We decided it was better to just mount it to the bottom.

We have provided a large number of exposed vias to the tab mounting area of the TO-220 voltage regulator. These vias will help to transfer heat from the package into the ground plane of the PCB. This means, for modest loads, no further heat sinking will be needed. If you want to have a higher load on the TO-220 regulator, having four MQ6 style air quality meters, for example, you should consider keeping it vertical on the PCB and adding additional heatsinking.

We have included an In-System Programming header (ISP) footprint that will allow you to program the device via the Arduino IDE, using the Arduino as ISP programmer option. This header is found on the Arduino Uno and Nano. This may be useful for some people who like to program via this method, however, it’s not the only way you can program the device.

For us, we simply have an Arduino Uno compatible device that uses the 28pin DIP IC. We place the blank microcontroller into this Arduino and program it as usual. When done, we simply remove the microcontroller and install it into the project.

To connect the buttons, you need to wire one side of each of the buttons together. This will be the ground signal, which is the 4th pin on the PCB header.

Pin 1 of this header goes to the top / + button.

Pin 2 goes to the middle / OK button

Pin 3 goes to the third / - button

The last task is to connect the DC power jack to the PCB. We chose to have this directly connected to the PCB and not via a switch. If you would rather use a switch, you can easily modify the front panel to accept a rocker. For us, we simply connected the centre pin tag to the positive of the PCB, and the – tag to the negative. If you’re not sure which tag goes to which pin, you can either check the datasheet from your supplier or you can just use your multimeter in continuity mode to check which tag goes to the centre pin.

Note: Most wall mains power supplies with a 2.5mm DC jack use a centre positive configuration, but not all. To check your power supply’s configuration, look at the label on it. This symbol shows you if the pin is positive or not. In our case, the picture shows the centre as positive and the outer shell as negative. If yours is centre negative you can just invert the connections to the PCB. The good news is, you won’t damage the device if you get this wrong because of the reverse polarity protection diode that will only allow current to flow the correct way. It simply won’t function if the polarity is incorrect.


For this project, we have created an enclosure to house all of the electronics. This enclosure follows the same basic concept as our Power Supply from Issue 028 and the Dummy Load from Issue 022. The main structure consists of a top and bottom shell that clamps together. This clamping secures the front fascia panel, which has cutouts to mount or otherwise allow access to all of the devices’ input and output functions. We designed the enclosure using Fusion 360 as it is freely available for hobbyist use. As usual, we will provide the .STL files so you can print your own. We will also provide the Fusion 360 working files so you can work on the design in Fusion 360 and alter it to suit your needs, or even use it for a completely different project.


The base of the enclosure was printed at 200-micron layer height on our Flashforge Creator Pro using Flashforge branded white PLA. The part prints flat on the build plate without needing and support. It took about 6.5 hours to print in this orientation.


The top of the enclosure was also printed at 200-micron layer height on the same Flashforge printer, using the same Flashforge PLA. Like the base, this part was designed to print flat on the build platform without needing any support material. In this orientation, the top took about 5.5 hours to print.


The front panel was printed on our Flashforge Creator Pro and was printed in one go using the two extruders on this printer. We used Simplify 3D to slice the file with two separate processes. The first process used the left extruder and printed the bottom of the print at 200-microns, using white Flashforge PLA and printed the first 1.0mm. The second process used the right extruder, loaded with black Flashforge PLA and printed from 1.0mm on at the same 200-micron layer height.

Note; It is possible to manually do this in other slicers and with single extruder machines by printing the first layer in one colour and the second in another colour. You just need to either program your slicer to do it, or pause the print and manually change filament at the correct time.

If you’re not worried about dual extrusion, you can print the panel in one go. This takes about 1.5 hours.


You don’t have to print the feet for this project, as most electronics retailers actually sell sticky feet perfectly designed for this task. However, if like us, you have TPU rubber and a 3D printer capable of printing with it, we have provided the file for you to do so.

We printed the feet in a generic TPU “ninjaflex” inspired rubber on our Flashforge Creator Pro at 100-micron layer height. Since we are printing with TPU, we dropped the speed right down to about 30 mm/sec. It took about 20 mins to print each foot. We printed them separately so a failure wouldn’t waste the material.


Since the final build is only very slightly different from the prototype, testing the device is not much different. If you’re having issues, we recommend you follow those troubleshooting directions described earlier. Any different issues here are likely a result of the power supply. For instance, if the device fails to power up, we highly recommend you first double check the diode D1’s polarity. You need to ensure the band on your diode matches the band on the PCB. If that is correct, and you’re still not getting any signs of life, double check the power supply for the microcontroller.

If you’re using the T0-92 power supply, check IC6, C31, C32, and C30 are correct. Also, ensure that SJ5 is left open circuit.

If you’re powering the device from the TO-220, make sure the device is a 5V regulator and check the components in C25, C27, C28, C26 for correct placement. Also ensure that solder jumper SJ5 has been bridged, allowing current to flow from the regulator to the microcontroller.

If you’re having issues with power to the sensors, double check the orientation and placement of all of the top right regulators and capacitors. If you’re powering the device from the T0-220 regulator, make sure the relevant jumpers have been shorted.


There are a number of ways that this project could be improved for more functionality. For us, one improvement would be to add some menu inputs to enable the user to set the time/number of readings taken. This could work as a timer, allowing you to set the specific time you want to take readings for.

For example, if you wanted to take readings for 24 hours with a sample taken every 5 minutes, you could tell the device to take a sample every 5 minutes and to take 288 readings.

24 hours x 60 minutes = 140 minutes in a 24 hour period.

1440 mins / 5 mins = 288 5-minute blocks in 24 hours.

You could sound a buzzer after the desired number of samples are taken, letting you know the device has finished. This would be ideal when you are comparing sensor readings over a specific period, as it completely automates the process You don’t need to filter out the undesired raw data when graphing the results.

This would be easy to implement by just following the same procedure we used in code, to set the sample rate to set the total samples. Then, make a small modification to the final loop so that the program only takes a sample if the program has taken less than the desired user input value.

 while (menu == 3) {
    if ((millis()- prev) >= pos) {
      prev = millis();

Change this part of the code to the following:

  while (menu == 3) {
    if (((millis()- prev) >= pos) && (loop < user_inpt)) {
      prev = millis();
      loop ++;

Note: For this to work, you would need to define a couple of variables called loop and user_input. This is just to provide an example of how you could implement the counter but it has not been tested.

Another improvement would be to use the RTC to measure time compared to the millis function. It seems, whilst the RTC we used isn’t very accurate, it is vastly more accurate than the millis function. This is because the millis function relies on the 16MHz resonator on the Arduino.

This resonator changes frequency in relation to temperature, and thus, is not an accurate timekeeper. If you want the device to be at least as accurate as the RTC, you could use the RTC as a counter and not the millis function. Since we were not chasing such high precision the millis function is suitable for our needs.

Johann's earlier prototype
Johann Wyss

Johann Wyss

Staff technical writer