Bitznbytes
Member
Long story short, I had reason to look at a simple and cheap way to create a multi-sensor temperature and humidity control system. I came across the DHT11 sensor, which looked ideal. But subsequently it became apparent that it wasn’t a good match for the Picaxe, which is the only microcontroller I have any (very limited) experience of, as it's data output was too fast. These forums have documented a few ways around this, but they tend to need external components or high end microcontrollers.
It occurred to me that whilst a lower end Picaxe may not be quick enough to catch every DHT11 data pulse, it might be able to catch every other pulse. So if I took two readings from the DHT11, one catching all the odd pulses, the other catching the even ones, I could re-construct the entire data stream and decode the readings. As long as the values didn’t change between readings!
So that’s what I did, running a 08M2 at 32MHz, with no external pre-processing components. Essentially, the code initialises the DHT11, then on one pass executes a Pauseus 0 command. Just running this command introduces a slight delay, which is enough for the following Pulsin to miss the first edge of the 80uS start pulse put out by the DHT11. Hence, that Pulsin picks up the next pulse, which is the 1st data pulse. It’s not quick enough to process the next pulse (2nd data pulse), so misses this and picks up the 3rd and so on, picking up all the odd data pulses. These are stored in sequential memory with @bptrinc.
The full data stream is then processed, but this is irrelevant when it’s just started up as there hasn’t been a second pass yet.
So we go round for the second pass and the DHT11 is initialised again. But no Pauseus 0 command this time. Without it, the next Pulsin picks up the 80uS start pulse (which is ignored later). It misses the next pulse (1st data) and picks up the 2nd, 4th, 6th etc. data pulses, ie all the even data pulses.
So you end up with 40 pulse width measurements in memory, if out of sequence! The subsequent code unscrambles them and extracts the 5 DHT11 data bytes.
The checksum value of the data is calculated. If it matches the checksum byte (byte 5), the temp and humid values are converted to ASCII and sent out to a 20x4 OLED screen (AXE134Y). If not, the existing values remain on the display and round we go again.
Next time, we acquire the odd pulses again and use these and the previous even bits to extract the 5 data byes. Then we go round again acquiring the even bits and combine them with the previous odd bits, and so on.
By way of checking how many times the data fails the checksum test, there’s an alternative bit of output code (gosub testout) where the calculated checksum and the checksum byte values are displayed, along with two counters indicating how many times the measurement succeeded or failed.
Overall, it seems to succeed 50%-60% of the time sitting in my office, which means a valid reading every few seconds or so. The main culprit for failure seems to be the jittery temperature decimal part. But it could be a noisy electrical environment, the fact that the DHT11 isn’t enclosed or even that the 08M2 fails to catch an edge every now and again. But actually, with the display propped up next to a couple of other temp / humid meters, it reads and responds as they do. If you have fast changing values, then this probably isn’t the solution for you. But then, neither is the DHT11! Essentially, it has to get two identical readings in a row to display a valid result – maybe not a bad thing?
The code is sloppy and won't win any awards, but that’s coz I’m not a programmer! I’m sure someone more skilled could make it slicker. I just wanted to see if I could make it work.
It occurred to me that whilst a lower end Picaxe may not be quick enough to catch every DHT11 data pulse, it might be able to catch every other pulse. So if I took two readings from the DHT11, one catching all the odd pulses, the other catching the even ones, I could re-construct the entire data stream and decode the readings. As long as the values didn’t change between readings!
So that’s what I did, running a 08M2 at 32MHz, with no external pre-processing components. Essentially, the code initialises the DHT11, then on one pass executes a Pauseus 0 command. Just running this command introduces a slight delay, which is enough for the following Pulsin to miss the first edge of the 80uS start pulse put out by the DHT11. Hence, that Pulsin picks up the next pulse, which is the 1st data pulse. It’s not quick enough to process the next pulse (2nd data pulse), so misses this and picks up the 3rd and so on, picking up all the odd data pulses. These are stored in sequential memory with @bptrinc.
The full data stream is then processed, but this is irrelevant when it’s just started up as there hasn’t been a second pass yet.
So we go round for the second pass and the DHT11 is initialised again. But no Pauseus 0 command this time. Without it, the next Pulsin picks up the 80uS start pulse (which is ignored later). It misses the next pulse (1st data) and picks up the 2nd, 4th, 6th etc. data pulses, ie all the even data pulses.
So you end up with 40 pulse width measurements in memory, if out of sequence! The subsequent code unscrambles them and extracts the 5 DHT11 data bytes.
The checksum value of the data is calculated. If it matches the checksum byte (byte 5), the temp and humid values are converted to ASCII and sent out to a 20x4 OLED screen (AXE134Y). If not, the existing values remain on the display and round we go again.
Next time, we acquire the odd pulses again and use these and the previous even bits to extract the 5 data byes. Then we go round again acquiring the even bits and combine them with the previous odd bits, and so on.
By way of checking how many times the data fails the checksum test, there’s an alternative bit of output code (gosub testout) where the calculated checksum and the checksum byte values are displayed, along with two counters indicating how many times the measurement succeeded or failed.
Overall, it seems to succeed 50%-60% of the time sitting in my office, which means a valid reading every few seconds or so. The main culprit for failure seems to be the jittery temperature decimal part. But it could be a noisy electrical environment, the fact that the DHT11 isn’t enclosed or even that the 08M2 fails to catch an edge every now and again. But actually, with the display propped up next to a couple of other temp / humid meters, it reads and responds as they do. If you have fast changing values, then this probably isn’t the solution for you. But then, neither is the DHT11! Essentially, it has to get two identical readings in a row to display a valid result – maybe not a bad thing?
The code is sloppy and won't win any awards, but that’s coz I’m not a programmer! I’m sure someone more skilled could make it slicker. I just wanted to see if I could make it work.
Attachments
-
670 KB Views: 11
-
342.2 KB Views: 27
-
367.5 KB Views: 27
-
5.4 KB Views: 7