Skip to content

Commit 23fb232

Browse files
committed
Moved code from atomvm_lib and made compatible with new registration model.
1 parent 9ede1b8 commit 23fb232

File tree

13 files changed

+286
-142
lines changed

13 files changed

+286
-142
lines changed

Kconfig

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
menu "ATOMVM_DHT Configuration"
2+
3+
config AVM_DHT_ENABLE
4+
bool "Enable AtomVM DHT driver"
5+
default y
6+
help
7+
Use this parameter to enable or disable the AtomVM DHT driver.
8+
9+
endmenu

README.md

Lines changed: 3 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -4,87 +4,7 @@ The AtomVM Nif can be used to drive DHT11 and DHT12 temperature and humidity sen
44

55
This driver is included as an add-on to the AtomVM base image. In order to use this driver, you must be able to build the AtomVM virtual machine, which in turn requires installation of the Espressif IDF SDK and tool chain.
66

7-
> Note. For build instructions of the AtomVM Virtual machine on the ESP32 platform, see [here](https://github.com/bettio/AtomVM/blob/master/doc/atomvm-esp32.md#adding-custom-nifs-and-third-party-components).
7+
Documentation for this component can be found in the following sections:
88

9-
## Getting Started
10-
11-
Clone this repository in the `src/platforms/esp32/components` directory of the AtomVM source tree.
12-
13-
shell$ cd .../AtomVM/src/platforms/esp32/components
14-
shell$ git clone https://github.com/fadushin/atomvm_dht.git
15-
16-
Create a `component_nifs.txt` file, if it does not already exist, in `src/platforms/esp32/main`. The contents of this file should contain a single line for the ESP32 cam driver:
17-
18-
atomvm_dht
19-
20-
Build and flash AtomVM (typically from `src/platforms/esp32`)
21-
22-
shell$ cd .../AtomVM/src/platforms/esp32
23-
shell$ make flash
24-
...
25-
26-
Once the AtomVM image is flashed to the ESP32 device, it includes NIFs for interfacing with DHT11 and DHT22 sensors attached to the device.
27-
28-
# DHT API
29-
30-
The DHT API can be used to drive common DHT11 and DHT22 temperature and humidity sensors.
31-
32-
DHT22 devices are reported to have higher resolution and range in both temperature and humidity readings.
33-
34-
Temperature and humity readings can be taken at intervals not less that 1 second apart for DHT11 devices, and 2 seonds apart for DHT22 devices. The DHT API will ensure that any one DHT instance will not read at less than the recommended interval.
35-
36-
### Sample Code
37-
38-
The following code illustrates use of the DHT API:
39-
40-
%% start a DHT11 reader on Pin 22
41-
{ok, DHT} = dht:start(22),
42-
43-
%% take a measurement and print the results
44-
case dht:measure(DHT) of
45-
{ok, Measurement} ->
46-
{Temp, TempFractional, Hum, HumFractional} = Measurement,
47-
io:format("Temperature: ~p.~pC Humidity: ~p.~p%~n", [Temp, TempFractional, Hum, HumFractional]);
48-
Error ->
49-
io:format("Error taking measurement: ~p~n", [Error])
50-
end,
51-
...
52-
53-
### Example Program
54-
55-
The `dht_example` program illustrates use of the DHT API by taking a temperature and humidity reading every 30 seconds, and displaying the result on the console.
56-
57-
> Note. Building and flashing the `dht_example` program requires installation of the [`rebar3`](https://www.rebar3.org) Erlang build tool.
58-
59-
To run this example program, connect the positive (+) lead on the DHT device to +3.3v power on the ESP32, the negative lead (-) to a ground pin on the ESP32, and the data pin to GPIO pin 21 on the ESP32 device.
60-
61-
+-----------+
62-
| o-------- +3.3v
63-
| DHT11 o-------- data
64-
| or o-------- unused
65-
| DHT22 o-------- gnd
66-
| |
67-
+-----------+
68-
69-
Build the example program and flash to your device:
70-
71-
shell$ cd .../AtomVM/src/platforms/esp32/components/atomvm_dht/examples/dht_example
72-
shell$ rebar3 esp32_flash
73-
74-
> Note. This build step makes use of the [`atomvm_rebar3_plugin`](https://github.com/fadushin/atomvm_rebar3_plugin). See the README.md for information about parameters for setting the serial port and baud rate for your platform.
75-
76-
Attach to the console usin gthe `monitor` Make target in the AtomVM ESP32 build:
77-
78-
shell$ cd .../AtomVM/src/platform/esp32
79-
shell$ make monitor
80-
Toolchain path: /work/opt/xtensa-esp32-elf/bin/xtensa-esp32-elf-gcc
81-
WARNING: Toolchain version is not supported: crosstool-ng-1.22.0-95-ge082013a
82-
...
83-
Found AVM partition: size: 1048576, address: 0x110000
84-
Booting file mapped at: 0x3f430000, size: 1048576
85-
Starting: dht_example.beam...
86-
---
87-
Temperature: 21.3C Humidity: 41.6%
88-
Temperature: 21.4C Humidity: 41.4%
89-
Temperature: 21.3C Humidity: 41.3%
90-
...
9+
* [Programmer's Guide](markdown/dht.md)
10+
* [Example Program](examples/dht_example/README.md)

component.mk

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1-
COMPONENT_ADD_INCLUDEDIRS := driver/include
2-
COMPONENT_SRCDIRS := driver
1+
COMPONENT_ADD_INCLUDEDIRS := nifs/include ../../main
2+
COMPONENT_ADD_LDFLAGS = -Wl,--whole-archive -l$(COMPONENT_NAME) -Wl,--no-whole-archive
3+
COMPONENT_SRCDIRS := nifs
34
CXXFLAGS += -fno-rtti

examples/dht_example/.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,4 @@
1+
src/config.erl
12
_build/**
3+
_checkouts/**
4+
rebar.lock

examples/dht_example/README.md

Lines changed: 78 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,81 @@
1-
# esp32_example
1+
# AtomVM DHT Example Program
22

3-
Welcome to the esp32_example AtomVM application.
3+
Welcome to the `dht_example` AtomVM application.
44

5-
To build and flash this application to your ESP32 device, issue the `esp32_flash` target
5+
This example application will drive a DHT11 or DHT22 temperature and humidity sensor attached to an ESP32 device using a single data wire and print readings to the console.
66

7-
shell$ rebar3 esp32_flash
7+
The `dht_example` program illustrates use of the DHT API by taking a temperature and humidity reading every 30 seconds, and displaying the result on the console.
8+
9+
For this application, you will need:
10+
11+
* An ESP32 device, flashed with the [AtomVM](https://github.com/bettio/AtomVM) image (including the VM and core libraries), and capable of connecting via UART to your development machine;
12+
* A DHT11 or DHT22 device, typically marketed as an integrated development board;
13+
* The [`esptool.py`](https://github.com/espressif/esptool) tool (for flashing);
14+
* The [`git`](https://git-scm.com) version control tool;
15+
* [Erlang/OTP 21](https://www.erlang.org) or higher, along with [`rebar3`](https://www.rebar3.org);
16+
* A serial monitor program of your choice (e.g, [`minicom`](https://en.wikipedia.org/wiki/Minicom))
17+
18+
While the [IDF SDK](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/) and required toolchains are not required, they may make life a little easier.
19+
20+
## Getting Started
21+
22+
### Connection
23+
24+
To run this example program, connect the positive (+) lead on the DHT device to +3.3v power on the ESP32, the negative lead (-) to a ground pin on the ESP32, and the data pin to GPIO pin 22 on the ESP32 device.
25+
26+
+-----------+ +-----------+
27+
| o-------- +3.3v ------------o VCC |
28+
| DHT11 o-------- data -------------o IO21 |
29+
| or o-------- unused | |
30+
| DHT22 o-------- gnd --------------o GND |
31+
| | | |
32+
+-----------+ | |
33+
| ESP32 |
34+
+-----------+
35+
36+
### Build Instructions
37+
38+
To build and flash this application to your ESP32 device, issue the `esp32_flash` target to the `rebar3` command, and optionally specify the device port and baud rate, if they do not match the defaults.
39+
40+
> Note. For information about the `esp32_flash` target, see the [`atomvm_rebar3_plugin`](https://github.com/atomvm/atomvm_rebar3_plugin) instructions.
41+
42+
shell$ rebar3 esp32_flash -p /dev/ttyUSB0 -b 115200
43+
===> Fetching atomvm_rebar3_plugin
44+
===> Fetching packbeam
45+
===> Analyzing applications...
46+
===> Compiling atomvm_rebar3_plugin
47+
===> Compiling packbeam
48+
===> Verifying dependencies...
49+
===> App atomvm_lib is a checkout dependency and cannot be locked.
50+
===> Analyzing applications...
51+
===> Compiling atomvm_lib
52+
===> Analyzing applications...
53+
===> Compiling dht_example
54+
===> AVM file written to : atomvm_lib.avm
55+
===> AVM file written to : dht_example.avm
56+
===> esptool.py --chip esp32 --port /dev/ttyUSB0 --baud 115200 --before default_reset --after hard_reset write_flash -u --flash_mode dio --flash_freq 40m --flash_size detect 0x210000 .../atomvm_lib/examples/dht_example/_build/default/lib/dht_example.avm
57+
58+
esptool.py v2.1
59+
Connecting........_____.
60+
Chip is ESP32D0WDQ6 (revision (unknown 0xa))
61+
Uploading stub...
62+
Running stub...
63+
Stub running...
64+
Configuring flash size...
65+
Auto-detected Flash size: 4MB
66+
Wrote 16384 bytes at 0x00210000 in 1.4 seconds (91.4 kbit/s)...
67+
Hash of data verified.
68+
69+
Leaving...
70+
Hard resetting...
71+
72+
Connect to the device using the USB port (e.g., via `minicom`), and you should see something like:
73+
74+
Found AVM partition: size: 1048576, address: 0x110000
75+
Booting file mapped at: 0x3f430000, size: 1048576
76+
Starting: dht_example.beam...
77+
---
78+
Temperature: 21.3C Humidity: 41.6%
79+
Temperature: 21.4C Humidity: 41.4%
80+
Temperature: 21.3C Humidity: 41.3%
81+
...

examples/dht_example/rebar.config

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
{erl_opts, [debug_info]}.
22
{deps, [
3-
{atomvm_dht, {git, "https://github.com/fadushin/atomvm_dht.git", {branch, "master"}}}
4-
]}.
5-
{plugins, [
6-
{atomvm_rebar3_plugin, {git, "https://github.com/fadushin/atomvm_rebar3_plugin.git", {branch, "master"}}}
3+
{atomvm_dht, {git, "https://github.com/atomvm/atomvm_dht.git", {branch, "master"}}}
74
]}.
5+
{plugins, [atomvm_rebar3_plugin]}.

examples/dht_example/src/dht_example.erl

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,17 +19,15 @@
1919
-export([start/0]).
2020

2121
start() ->
22-
Pin = 21,
23-
{ok, DHT} = dht:start(Pin, dht11),
22+
{ok, DHT} = dht:start(#{pin => 21, device => dht_11}),
2423
loop(DHT).
2524

2625
loop(DHT) ->
27-
case dht:measure(DHT) of
28-
{ok, Measurement} ->
29-
{Temp, TempFractional, Hum, HumFractional} = Measurement,
26+
case dht:take_reading(DHT) of
27+
{ok, {{Temp, TempFractional}, {Hum, HumFractional}}} ->
3028
io:format("Temperature: ~p.~pC Humidity: ~p.~p%~n", [Temp, TempFractional, Hum, HumFractional]);
3129
Error ->
32-
io:format("Error taking measurement: ~p~n", [Error])
30+
io:format("Error taking reading: ~p~n", [Error])
3331
end,
34-
timer:sleep(30000),
32+
timer:sleep(5000),
3533
loop(DHT).

include/trace.hrl

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
%%
2+
%% Copyright (c) dushin.net
3+
%% All rights reserved.
4+
%%
5+
%% Licensed under the Apache License, Version 2.0 (the "License");
6+
%% you may not use this file except in compliance with the License.
7+
%% You may obtain a copy of the License at
8+
%%
9+
%% http://www.apache.org/licenses/LICENSE-2.0
10+
%%
11+
%% Unless required by applicable law or agreed to in writing, software
12+
%% distributed under the License is distributed on an "AS IS" BASIS,
13+
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
%% See the License for the specific language governing permissions and
15+
%% limitations under the License.
16+
%%
17+
18+
-ifdef(TRACE_ENABLED).
19+
-define(TRACE(Format, Args), io:format("~p [~p:~p/~p:~p] " ++ Format ++ "~n", [erlang:system_time(millisecond), ?MODULE, ?FUNCTION_NAME, ?FUNCTION_ARITY, ?LINE | Args])).
20+
-else.
21+
-define(TRACE(Format, Args), ok).
22+
-endif.

markdown/dht.md

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
# DHT
2+
3+
The AtomVM DHT library can be used to drive DHT11 and DHT12 temperature and humidity sensors that can be attached to ESP32 devices.
4+
5+
The AtomVM DHT library is only supported on the ESP32 platform.
6+
7+
> Note. The DHT11 and DHT12 are notoriously inaccurate temperature sensors, though they are cheap and may be good enough for simple applications. This driver uses bit banging on GPIO pins and may not make the best use of resources on your ESP32. Consider alternative temperature sensors, such as the SHT3x or Bosch BMP or BME line of sensors.
8+
9+
## Build Instructions
10+
11+
The AtomVM DHT library is implemented as an AtomVM component, which includes some native C code that must be linked into the ESP32 AtomVM image. In order to build and deploy this client code, you must build an AtomVM binary image with this component included.
12+
13+
For general instructions about how to build AtomVM and include third-party components into an AtomVM image, see the [AtomVM Build Instructions](https://doc.atomvm.net/build-instructions.html).
14+
15+
Once the AtomVM image including this component has been built, you can flash the image to your ESP32 device. For instructions about how to flash AtomVM images to your ESP32 device, see the AtomVM [Getting Started Guide](https://doc.atomvm.net/getting-started-guide.html).
16+
17+
Once the AtomVM image including this component has been flashed to your ESP32 device, you can then include this project into your [`rebar3`](https://www.rebar3.org) project using the [`atomvm_rebar3_plugin`](https://github.com/atomvm/atomvm_rebar3_plugin), which provides targets for building AtomVM packbeam files and flashing them to your device.
18+
19+
## Programmer's Guide
20+
21+
The DHT API can be used to drive common DHT11 and DHT22 temperature and humidity sensors.
22+
23+
DHT22 devices are reported to have higher resolution and range in both temperature and humidity readings.
24+
25+
Temperature and humidity readings can be taken at intervals not less that 1 second apart for DHT11 devices, and 2 seconds apart for DHT22 devices. The DHT API will ensure that any one DHT instance will not read at less than the recommended interval.
26+
27+
### Lifecycle
28+
29+
To start the DHT driver, use the `dht:start/1` function. Pass in a configuration map, which may contain the following entries
30+
31+
| Key | Value | Default | Required | Description |
32+
|-----|-------|---------|----------|-------------|
33+
| `pin` | `integer()` | none | yes | The data pin to which the DHT11 or DHT22 is connected. |
34+
| `device` | `dht_11 \| dht_12` | `dht_11` | no | The device type (DHT11 or DHT12). |
35+
36+
For example:
37+
38+
%% erlang
39+
Config = #{
40+
pin => 22,
41+
device => dht_11
42+
},
43+
{ok, DHT} = dht:start(Config),
44+
...
45+
46+
Stop the DHT driver via the `dht:stop/1` function. Supply the reference to the DHT instance returned from `dht:start/1`:
47+
48+
%% erlang
49+
ok = dht:stop(DHT)
50+
51+
### Taking Readings
52+
53+
Take readings using the `dht:take_reading/1` function. Supply a reference to the DHT instance returned from `dht:start/1`.
54+
55+
A reading is expressed as pair containing the temperature (in degrees celcius) and relative humidity (expressed as a percentage). The temperature and humidity readings are each pairs of integers, representing the whole and fractional part (to a precision of one digit).
56+
57+
For example,
58+
59+
%% erlang
60+
case dht:take_reading(DHT) of
61+
{ok, Reading} ->
62+
{{Temp, TempFractional}, {Hum, HumFractional}} = Reading,
63+
io:format("Temperature: ~p.~pC Humidity: ~p.~p%~n", [Temp, TempFractional, Hum, HumFractional]);
64+
Error ->
65+
io:format("Error taking reading: ~p~n", [Error])
66+
end,
67+
...

driver/atomvm_dht.c renamed to nifs/atomvm_dht.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424

2525
#include <context.h>
2626
#include <defaultatoms.h>
27+
#include <esp32_sys.h>
2728
#include <interop.h>
2829
#include <nifs.h>
2930
#include <port.h>
@@ -224,6 +225,11 @@ static const struct Nif dht_read_nif =
224225
.nif_ptr = nif_dht_read
225226
};
226227

228+
void atomvm_dht_init(GlobalContext *global)
229+
{
230+
// no-op
231+
}
232+
227233
const struct Nif *atomvm_dht_get_nif(const char *nifname)
228234
{
229235
if (strcmp("dht:read/1", nifname) == 0) {
@@ -232,3 +238,8 @@ const struct Nif *atomvm_dht_get_nif(const char *nifname)
232238
}
233239
return NULL;
234240
}
241+
242+
#include <sdkconfig.h>
243+
#ifdef CONFIG_AVM_DHT_ENABLE
244+
REGISTER_NIF_COLLECTION(atomvm_dht, atomvm_dht_init, atomvm_dht_get_nif)
245+
#endif

0 commit comments

Comments
 (0)