For this project I need to measure the temperature both inside and outside. So far I have one sensor working, and I need two. One for inside and one for outside. Rather than deep dive into all of them I'd decided to do some preliminary tests to see what worked well and what did not. These are the results.
Thermistor
First let’s start old school with a good old thermistor. It simply changes resistance in line with the temperature, so with the aid of a fixed resistor we can create a potential divider. The fact you are reading this blog post probably means you likely know all about thermistors, but I will include it for completeness.
In this example I have used a 4.7K resistor to GND and the thermistor to 3v3 to create a potential divider. The analog pin on the Seeeduino XIAO is pin 0 on the hardware, but internally is GPIO 2, and the latter is needed in MicroPython.
If you have got here searching for Seeeduino XIAO, MicroPython and ADC in the hopes to find out why you are getting errors when trying to use the read() method, then I have also been there. The solution is to use read_u16() instead. This test code works for reading analogue values from the A0 pin.
from machine import Pin, ADC import time adc = ADC(Pin(2)) while True: print(adc.read_u16()); time.sleep(1)
To be useful the value needs to be calibrated and converted into an actual temperature, but that calculation depends on the thermistor and resistor used. As this is an “also ran” experiment I am not going to bother to do this for the evaluation.
DHT11
This DHT11 is the ubiquitous temperature sensor that is the base of many projects needing to know the temperature. It uses a 40-bit serial output at a data rate around 10kbps. The data rate varies depending on the data because of the encoding used.
Sadly this is not currently a viable option to use in Micropython on the Seeeduino XIAO.
Because the custom protocol is not supported by most hardware natively, and the speed required is faster than most microcontrollers can support if written in MicroPython, the DHT11 functionality is built into MicorPython and the C level [https://docs.micropython.org/en/latest/samd/quickref.html]. It however is not currently compiled into the SAMD21 build, and that is the base build that is used by the Seeeduino XIAO distribution that we are using.
I gave it a go, and kudos to Robert H for some great test code, but it was just not functional.
If using the DHT11 on the Seeeduino XIAO is important then using the C and Arduino libraries would be a more appropriate solution over using MicorPython.
DHT12
The DHT12 is a more modern, more accurate, and all round improved version of the DHT11. It supports both the original 40-bit serial output (that is of no use to us), and I²C like the DHT20 we tested in the last blog post.
The hardware layer communications protocol I²C is supported directly by the Seeeduino XIAO but we still need a library to convert the numbers in to a temperature. I used https://github.com/mcauser/micropython-dht12 for this and it works well.
Here is the test code. The delay is important as the device will fail if the device is queried any faster. This will not be a problem in the final project as we will be sampling every few seconds at best.
import time from machine import Pin, I2C from dht12 import DHT12 i2c = I2C(0, scl=Pin(9), sda=Pin(8)) dht12 = DHT12(i2c, 0x5c) while True: dht12.measure() temper = dht12.temperature() humidity = dht12.humidity() print("temper : " + str(temper)) print("humidity : " + str(humidity)) time.sleep_ms(40)
Like the DHT20 this works well and is a serious contender for the final solution. It also uses a different I²C address so can be used with the DHT20 without needing to add more circuitry.
DHT20
We covered this before in this blog post so you can read that for further details. In short it is like the DHT12. Slightly more accurate in fact. It is another serious contender.
Grove Infrared Temperature Sensor 1.2
This is a non-contact IR heat sensor and is, in my personal opinion, really cool. I really wanted to use this sensor in the Cool Wave project just to experiment with it, but in reality the sensor is for measuring the temperature of an object and not the ambient temperature, so is not appropriate. We can still give it a test and a quick evaluation here.
For the test I simply connected GND (Black) to GND, VCC (Red) to V3V, and OBJ (White) to 0 (A0). The output from the module is a simple analogue voltage, and here is some simple code to display the approximate temperature of the object directly in front of the sensor.
from machine import Pin, ADC import time adc = ADC(Pin(2)) while True: print(adc.read_u16()*1.1/1023); time.sleep(1)
It at first appears to work well, and for a lot of projects this simple reading will be appropriate, but it is not as accurate as the module can be. There are in fact two sensors on the module, the IR sensor, and an ambient sensor. To get a more accurate reading from the IR sensor we need to calibrate it using the ambient sensor. The documents about this can be downloaded from https://wiki.seeedstudio.com/Grove-Infrared_Temperature_Sensor/. As the Seeeduino XIAO only has one analogue input we can not access both sensors at the same time without an external ADC.
Update: According to the SAM D21 datasheet (section 33.8.8) the ADC can be mapped to different pins. This allows us to switch between different input pins and to read multiple analogue inputs over time. This means both inputs can be used without external circuitry.
Yes, I know I could use this ambient sensor for the project, but it is like using a Ferrari to store the garden tools when I already have a number of garden sheds.
DS18B20
The DS18B20 style sensor is also commonly seen because of its low cost, durability and comparative accuracy.
Natively they come in a TO-92 package, but they are often potted in a waterproof stainless steel package for measuring the temperature of liquids and more harsh environments. For communication it uses the 1-Wire bus protocol, which as the name suggests uses one wire for all communication.
By default it operates at 15.4 kbps, and unfortunately like the DHT11, the 1-Wire code is not currently compiled into the SAMD21 build MicroPython. Sadly this makes it impractical to use these sensors under MicroPython on the Seeeduino XIAO.
I have tried proting the https://github.com/robert-hh/Onewire_DS18X20 library but it is just not able to communicate with the DS18B20. My hope is that in time the issues in the Seeeduino XIAO build of MicroPython will be addressed.
Conclusion
At this point, assuming I am going to stick with using MicroPython, the solution for Cool Wave is to use a DHT12 and a DHT20.
If I consider moving away from MicroPython then I would give serious consideration to using the DS18B20. What I gain is better weather protection without needing to develop a more complex enclosure. When I lose is the ability to monitor humidity. Although I was not planning on using humidity now it is something that may be useful to know in the future.
For the record I chose a Python based solution as the language that is most accessible to the community who will be able to utilise my work, and I chose MicroPython over CircuitPython because I am more familiar with it. Creating a C based firmware instead of Python would give me more sensor options, but I am currently happy with the DHT12 and a DHT20 options so I have decided not to pivot the design.
Top Comments