Compare commits
505 commits
migrate-ap
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9b79afc177 | ||
|
|
e60be99cbd | ||
|
|
19d7984a9e | ||
|
|
8c0e9803b3 | ||
|
|
4258c12206 | ||
|
|
7a275e5d02 | ||
|
|
d2d51db455 | ||
|
|
71b8dd42d2 | ||
|
|
6deba1dea6 | ||
|
|
5be2eb1b4a | ||
|
|
6de22b6d25 | ||
|
|
9fc7c60893 | ||
|
|
fc71187a3f | ||
|
|
dda19cd00a | ||
|
|
78367af420 | ||
|
|
0a43f57744 | ||
|
|
39a15fd584 | ||
|
|
40a7ecbce7 | ||
|
|
d3919890fb | ||
|
|
79f372af44 | ||
|
|
96fa8d2066 | ||
|
|
dc5ff4ae9f | ||
|
|
32f85f7b47 | ||
|
|
28dff4e04d | ||
|
|
f007fe83ef | ||
|
|
54ee1a632a | ||
|
|
e873237b5e | ||
|
|
e06ebab53a | ||
|
|
bc97ca02ad | ||
|
|
5e79a3725b | ||
|
|
68db0345da | ||
|
|
7f9bbb01ae | ||
|
|
a4c53f7727 | ||
|
|
81c8b2697f | ||
|
|
9b14c3932b | ||
|
|
bfb5ef2e80 | ||
|
|
255a958ec1 | ||
|
|
7fd61698c2 | ||
|
|
0106eefbad | ||
|
|
c28334635d | ||
|
|
1224fd01bc | ||
|
|
4003fdc574 | ||
|
|
e59d7913d4 | ||
|
|
65476e8278 | ||
|
|
114aa7aa7b | ||
|
|
5e76adca6a | ||
|
|
f4788c0207 | ||
|
|
98f045e3c7 | ||
|
|
315e4e8791 | ||
|
|
80a6cdc6e0 | ||
|
|
1cee8e8ca5 | ||
|
|
5088cb6c8b | ||
|
|
0b61e2b8a9 | ||
|
|
74e2f53aa7 | ||
|
|
0b6964b131 | ||
|
|
6304d73d88 | ||
|
|
895bd13011 | ||
|
|
029602abb0 | ||
|
|
ae5f4199ea | ||
|
|
fbacaa46aa | ||
|
|
591f801f8a | ||
|
|
2e975746b5 | ||
|
|
51dcd252bc | ||
|
|
94bcecc020 | ||
|
|
10c9ef1542 | ||
|
|
4dd956eee9 | ||
|
|
ca3d5c7d19 | ||
|
|
00ca0190f6 | ||
|
|
c7c007b6b9 | ||
|
|
d8595b215c | ||
|
|
81f43d589e | ||
|
|
6a98837c3c | ||
|
|
effe76b2e1 | ||
|
|
8b02c9b910 | ||
|
|
921527a9e2 | ||
|
|
52edecfa07 | ||
|
|
2667caf75f | ||
|
|
c653e06fcf | ||
|
|
e0ccdc28fd | ||
|
|
69cf749316 | ||
|
|
714974ff13 | ||
|
|
0c08eddde0 | ||
|
|
01a99d9313 | ||
|
|
5964f2ee5b | ||
|
|
61590ea1c0 | ||
|
|
0a757d6b8f | ||
|
|
b9746ad1c5 | ||
|
|
9297c020ad | ||
|
|
17bc2a2c47 | ||
|
|
592c75abcd | ||
|
|
df4d9163a6 | ||
|
|
3ed453636c | ||
|
|
09e4a79ab1 | ||
|
|
26c6c32077 | ||
|
|
7bf7357328 | ||
|
|
2fc427c908 | ||
|
|
451ac02e2e | ||
|
|
3ad6500f61 | ||
|
|
87cea3a14d | ||
|
|
9f70757b9c | ||
|
|
21144c0ce1 | ||
|
|
331c6c85ba | ||
|
|
b45d08b0cd | ||
|
|
6d5c8c4a7b | ||
|
|
e6d7f40b7a | ||
|
|
f62527af5b | ||
|
|
f3c85efb53 | ||
|
|
a6e23a95c4 | ||
|
|
5f8c3ac364 | ||
|
|
5513004820 | ||
|
|
c21ffb7512 | ||
|
|
002cdfd6da | ||
|
|
0489a41130 | ||
|
|
19bb4016ff | ||
|
|
2091034df0 | ||
|
|
398fb7d8b3 | ||
|
|
b637366898 | ||
|
|
51b9335df8 | ||
|
|
860822a172 | ||
|
|
29ef4c20d9 | ||
|
|
3308d7268f | ||
|
|
08fa3ac978 | ||
|
|
a4723b7ff2 | ||
|
|
f95ec8d84d | ||
|
|
c9e728c0a0 | ||
|
|
9a8033638c | ||
|
|
ba22d203d3 | ||
|
|
1c50e12d89 | ||
|
|
a1cdc0142f | ||
|
|
50b924c937 | ||
|
|
00deb173a8 | ||
|
|
fe32ce6170 | ||
|
|
999bd73547 | ||
|
|
3e2f7e4043 | ||
|
|
9695762e75 | ||
|
|
0d6a5538b0 | ||
|
|
ebd3938ae9 | ||
|
|
ec4e48bb86 | ||
|
|
a8be947ec5 | ||
|
|
47bcf53134 | ||
|
|
71f829bbdc | ||
|
|
bc99adf69b | ||
|
|
305cc45680 | ||
|
|
f95481c52b | ||
|
|
13aa6419e6 | ||
|
|
6ccd81433a | ||
|
|
13bfecf33a | ||
|
|
c3bc7a83d6 | ||
|
|
c5b8706980 | ||
|
|
7f0f1a2df3 | ||
|
|
1e313842b6 | ||
|
|
e0d9da4d47 | ||
|
|
0c55b0320d | ||
|
|
09c8eb0387 | ||
|
|
e632bc6373 | ||
|
|
651395638d | ||
|
|
7b83905e55 | ||
|
|
a89218cae1 | ||
|
|
02223db340 | ||
|
|
4b2859d6fb | ||
|
|
d46f29c84a | ||
|
|
d97123bf75 | ||
|
|
def13e627c | ||
|
|
b93d58203d | ||
|
|
3d3d44b5ab | ||
|
|
cdc6588e57 | ||
|
|
f7ec0e5d4a | ||
|
|
0bdbc05092 | ||
|
|
aa2d7d40c3 | ||
|
|
7f491da2f8 | ||
|
|
db31909eb0 | ||
|
|
12db602a62 | ||
|
|
d109ea6905 | ||
|
|
5fa3e2dc0c | ||
|
|
3a9137480d | ||
|
|
3be45da123 | ||
|
|
ebf5e40edd | ||
|
|
b047125981 | ||
|
|
44024f6d15 | ||
|
|
f7c094c759 | ||
|
|
275bedeec7 | ||
|
|
172646a55a | ||
|
|
cfdbfd6c79 | ||
|
|
4e9d959004 | ||
|
|
b35c2c2e56 | ||
|
|
b4bf4362a4 | ||
|
|
1c6813f529 | ||
|
|
b3915857c8 | ||
|
|
af62bccf0d | ||
|
|
f6af170e60 | ||
|
|
92d769e321 | ||
|
|
7ce619455d | ||
|
|
9a144fdb01 | ||
|
|
ab3284ecb1 | ||
|
|
13d4ca9368 | ||
|
|
b9a33a7397 | ||
|
|
159cf772b5 | ||
|
|
ed75830d68 | ||
|
|
6333e8e8d2 | ||
|
|
e5a3acfb39 | ||
|
|
cb65ab35bb | ||
|
|
e2225f53e4 | ||
|
|
4494e3ea13 | ||
|
|
b06aea09f4 | ||
|
|
02ace5cf52 | ||
|
|
d784e8a7ca | ||
|
|
dd97c84df2 | ||
|
|
5c61a83323 | ||
|
|
67b851fb7b | ||
|
|
6e9ce5cbc3 | ||
|
|
67abbc6cdf | ||
|
|
6bf81185f5 | ||
|
|
3eed1bcb16 | ||
|
|
050216d0eb | ||
|
|
eed66c7984 | ||
|
|
964760ad96 | ||
|
|
6e7daf9027 | ||
|
|
7c674fa52a | ||
|
|
d7008d9cb0 | ||
|
|
f544a7c5ed | ||
|
|
d8727d7075 | ||
|
|
d0463bf3b6 | ||
|
|
564191c4eb | ||
|
|
bb0d40644a | ||
|
|
486422c821 | ||
|
|
ab82347fc2 | ||
|
|
86896852e4 | ||
|
|
9e1d67722c | ||
|
|
c4c0fcdb26 | ||
|
|
fa0b3c6555 | ||
|
|
47afeb7b7f | ||
|
|
a86ead8457 | ||
|
|
8529924d16 | ||
|
|
ff4a4167d0 | ||
|
|
c1d96985b5 | ||
|
|
092c796ed1 | ||
|
|
0e19aa0675 | ||
|
|
c281ed8971 | ||
|
|
6202ecac62 | ||
|
|
c470fa3093 | ||
|
|
3ae7029a51 | ||
|
|
420d319cc6 | ||
|
|
a4d9e9d6eb | ||
|
|
f6c406ab86 | ||
|
|
00bb2bf62d | ||
|
|
645fd4d77c | ||
|
|
cc3a3c5095 | ||
|
|
5265e25462 | ||
|
|
d25aba8e72 | ||
|
|
bcf1d08d58 | ||
|
|
f92df0a2c9 | ||
|
|
3fa0d82d66 | ||
|
|
88f2a87b19 | ||
|
|
f1e608691b | ||
|
|
e50a1648a9 | ||
|
|
8e5bf4f798 | ||
|
|
e18d7cb4ae | ||
|
|
9c6ee194d4 | ||
|
|
5658c88d1f | ||
|
|
1f69fde777 | ||
|
|
2bbdc1edae | ||
|
|
31eed58731 | ||
|
|
322c72e14b | ||
|
|
6b3996ae57 | ||
|
|
e0bb91f422 | ||
|
|
6401b504b5 | ||
|
|
89873252d4 | ||
|
|
0218e061ef | ||
|
|
cd5e7e01fb | ||
|
|
a360a92054 | ||
|
|
80f1d87973 | ||
|
|
fde128ca3a | ||
|
|
3b20073662 | ||
|
|
25f28b4fdf | ||
|
|
afd0e86d19 | ||
|
|
0bf00bcafa | ||
|
|
16c6723d3c | ||
|
|
ba1f09fde9 | ||
|
|
272c1fc5f8 | ||
|
|
712e434a87 | ||
|
|
47f306c311 | ||
|
|
393fffa145 | ||
|
|
bcd3bd7288 | ||
|
|
d79457f92d | ||
|
|
547d46cf1b | ||
|
|
628b98a411 | ||
|
|
d4e88a39be | ||
|
|
093d51779f | ||
|
|
722a41d3fb | ||
|
|
66fe637443 | ||
|
|
39971499f2 | ||
|
|
c6f15b5f1a | ||
|
|
fce17a3c38 | ||
|
|
dfa628fea9 | ||
|
|
f64833ad74 | ||
|
|
53c95ace17 | ||
|
|
e92e740192 | ||
|
|
abe3c9756b | ||
|
|
e2ae5a0494 | ||
|
|
987fd605df | ||
|
|
e77cec2730 | ||
|
|
e694a935ee | ||
|
|
a7a10a3d6f | ||
|
|
7dea9042e3 | ||
|
|
8329d2531f | ||
|
|
b307521a77 | ||
|
|
3f827eb080 | ||
|
|
26e3b6490a | ||
|
|
e187db7d91 | ||
|
|
20d936d10d | ||
|
|
abf14e0252 | ||
|
|
929eb9a83a | ||
|
|
250cbf0106 | ||
|
|
df71485155 | ||
|
|
df2b6b06f4 | ||
|
|
36a4c89fce | ||
|
|
923428aa6c | ||
|
|
7ab9e78834 | ||
|
|
b91a38752a | ||
|
|
c2fac61aae | ||
|
|
861d67745d | ||
|
|
417009a564 | ||
|
|
fac20289eb | ||
|
|
9c9a98dd9b | ||
|
|
4f1d110436 | ||
|
|
c17db48512 | ||
|
|
19dd739b82 | ||
|
|
8c1d1c0d8e | ||
|
|
13e8800825 | ||
|
|
37b339e941 | ||
|
|
7ce32d8511 | ||
|
|
a0c8c75919 | ||
|
|
64ce6eb922 | ||
|
|
a744b2fe17 | ||
|
|
b59c15e8e8 | ||
|
|
d3cd109059 | ||
|
|
d9455c30e0 | ||
|
|
a5c4811a3b | ||
|
|
519b0ddf90 | ||
|
|
3504dc952e | ||
|
|
044029caa0 | ||
|
|
0f65b97ad5 | ||
|
|
fe2eae61ba | ||
|
|
70cf730454 | ||
|
|
8086b44129 | ||
|
|
0957f827bb | ||
|
|
9df4d89aa1 | ||
|
|
aba5d513f8 | ||
|
|
570c166691 | ||
|
|
0923b82715 | ||
|
|
4c0febc001 | ||
|
|
f46c204285 | ||
|
|
418e785c54 | ||
|
|
8b62a09914 | ||
|
|
bcd502d941 | ||
|
|
e78470e4c7 | ||
|
|
0de83b9925 | ||
|
|
9af386754d | ||
|
|
24cf18051b | ||
|
|
86936f2acf | ||
|
|
952ef3ce60 | ||
|
|
34cd2bd7d9 | ||
|
|
b594a3b872 | ||
|
|
f87a2083ac | ||
|
|
04dbf36da5 | ||
|
|
9ddb1206d3 | ||
|
|
2475f33072 | ||
|
|
04f1c3cce1 | ||
|
|
45461242f2 | ||
|
|
53ca34914f | ||
|
|
e92cd181ec | ||
|
|
1ceafabf7a | ||
|
|
0f91cb9cfb | ||
|
|
9b8479425c | ||
|
|
8ea03941be | ||
|
|
99ece2f7d3 | ||
|
|
16bc28af11 | ||
|
|
2409c85e29 | ||
|
|
0a3e82204a | ||
|
|
b5dd8ed474 | ||
|
|
3a66b011b0 | ||
|
|
b75aae3e2d | ||
|
|
ecc98848f2 | ||
|
|
b3b81e4944 | ||
|
|
5fee86b9f0 | ||
|
|
e898d1b51d | ||
|
|
a1a4ff2ed4 | ||
|
|
353b036d22 | ||
|
|
0e9993b125 | ||
|
|
18f08eb31a | ||
|
|
9c6187f41a | ||
|
|
0411093a49 | ||
|
|
7b10b132ec | ||
|
|
872a3f5d77 | ||
|
|
2947fb63bb | ||
|
|
265ce3d5b9 | ||
|
|
0d4c7ef1d5 | ||
|
|
016e076550 | ||
|
|
83721a01dc | ||
|
|
d9adf25ed1 | ||
|
|
270344d6cb | ||
|
|
6a2f67ae0b | ||
|
|
bd05dd2802 | ||
|
|
7fe6cfa534 | ||
|
|
63b812b4d9 | ||
|
|
45af854ed2 | ||
|
|
453dc6d62c | ||
|
|
0760b45e44 | ||
|
|
7b419274ab | ||
|
|
db79e617f2 | ||
|
|
f0ebfd0e9c | ||
|
|
3e48594c63 | ||
|
|
c3bc657488 | ||
|
|
b0e8902675 | ||
|
|
e3e09946ff | ||
|
|
d0dc679c5e | ||
|
|
5731ce2c56 | ||
|
|
d8bc70ad24 | ||
|
|
45ffc1e916 | ||
|
|
a999a73e9f | ||
|
|
3086e0d362 | ||
|
|
9d3442c72d | ||
|
|
92286c87ee | ||
|
|
0c3636cc69 | ||
|
|
9b2255ac1a | ||
|
|
800a87ebad | ||
|
|
f73d6fe941 | ||
|
|
9570cc583a | ||
|
|
1d10247540 | ||
|
|
9844ee3ee7 | ||
|
|
13cd5b0ffb | ||
|
|
04c39b0c34 | ||
|
|
e2045f0cd3 | ||
|
|
ebc002a673 | ||
|
|
c0af0ade93 | ||
|
|
e2815766d8 | ||
|
|
86e05d2545 | ||
|
|
ebc522ffe4 | ||
|
|
d8c6b94b50 | ||
|
|
66ab83ffa5 | ||
|
|
13b1a3de3e | ||
|
|
dc73b7ddc8 | ||
|
|
3530c2eae9 | ||
|
|
8c66505a98 | ||
|
|
cf3b61f81e | ||
|
|
30c871ef73 | ||
|
|
e0ebc7bb5e | ||
|
|
708b9de1f4 | ||
|
|
a12f51db9a | ||
|
|
d965898c7e | ||
|
|
2ef6d725e2 | ||
|
|
901e2a4879 | ||
|
|
d01e5d748d | ||
|
|
96af0e0a20 | ||
|
|
7b51b5a41e | ||
|
|
9dfccb6a47 | ||
|
|
198a0e5226 | ||
|
|
574ad66ffd | ||
|
|
6e49411893 | ||
|
|
06427ff916 | ||
|
|
784a166af4 | ||
|
|
2a0564b970 | ||
|
|
d1898c962d | ||
|
|
8ee25a5fea | ||
|
|
4eb816e2cc | ||
|
|
5d0241fd91 | ||
|
|
e1206880d9 | ||
|
|
0210209a94 | ||
|
|
2da710586f | ||
|
|
d286ff5899 | ||
|
|
47da59470d | ||
|
|
3ab29705d0 | ||
|
|
9e9a19b359 | ||
|
|
bcb158093a | ||
|
|
41f2813956 | ||
|
|
8c2978d378 | ||
|
|
1ab027e7b8 | ||
|
|
8f16b4fb6d | ||
|
|
a3d74c9c0b | ||
|
|
9ecd9cae58 | ||
|
|
8e8ac1a85f | ||
|
|
a429d9f429 | ||
|
|
a751f1aade | ||
|
|
420793d1d4 | ||
|
|
76f3f6aa63 | ||
|
|
ccb12e1e02 | ||
|
|
bde9d2f5fd | ||
|
|
1236bd025b | ||
|
|
b59f126dd0 | ||
|
|
4e698782ea | ||
|
|
a5e68f0f8b | ||
|
|
59900023f6 | ||
|
|
5c4dda0fe4 | ||
|
|
4e9cd30c00 | ||
|
|
b52f6ff976 | ||
|
|
5f6b814aed | ||
|
|
176ff81433 | ||
|
|
d2e0d0929f | ||
|
|
ea3cc6205b | ||
|
|
c7c441eda9 | ||
|
|
64d73b27ad | ||
|
|
baa61c340c | ||
|
|
9303d7b22a | ||
|
|
b374aca37d | ||
|
|
97999e5eaa |
125 changed files with 5405 additions and 107667 deletions
807
.github/workflows/build-clang-doxy.yml
vendored
807
.github/workflows/build-clang-doxy.yml
vendored
File diff suppressed because it is too large
Load diff
12
.github/workflows/release-callee.yml
vendored
12
.github/workflows/release-callee.yml
vendored
|
|
@ -12,16 +12,16 @@ jobs:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Download build artifacts from build-platform steps
|
- name: Download build artifacts from build-platform steps
|
||||||
uses: actions/download-artifact@v2
|
uses: actions/download-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: build-files
|
path: .
|
||||||
- name: List Files
|
- name: List Files
|
||||||
run: ls
|
run: ls
|
||||||
- name: Upload Assets to the GitHub Release
|
- name: Upload Assets to the GitHub Release
|
||||||
uses: softprops/action-gh-release@v1
|
uses: softprops/action-gh-release@v2
|
||||||
if: startsWith(github.ref, 'refs/tags/')
|
if: startsWith(github.ref, 'refs/tags/')
|
||||||
with:
|
with:
|
||||||
files: |
|
files: |
|
||||||
wippersnapper.*.uf2
|
build-files/wippersnapper.*.uf2
|
||||||
wippersnapper.*.bin
|
build-files/wippersnapper.*.bin
|
||||||
wippersnapper.*.zip
|
build-files/wippersnapper.*.zip
|
||||||
|
|
|
||||||
6
.gitignore
vendored
6
.gitignore
vendored
|
|
@ -48,4 +48,8 @@ examples/Wippersnapper_demo/build/
|
||||||
.pio/
|
.pio/
|
||||||
|
|
||||||
# Secrets
|
# Secrets
|
||||||
data/
|
data/
|
||||||
|
|
||||||
|
# Misc. Data
|
||||||
|
tests/
|
||||||
|
venv/
|
||||||
4
.vscode/settings.json
vendored
4
.vscode/settings.json
vendored
|
|
@ -5,5 +5,7 @@
|
||||||
},
|
},
|
||||||
"C_Cpp.dimInactiveRegions": true,
|
"C_Cpp.dimInactiveRegions": true,
|
||||||
"dotnet.defaultSolution": "disable",
|
"dotnet.defaultSolution": "disable",
|
||||||
"cmake.configureOnOpen": false
|
"cmake.configureOnOpen": false,
|
||||||
|
"C_Cpp.clang_format_fallbackStyle": "Google",
|
||||||
|
"C_Cpp.clang_format_style": "file"
|
||||||
}
|
}
|
||||||
11
README.md
11
README.md
|
|
@ -5,9 +5,9 @@
|
||||||
# Adafruit WipperSnapper
|
# Adafruit WipperSnapper
|
||||||
[](http://adafruit.github.io/Adafruit_Wippersnapper_Arduino/html/index.html)
|
[](http://adafruit.github.io/Adafruit_Wippersnapper_Arduino/html/index.html)
|
||||||
|
|
||||||
Adafruit.io WipperSnapper is a firmware designed to turn any Wi-Fi capable board into an Internet-of-Things (IoT) device. No code required!
|
Adafruit.io WipperSnapper is a firmware designed to turn any Wi-Fi-capable board into an Internet-of-Things (IoT) device. No programming is required!
|
||||||
|
|
||||||
WipperSnapper works with multiple microcontroller architectures such as ESP8266, ESP32, ESP32-S2, ESP32-C3, RP2040, and ATSAMD51.
|
WipperSnapper works with multiple microcontroller architectures such as ESP8266, ESP32, ESP32-Sx, ESP32-Cx, RP2040, RP2350, and ATSAMD51.
|
||||||
|
|
||||||
You will need a **free** [Adafruit IO](https://io.adafruit.com) account to use WipperSnapper.
|
You will need a **free** [Adafruit IO](https://io.adafruit.com) account to use WipperSnapper.
|
||||||
|
|
||||||
|
|
@ -16,17 +16,14 @@ You will need a **free** [Adafruit IO](https://io.adafruit.com) account to use W
|
||||||
# Get Started
|
# Get Started
|
||||||
[Learn how to install and use WipperSnapper by following this guide on the Adafruit Learning System - QuickStart: Adafruit IO WipperSnapper](https://learn.adafruit.com/quickstart-adafruit-io-wippersnapper).
|
[Learn how to install and use WipperSnapper by following this guide on the Adafruit Learning System - QuickStart: Adafruit IO WipperSnapper](https://learn.adafruit.com/quickstart-adafruit-io-wippersnapper).
|
||||||
|
|
||||||
|
|
||||||
## Get WipperSnapper
|
|
||||||
Pre-compiled binaries and UF2 files for supported hardware are provided on the [releases page](https://github.com/adafruit/Adafruit_Wippersnapper_Arduino/releases) of this repository.
|
|
||||||
|
|
||||||
## Supported Platforms
|
## Supported Platforms
|
||||||
|
|
||||||
|Platform| MCU(s) |
|
|Platform| MCU(s) |
|
||||||
|--|--|
|
|--|--|
|
||||||
|[ESP32-x](https://github.com/espressif/arduino-esp32)| ESP32, ESP32-S2, ESP32-S3, ESP32-C3 |
|
|[ESP32-x](https://github.com/espressif/arduino-esp32)| ESP32, ESP32-Sx, ESP32-C3 |
|
||||||
|[ESP8266](https://github.com/esp8266/Arduino)| ESP8266 |
|
|[ESP8266](https://github.com/esp8266/Arduino)| ESP8266 |
|
||||||
|[RP2040](https://github.com/earlephilhower/arduino-pico)| RP2040 MCU w/WiFi (i.e: Pico W) |
|
|[RP2040](https://github.com/earlephilhower/arduino-pico)| RP2040 MCU w/WiFi (i.e: Pico W) |
|
||||||
|
|[RP2350](https://github.com/earlephilhower/arduino-pico)| RP2350 MCU w/WiFi (i.e: Pico 2W) |
|
||||||
|[ATSAMD](https://github.com/adafruit/ArduinoCore-samd/)| SAMD51 MCU w/separate WiFi Co-Processor (i.e: Adafruit "AirLift")|
|
|[ATSAMD](https://github.com/adafruit/ArduinoCore-samd/)| SAMD51 MCU w/separate WiFi Co-Processor (i.e: Adafruit "AirLift")|
|
||||||
|
|
||||||
## Contributing to Adafruit.io and WipperSnapper
|
## Contributing to Adafruit.io and WipperSnapper
|
||||||
|
|
|
||||||
BIN
examples/Wippersnapper_NoFS/.DS_Store
vendored
BIN
examples/Wippersnapper_NoFS/.DS_Store
vendored
Binary file not shown.
|
|
@ -1 +0,0 @@
|
||||||
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
|
|
||||||
|
|
@ -1,45 +0,0 @@
|
||||||
// Adafruit IO WipperSnapper Beta
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// NOTE: This software is a BETA release and in active development.
|
|
||||||
// Please report bugs or errors to
|
|
||||||
// https://github.com/adafruit/Adafruit_Wippersnapper_Arduino/issues
|
|
||||||
//
|
|
||||||
// This sketch is for devices which lack USB-MSD or LittleFS support such
|
|
||||||
// as the Arduino MKR WiFi 1010, Arduino Nano 33 IoT.
|
|
||||||
//
|
|
||||||
// Adafruit invests time and resources providing this open source code.
|
|
||||||
// Please support Adafruit and open source hardware by purchasing
|
|
||||||
// products from Adafruit!
|
|
||||||
//
|
|
||||||
// Brent Rubell for Adafruit Industries, 2021
|
|
||||||
//
|
|
||||||
// All text above must be included in any redistribution.
|
|
||||||
|
|
||||||
#include "Wippersnapper_Networking.h"
|
|
||||||
|
|
||||||
/************************ Adafruit IO Config *******************************/
|
|
||||||
|
|
||||||
// Visit io.adafruit.com if you need to create an account,
|
|
||||||
// or if you need your Adafruit IO key.
|
|
||||||
#define IO_USERNAME "YOUR_AIO_USERNAME"
|
|
||||||
#define IO_KEY "YOUR_AIO_KEY"
|
|
||||||
|
|
||||||
/**************************** WiFi Config ***********************************/
|
|
||||||
#define WIFI_SSID "YOUR_WIFI_SSID"
|
|
||||||
#define WIFI_PASS "YOUR_WIFI_PASSWORD"
|
|
||||||
|
|
||||||
#include "Wippersnapper_Networking.h"
|
|
||||||
Wippersnapper_WiFi wipper(IO_USERNAME, IO_KEY, WIFI_SSID, WIFI_PASS);
|
|
||||||
|
|
||||||
void setup() {
|
|
||||||
// Provisioning must occur prior to serial init.
|
|
||||||
wipper.provision();
|
|
||||||
|
|
||||||
Serial.begin(115200);
|
|
||||||
// while (!Serial) delay(10);
|
|
||||||
|
|
||||||
wipper.connect();
|
|
||||||
}
|
|
||||||
|
|
||||||
void loop() { wipper.run(); }
|
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
|
|
@ -1 +1 @@
|
||||||
|
|
||||||
|
|
@ -1,2 +1,3 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1,2 +1,3 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
|
||||||
|
|
@ -1,2 +1,3 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
name=Adafruit WipperSnapper
|
name=Adafruit WipperSnapper
|
||||||
version=1.0.0-beta.88
|
version=1.0.0-beta.111
|
||||||
author=Adafruit
|
author=Adafruit
|
||||||
maintainer=Adafruit <adafruitio@adafruit.com>
|
maintainer=Adafruit <adafruitio@adafruit.com>
|
||||||
sentence=Arduino application for Adafruit.io WipperSnapper
|
sentence=Arduino application for Adafruit.io WipperSnapper
|
||||||
|
|
@ -7,4 +7,4 @@ paragraph=Arduino application for Adafruit.io WipperSnapper
|
||||||
category=Communication
|
category=Communication
|
||||||
url=https://github.com/adafruit/Adafruit_Wippersnapper_Arduino
|
url=https://github.com/adafruit/Adafruit_Wippersnapper_Arduino
|
||||||
architectures=*
|
architectures=*
|
||||||
depends=Adafruit NeoPixel, Adafruit SPIFlash, ArduinoJson, Adafruit DotStar, Adafruit INA219, Adafruit LTR329 and LTR303, Adafruit LTR390 Library, Adafruit MCP3421, Adafruit NAU7802 Library, Adafruit SleepyDog Library, Adafruit TMP117, Adafruit TinyUSB Library, Adafruit AHTX0, Adafruit BME280 Library, Adafruit BMP280 Library, Adafruit BMP3XX Library, Adafruit DPS310, Adafruit DS248x, Adafruit SCD30, Adafruit SGP30 Sensor, Adafruit SGP40 Sensor, Sensirion I2C SCD4x, Sensirion I2C SEN5X, arduino-sht, Adafruit Si7021 Library, Adafruit MQTT Library, Adafruit MS8607, Adafruit MCP9808 Library, Adafruit MCP9600 Library, Adafruit MPL115A2, Adafruit MPRLS Library, Adafruit TSL2591 Library, Adafruit_VL53L0X, Adafruit VL53L1X, STM32duino VL53L4CD, STM32duino VL53L4CX, Adafruit_VL6180X, Adafruit PM25 AQI Sensor, Adafruit VCNL4020 Library, Adafruit VCNL4040, Adafruit VEML7700 Library, Adafruit LC709203F, Adafruit LPS2X, Adafruit LPS35HW, Adafruit seesaw Library, Adafruit BME680 Library, Adafruit MAX1704X, Adafruit ADT7410 Library, Adafruit HTS221, Adafruit HTU21DF Library, Adafruit HTU31D Library, Adafruit PCT2075, hp_BH1750, ENS160 - Adafruit Fork
|
depends=OmronD6T - Community Fork, SdFat - Adafruit Fork, Adafruit NeoPixel, Adafruit SPIFlash, ArduinoJson, Adafruit DotStar, Adafruit HDC302x, Adafruit INA219, Adafruit INA260 Library, Adafruit INA237 and INA238 Library, Adafruit LTR329 and LTR303, Adafruit LTR390 Library, Adafruit MCP3421, Adafruit MLX90632 Library, Adafruit NAU7802 Library, Adafruit SleepyDog Library, Adafruit TMP117, Adafruit TinyUSB Library, Adafruit AHTX0, Adafruit AS5600 Library, Adafruit BME280 Library, Adafruit BMP280 Library, Adafruit BMP3XX Library, Adafruit DPS310, Adafruit DS248x, Adafruit SCD30, Adafruit SGP30 Sensor, Adafruit SGP40 Sensor, Sensirion I2C SCD4x, Sensirion I2C SEN5X, Sensirion I2C SEN66, arduino-sht, Adafruit Si7021 Library, Adafruit MQTT Library, Adafruit MS8607, Adafruit MCP9808 Library, Adafruit MCP9600 Library, Adafruit MPL115A2, Adafruit MPRLS Library, Adafruit TSL2591 Library, Adafruit_VL53L0X, Adafruit VL53L1X, STM32duino VL53L4CD, STM32duino VL53L4CX, Adafruit_VL6180X, Adafruit PM25 AQI Sensor, Adafruit VCNL4020 Library, Adafruit VCNL4040, Adafruit VCNL4200 Library, Adafruit VEML7700 Library, Adafruit LC709203F, Adafruit LPS2X, Adafruit LPS28, Adafruit LPS35HW, Adafruit seesaw Library, Adafruit BME680 Library, Adafruit MAX1704X, Adafruit ADT7410 Library, Adafruit HTS221, Adafruit HTU21DF Library, Adafruit HTU31D Library, Adafruit PCT2075, hp_BH1750, ENS160 - Adafruit Fork, Adafruit BusIO, Adafruit Unified Sensor, Sensirion Core, Adafruit GFX Library, Adafruit LED Backpack Library, Adafruit LiquidCrystal, Adafruit SH110X, Adafruit SSD1306
|
||||||
|
|
|
||||||
394
platformio.ini
394
platformio.ini
|
|
@ -6,7 +6,7 @@
|
||||||
; PlatformIO Defaults
|
; PlatformIO Defaults
|
||||||
[platformio]
|
[platformio]
|
||||||
description = "Adafruit.IO WipperSnapper Firmware"
|
description = "Adafruit.IO WipperSnapper Firmware"
|
||||||
default_envs = adafruit_feather_esp32s3_tft, adafruit_magtag29_esp32s2, adafruit_feather_esp32s3, featheresp32s2, adafruit_feather_esp32s2_reversetft, adafruit_metro_esp32s2, adafruit_qtpy_esp32s2, adafruit_feather_esp32s3_reversetft, adafruit_feather_esp32s3_nopsram, adafruit_feather_esp32s2_tft, adafruit_qtpy_esp32, adafruit_qtpy_esp32c3, featheresp32, adafruit_qtpy_esp32s3_nopsram, featheresp32v2, huzzah, adafruit_pyportal_m4, adafruit_pyportal_m4_titano
|
default_envs = adafruit_feather_esp32s3_tft, adafruit_magtag29_esp32s2, adafruit_feather_esp32s3, featheresp32s2, adafruit_feather_esp32s2_reversetft, adafruit_metro_esp32s2, adafruit_qtpy_esp32s2, adafruit_feather_esp32s3_reversetft, adafruit_feather_esp32s3_nopsram, adafruit_feather_esp32s2_tft, adafruit_qtpy_esp32, adafruit_qtpy_esp32c3, featheresp32, adafruit_qtpy_esp32s3_nopsram, featheresp32v2, huzzah, adafruit_pyportal_m4, adafruit_pyportal_m4_titano, dfrobot_beetle_esp32c3
|
||||||
|
|
||||||
|
|
||||||
; Common Build Environment
|
; Common Build Environment
|
||||||
|
|
@ -16,20 +16,32 @@ framework = arduino
|
||||||
monitor_speed = 115200
|
monitor_speed = 115200
|
||||||
lib_compat_mode = strict
|
lib_compat_mode = strict
|
||||||
lib_deps =
|
lib_deps =
|
||||||
|
;;;;;;;;;;; FunHouse / LVGL Boards uncomment these ;;;;;;;;;;;;;;
|
||||||
|
; https://github.com/adafruit/Adafruit_HX8357_Library.git
|
||||||
|
; https://github.com/adafruit/Adafruit_ILI9341.git
|
||||||
|
; https://github.com/adafruit/Adafruit_STMPE610.git
|
||||||
|
; https://github.com/adafruit/Adafruit-ST7735-Library.git
|
||||||
|
; https://github.com/adafruit/Adafruit_TouchScreen.git
|
||||||
|
; https://github.com/brentru/lvgl.git#wippersnapper
|
||||||
|
; https://github.com/brentru/Adafruit_LvGL_Glue.git#development
|
||||||
|
;;;;;;;;;;; All Boards need these libraries included ;;;;;;;;;;;;;;
|
||||||
adafruit/Adafruit Zero DMA Library
|
adafruit/Adafruit Zero DMA Library
|
||||||
adafruit/Adafruit TinyUSB Library
|
|
||||||
adafruit/Adafruit NeoPixel
|
adafruit/Adafruit NeoPixel
|
||||||
adafruit/Adafruit SPIFlash
|
adafruit/Adafruit SPIFlash
|
||||||
adafruit/Adafruit DotStar
|
adafruit/Adafruit DotStar
|
||||||
adafruit/ENS160 - Adafruit Fork
|
adafruit/ENS160 - Adafruit Fork
|
||||||
adafruit/Adafruit SleepyDog Library
|
adafruit/Adafruit SleepyDog Library
|
||||||
adafruit/Adafruit AHTX0
|
adafruit/Adafruit AHTX0
|
||||||
|
adafruit/Adafruit AS5600 Library
|
||||||
adafruit/Adafruit BME280 Library
|
adafruit/Adafruit BME280 Library
|
||||||
adafruit/Adafruit BMP280 Library
|
adafruit/Adafruit BMP280 Library
|
||||||
adafruit/Adafruit BMP3XX Library
|
adafruit/Adafruit BMP3XX Library
|
||||||
adafruit/Adafruit DPS310
|
adafruit/Adafruit DPS310
|
||||||
adafruit/Adafruit DS248x
|
adafruit/Adafruit DS248x
|
||||||
adafruit/Adafruit INA219
|
adafruit/Adafruit INA219
|
||||||
|
adafruit/Adafruit INA260 Library
|
||||||
|
adafruit/Adafruit INA237 and INA238 Library
|
||||||
|
adafruit/Adafruit HDC302x
|
||||||
adafruit/Adafruit HTS221
|
adafruit/Adafruit HTS221
|
||||||
adafruit/Adafruit HTU21DF Library
|
adafruit/Adafruit HTU21DF Library
|
||||||
adafruit/Adafruit HTU31D Library
|
adafruit/Adafruit HTU31D Library
|
||||||
|
|
@ -42,9 +54,11 @@ lib_deps =
|
||||||
adafruit/Adafruit Si7021 Library
|
adafruit/Adafruit Si7021 Library
|
||||||
adafruit/Adafruit VCNL4020 Library
|
adafruit/Adafruit VCNL4020 Library
|
||||||
adafruit/Adafruit VCNL4040
|
adafruit/Adafruit VCNL4040
|
||||||
|
adafruit/Adafruit VCNL4200 Library
|
||||||
adafruit/Adafruit MCP3421
|
adafruit/Adafruit MCP3421
|
||||||
adafruit/Adafruit MCP9808 Library
|
adafruit/Adafruit MCP9808 Library
|
||||||
adafruit/Adafruit MCP9600 Library
|
adafruit/Adafruit MCP9600 Library
|
||||||
|
adafruit/Adafruit MLX90632 Library
|
||||||
adafruit/Adafruit MPL115A2
|
adafruit/Adafruit MPL115A2
|
||||||
adafruit/Adafruit MPRLS Library
|
adafruit/Adafruit MPRLS Library
|
||||||
adafruit/Adafruit MS8607
|
adafruit/Adafruit MS8607
|
||||||
|
|
@ -56,10 +70,10 @@ lib_deps =
|
||||||
stm32duino/STM32duino VL53L4CD
|
stm32duino/STM32duino VL53L4CD
|
||||||
stm32duino/STM32duino VL53L4CX
|
stm32duino/STM32duino VL53L4CX
|
||||||
adafruit/Adafruit_VL6180X
|
adafruit/Adafruit_VL6180X
|
||||||
adafruit/Adafruit PM25 AQI Sensor
|
|
||||||
adafruit/Adafruit VEML7700 Library
|
adafruit/Adafruit VEML7700 Library
|
||||||
adafruit/Adafruit LC709203F
|
adafruit/Adafruit LC709203F
|
||||||
adafruit/Adafruit LPS2X
|
adafruit/Adafruit LPS2X
|
||||||
|
adafruit/Adafruit LPS28
|
||||||
adafruit/Adafruit LPS35HW
|
adafruit/Adafruit LPS35HW
|
||||||
adafruit/Adafruit seesaw Library
|
adafruit/Adafruit seesaw Library
|
||||||
adafruit/Adafruit BME680 Library
|
adafruit/Adafruit BME680 Library
|
||||||
|
|
@ -70,25 +84,41 @@ lib_deps =
|
||||||
adafruit/Adafruit TouchScreen
|
adafruit/Adafruit TouchScreen
|
||||||
adafruit/Adafruit MQTT Library
|
adafruit/Adafruit MQTT Library
|
||||||
bblanchon/ArduinoJson
|
bblanchon/ArduinoJson
|
||||||
https://github.com/PaulStoffregen/OneWire.git
|
adafruit/Adafruit LiquidCrystal
|
||||||
|
adafruit/Adafruit LED Backpack Library
|
||||||
|
adafruit/Adafruit PM25 AQI Sensor
|
||||||
|
adafruit/Adafruit SH110X
|
||||||
|
adafruit/Adafruit SSD1306
|
||||||
|
https://github.com/tyeth/omron-devhub_d6t-arduino.git
|
||||||
|
https://github.com/pstolarz/OneWireNg.git
|
||||||
|
; COMMENT OUT FOR RP2040/RP2350 BOARDS
|
||||||
https://github.com/milesburton/Arduino-Temperature-Control-Library.git
|
https://github.com/milesburton/Arduino-Temperature-Control-Library.git
|
||||||
|
; AND UNCOMMENT FOR RP2040/RP2350 BOARDS
|
||||||
|
; https://github.com/pstolarz/Arduino-Temperature-Control-Library.git
|
||||||
https://github.com/Sensirion/arduino-sht.git
|
https://github.com/Sensirion/arduino-sht.git
|
||||||
https://github.com/Sensirion/arduino-i2c-scd4x.git
|
https://github.com/Sensirion/arduino-i2c-scd4x.git
|
||||||
https://github.com/Sensirion/arduino-i2c-sen5x.git
|
https://github.com/Sensirion/arduino-i2c-sen5x.git
|
||||||
|
https://github.com/Sensirion/arduino-i2c-sen66.git
|
||||||
https://github.com/adafruit/WiFiNINA.git
|
https://github.com/adafruit/WiFiNINA.git
|
||||||
https://github.com/Starmbi/hp_BH1750.git
|
https://github.com/Starmbi/hp_BH1750.git
|
||||||
|
https://github.com/adafruit/Adafruit_TinyUSB_Arduino.git
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
; Common build environment for ESP32 platform
|
; Common build environment for ESP32 platform
|
||||||
[common:esp32]
|
[common:esp32]
|
||||||
platform = https://github.com/pioarduino/platform-espressif32/releases/download/51.03.03/platform-espressif32.zip
|
platform = https://github.com/pioarduino/platform-espressif32/releases/download/53.03.13/platform-espressif32.zip
|
||||||
lib_ignore = WiFiNINA, WiFi101
|
;;Funhouse uses 3.0.7 of arduino-esp32 for now:
|
||||||
|
; platform = https://github.com/pioarduino/platform-espressif32/releases/download/51.03.07/platform-espressif32.zip
|
||||||
|
; This is needed for occasional new features and bug fixes
|
||||||
|
; platform = https://github.com/pioarduino/platform-espressif32#develop
|
||||||
|
lib_ignore = WiFiNINA, WiFi101, OneWire
|
||||||
monitor_filters = esp32_exception_decoder, time
|
monitor_filters = esp32_exception_decoder, time
|
||||||
|
|
||||||
; Common build environment for ESP8266 platform
|
; Common build environment for ESP8266 platform
|
||||||
[common:esp8266]
|
[common:esp8266]
|
||||||
platform = espressif8266
|
platform = espressif8266
|
||||||
lib_ignore = WiFiNINA, WiFi101, Adafruit TinyUSB Library
|
lib_ignore = WiFiNINA, WiFi101, Adafruit TinyUSB Library, OneWire
|
||||||
|
|
||||||
; Common build environment for Atmel/Microchip SAMDx platform
|
; Common build environment for Atmel/Microchip SAMDx platform
|
||||||
[common:atsamd]
|
[common:atsamd]
|
||||||
|
|
@ -96,22 +126,20 @@ platform = atmelsam
|
||||||
platform_packages =
|
platform_packages =
|
||||||
platformio/framework-arduino-samd-adafruit@^1.7.13
|
platformio/framework-arduino-samd-adafruit@^1.7.13
|
||||||
platformio/tool-jlink@^1.78811.0
|
platformio/tool-jlink@^1.78811.0
|
||||||
lib_ldf_mode = deep
|
lib_ldf_mode = chain+
|
||||||
|
lib_compat_mode = strict
|
||||||
lib_archive = no ; debug timer issues see https://community.platformio.org/t/choose-usb-stack-as-tiny-usb/22451/5
|
lib_archive = no ; debug timer issues see https://community.platformio.org/t/choose-usb-stack-as-tiny-usb/22451/5
|
||||||
|
lib_ignore = OneWire, USBHost
|
||||||
|
|
||||||
[common:rp2040]
|
; Common build environment for Arduino-Pico platforms
|
||||||
platform = https://github.com/maxgerhardt/platform-raspberrypi.git
|
[common:arduinopico]
|
||||||
; platform_packages =
|
platform = https://github.com/maxgerhardt/platform-raspberrypi.git#develop
|
||||||
; framework-arduinopico @ symlink:///Users/tyeth/Projects/arduino-pico
|
platform_packages = framework-arduinopico@https://github.com/earlephilhower/arduino-pico.git
|
||||||
; framework-arduinopico@https://github.com/earlephilhower/arduino-pico.git#master
|
|
||||||
board = rpipicow
|
|
||||||
framework = arduino
|
framework = arduino
|
||||||
board_build.core = earlephilhower
|
board_build.core = earlephilhower
|
||||||
board_build.filesystem_size = 0.5m
|
board_build.filesystem_size = 0.5m
|
||||||
build_flags = -DUSE_TINYUSB
|
lib_ignore = WiFiNINA, WiFi101, Adafruit Zero DMA Library, OneWire
|
||||||
; Once https://github.com/platformio/platformio-core > 6.1.11 these can be removed
|
lib_compat_mode = soft ; can be stricter once pio detects SleepyDog on RP2040
|
||||||
lib_ignore = WiFiNINA, WiFi101, Adafruit Zero DMA Library
|
|
||||||
lib_compat_mode = soft ; can be strict once pio detects SleepyDog on RP2040
|
|
||||||
|
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Individual Board Definitions ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Individual Board Definitions ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
@ -142,13 +170,43 @@ board = adafruit_itsybitsy_esp32
|
||||||
build_flags = -DARDUINO_ADAFRUIT_ITSYBITSY_ESP32
|
build_flags = -DARDUINO_ADAFRUIT_ITSYBITSY_ESP32
|
||||||
board_build.filesystem = littlefs
|
board_build.filesystem = littlefs
|
||||||
|
|
||||||
|
; Adafruit ESP32 Feather C6
|
||||||
|
[env:adafruit_feather_esp32c6_4mbflash_nopsram]
|
||||||
|
extends = common:esp32
|
||||||
|
board = adafruit_feather_esp32c6
|
||||||
|
build_flags =
|
||||||
|
-DARDUINO_ADAFRUIT_FEATHER_ESP32C6
|
||||||
|
-DARDUINO_USB_CDC_ON_BOOT=1
|
||||||
|
-DCORE_DEBUG_LEVEL=5
|
||||||
|
board_build.filesystem = littlefs
|
||||||
|
board_build.partitions = min_spiffs.csv
|
||||||
|
|
||||||
|
; Espressif ESP32-C6 4MB NO PSRAM esp32-c6-devkitm-1
|
||||||
|
[env:espressif_esp32-c6-devkitm-1]
|
||||||
|
extends = common:esp32
|
||||||
|
board = esp32-c6-devkitm-1
|
||||||
|
build_type = debug
|
||||||
|
build_flags =
|
||||||
|
-DARDUINO_ESPRESSIF_ESP32C6_DEVKITM_1
|
||||||
|
-DARDUINO_ADAFRUIT_FEATHER_ESP32C6
|
||||||
|
-DNDEBUG=1
|
||||||
|
-DDEBUG=1
|
||||||
|
-DESP_LOG_LEVEL=5
|
||||||
|
-DARDUINO_CORE_DEBUG_LEVEL=5
|
||||||
|
-DARDUINO_DEBUG_LEVEL=5
|
||||||
|
-DARDUINO_LOG_LEVEL=5
|
||||||
|
-DCORE_DEBUG_LEVEL=5
|
||||||
|
-DARDUHAL_LOG_LEVEL=5
|
||||||
|
board_build.filesystem = littlefs
|
||||||
|
board_build.partitions = min_spiffs.csv
|
||||||
|
|
||||||
; Adafruit Feather ESP32-S2
|
; Adafruit Feather ESP32-S2
|
||||||
[env:featheresp32s2]
|
[env:featheresp32s2]
|
||||||
extends = common:esp32
|
extends = common:esp32
|
||||||
board = featheresp32-s2
|
board = featheresp32-s2
|
||||||
build_flags = -DARDUINO_ADAFRUIT_FEATHER_ESP32S2 -DBOARD_HAS_PSRAM
|
build_flags = -DARDUINO_ADAFRUIT_FEATHER_ESP32S2 -DBOARD_HAS_PSRAM
|
||||||
board_build.partitions = tinyuf2-partitions-4MB.csv
|
;set partition to tinyuf2-partitions-4MB-noota.csv as of CPY 10
|
||||||
|
board_build.partitions = tinyuf2-partitions-4MB-noota.csv
|
||||||
extra_scripts = pre:rename_usb_config.py
|
extra_scripts = pre:rename_usb_config.py
|
||||||
|
|
||||||
; Adafruit Feather ESP32-S2 TFT
|
; Adafruit Feather ESP32-S2 TFT
|
||||||
|
|
@ -156,7 +214,8 @@ extra_scripts = pre:rename_usb_config.py
|
||||||
extends = common:esp32
|
extends = common:esp32
|
||||||
board = adafruit_feather_esp32s2_tft
|
board = adafruit_feather_esp32s2_tft
|
||||||
build_flags = -DARDUINO_ADAFRUIT_FEATHER_ESP32S2_TFT -DBOARD_HAS_PSRAM
|
build_flags = -DARDUINO_ADAFRUIT_FEATHER_ESP32S2_TFT -DBOARD_HAS_PSRAM
|
||||||
board_build.partitions = tinyuf2-partitions-4MB.csv
|
;set partition to tinyuf2-partitions-4MB-noota.csv as of CPY 10
|
||||||
|
board_build.partitions = tinyuf2-partitions-4MB-noota.csv
|
||||||
extra_scripts = pre:rename_usb_config.py
|
extra_scripts = pre:rename_usb_config.py
|
||||||
|
|
||||||
; Adafruit Feather ESP32-S2 Reverse TFT
|
; Adafruit Feather ESP32-S2 Reverse TFT
|
||||||
|
|
@ -164,7 +223,8 @@ extra_scripts = pre:rename_usb_config.py
|
||||||
extends = common:esp32
|
extends = common:esp32
|
||||||
board = adafruit_feather_esp32s2_reversetft
|
board = adafruit_feather_esp32s2_reversetft
|
||||||
build_flags = -DARDUINO_ADAFRUIT_FEATHER_ESP32S2_REVTFT -DBOARD_HAS_PSRAM
|
build_flags = -DARDUINO_ADAFRUIT_FEATHER_ESP32S2_REVTFT -DBOARD_HAS_PSRAM
|
||||||
board_build.partitions = tinyuf2-partitions-4MB.csv
|
;set partition to tinyuf2-partitions-4MB-noota.csv as of CPY 10
|
||||||
|
board_build.partitions = tinyuf2-partitions-4MB-noota.csv
|
||||||
extra_scripts = pre:rename_usb_config.py
|
extra_scripts = pre:rename_usb_config.py
|
||||||
|
|
||||||
; Adafruit Feather ESP32-S3 2MB PSRAM
|
; Adafruit Feather ESP32-S3 2MB PSRAM
|
||||||
|
|
@ -172,8 +232,8 @@ extra_scripts = pre:rename_usb_config.py
|
||||||
extends = common:esp32
|
extends = common:esp32
|
||||||
board = adafruit_feather_esp32s3
|
board = adafruit_feather_esp32s3
|
||||||
build_flags = -DARDUINO_ADAFRUIT_FEATHER_ESP32S3 -DBOARD_HAS_PSRAM
|
build_flags = -DARDUINO_ADAFRUIT_FEATHER_ESP32S3 -DBOARD_HAS_PSRAM
|
||||||
;set partition to tinyuf2-partitions-4MB.csv as of idf 5.1
|
;set partition to tinyuf2-partitions-4MB-noota.csv as of CPY 10
|
||||||
board_build.partitions = tinyuf2-partitions-4MB.csv
|
board_build.partitions = tinyuf2-partitions-4MB-noota.csv
|
||||||
extra_scripts = pre:rename_usb_config.py
|
extra_scripts = pre:rename_usb_config.py
|
||||||
|
|
||||||
; Adafruit Feather ESP32-S3 NO PSRAM
|
; Adafruit Feather ESP32-S3 NO PSRAM
|
||||||
|
|
@ -181,6 +241,7 @@ extra_scripts = pre:rename_usb_config.py
|
||||||
extends = common:esp32
|
extends = common:esp32
|
||||||
board = adafruit_feather_esp32s3_nopsram
|
board = adafruit_feather_esp32s3_nopsram
|
||||||
build_flags = -DARDUINO_ADAFRUIT_FEATHER_ESP32S3_NOPSRAM
|
build_flags = -DARDUINO_ADAFRUIT_FEATHER_ESP32S3_NOPSRAM
|
||||||
|
board_build.partitions = tinyuf2-partitions-8MB.csv
|
||||||
extra_scripts = pre:rename_usb_config.py
|
extra_scripts = pre:rename_usb_config.py
|
||||||
|
|
||||||
; Adafruit Feather ESP32-S3 TFT
|
; Adafruit Feather ESP32-S3 TFT
|
||||||
|
|
@ -190,8 +251,8 @@ build_type = debug
|
||||||
debug_tool = esp-builtin
|
debug_tool = esp-builtin
|
||||||
board = adafruit_feather_esp32s3_tft
|
board = adafruit_feather_esp32s3_tft
|
||||||
build_flags = -DARDUINO_ADAFRUIT_FEATHER_ESP32S3_TFT -DBOARD_HAS_PSRAM
|
build_flags = -DARDUINO_ADAFRUIT_FEATHER_ESP32S3_TFT -DBOARD_HAS_PSRAM
|
||||||
;set partition to tinyuf2-partitions-4MB.csv as of idf 5.1
|
;set partition to tinyuf2-partitions-4MB-noota.csv as of CPY 10
|
||||||
board_build.partitions = tinyuf2-partitions-4MB.csv
|
board_build.partitions = tinyuf2-partitions-4MB-noota.csv
|
||||||
extra_scripts = pre:rename_usb_config.py
|
extra_scripts = pre:rename_usb_config.py
|
||||||
|
|
||||||
; Adafruit Feather ESP32-S3 Reverse TFT
|
; Adafruit Feather ESP32-S3 Reverse TFT
|
||||||
|
|
@ -199,8 +260,8 @@ extra_scripts = pre:rename_usb_config.py
|
||||||
extends = common:esp32
|
extends = common:esp32
|
||||||
board = adafruit_feather_esp32s3_reversetft
|
board = adafruit_feather_esp32s3_reversetft
|
||||||
build_flags = -DARDUINO_ADAFRUIT_FEATHER_ESP32S3_REVTFT -DBOARD_HAS_PSRAM
|
build_flags = -DARDUINO_ADAFRUIT_FEATHER_ESP32S3_REVTFT -DBOARD_HAS_PSRAM
|
||||||
;set partition to tinyuf2-partitions-4MB.csv as of idf 5.1
|
;set partition to tinyuf2-partitions-4MB-noota.csv as of CPY 10
|
||||||
board_build.partitions = tinyuf2-partitions-4MB.csv
|
board_build.partitions = tinyuf2-partitions-4MB-noota.csv
|
||||||
extra_scripts = pre:rename_usb_config.py
|
extra_scripts = pre:rename_usb_config.py
|
||||||
|
|
||||||
; Adafruit Magtag ESP32-S2
|
; Adafruit Magtag ESP32-S2
|
||||||
|
|
@ -208,8 +269,8 @@ extra_scripts = pre:rename_usb_config.py
|
||||||
extends = common:esp32
|
extends = common:esp32
|
||||||
board = adafruit_magtag29_esp32s2
|
board = adafruit_magtag29_esp32s2
|
||||||
build_flags = -DARDUINO_MAGTAG29_ESP32S2 -DBOARD_HAS_PSRAM
|
build_flags = -DARDUINO_MAGTAG29_ESP32S2 -DBOARD_HAS_PSRAM
|
||||||
;set partition to tinyuf2-partitions-4MB.csv as of idf 5.1
|
;set partition to tinyuf2-partitions-4MB-noota.csv as of CPY 10
|
||||||
board_build.partitions = tinyuf2-partitions-4MB.csv
|
board_build.partitions = tinyuf2-partitions-4MB-noota.csv
|
||||||
extra_scripts = pre:rename_usb_config.py
|
extra_scripts = pre:rename_usb_config.py
|
||||||
|
|
||||||
; Adafruit Metro ESP32-S2
|
; Adafruit Metro ESP32-S2
|
||||||
|
|
@ -217,8 +278,59 @@ extra_scripts = pre:rename_usb_config.py
|
||||||
extends = common:esp32
|
extends = common:esp32
|
||||||
board = adafruit_metro_esp32s2
|
board = adafruit_metro_esp32s2
|
||||||
build_flags = -DARDUINO_METRO_ESP32S2 -DBOARD_HAS_PSRAM
|
build_flags = -DARDUINO_METRO_ESP32S2 -DBOARD_HAS_PSRAM
|
||||||
;set partition to tinyuf2-partitions-4MB.csv as of idf 5.1
|
;set partition to tinyuf2-partitions-4MB-noota.csv as of CPY 10
|
||||||
board_build.partitions = tinyuf2-partitions-4MB.csv
|
board_build.partitions = tinyuf2-partitions-4MB-noota.csv
|
||||||
|
extra_scripts = pre:rename_usb_config.py
|
||||||
|
; debug_tool = jlink
|
||||||
|
; upload_protocol = jlink
|
||||||
|
; debug_init_break = tbreak WipperSnapper_I2C_Driver_MLX90632D
|
||||||
|
|
||||||
|
; Adafruit Metro ESP32-S3
|
||||||
|
[env:adafruit_metro_esp32s3]
|
||||||
|
extends = common:esp32
|
||||||
|
board = adafruit_metro_esp32s3
|
||||||
|
build_flags = -DARDUINO_METRO_ESP32S3 -DBOARD_HAS_PSRAM
|
||||||
|
;set partition to tinyuf2-partitions-16MB.csv as of idf 5.1
|
||||||
|
board_build.partitions = tinyuf2-partitions-16MB.csv
|
||||||
|
extra_scripts = pre:rename_usb_config.py
|
||||||
|
debug_tool = jlink
|
||||||
|
|
||||||
|
; Adafruit Funhouse ESP32-S2
|
||||||
|
[env:adafruit_funhouse_esp32s2]
|
||||||
|
extends = common:esp32
|
||||||
|
board = adafruit_funhouse_esp32s2
|
||||||
|
build_flags = -DARDUINO_FUNHOUSE -DBOARD_HAS_PSRAM
|
||||||
|
;set partition to tinyuf2-partitions-4MB-noota.csv as of CPY 10
|
||||||
|
board_build.partitions = tinyuf2-partitions-4MB-noota.csv
|
||||||
|
extra_scripts = pre:rename_usb_config.py
|
||||||
|
|
||||||
|
; Adafruit Funhouse ESP32-S2
|
||||||
|
[env:adafruit_funhouse_esp32s2_debug]
|
||||||
|
extends = common:esp32
|
||||||
|
board = adafruit_funhouse_esp32s2
|
||||||
|
;lib_extra_dirs =
|
||||||
|
build_type = debug
|
||||||
|
build_flags =
|
||||||
|
-DARDUINO_FUNHOUSE
|
||||||
|
-DBOARD_HAS_PSRAM
|
||||||
|
-DCFG_TUSB_DEBUG=1
|
||||||
|
-DDEBUG=1
|
||||||
|
-DESP_LOG_LEVEL=ESP_LOG_VERBOSE
|
||||||
|
-DARDUINO_CORE_DEBUG_LEVEL=5
|
||||||
|
-DCORE_DEBUG_LEVEL=5
|
||||||
|
-DARDUHAL_LOG_LEVEL=5
|
||||||
|
; USB Configuration
|
||||||
|
; Uncomment if USB CDC on boot is needed
|
||||||
|
; -DARDUINO_USB_CDC_ON_BOOT=1
|
||||||
|
; -DARDUINO_USB_MODE=0 ; 0 for CDC + TinyUSB, 1 for Hardware CDC + JTAG
|
||||||
|
; LVGL Debugging
|
||||||
|
-DLV_USE_DEBUG=1
|
||||||
|
-DLV_USE_LOG=1
|
||||||
|
-DLV_LOG_PRINTF=1
|
||||||
|
-DLV_LOG_COLOR=1
|
||||||
|
-DLV_LOG_LEVEL=LV_LOG_LEVEL_TRACE
|
||||||
|
;set partition to tinyuf2-partitions-4MB-noota.csv as of CPY 10
|
||||||
|
board_build.partitions = tinyuf2-partitions-4MB-noota.csv
|
||||||
extra_scripts = pre:rename_usb_config.py
|
extra_scripts = pre:rename_usb_config.py
|
||||||
|
|
||||||
; Adafruit QT Py ESP32 Pico
|
; Adafruit QT Py ESP32 Pico
|
||||||
|
|
@ -230,6 +342,22 @@ board_build.filesystem = littlefs
|
||||||
build_type = debug
|
build_type = debug
|
||||||
build_flags = -DARDUINO_ADAFRUIT_QTPY_ESP32
|
build_flags = -DARDUINO_ADAFRUIT_QTPY_ESP32
|
||||||
|
|
||||||
|
; Adafruit Mini Sparkle Motion
|
||||||
|
[env:adafruit_sparklemotionmini_esp32]
|
||||||
|
extends = common:esp32
|
||||||
|
board = adafruit_sparklemotionmini_esp32
|
||||||
|
board_build.partitions = min_spiffs.csv
|
||||||
|
board_build.filesystem = littlefs
|
||||||
|
build_flags = -DARDUINO_SPARKLEMOTIONMINI_ESP32
|
||||||
|
|
||||||
|
; Adafruit Sparkle Motion Stick
|
||||||
|
[env:adafruit_sparklemotionstick_esp32]
|
||||||
|
extends = common:esp32
|
||||||
|
board = adafruit_sparklemotionstick_esp32
|
||||||
|
board_build.partitions = min_spiffs.csv
|
||||||
|
board_build.filesystem = littlefs
|
||||||
|
build_flags = -DARDUINO_SPARKLEMOTIONSTICK_ESP32
|
||||||
|
|
||||||
; Adafruit QT Py ESP32-C3
|
; Adafruit QT Py ESP32-C3
|
||||||
[env:adafruit_qtpy_esp32c3]
|
[env:adafruit_qtpy_esp32c3]
|
||||||
extends = common:esp32
|
extends = common:esp32
|
||||||
|
|
@ -243,8 +371,8 @@ board_build.partitions = min_spiffs.csv
|
||||||
extends = common:esp32
|
extends = common:esp32
|
||||||
board = adafruit_qtpy_esp32s2
|
board = adafruit_qtpy_esp32s2
|
||||||
build_flags = -DARDUINO_ADAFRUIT_QTPY_ESP32S2 -DBOARD_HAS_PSRAM
|
build_flags = -DARDUINO_ADAFRUIT_QTPY_ESP32S2 -DBOARD_HAS_PSRAM
|
||||||
;set partition to tinyuf2-partitions-4MB.csv as of idf 5.1
|
;set partition to tinyuf2-partitions-4MB-noota.csv as of CPY 10
|
||||||
board_build.partitions = tinyuf2-partitions-4MB.csv
|
board_build.partitions = tinyuf2-partitions-4MB-noota.csv
|
||||||
extra_scripts = pre:rename_usb_config.py
|
extra_scripts = pre:rename_usb_config.py
|
||||||
|
|
||||||
; Adafruit QT Py ESP32-S3 NO PSRAM
|
; Adafruit QT Py ESP32-S3 NO PSRAM
|
||||||
|
|
@ -252,36 +380,109 @@ extra_scripts = pre:rename_usb_config.py
|
||||||
extends = common:esp32
|
extends = common:esp32
|
||||||
board = adafruit_qtpy_esp32s3_nopsram
|
board = adafruit_qtpy_esp32s3_nopsram
|
||||||
build_flags = -DARDUINO_ADAFRUIT_QTPY_ESP32S3_NOPSRAM
|
build_flags = -DARDUINO_ADAFRUIT_QTPY_ESP32S3_NOPSRAM
|
||||||
|
board_build.partitions = tinyuf2-partitions-8MB.csv
|
||||||
|
extra_scripts = pre:rename_usb_config.py
|
||||||
|
|
||||||
|
; Adafruit QT Py ESP32-S3 with PSRAM
|
||||||
|
[env:adafruit_qtpy_esp32s3_with_psram]
|
||||||
|
extends = common:esp32
|
||||||
|
board = adafruit_qtpy_esp32s3_n4r2
|
||||||
|
build_flags = -DARDUINO_ADAFRUIT_QTPY_ESP32S3_N4R2 -DBOARD_HAS_PSRAM
|
||||||
|
;set partition to tinyuf2-partitions-4MB-noota.csv as of CPY 10
|
||||||
|
board_build.partitions = tinyuf2-partitions-4MB-noota.csv
|
||||||
|
extra_scripts = pre:rename_usb_config.py
|
||||||
|
|
||||||
|
[env:adafruit_qtpy_esp32s3_with_psram_debug]
|
||||||
|
extends = common:esp32
|
||||||
|
board = adafruit_qtpy_esp32s3_n4r2
|
||||||
|
;set partition to tinyuf2-partitions-4MB-noota.csv as of CPY 10
|
||||||
|
board_build.partitions = tinyuf2-partitions-4MB-noota.csv
|
||||||
|
build_type = debug
|
||||||
|
build_flags =
|
||||||
|
-DARDUINO_ADAFRUIT_QTPY_ESP32S3_N4R2
|
||||||
|
-DBOARD_HAS_PSRAM
|
||||||
|
-DCFG_TUSB_DEBUG=1
|
||||||
|
-DNDEBUG=1
|
||||||
|
-DDEBUG=1
|
||||||
|
-DESP_LOG_LEVEL=5
|
||||||
|
-DARDUINO_CORE_DEBUG_LEVEL=5
|
||||||
|
-DARDUINO_DEBUG_LEVEL=5
|
||||||
|
# -DARDUINO_DEBUG_OUTPUT=Serial
|
||||||
|
# -DARDUINO_DEBUG_BAUD=115200
|
||||||
|
-DARDUINO_USB_CDC_ON_BOOT=1
|
||||||
|
; cdc + usb otg (tinyusb)
|
||||||
|
-DARDUINO_USB_MODE=0
|
||||||
|
; hwcdc jtag
|
||||||
|
;-DARDUINO_USB_MODE=1
|
||||||
|
-DARDUINO_LOG_LEVEL=5
|
||||||
|
-DCORE_DEBUG_LEVEL=5
|
||||||
|
-DARDUHAL_LOG_LEVEL=5
|
||||||
extra_scripts = pre:rename_usb_config.py
|
extra_scripts = pre:rename_usb_config.py
|
||||||
|
|
||||||
; Espressif ESP32-S3 NO PSRAM espressif_esp32s3_devkitc_1_n8
|
; Espressif ESP32-S3 NO PSRAM espressif_esp32s3_devkitc_1_n8
|
||||||
[env:espressif_esp32s3_devkitc_1_n8]
|
[env:espressif_esp32s3_devkitc_1_n8]
|
||||||
extends = common:esp32
|
extends = common:esp32
|
||||||
board = esp32-s3-devkitc-1
|
board = esp32-s3-devkitc-1
|
||||||
|
build_flags = -DARDUINO_ESPRESSIF_ESP32S3_DEVKITC_1_N8 -DUSE_TINYUSB=1 -DARDUINO_USB_MODE=0 -DARDUINO_USB_CDC_ON_BOOT=1
|
||||||
|
board_build.partitions = noota_ffat.csv
|
||||||
|
; board_build.partitions = tinyuf2-partitions-8MB.csv
|
||||||
|
; extra_scripts = pre:rename_usb_config.py
|
||||||
|
|
||||||
|
; Espressif ESP32-S3 NO PSRAM espressif_esp32s3_devkitc_1_n8 (DEBUG)
|
||||||
|
[env:espressif_esp32s3_devkitc_1_n8_debug]
|
||||||
|
extends = common:esp32
|
||||||
|
board = esp32-s3-devkitc-1
|
||||||
build_type = debug
|
build_type = debug
|
||||||
build_flags =
|
build_flags =
|
||||||
-DUSE_TINYUSB=1
|
-DUSE_TINYUSB=1
|
||||||
|
-DARDUINO_USB_MODE=0
|
||||||
|
-DARDUINO_USB_CDC_ON_BOOT=1
|
||||||
-DARDUINO_ESPRESSIF_ESP32S3_DEVKITC_1_N8
|
-DARDUINO_ESPRESSIF_ESP32S3_DEVKITC_1_N8
|
||||||
-DNDEBUG=1
|
|
||||||
-DDEBUG=1
|
-DDEBUG=1
|
||||||
-DESP_LOG_LEVEL=5
|
-DESP_LOG_LEVEL=5
|
||||||
-DARDUINO_CORE_DEBUG_LEVEL=5
|
-DARDUINO_CORE_LOG_LEVEL=5
|
||||||
-DARDUINO_DEBUG_LEVEL=5
|
|
||||||
; -DARDUINO_DEBUG_OUTPUT=Serial
|
|
||||||
; -DARDUINO_DEBUG_BAUD=115200
|
|
||||||
-DARDUINO_LOG_LEVEL=5
|
-DARDUINO_LOG_LEVEL=5
|
||||||
-DCORE_DEBUG_LEVEL=5
|
|
||||||
-DARDUHAL_LOG_LEVEL=5
|
-DARDUHAL_LOG_LEVEL=5
|
||||||
|
; board_build.partitions = tinyuf2-partitions-8MB.csv
|
||||||
|
board_build.partitions = noota_ffat.csv
|
||||||
|
; extra_scripts = pre:rename_usb_config.py
|
||||||
|
|
||||||
|
; Seeed Studio ESP32 boards:
|
||||||
|
|
||||||
|
; Xiao ESP32S3 N8R8 (SENSE)
|
||||||
|
[env:seeed-xiao_esp32s3_n8r8]
|
||||||
|
extends = common:esp32
|
||||||
|
board = seeed_xiao_esp32s3
|
||||||
|
build_flags = -DARDUINO_XIAO_ESP32S3 -DUSE_TINYUSB -DBOARD_HAS_PSRAM -DARDUINO_USB_CDC_ON_BOOT=1 -DARDUINO_USB_MODE=0
|
||||||
board_build.partitions = tinyuf2-partitions-8MB.csv
|
board_build.partitions = tinyuf2-partitions-8MB.csv
|
||||||
extra_scripts = pre:rename_usb_config.py
|
extra_scripts = pre:rename_usb_config.py
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
; ESP8266 Boards
|
; ESP8266 Boards
|
||||||
|
|
||||||
; Adafruit Feather HUZZAH ESP8266
|
; Adafruit Feather HUZZAH ESP8266
|
||||||
[env:huzzah]
|
[env:huzzah]
|
||||||
extends=common:esp8266
|
extends=common:esp8266
|
||||||
board = huzzah
|
board = huzzah
|
||||||
build_flags = -DARDUINO_ESP8266_ADAFRUIT_HUZZAH
|
board_build.f_cpu = 80000000L
|
||||||
|
; Arduino CLI uses this from adafruit_ci#ci-wippersnapper
|
||||||
|
; esp8266:esp8266:huzzah:xtal=80,vt=flash,exception=disabled,stacksmash=disabled,ssl=all,mmu=3232,non32xfer=fast,eesz=4M2M,ip=lm2f,dbg=Disabled,lvl=None____,wipe=none,baud=115200
|
||||||
|
build_flags =
|
||||||
|
-Wl,--gc-sections
|
||||||
|
-Wl,-Map=output.map
|
||||||
|
-DARDUINO_ESP8266_ADAFRUIT_HUZZAH
|
||||||
|
-DDEBUG_ESP_PORT=Serial
|
||||||
|
-DVTABLES_IN_FLASH
|
||||||
|
-DNO_EXCEPTIONS
|
||||||
|
-DNO_STACK_SMASH_PROTECTION
|
||||||
|
-DSSL_ALL
|
||||||
|
-DMMU_3232
|
||||||
|
-DNON32XFER_FAST
|
||||||
|
-DDEBUG_DISABLED
|
||||||
|
-DDEBUG_LEVEL_NONE
|
||||||
|
board_build.eesz=4M2M
|
||||||
board_build.filesystem = littlefs
|
board_build.filesystem = littlefs
|
||||||
upload_port = /dev/cu.SLAB_USBtoUART
|
upload_port = /dev/cu.SLAB_USBtoUART
|
||||||
|
|
||||||
|
|
@ -291,8 +492,9 @@ upload_port = /dev/cu.SLAB_USBtoUART
|
||||||
[env:adafruit_pyportal_m4]
|
[env:adafruit_pyportal_m4]
|
||||||
extends = common:atsamd
|
extends = common:atsamd
|
||||||
board = adafruit_pyportal_m4
|
board = adafruit_pyportal_m4
|
||||||
build_flags = -DUSE_TINYUSB=1
|
build_flags = -DUSE_TINYUSB
|
||||||
-DADAFRUIT_PYPORTAL
|
-DADAFRUIT_PYPORTAL
|
||||||
|
extra_scripts = pre:rename_usb_config.py
|
||||||
|
|
||||||
; Adafruit PyPortal M4 Titano
|
; Adafruit PyPortal M4 Titano
|
||||||
[env:adafruit_pyportal_m4_titano]
|
[env:adafruit_pyportal_m4_titano]
|
||||||
|
|
@ -308,13 +510,13 @@ monitor_port = auto
|
||||||
; debug_init_break = tbreak clearConfiguration
|
; debug_init_break = tbreak clearConfiguration
|
||||||
lib_ignore = USBHost
|
lib_ignore = USBHost
|
||||||
build_flags = -DUSE_TINYUSB
|
build_flags = -DUSE_TINYUSB
|
||||||
-D__SAMD51J20A__
|
-D__SAMD51J20A__
|
||||||
-DCRYSTALLESS
|
-DCRYSTALLESS
|
||||||
-DADAFRUIT_PYPORTAL_M4_TITANO
|
-DADAFRUIT_PYPORTAL_M4_TITANO
|
||||||
-D__SAMD51__
|
-D__SAMD51__
|
||||||
-D__FPU_PRESENT
|
-D__FPU_PRESENT
|
||||||
-DARM_MATH_CM4
|
-DARM_MATH_CM4
|
||||||
-mfloat-abi=hard
|
-mfloat-abi=hard
|
||||||
-mfpu=fpv4-sp-d16
|
-mfpu=fpv4-sp-d16
|
||||||
-DCORE_DEBUG_LEVEL=5
|
-DCORE_DEBUG_LEVEL=5
|
||||||
-DARDUINO_USB_CDC_ON_BOOT=1
|
-DARDUINO_USB_CDC_ON_BOOT=1
|
||||||
|
|
@ -336,17 +538,39 @@ build_flags = -DUSE_TINYUSB
|
||||||
[env:adafruit_metro_m4_airliftlite]
|
[env:adafruit_metro_m4_airliftlite]
|
||||||
extends = common:atsamd
|
extends = common:atsamd
|
||||||
board = adafruit_metro_m4_airliftlite
|
board = adafruit_metro_m4_airliftlite
|
||||||
build_flags = -DUSE_TINYUSB=1
|
build_flags = -DUSE_TINYUSB
|
||||||
-DADAFRUIT_METRO_M4_AIRLIFT_LITE
|
-DADAFRUIT_METRO_M4_AIRLIFT_LITE
|
||||||
|
; extra_scripts = pre:rename_usb_config.py
|
||||||
upload_port = /dev/cu.usbmodem1201
|
upload_port = /dev/cu.usbmodem1201
|
||||||
|
|
||||||
|
; DFRobot Beetle ESP32-C3
|
||||||
|
[env:dfrobot_beetle_esp32c3]
|
||||||
|
extends = common:esp32
|
||||||
|
board = dfrobot_beetle_esp32c3
|
||||||
|
; Note: this board reuses a generic preprocessor define
|
||||||
|
; espressif/arduino-esp32@fcd4799c6de6eb5a5a8eba94818adf770238ecc0
|
||||||
|
; rather than creating one unique to the device.
|
||||||
|
build_flags = -DARDUINO_ESP32C3_DEV
|
||||||
|
board_build.filesystem = littlefs
|
||||||
|
board_build.partitions = min_spiffs.csv
|
||||||
|
|
||||||
|
|
||||||
[env:raspberypi_picow]
|
[env:raspberypi_picow]
|
||||||
extends = common:rp2040
|
extends = common:arduinopico
|
||||||
|
board = rpipicow
|
||||||
|
build_flags =
|
||||||
|
-DUSE_TINYUSB
|
||||||
|
|
||||||
|
[env:raspberypi_picow_debug_port_only]
|
||||||
|
extends = common:arduinopico
|
||||||
|
board = rpipicow
|
||||||
|
build_flags =
|
||||||
|
-DUSE_TINYUSB
|
||||||
|
-DDEBUG_RP2040_PORT=Serial
|
||||||
|
|
||||||
[env:raspberypi_picow_debug]
|
[env:raspberypi_picow_debug]
|
||||||
extends = common:rp2040
|
extends = common:arduinopico
|
||||||
platform = https://github.com/maxgerhardt/platform-raspberrypi.git
|
; platform = https://github.com/maxgerhardt/platform-raspberrypi.git
|
||||||
; platform_packages =
|
; platform_packages =
|
||||||
; framework-arduinopico @ symlink:///Users/tyeth/Projects/arduino-pico
|
; framework-arduinopico @ symlink:///Users/tyeth/Projects/arduino-pico
|
||||||
; framework-arduinopico@https://github.com/earlephilhower/arduino-pico.git#master
|
; framework-arduinopico@https://github.com/earlephilhower/arduino-pico.git#master
|
||||||
|
|
@ -367,7 +591,7 @@ build_flags =
|
||||||
-DDEBUG_RP2040_CORE
|
-DDEBUG_RP2040_CORE
|
||||||
-DDEBUG_RP2040_WIFI
|
-DDEBUG_RP2040_WIFI
|
||||||
-DNDEBUG
|
-DNDEBUG
|
||||||
-DLWIP_DEBUG
|
-DLWIP_DEBUG=1
|
||||||
-DDEBUG_RP2040_PORT=Serial1
|
-DDEBUG_RP2040_PORT=Serial1
|
||||||
-DDEBUG_RP2040_UART_1
|
-DDEBUG_RP2040_UART_1
|
||||||
-DDEBUG_RP2040_UART=1
|
-DDEBUG_RP2040_UART=1
|
||||||
|
|
@ -384,4 +608,64 @@ build_flags =
|
||||||
; ; No USB stack
|
; ; No USB stack
|
||||||
; build_flags = -DPIO_FRAMEWORK_ARDUINO_NO_USB
|
; build_flags = -DPIO_FRAMEWORK_ARDUINO_NO_USB
|
||||||
; -DPIO_FRAMEWORK_ARDUINO_ENABLE_IPV6
|
; -DPIO_FRAMEWORK_ARDUINO_ENABLE_IPV6
|
||||||
|
|
||||||
|
|
||||||
|
[env:raspberypi_pico2w]
|
||||||
|
extends = common:arduinopico
|
||||||
|
platform = https://github.com/maxgerhardt/platform-raspberrypi.git#develop
|
||||||
|
platform_packages =
|
||||||
|
framework-arduinopico@https://github.com/earlephilhower/arduino-pico.git
|
||||||
|
board = rpipico2w
|
||||||
|
build_flags =
|
||||||
|
-DWIFICC=CYW43_COUNTRY_UK
|
||||||
|
-DUSE_TINYUSB
|
||||||
|
; -DARDUINO_ARCH_RP2040
|
||||||
|
; -DUSBD_MAX_POWER_MA=250
|
||||||
|
; -DPICO_CYW43_SUPPORTED=1
|
||||||
|
|
||||||
|
[env:raspberypi_pico2w_debug]
|
||||||
|
extends = common:arduinopico
|
||||||
|
board = rpipico2w
|
||||||
|
build_type = debug
|
||||||
|
framework = arduino
|
||||||
|
debug_tool = cmsis-dap
|
||||||
|
upload_protocol = cmsis-dap
|
||||||
|
; board can use both Arduino cores -- we select Arduino-Pico here
|
||||||
|
board_build.core = earlephilhower
|
||||||
|
board_build.filesystem_size = 0.5m
|
||||||
|
debug_init_break = tbreak runNetFSM
|
||||||
|
build_flags =
|
||||||
|
; -UARDUINO
|
||||||
|
; -DPICO_BUILD
|
||||||
|
-DARDUINO_ARCH_RP2040
|
||||||
|
-DUSBD_MAX_POWER_MA=250
|
||||||
|
-DPICO_CYW43_SUPPORTED=1
|
||||||
|
-DWIFICC=CYW43_COUNTRY_UK
|
||||||
|
; -DDEBUG
|
||||||
|
; -DDEBUG_RP2040_WIRE
|
||||||
|
; -DDEBUG_RP2040_SPI
|
||||||
|
; -DDEBUG_RP2040_CORE
|
||||||
|
; -DDEBUG_RP2040_WIFI
|
||||||
|
; -DNDEBUG
|
||||||
|
; -DLWIP_DEBUG
|
||||||
|
; -DDEBUG_RP2040_PORT=Serial1
|
||||||
|
; -DDEBUG_RP2040_UART_1
|
||||||
|
; -DDEBUG_RP2040_UART=1
|
||||||
|
-Og
|
||||||
|
; Enable debug stack protection
|
||||||
|
-fstack-protector
|
||||||
|
; Enable Exceptions
|
||||||
|
-DPIO_FRAMEWORK_ARDUINO_ENABLE_EXCEPTIONS
|
||||||
|
; Enable RTTI
|
||||||
|
-DPIO_FRAMEWORK_ARDUINO_ENABLE_RTTI
|
||||||
|
; ; Enable default USB Stack of Pico SDK USB Stack with none of below usb options
|
||||||
|
; Adafruit TinyUSB
|
||||||
|
-DUSE_TINYUSB
|
||||||
|
; ; No USB stack
|
||||||
|
; build_flags = -DPIO_FRAMEWORK_ARDUINO_NO_USB
|
||||||
|
; -DPIO_FRAMEWORK_ARDUINO_ENABLE_IPV6
|
||||||
|
|
||||||
|
[env:adafruit_fruitjam]
|
||||||
|
board = adafruit_fruitjam
|
||||||
|
lib_ignore = WiFi, WiFi101, Adafruit Zero DMA Library
|
||||||
|
build_flags = -DUSE_TINYUSB -DADAFRUIT_FRUITJAM_RP2350
|
||||||
|
|
@ -108,7 +108,9 @@ void Wippersnapper::provision() {
|
||||||
#ifdef USE_DISPLAY
|
#ifdef USE_DISPLAY
|
||||||
// Initialize the display
|
// Initialize the display
|
||||||
displayConfig config;
|
displayConfig config;
|
||||||
WS._fileSystem->parseDisplayConfig(config);
|
if (!WS._fileSystem->parseDisplayConfig(config)) {
|
||||||
|
WS._fileSystem->parseDisplayConfig(config, true);
|
||||||
|
}
|
||||||
WS._display = new ws_display_driver(config);
|
WS._display = new ws_display_driver(config);
|
||||||
// Begin display
|
// Begin display
|
||||||
if (!WS._display->begin()) {
|
if (!WS._display->begin()) {
|
||||||
|
|
@ -174,7 +176,7 @@ void Wippersnapper::_disconnect() {
|
||||||
|
|
||||||
/****************************************************************************/
|
/****************************************************************************/
|
||||||
/*!
|
/*!
|
||||||
@brief Sets the network interface's unique identifer, typically the
|
@brief Sets the network interface's unique identifier, typically the
|
||||||
MAC address.
|
MAC address.
|
||||||
*/
|
*/
|
||||||
/****************************************************************************/
|
/****************************************************************************/
|
||||||
|
|
@ -254,7 +256,7 @@ bool Wippersnapper::check_valid_ssid() {
|
||||||
/*!
|
/*!
|
||||||
@brief Configures the device's Adafruit IO credentials. This method
|
@brief Configures the device's Adafruit IO credentials. This method
|
||||||
should be used only if filesystem-backed provisioning is
|
should be used only if filesystem-backed provisioning is
|
||||||
not avaliable.
|
not available.
|
||||||
*/
|
*/
|
||||||
/****************************************************************************/
|
/****************************************************************************/
|
||||||
void Wippersnapper::set_user_key() {
|
void Wippersnapper::set_user_key() {
|
||||||
|
|
@ -491,7 +493,7 @@ bool cbSignalMsg(pb_istream_t *stream, const pb_field_t *field, void **arg) {
|
||||||
/**************************************************************************/
|
/**************************************************************************/
|
||||||
/*!
|
/*!
|
||||||
@brief Decodes a signal buffer protobuf message.
|
@brief Decodes a signal buffer protobuf message.
|
||||||
NOTE: Should be executed in-order after a new _buffer is recieved.
|
NOTE: Should be executed in-order after a new _buffer is received.
|
||||||
@param encodedSignalMsg
|
@param encodedSignalMsg
|
||||||
Encoded signal message.
|
Encoded signal message.
|
||||||
@return true if successfully decoded signal message, false otherwise.
|
@return true if successfully decoded signal message, false otherwise.
|
||||||
|
|
@ -871,6 +873,28 @@ bool cbDecodeSignalRequestI2C(pb_istream_t *stream, const pb_field_t *field,
|
||||||
if (!encodeI2CResponse(&msgi2cResponse)) {
|
if (!encodeI2CResponse(&msgi2cResponse)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
} else if (field->tag ==
|
||||||
|
wippersnapper_signal_v1_I2CRequest_req_i2c_device_out_write_tag) {
|
||||||
|
WS_DEBUG_PRINTLN("[app] I2C Device Output Write");
|
||||||
|
// Decode stream into an I2CDeviceDeinitRequest
|
||||||
|
wippersnapper_i2c_v1_I2CDeviceOutputWrite msgDeviceWrite =
|
||||||
|
wippersnapper_i2c_v1_I2CDeviceOutputWrite_init_zero;
|
||||||
|
// Decode stream into struct, msgI2CDeviceDeinitRequest
|
||||||
|
if (!ws_pb_decode(stream, wippersnapper_i2c_v1_I2CDeviceOutputWrite_fields,
|
||||||
|
&msgDeviceWrite)) {
|
||||||
|
WS_DEBUG_PRINTLN(
|
||||||
|
"[app] ERROR: Failed decoding I2CDeviceOutputWrite message.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!WS._i2cPort0->Handle_I2cDeviceOutputWrite(&msgDeviceWrite)) {
|
||||||
|
WS_DEBUG_PRINTLN("[app] ERROR: Failed to write to I2C output device.");
|
||||||
|
return false; // fail out if we can't decode, we don't have a response to
|
||||||
|
// publish
|
||||||
|
}
|
||||||
|
WS_DEBUG_PRINTLN("[app] I2C Device Output Write Done");
|
||||||
|
return true; // we successfully wrote to the device, this subtype has no
|
||||||
|
// response to publish to IO
|
||||||
} else {
|
} else {
|
||||||
WS_DEBUG_PRINTLN("ERROR: Undefined I2C message tag");
|
WS_DEBUG_PRINTLN("ERROR: Undefined I2C message tag");
|
||||||
return false; // fail out, we didn't encode anything to publish
|
return false; // fail out, we didn't encode anything to publish
|
||||||
|
|
@ -1065,7 +1089,7 @@ bool cbDecodeServoMsg(pb_istream_t *stream, const pb_field_t *field,
|
||||||
|
|
||||||
/**************************************************************************/
|
/**************************************************************************/
|
||||||
/*!
|
/*!
|
||||||
@brief Called when the device recieves a new message from the
|
@brief Called when the device receives a new message from the
|
||||||
/servo/ topic.
|
/servo/ topic.
|
||||||
@param data
|
@param data
|
||||||
Incoming data from MQTT broker.
|
Incoming data from MQTT broker.
|
||||||
|
|
@ -1191,7 +1215,7 @@ bool cbPWMDecodeMsg(pb_istream_t *stream, const pb_field_t *field, void **arg) {
|
||||||
#endif
|
#endif
|
||||||
return false; // fail out if we can't decode the request
|
return false; // fail out if we can't decode the request
|
||||||
}
|
}
|
||||||
// execute PWM pin detatch request
|
// execute PWM pin detach request
|
||||||
char *pwmPin = msgPWMDetachRequest.pin + 1;
|
char *pwmPin = msgPWMDetachRequest.pin + 1;
|
||||||
WS._pwmComponent->detach(atoi(pwmPin));
|
WS._pwmComponent->detach(atoi(pwmPin));
|
||||||
|
|
||||||
|
|
@ -1274,7 +1298,7 @@ bool cbPWMDecodeMsg(pb_istream_t *stream, const pb_field_t *field, void **arg) {
|
||||||
|
|
||||||
/**************************************************************************/
|
/**************************************************************************/
|
||||||
/*!
|
/*!
|
||||||
@brief Called when the device recieves a new message from the
|
@brief Called when the device receives a new message from the
|
||||||
/pwm/ topic.
|
/pwm/ topic.
|
||||||
@param data
|
@param data
|
||||||
Incoming data from MQTT broker.
|
Incoming data from MQTT broker.
|
||||||
|
|
@ -1477,7 +1501,7 @@ bool cbDecodePixelsMsg(pb_istream_t *stream, const pb_field_t *field,
|
||||||
|
|
||||||
/**************************************************************************/
|
/**************************************************************************/
|
||||||
/*!
|
/*!
|
||||||
@brief Called when the device recieves a new message from the
|
@brief Called when the device receives a new message from the
|
||||||
/pixels/ topic.
|
/pixels/ topic.
|
||||||
@param data
|
@param data
|
||||||
Incoming data from MQTT broker.
|
Incoming data from MQTT broker.
|
||||||
|
|
@ -2494,14 +2518,27 @@ void Wippersnapper::runNetFSM() {
|
||||||
@brief Prints an error to the serial and halts the hardware until
|
@brief Prints an error to the serial and halts the hardware until
|
||||||
the WDT bites.
|
the WDT bites.
|
||||||
@param error
|
@param error
|
||||||
The desired error to print to serial.
|
The error to print to serial.
|
||||||
@param ledStatusColor
|
@param ledStatusColor
|
||||||
The desired color to blink.
|
The color to blink.
|
||||||
|
@param seconds_until_reboot
|
||||||
|
The amount of time to wait before rebooting.
|
||||||
*/
|
*/
|
||||||
/**************************************************************************/
|
/**************************************************************************/
|
||||||
void Wippersnapper::haltError(String error, ws_led_status_t ledStatusColor) {
|
void Wippersnapper::haltError(String error, ws_led_status_t ledStatusColor,
|
||||||
for (;;) {
|
int seconds_until_reboot) {
|
||||||
WS_DEBUG_PRINT("ERROR [WDT RESET]: ");
|
#ifdef ARDUINO_ARCH_ESP8266
|
||||||
|
int wdt_timeout_ms = 3200;
|
||||||
|
#else
|
||||||
|
int wdt_timeout_ms = 5000;
|
||||||
|
#endif
|
||||||
|
int seconds_until_wdt_enable =
|
||||||
|
seconds_until_reboot - (int)(wdt_timeout_ms / 1000);
|
||||||
|
|
||||||
|
for (int i = 0;; i++) {
|
||||||
|
WS_DEBUG_PRINT("ERROR [WDT RESET IN ");
|
||||||
|
WS_DEBUG_PRINT(seconds_until_reboot - i);
|
||||||
|
WS_DEBUG_PRINTLN("]: ");
|
||||||
WS_DEBUG_PRINTLN(error);
|
WS_DEBUG_PRINTLN(error);
|
||||||
// let the WDT fail out and reset!
|
// let the WDT fail out and reset!
|
||||||
statusLEDSolid(ledStatusColor);
|
statusLEDSolid(ledStatusColor);
|
||||||
|
|
@ -2512,6 +2549,12 @@ void Wippersnapper::haltError(String error, ws_led_status_t ledStatusColor) {
|
||||||
// hardware and software watchdog timers, delayMicroseconds does not.
|
// hardware and software watchdog timers, delayMicroseconds does not.
|
||||||
delayMicroseconds(1000000);
|
delayMicroseconds(1000000);
|
||||||
#endif
|
#endif
|
||||||
|
if (i < seconds_until_wdt_enable) {
|
||||||
|
yield();
|
||||||
|
WS.feedWDT(); // feed the WDT for the first X-5 seconds
|
||||||
|
} else if (i == seconds_until_reboot) {
|
||||||
|
WS.enableWDT(wdt_timeout_ms);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2693,7 +2736,7 @@ void print_reset_reason(int reason) {
|
||||||
break; /**<13, RTC Watch dog Reset CPU*/
|
break; /**<13, RTC Watch dog Reset CPU*/
|
||||||
case 14:
|
case 14:
|
||||||
WS_DEBUG_PRINTLN("EXT_CPU_RESET");
|
WS_DEBUG_PRINTLN("EXT_CPU_RESET");
|
||||||
break; /**<14, for APP CPU, reseted by PRO CPU*/
|
break; /**<14, for APP CPU, reset by PRO CPU*/
|
||||||
case 15:
|
case 15:
|
||||||
WS_DEBUG_PRINTLN("RTCWDT_BROWN_OUT_RESET");
|
WS_DEBUG_PRINTLN("RTCWDT_BROWN_OUT_RESET");
|
||||||
break; /**<15, Reset when the vdd voltage is not stable*/
|
break; /**<15, Reset when the vdd voltage is not stable*/
|
||||||
|
|
@ -2748,15 +2791,12 @@ void Wippersnapper::connect() {
|
||||||
// Dump device info to the serial monitor
|
// Dump device info to the serial monitor
|
||||||
printDeviceInfo();
|
printDeviceInfo();
|
||||||
|
|
||||||
// enable global WDT
|
|
||||||
WS.enableWDT(WS_WDT_TIMEOUT);
|
|
||||||
|
|
||||||
// Generate device identifier
|
// Generate device identifier
|
||||||
if (!generateDeviceUID()) {
|
if (!generateDeviceUID()) {
|
||||||
haltError("Unable to generate Device UID");
|
haltError("Unable to generate Device UID");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize MQTT client with device identifer
|
// Initialize MQTT client with device identifier
|
||||||
setupMQTTClient(_device_uid);
|
setupMQTTClient(_device_uid);
|
||||||
|
|
||||||
WS_DEBUG_PRINTLN("Generating device's MQTT topics...");
|
WS_DEBUG_PRINTLN("Generating device's MQTT topics...");
|
||||||
|
|
@ -2772,7 +2812,9 @@ void Wippersnapper::connect() {
|
||||||
WS_DEBUG_PRINTLN("Running Network FSM...");
|
WS_DEBUG_PRINTLN("Running Network FSM...");
|
||||||
// Run the network fsm
|
// Run the network fsm
|
||||||
runNetFSM();
|
runNetFSM();
|
||||||
WS.feedWDT();
|
|
||||||
|
// Enable WDT after wifi connection as wifiMulti doesnt feed WDT
|
||||||
|
WS.enableWDT(WS_WDT_TIMEOUT);
|
||||||
|
|
||||||
#ifdef USE_DISPLAY
|
#ifdef USE_DISPLAY
|
||||||
WS._ui_helper->set_load_bar_icon_complete(loadBarIconCloud);
|
WS._ui_helper->set_load_bar_icon_complete(loadBarIconCloud);
|
||||||
|
|
@ -2796,7 +2838,6 @@ void Wippersnapper::connect() {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Configure hardware
|
// Configure hardware
|
||||||
WS.pinCfgCompleted = false;
|
|
||||||
while (!WS.pinCfgCompleted) {
|
while (!WS.pinCfgCompleted) {
|
||||||
WS_DEBUG_PRINTLN(
|
WS_DEBUG_PRINTLN(
|
||||||
"Polling for message containing hardware configuration...");
|
"Polling for message containing hardware configuration...");
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@
|
||||||
* please support Adafruit and open-source hardware by purchasing
|
* please support Adafruit and open-source hardware by purchasing
|
||||||
* products from Adafruit!
|
* products from Adafruit!
|
||||||
*
|
*
|
||||||
* Copyright (c) Brent Rubell 2020-2024 for Adafruit Industries.
|
* Copyright (c) Brent Rubell 2020-2025 for Adafruit Industries.
|
||||||
*
|
*
|
||||||
* BSD license, all text here must be included in any redistribution.
|
* BSD license, all text here must be included in any redistribution.
|
||||||
*
|
*
|
||||||
|
|
@ -142,7 +142,7 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define WS_VERSION \
|
#define WS_VERSION \
|
||||||
"1.0.0-beta.88" ///< WipperSnapper app. version (semver-formatted)
|
"1.0.0-beta.111" ///< WipperSnapper app. version (semver-formatted)
|
||||||
|
|
||||||
// Reserved Adafruit IO MQTT topics
|
// Reserved Adafruit IO MQTT topics
|
||||||
#define TOPIC_IO_THROTTLE "/throttle" ///< Adafruit IO Throttle MQTT Topic
|
#define TOPIC_IO_THROTTLE "/throttle" ///< Adafruit IO Throttle MQTT Topic
|
||||||
|
|
@ -214,7 +214,12 @@ typedef enum {
|
||||||
FSM_NET_ESTABLISH_MQTT,
|
FSM_NET_ESTABLISH_MQTT,
|
||||||
} fsm_net_t;
|
} fsm_net_t;
|
||||||
|
|
||||||
#define WS_WDT_TIMEOUT 60000 ///< WDT timeout
|
#ifdef ARDUINO_ARCH_RP2040
|
||||||
|
#define WS_WDT_TIMEOUT 8388 ///< RP2040 Max WDT timeout
|
||||||
|
#else
|
||||||
|
#define WS_WDT_TIMEOUT 60000 ///< WDT timeout
|
||||||
|
#endif
|
||||||
|
|
||||||
#define WS_MAX_ALT_WIFI_NETWORKS 3 ///< Maximum number of alternative networks
|
#define WS_MAX_ALT_WIFI_NETWORKS 3 ///< Maximum number of alternative networks
|
||||||
/* MQTT Configuration */
|
/* MQTT Configuration */
|
||||||
#define WS_KEEPALIVE_INTERVAL_MS \
|
#define WS_KEEPALIVE_INTERVAL_MS \
|
||||||
|
|
@ -306,7 +311,8 @@ public:
|
||||||
|
|
||||||
// Error handling helpers
|
// Error handling helpers
|
||||||
void haltError(String error,
|
void haltError(String error,
|
||||||
ws_led_status_t ledStatusColor = WS_LED_STATUS_ERROR_RUNTIME);
|
ws_led_status_t ledStatusColor = WS_LED_STATUS_ERROR_RUNTIME,
|
||||||
|
int seconds_until_reboot = 25);
|
||||||
void errorWriteHang(String error);
|
void errorWriteHang(String error);
|
||||||
|
|
||||||
// MQTT topic callbacks //
|
// MQTT topic callbacks //
|
||||||
|
|
|
||||||
|
|
@ -51,6 +51,22 @@
|
||||||
#define STATUS_NEOPIXEL_PIN 45
|
#define STATUS_NEOPIXEL_PIN 45
|
||||||
#define STATUS_NEOPIXEL_NUM 1
|
#define STATUS_NEOPIXEL_NUM 1
|
||||||
#define USE_PSRAM ///< Board has PSRAM, use it for dynamic memory allocation
|
#define USE_PSRAM ///< Board has PSRAM, use it for dynamic memory allocation
|
||||||
|
#elif defined(ARDUINO_ESP32S3_DEV)
|
||||||
|
#define BOARD_ID "esp32s3-devkitc-1-n8"
|
||||||
|
#define USE_TINYUSB
|
||||||
|
#define USE_STATUS_NEOPIXEL
|
||||||
|
#define STATUS_NEOPIXEL_PIN 48
|
||||||
|
#define STATUS_NEOPIXEL_NUM 1
|
||||||
|
#ifdef BOARD_HAS_PSRAM
|
||||||
|
#define USE_PSRAM ///< Board has PSRAM, use it for dynamic memory allocation
|
||||||
|
#endif
|
||||||
|
#elif defined(ARDUINO_METRO_ESP32S3)
|
||||||
|
#define BOARD_ID "metroesp32s3"
|
||||||
|
#define USE_TINYUSB
|
||||||
|
#define USE_STATUS_NEOPIXEL
|
||||||
|
#define STATUS_NEOPIXEL_PIN 46
|
||||||
|
#define STATUS_NEOPIXEL_NUM 1
|
||||||
|
#define USE_PSRAM ///< Board has PSRAM, use it for dynamic memory allocation
|
||||||
#elif defined(ARDUINO_MAGTAG29_ESP32S2)
|
#elif defined(ARDUINO_MAGTAG29_ESP32S2)
|
||||||
#define BOARD_ID "magtag"
|
#define BOARD_ID "magtag"
|
||||||
#define USE_TINYUSB
|
#define USE_TINYUSB
|
||||||
|
|
@ -150,6 +166,12 @@
|
||||||
#define USE_LITTLEFS
|
#define USE_LITTLEFS
|
||||||
#define USE_STATUS_LED
|
#define USE_STATUS_LED
|
||||||
#define STATUS_LED_PIN 13
|
#define STATUS_LED_PIN 13
|
||||||
|
#elif defined(ARDUINO_ADAFRUIT_FEATHER_ESP32C6)
|
||||||
|
#define BOARD_ID "feather-esp32c6"
|
||||||
|
#define USE_LITTLEFS
|
||||||
|
#define USE_STATUS_NEOPIXEL
|
||||||
|
#define STATUS_NEOPIXEL_PIN PIN_NEOPIXEL
|
||||||
|
#define STATUS_NEOPIXEL_NUM 1
|
||||||
#elif defined(ARDUINO_ADAFRUIT_FEATHER_ESP32_V2)
|
#elif defined(ARDUINO_ADAFRUIT_FEATHER_ESP32_V2)
|
||||||
#define BOARD_ID "feather-esp32-v2"
|
#define BOARD_ID "feather-esp32-v2"
|
||||||
#define USE_LITTLEFS
|
#define USE_LITTLEFS
|
||||||
|
|
@ -164,19 +186,49 @@
|
||||||
#define STATUS_NEOPIXEL_PIN PIN_NEOPIXEL
|
#define STATUS_NEOPIXEL_PIN PIN_NEOPIXEL
|
||||||
#define STATUS_NEOPIXEL_NUM 1
|
#define STATUS_NEOPIXEL_NUM 1
|
||||||
#define USE_PSRAM ///< Board has PSRAM, use it for dynamic memory allocation
|
#define USE_PSRAM ///< Board has PSRAM, use it for dynamic memory allocation
|
||||||
#elif defined(ARDUINO_SAMD_NANO_33_IOT)
|
#elif defined(ARDUINO_ESP32C3_DEV)
|
||||||
#define BOARD_ID "nano-33-iot"
|
// Note: this board reuses a generic preprocessor define
|
||||||
|
// espressif/arduino-esp32@fcd4799c6de6eb5a5a8eba94818adf770238ecc0
|
||||||
|
// rather than creating one unique to the device.
|
||||||
|
#define BOARD_ID "dfrobot-beetle-esp32c3"
|
||||||
|
#define USE_LITTLEFS
|
||||||
#define USE_STATUS_LED
|
#define USE_STATUS_LED
|
||||||
#define STATUS_LED_PIN 13
|
#define STATUS_LED_PIN LED_BUILTIN
|
||||||
#elif defined(ARDUINO_SAMD_MKRWIFI1010)
|
#elif defined(ARDUINO_SPARKLEMOTIONMINI_ESP32)
|
||||||
#define BOARD_ID "mkrwifi1010"
|
#define BOARD_ID "sparklemotionmini-esp32"
|
||||||
#define USE_STATUS_LED
|
#define USE_LITTLEFS
|
||||||
#define STATUS_LED_PIN 6
|
#define USE_STATUS_NEOPIXEL
|
||||||
|
#define STATUS_NEOPIXEL_PIN PIN_NEOPIXEL
|
||||||
|
#define STATUS_NEOPIXEL_NUM 1
|
||||||
|
#elif defined(ARDUINO_SPARKLEMOTIONSTICK_ESP32)
|
||||||
|
#define BOARD_ID "sparklemotionstick-esp32"
|
||||||
|
#define USE_LITTLEFS
|
||||||
|
#define USE_STATUS_NEOPIXEL
|
||||||
|
#define STATUS_NEOPIXEL_PIN PIN_NEOPIXEL
|
||||||
|
#define STATUS_NEOPIXEL_NUM 1
|
||||||
#elif defined(ARDUINO_RASPBERRY_PI_PICO_W)
|
#elif defined(ARDUINO_RASPBERRY_PI_PICO_W)
|
||||||
#define BOARD_ID "rpi-pico-w"
|
#define BOARD_ID "rpi-pico-w"
|
||||||
#define USE_TINYUSB
|
#define USE_TINYUSB
|
||||||
#define USE_STATUS_LED
|
#define USE_STATUS_LED
|
||||||
#define STATUS_LED_PIN 32
|
#define STATUS_LED_PIN LED_BUILTIN
|
||||||
|
#elif defined(ARDUINO_RASPBERRY_PI_PICO_2W)
|
||||||
|
#define BOARD_ID "rpi-pico-2w"
|
||||||
|
#define USE_TINYUSB
|
||||||
|
#define USE_STATUS_LED
|
||||||
|
#define STATUS_LED_PIN LED_BUILTIN
|
||||||
|
#elif defined(ARDUINO_XIAO_ESP32S3)
|
||||||
|
#define BOARD_ID "xiao-esp32s3"
|
||||||
|
#define BOARD_HAS_PSRAM
|
||||||
|
#define USE_PSRAM
|
||||||
|
#define USE_TINYUSB
|
||||||
|
#define USE_STATUS_LED
|
||||||
|
#define STATUS_LED_PIN LED_BUILTIN
|
||||||
|
#elif defined(ARDUINO_ADAFRUIT_FRUITJAM_RP2350)
|
||||||
|
#define BOARD_ID "fruitjam"
|
||||||
|
#define USE_TINYUSB
|
||||||
|
#define USE_STATUS_NEOPIXEL
|
||||||
|
#define STATUS_NEOPIXEL_PIN PIN_NEOPIXEL
|
||||||
|
#define STATUS_NEOPIXEL_NUM 5
|
||||||
#else
|
#else
|
||||||
#warning "Board type not identified within Wippersnapper_Boards.h!"
|
#warning "Board type not identified within Wippersnapper_Boards.h!"
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -1,44 +1,46 @@
|
||||||
/*!
|
/*!
|
||||||
* @file Wippersnapper_Networking.h
|
* @file Wippersnapper_Networking.h
|
||||||
*
|
*
|
||||||
* This file includes network interfaces at compile-time.
|
* This file includes network interfaces at compile-time.
|
||||||
*
|
*
|
||||||
* Adafruit invests time and resources providing this open source code,
|
* Adafruit invests time and resources providing this open source code,
|
||||||
* please support Adafruit and open-source hardware by purchasing
|
* please support Adafruit and open-source hardware by purchasing
|
||||||
* products from Adafruit!
|
* products from Adafruit!
|
||||||
*
|
*
|
||||||
* Copyright (c) Brent Rubell 2020-2021 for Adafruit Industries.
|
* Copyright (c) Brent Rubell 2020-2021 for Adafruit Industries.
|
||||||
*
|
*
|
||||||
* BSD license, all text here must be included in any redistribution.
|
* BSD license, all text here must be included in any redistribution.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef WIPPERSNAPPER_NETWORKING_H
|
#ifndef WIPPERSNAPPER_NETWORKING_H
|
||||||
#define WIPPERSNAPPER_NETWORKING_H
|
#define WIPPERSNAPPER_NETWORKING_H
|
||||||
|
|
||||||
#if defined(ADAFRUIT_METRO_M4_EXPRESS) || \
|
#ifndef WL_MAC_ADDR_LENGTH
|
||||||
defined(ADAFRUIT_METRO_M4_AIRLIFT_LITE) || defined(ADAFRUIT_PYPORTAL) || \
|
#define WL_MAC_ADDR_LENGTH 6 ///< MAC address length - from RP2040 BSP
|
||||||
defined(ADAFRUIT_PYPORTAL_M4_TITANO) || defined(USE_AIRLIFT)
|
#endif
|
||||||
#include "network_interfaces/Wippersnapper_AIRLIFT.h"
|
#define WS_MAX_ALT_WIFI_NETWORKS 3 ///< Maximum number of alternative networks
|
||||||
/** Nina-FW (adafruit fork) networking class */
|
|
||||||
typedef Wippersnapper_AIRLIFT Wippersnapper_WiFi;
|
#if defined(ADAFRUIT_METRO_M4_EXPRESS) || \
|
||||||
#elif defined(ARDUINO_ARCH_ESP8266)
|
defined(ADAFRUIT_METRO_M4_AIRLIFT_LITE) || defined(ADAFRUIT_PYPORTAL) || \
|
||||||
#include "network_interfaces/Wippersnapper_ESP8266.h"
|
defined(ADAFRUIT_PYPORTAL_M4_TITANO) || defined(USE_AIRLIFT) || \
|
||||||
/** ESP8266's networking class */
|
defined(ADAFRUIT_FRUITJAM_RP2350)
|
||||||
typedef Wippersnapper_ESP8266 Wippersnapper_WiFi;
|
#include "network_interfaces/Wippersnapper_AIRLIFT.h"
|
||||||
#elif defined(ARDUINO_ARCH_ESP32)
|
/** Nina-FW (adafruit fork) networking class */
|
||||||
#include "network_interfaces/Wippersnapper_ESP32.h"
|
typedef Wippersnapper_AIRLIFT Wippersnapper_WiFi;
|
||||||
/** ESP32's networking class */
|
#elif defined(ARDUINO_ARCH_ESP8266)
|
||||||
typedef Wippersnapper_ESP32 Wippersnapper_WiFi;
|
#include "network_interfaces/Wippersnapper_ESP8266.h"
|
||||||
#elif defined(ARDUINO_ARCH_RP2040)
|
/** ESP8266's networking class */
|
||||||
#include "network_interfaces/ws_networking_pico.h"
|
typedef Wippersnapper_ESP8266 Wippersnapper_WiFi;
|
||||||
typedef ws_networking_pico Wippersnapper_WiFi;
|
#elif defined(ARDUINO_ARCH_ESP32)
|
||||||
#elif defined(ARDUINO_SAMD_NANO_33_IOT) || defined(ARDUINO_SAMD_MKRWIFI1010)
|
#include "network_interfaces/Wippersnapper_ESP32.h"
|
||||||
/** Nina-FW (arduino) networking class */
|
/** ESP32's networking class */
|
||||||
#include "network_interfaces/Wippersnapper_WIFININA.h"
|
typedef Wippersnapper_ESP32 Wippersnapper_WiFi;
|
||||||
typedef Wippersnapper_WIFININA Wippersnapper_WiFi;
|
#elif defined(ARDUINO_ARCH_RP2040)
|
||||||
#else
|
#include "network_interfaces/ws_networking_pico.h"
|
||||||
#warning "Must define network interface in config.h!"
|
typedef ws_networking_pico Wippersnapper_WiFi;
|
||||||
#endif
|
#else
|
||||||
|
#warning "Must define network interface in config.h!"
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif // WIPPERSNAPPER_NETWORKING_H
|
#endif // WIPPERSNAPPER_NETWORKING_H
|
||||||
|
|
@ -87,8 +87,13 @@ void Wippersnapper_AnalogIO::setADCResolution(int resolution) {
|
||||||
analogReadResolution(16);
|
analogReadResolution(16);
|
||||||
_nativeResolution = 12;
|
_nativeResolution = 12;
|
||||||
#elif defined(ARDUINO_ARCH_ESP32)
|
#elif defined(ARDUINO_ARCH_ESP32)
|
||||||
scaleAnalogRead = true;
|
scaleAnalogRead = false; // handled in bsp (analogReadResolution)
|
||||||
_nativeResolution = 13;
|
analogReadResolution(resolution); // 16 bit values (shifted from 12 or 13bit)
|
||||||
|
#if defined(ESP32S3)
|
||||||
|
_nativeResolution = 13; // S3 ADC is 13-bit, others are 12-bit
|
||||||
|
#else
|
||||||
|
_nativeResolution = 12;
|
||||||
|
#endif
|
||||||
#elif defined(ARDUINO_ARCH_RP2040)
|
#elif defined(ARDUINO_ARCH_RP2040)
|
||||||
scaleAnalogRead = true;
|
scaleAnalogRead = true;
|
||||||
_nativeResolution = 10;
|
_nativeResolution = 10;
|
||||||
|
|
@ -96,7 +101,6 @@ void Wippersnapper_AnalogIO::setADCResolution(int resolution) {
|
||||||
scaleAnalogRead = true;
|
scaleAnalogRead = true;
|
||||||
_nativeResolution = 10;
|
_nativeResolution = 10;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
_adcResolution = resolution;
|
_adcResolution = resolution;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -232,8 +236,12 @@ uint16_t Wippersnapper_AnalogIO::getPinValue(int pin) {
|
||||||
*/
|
*/
|
||||||
/**********************************************************/
|
/**********************************************************/
|
||||||
float Wippersnapper_AnalogIO::getPinValueVolts(int pin) {
|
float Wippersnapper_AnalogIO::getPinValueVolts(int pin) {
|
||||||
|
#ifdef ARDUINO_ARCH_ESP32
|
||||||
|
return analogReadMilliVolts(pin) / 1000.0;
|
||||||
|
#else
|
||||||
uint16_t rawValue = getPinValue(pin);
|
uint16_t rawValue = getPinValue(pin);
|
||||||
return rawValue * getAref() / 65536;
|
return rawValue * getAref() / 65536;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************/
|
/******************************************************************/
|
||||||
|
|
@ -303,6 +311,52 @@ bool Wippersnapper_AnalogIO::encodePinEvent(
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**********************************************************/
|
||||||
|
/*!
|
||||||
|
@brief Calculates the hysteresis for the pin value.
|
||||||
|
@param pin
|
||||||
|
The desired analog pin to calculate hysteresis for.
|
||||||
|
@param pinValRaw
|
||||||
|
The pin's raw value.
|
||||||
|
@param pinValThreshHi
|
||||||
|
The pin's high threshold value.
|
||||||
|
@param pinValThreshLow
|
||||||
|
The pin's low threshold value.
|
||||||
|
*/
|
||||||
|
/**********************************************************/
|
||||||
|
void calculateHysteresis(analogInputPin pin, uint16_t pinValRaw,
|
||||||
|
uint16_t &pinValThreshHi, uint16_t &pinValThreshLow) {
|
||||||
|
// All boards ADC values scaled to 16bit, in future we may need to
|
||||||
|
// adjust dynamically
|
||||||
|
uint16_t maxDecimalValue = 65535;
|
||||||
|
|
||||||
|
// Calculate threshold values - using DEFAULT_HYSTERISIS for first third
|
||||||
|
// (1/3) of the range, then 2x DEFAULT_HYSTERISIS for the middle 1/3,
|
||||||
|
// and 4x DEFAULT_HYSTERISIS for the last 1/3. This should allow a more
|
||||||
|
// wifi blip tolerant threshold for the both ends of the range.
|
||||||
|
float CURRENT_HYSTERISIS;
|
||||||
|
if (pinValRaw < maxDecimalValue / 3) {
|
||||||
|
CURRENT_HYSTERISIS = maxDecimalValue * DEFAULT_HYSTERISIS;
|
||||||
|
} else if (pinValRaw < (maxDecimalValue / 3) * 2) {
|
||||||
|
CURRENT_HYSTERISIS = maxDecimalValue * DEFAULT_HYSTERISIS * 2;
|
||||||
|
} else {
|
||||||
|
CURRENT_HYSTERISIS = maxDecimalValue * DEFAULT_HYSTERISIS * 4;
|
||||||
|
}
|
||||||
|
// get the threshold values for previous pin value, but don't overflow
|
||||||
|
float overflowableThHi = pin.prvPinVal + CURRENT_HYSTERISIS;
|
||||||
|
float overflowableThLow = pin.prvPinVal - CURRENT_HYSTERISIS;
|
||||||
|
if (overflowableThHi > maxDecimalValue) {
|
||||||
|
pinValThreshHi = maxDecimalValue;
|
||||||
|
} else {
|
||||||
|
pinValThreshHi = overflowableThHi;
|
||||||
|
}
|
||||||
|
if (overflowableThLow < 0) {
|
||||||
|
pinValThreshLow = 0;
|
||||||
|
} else {
|
||||||
|
pinValThreshLow = overflowableThLow;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**********************************************************/
|
/**********************************************************/
|
||||||
/*!
|
/*!
|
||||||
@brief Checks if pin's period is expired.
|
@brief Checks if pin's period is expired.
|
||||||
|
|
@ -310,13 +364,17 @@ bool Wippersnapper_AnalogIO::encodePinEvent(
|
||||||
The current software timer value.
|
The current software timer value.
|
||||||
@param pin
|
@param pin
|
||||||
The desired analog pin to check
|
The desired analog pin to check
|
||||||
|
@param periodOffset
|
||||||
|
Offset to add to the pin's period (used for on_change).
|
||||||
@returns True if pin's period expired, False otherwise.
|
@returns True if pin's period expired, False otherwise.
|
||||||
*/
|
*/
|
||||||
/**********************************************************/
|
/**********************************************************/
|
||||||
bool Wippersnapper_AnalogIO::timerExpired(long currentTime,
|
bool Wippersnapper_AnalogIO::timerExpired(long currentTime, analogInputPin pin,
|
||||||
analogInputPin pin) {
|
long periodOffset) {
|
||||||
if (currentTime - pin.prvPeriod > pin.period && pin.period != 0L)
|
if (pin.period + periodOffset != 0L &&
|
||||||
|
currentTime - pin.prvPeriod > (pin.period + periodOffset)) {
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -335,9 +393,8 @@ void Wippersnapper_AnalogIO::update() {
|
||||||
if (_analog_input_pins[i].enabled == true) {
|
if (_analog_input_pins[i].enabled == true) {
|
||||||
|
|
||||||
// Does the pin execute on-period?
|
// Does the pin execute on-period?
|
||||||
if ((long)millis() - _analog_input_pins[i].prvPeriod >
|
if (_analog_input_pins[i].period != 0L &&
|
||||||
_analog_input_pins[i].period &&
|
timerExpired(millis(), _analog_input_pins[i])) {
|
||||||
_analog_input_pins[i].period != 0L) {
|
|
||||||
WS_DEBUG_PRINT("Executing periodic event on A");
|
WS_DEBUG_PRINT("Executing periodic event on A");
|
||||||
WS_DEBUG_PRINTLN(_analog_input_pins[i].pinName);
|
WS_DEBUG_PRINTLN(_analog_input_pins[i].pinName);
|
||||||
|
|
||||||
|
|
@ -359,28 +416,33 @@ void Wippersnapper_AnalogIO::update() {
|
||||||
encodePinEvent(_analog_input_pins[i].pinName,
|
encodePinEvent(_analog_input_pins[i].pinName,
|
||||||
_analog_input_pins[i].readMode, pinValRaw, pinValVolts);
|
_analog_input_pins[i].readMode, pinValRaw, pinValVolts);
|
||||||
|
|
||||||
// IMPT - reset the digital pin
|
// mark last execution time
|
||||||
_analog_input_pins[i].prvPeriod = millis();
|
_analog_input_pins[i].prvPeriod = millis();
|
||||||
}
|
}
|
||||||
// Does the pin execute on_change?
|
// Does the pin execute on_change?
|
||||||
else if (_analog_input_pins[i].period == 0L) {
|
else if (_analog_input_pins[i].period == 0L) {
|
||||||
|
|
||||||
|
// not first run and timer not expired, skip
|
||||||
|
if (_analog_input_pins[i].prvPeriod != 0L &&
|
||||||
|
!timerExpired(millis(), _analog_input_pins[i], 500)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// note: on-change requires ADC DEFAULT_HYSTERISIS to check against prv
|
// note: on-change requires ADC DEFAULT_HYSTERISIS to check against prv
|
||||||
// pin value
|
// pin value
|
||||||
uint16_t pinValRaw = getPinValue(_analog_input_pins[i].pinName);
|
uint16_t pinValRaw = getPinValue(_analog_input_pins[i].pinName);
|
||||||
|
|
||||||
uint16_t _pinValThreshHi =
|
// check if pin value has changed enough
|
||||||
_analog_input_pins[i].prvPinVal +
|
uint16_t pinValThreshHi, pinValThreshLow;
|
||||||
(_analog_input_pins[i].prvPinVal * DEFAULT_HYSTERISIS);
|
calculateHysteresis(_analog_input_pins[i], pinValRaw, pinValThreshHi,
|
||||||
uint16_t _pinValThreshLow =
|
pinValThreshLow);
|
||||||
_analog_input_pins[i].prvPinVal -
|
|
||||||
(_analog_input_pins[i].prvPinVal * DEFAULT_HYSTERISIS);
|
|
||||||
|
|
||||||
if (pinValRaw > _pinValThreshHi || pinValRaw < _pinValThreshLow) {
|
if (_analog_input_pins[i].prvPeriod == 0 ||
|
||||||
|
pinValRaw > pinValThreshHi || pinValRaw < pinValThreshLow) {
|
||||||
// Perform voltage conversion if we need to
|
// Perform voltage conversion if we need to
|
||||||
if (_analog_input_pins[i].readMode ==
|
if (_analog_input_pins[i].readMode ==
|
||||||
wippersnapper_pin_v1_ConfigurePinRequest_AnalogReadMode_ANALOG_READ_MODE_PIN_VOLTAGE) {
|
wippersnapper_pin_v1_ConfigurePinRequest_AnalogReadMode_ANALOG_READ_MODE_PIN_VOLTAGE) {
|
||||||
pinValVolts = pinValRaw * getAref() / 65536;
|
pinValVolts = getPinValueVolts(_analog_input_pins[i].pinName);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Publish pin event to IO
|
// Publish pin event to IO
|
||||||
|
|
@ -388,12 +450,13 @@ void Wippersnapper_AnalogIO::update() {
|
||||||
_analog_input_pins[i].readMode, pinValRaw,
|
_analog_input_pins[i].readMode, pinValRaw,
|
||||||
pinValVolts);
|
pinValVolts);
|
||||||
|
|
||||||
} else {
|
// mark last execution time
|
||||||
// WS_DEBUG_PRINTLN("ADC has not changed enough, continue...");
|
_analog_input_pins[i].prvPeriod = millis();
|
||||||
|
|
||||||
|
} else { // ADC has not changed enough
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// set the pin value in the digital pin object for comparison on next
|
// set the pin value in the digital pin object for comparison next run
|
||||||
// run
|
|
||||||
_analog_input_pins[i].prvPinVal = pinValRaw;
|
_analog_input_pins[i].prvPinVal = pinValRaw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -63,7 +63,8 @@ public:
|
||||||
void setADCResolution(int resolution);
|
void setADCResolution(int resolution);
|
||||||
int getADCresolution();
|
int getADCresolution();
|
||||||
int getNativeResolution();
|
int getNativeResolution();
|
||||||
bool timerExpired(long currentTime, analogInputPin pin);
|
bool timerExpired(long currentTime, analogInputPin pin,
|
||||||
|
long periodOffset = 0);
|
||||||
|
|
||||||
void update();
|
void update();
|
||||||
bool encodePinEvent(
|
bool encodePinEvent(
|
||||||
|
|
|
||||||
|
|
@ -82,7 +82,6 @@ WipperSnapper_Component_I2C::WipperSnapper_Component_I2C(
|
||||||
} else {
|
} else {
|
||||||
_isInit = true; // if the peripheral was configured incorrectly
|
_isInit = true; // if the peripheral was configured incorrectly
|
||||||
}
|
}
|
||||||
_i2c->setClock(50000);
|
|
||||||
#elif defined(ARDUINO_ARCH_ESP8266)
|
#elif defined(ARDUINO_ARCH_ESP8266)
|
||||||
_i2c = new TwoWire();
|
_i2c = new TwoWire();
|
||||||
_i2c->begin(msgInitRequest->i2c_pin_sda, msgInitRequest->i2c_pin_scl);
|
_i2c->begin(msgInitRequest->i2c_pin_sda, msgInitRequest->i2c_pin_scl);
|
||||||
|
|
@ -143,8 +142,6 @@ wippersnapper_i2c_v1_BusResponse WipperSnapper_Component_I2C::getBusStatus() {
|
||||||
/************************************************************************/
|
/************************************************************************/
|
||||||
wippersnapper_i2c_v1_I2CBusScanResponse
|
wippersnapper_i2c_v1_I2CBusScanResponse
|
||||||
WipperSnapper_Component_I2C::scanAddresses() {
|
WipperSnapper_Component_I2C::scanAddresses() {
|
||||||
uint8_t endTransmissionRC;
|
|
||||||
uint16_t address;
|
|
||||||
wippersnapper_i2c_v1_I2CBusScanResponse scanResp =
|
wippersnapper_i2c_v1_I2CBusScanResponse scanResp =
|
||||||
wippersnapper_i2c_v1_I2CBusScanResponse_init_zero;
|
wippersnapper_i2c_v1_I2CBusScanResponse_init_zero;
|
||||||
|
|
||||||
|
|
@ -156,37 +153,45 @@ WipperSnapper_Component_I2C::scanAddresses() {
|
||||||
|
|
||||||
// Scan all I2C addresses between 0x08 and 0x7F inclusive and return a list of
|
// Scan all I2C addresses between 0x08 and 0x7F inclusive and return a list of
|
||||||
// those that respond.
|
// those that respond.
|
||||||
WS_DEBUG_PRINTLN("EXEC: I2C Scan");
|
WS_DEBUG_PRINTLN("[i2c]: Scanning I2C Bus for Devices...");
|
||||||
for (address = 0x08; address < 0x7F; address++) {
|
for (uint8_t address = 1; address < 127; ++address) {
|
||||||
|
WS_DEBUG_PRINT("[i2c] Scanning Address: 0x");
|
||||||
|
WS_DEBUG_PRINTLN(address, HEX);
|
||||||
_i2c->beginTransmission(address);
|
_i2c->beginTransmission(address);
|
||||||
endTransmissionRC = _i2c->endTransmission();
|
uint8_t endTransmissionRC = _i2c->endTransmission();
|
||||||
|
|
||||||
#if defined(ARDUINO_ARCH_ESP32)
|
|
||||||
// Check endTransmission()'s return code (Arduino-ESP32 ONLY)
|
|
||||||
// https://github.com/espressif/arduino-esp32/blob/master/libraries/Wire/src/Wire.cpp
|
|
||||||
if (endTransmissionRC == 5) {
|
|
||||||
WS_DEBUG_PRINTLN("ESP_ERR_TIMEOUT: I2C Bus Busy");
|
|
||||||
scanResp.bus_response =
|
|
||||||
wippersnapper_i2c_v1_BusResponse_BUS_RESPONSE_ERROR_HANG;
|
|
||||||
// NOTE: ESP-IDF appears to handle this "behind the scenes" by
|
|
||||||
// resetting/clearing the bus. The user should be prompted to
|
|
||||||
// perform a bus scan again.
|
|
||||||
break;
|
|
||||||
} else if (endTransmissionRC == 7) {
|
|
||||||
WS_DEBUG_PRINT("I2C_ESP_ERR: SDA/SCL shorted, requests queued: ");
|
|
||||||
WS_DEBUG_PRINTLN(endTransmissionRC);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Found device!
|
|
||||||
if (endTransmissionRC == 0) {
|
if (endTransmissionRC == 0) {
|
||||||
WS_DEBUG_PRINT("Found I2C Device at 0x");
|
WS_DEBUG_PRINTLN("[i2c] Found Device!");
|
||||||
WS_DEBUG_PRINTLN(address);
|
|
||||||
scanResp.addresses_found[scanResp.addresses_found_count] =
|
scanResp.addresses_found[scanResp.addresses_found_count] =
|
||||||
(uint32_t)address;
|
(uint32_t)address;
|
||||||
scanResp.addresses_found_count++;
|
scanResp.addresses_found_count++;
|
||||||
}
|
}
|
||||||
|
#if defined(ARDUINO_ARCH_ESP32)
|
||||||
|
// Check endTransmission()'s return code (Arduino-ESP32 ONLY)
|
||||||
|
else if (endTransmissionRC == 3) {
|
||||||
|
WS_DEBUG_PRINTLN("[i2c] Did not find device: NACK on transmit of data!");
|
||||||
|
continue;
|
||||||
|
} else if (endTransmissionRC == 2) {
|
||||||
|
WS_DEBUG_PRINTLN(
|
||||||
|
"[i2c] Did not find device: NACK on transmit of address!");
|
||||||
|
continue;
|
||||||
|
} else if (endTransmissionRC == 1) {
|
||||||
|
WS_DEBUG_PRINTLN(
|
||||||
|
"[i2c] Did not find device: data too long to fit in xmit buffer!");
|
||||||
|
continue;
|
||||||
|
} else if (endTransmissionRC == 4) {
|
||||||
|
WS_DEBUG_PRINTLN(
|
||||||
|
"[i2c] Did not find device: Unspecified bus error occurred!");
|
||||||
|
continue;
|
||||||
|
} else if (endTransmissionRC == 5) {
|
||||||
|
WS_DEBUG_PRINTLN("[i2c] Did not find device: Bus timed out!");
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
WS_DEBUG_PRINTLN(
|
||||||
|
"[i2c] Did not find device: Unknown bus error has occurred!");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef ARDUINO_ARCH_ESP32
|
#ifndef ARDUINO_ARCH_ESP32
|
||||||
|
|
@ -195,8 +200,9 @@ WipperSnapper_Component_I2C::scanAddresses() {
|
||||||
WS.feedWDT();
|
WS.feedWDT();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
WS_DEBUG_PRINT("I2C Devices Found: ")
|
WS_DEBUG_PRINT("[i2c] Scan Complete! Found: ")
|
||||||
WS_DEBUG_PRINTLN(scanResp.addresses_found_count);
|
WS_DEBUG_PRINT(scanResp.addresses_found_count);
|
||||||
|
WS_DEBUG_PRINTLN(" Devices on bus.");
|
||||||
|
|
||||||
scanResp.bus_response = wippersnapper_i2c_v1_BusResponse_BUS_RESPONSE_SUCCESS;
|
scanResp.bus_response = wippersnapper_i2c_v1_BusResponse_BUS_RESPONSE_SUCCESS;
|
||||||
return scanResp;
|
return scanResp;
|
||||||
|
|
@ -217,6 +223,7 @@ bool WipperSnapper_Component_I2C::initI2CDevice(
|
||||||
|
|
||||||
uint16_t i2cAddress = (uint16_t)msgDeviceInitReq->i2c_device_address;
|
uint16_t i2cAddress = (uint16_t)msgDeviceInitReq->i2c_device_address;
|
||||||
if ((strcmp("aht20", msgDeviceInitReq->i2c_device_name) == 0) ||
|
if ((strcmp("aht20", msgDeviceInitReq->i2c_device_name) == 0) ||
|
||||||
|
(strcmp("aht21", msgDeviceInitReq->i2c_device_name) == 0) ||
|
||||||
(strcmp("am2301b", msgDeviceInitReq->i2c_device_name) == 0) ||
|
(strcmp("am2301b", msgDeviceInitReq->i2c_device_name) == 0) ||
|
||||||
(strcmp("am2315c", msgDeviceInitReq->i2c_device_name) == 0) ||
|
(strcmp("am2315c", msgDeviceInitReq->i2c_device_name) == 0) ||
|
||||||
(strcmp("dht20", msgDeviceInitReq->i2c_device_name) == 0)) {
|
(strcmp("dht20", msgDeviceInitReq->i2c_device_name) == 0)) {
|
||||||
|
|
@ -229,6 +236,16 @@ bool WipperSnapper_Component_I2C::initI2CDevice(
|
||||||
}
|
}
|
||||||
_ahtx0->configureDriver(msgDeviceInitReq);
|
_ahtx0->configureDriver(msgDeviceInitReq);
|
||||||
drivers.push_back(_ahtx0);
|
drivers.push_back(_ahtx0);
|
||||||
|
} else if (strcmp("as5600", msgDeviceInitReq->i2c_device_name) == 0) {
|
||||||
|
_as5600 = new WipperSnapper_I2C_Driver_AS5600(this->_i2c, i2cAddress);
|
||||||
|
if (!_as5600->begin()) {
|
||||||
|
WS_DEBUG_PRINTLN("ERROR: Failed to initialize AS5600 chip!");
|
||||||
|
_busStatusResponse =
|
||||||
|
wippersnapper_i2c_v1_BusResponse_BUS_RESPONSE_DEVICE_INIT_FAIL;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
_as5600->configureDriver(msgDeviceInitReq);
|
||||||
|
drivers.push_back(_as5600);
|
||||||
} else if (strcmp("bh1750", msgDeviceInitReq->i2c_device_name) == 0) {
|
} else if (strcmp("bh1750", msgDeviceInitReq->i2c_device_name) == 0) {
|
||||||
_bh1750 = new WipperSnapper_I2C_Driver_BH1750(this->_i2c, i2cAddress);
|
_bh1750 = new WipperSnapper_I2C_Driver_BH1750(this->_i2c, i2cAddress);
|
||||||
if (!_bh1750->begin()) {
|
if (!_bh1750->begin()) {
|
||||||
|
|
@ -285,6 +302,17 @@ bool WipperSnapper_Component_I2C::initI2CDevice(
|
||||||
_bme680->configureDriver(msgDeviceInitReq);
|
_bme680->configureDriver(msgDeviceInitReq);
|
||||||
drivers.push_back(_bme680);
|
drivers.push_back(_bme680);
|
||||||
WS_DEBUG_PRINTLN("BME680 Initialized Successfully!");
|
WS_DEBUG_PRINTLN("BME680 Initialized Successfully!");
|
||||||
|
} else if (strcmp("d6t1a", msgDeviceInitReq->i2c_device_name) == 0) {
|
||||||
|
_d6t1a = new WipperSnapper_I2C_Driver_D6T1A(this->_i2c, i2cAddress);
|
||||||
|
if (!_d6t1a->begin()) {
|
||||||
|
WS_DEBUG_PRINTLN("ERROR: Failed to initialize D6T1A");
|
||||||
|
_busStatusResponse =
|
||||||
|
wippersnapper_i2c_v1_BusResponse_BUS_RESPONSE_DEVICE_INIT_FAIL;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
_d6t1a->configureDriver(msgDeviceInitReq);
|
||||||
|
drivers.push_back(_d6t1a);
|
||||||
|
WS_DEBUG_PRINTLN("D6T1A Initialized Successfully!");
|
||||||
} else if (strcmp("dps310", msgDeviceInitReq->i2c_device_name) == 0) {
|
} else if (strcmp("dps310", msgDeviceInitReq->i2c_device_name) == 0) {
|
||||||
_dps310 = new WipperSnapper_I2C_Driver_DPS310(this->_i2c, i2cAddress);
|
_dps310 = new WipperSnapper_I2C_Driver_DPS310(this->_i2c, i2cAddress);
|
||||||
if (!_dps310->begin()) {
|
if (!_dps310->begin()) {
|
||||||
|
|
@ -318,6 +346,17 @@ bool WipperSnapper_Component_I2C::initI2CDevice(
|
||||||
_ens160->configureDriver(msgDeviceInitReq);
|
_ens160->configureDriver(msgDeviceInitReq);
|
||||||
drivers.push_back(_ens160);
|
drivers.push_back(_ens160);
|
||||||
WS_DEBUG_PRINTLN("ENS160 Initialized Successfully!");
|
WS_DEBUG_PRINTLN("ENS160 Initialized Successfully!");
|
||||||
|
} else if (strcmp("hdc302x", msgDeviceInitReq->i2c_device_name) == 0) {
|
||||||
|
_hdc302x = new WipperSnapper_I2C_Driver_HDC302X(this->_i2c, i2cAddress);
|
||||||
|
if (!_hdc302x->begin()) {
|
||||||
|
WS_DEBUG_PRINTLN("ERROR: Failed to initialize HDC302X!");
|
||||||
|
_busStatusResponse =
|
||||||
|
wippersnapper_i2c_v1_BusResponse_BUS_RESPONSE_DEVICE_INIT_FAIL;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
_hdc302x->configureDriver(msgDeviceInitReq);
|
||||||
|
drivers.push_back(_hdc302x);
|
||||||
|
WS_DEBUG_PRINTLN("HDC302X Initialized Successfully!");
|
||||||
} else if (strcmp("hts221", msgDeviceInitReq->i2c_device_name) == 0) {
|
} else if (strcmp("hts221", msgDeviceInitReq->i2c_device_name) == 0) {
|
||||||
_hts221 = new WipperSnapper_I2C_Driver_HTS221(this->_i2c, i2cAddress);
|
_hts221 = new WipperSnapper_I2C_Driver_HTS221(this->_i2c, i2cAddress);
|
||||||
if (!_hts221->begin()) {
|
if (!_hts221->begin()) {
|
||||||
|
|
@ -362,6 +401,39 @@ bool WipperSnapper_Component_I2C::initI2CDevice(
|
||||||
_scd30->configureDriver(msgDeviceInitReq);
|
_scd30->configureDriver(msgDeviceInitReq);
|
||||||
drivers.push_back(_scd30);
|
drivers.push_back(_scd30);
|
||||||
WS_DEBUG_PRINTLN("SCD30 Initialized Successfully!");
|
WS_DEBUG_PRINTLN("SCD30 Initialized Successfully!");
|
||||||
|
} else if (strcmp("ina237", msgDeviceInitReq->i2c_device_name) == 0) {
|
||||||
|
_ina237 = new WipperSnapper_I2C_Driver_INA237(this->_i2c, i2cAddress);
|
||||||
|
if (!_ina237->begin()) {
|
||||||
|
WS_DEBUG_PRINTLN("ERROR: Failed to initialize INA237");
|
||||||
|
_busStatusResponse =
|
||||||
|
wippersnapper_i2c_v1_BusResponse_BUS_RESPONSE_DEVICE_INIT_FAIL;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
_ina237->configureDriver(msgDeviceInitReq);
|
||||||
|
drivers.push_back(_ina237);
|
||||||
|
WS_DEBUG_PRINTLN("INA237 Initialized Successfully!");
|
||||||
|
} else if (strcmp("ina238", msgDeviceInitReq->i2c_device_name) == 0) {
|
||||||
|
_ina238 = new WipperSnapper_I2C_Driver_INA238(this->_i2c, i2cAddress);
|
||||||
|
if (!_ina238->begin()) {
|
||||||
|
WS_DEBUG_PRINTLN("ERROR: Failed to initialize INA238");
|
||||||
|
_busStatusResponse =
|
||||||
|
wippersnapper_i2c_v1_BusResponse_BUS_RESPONSE_DEVICE_INIT_FAIL;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
_ina238->configureDriver(msgDeviceInitReq);
|
||||||
|
drivers.push_back(_ina238);
|
||||||
|
WS_DEBUG_PRINTLN("INA238 Initialized Successfully!");
|
||||||
|
} else if (strcmp("ina228", msgDeviceInitReq->i2c_device_name) == 0) {
|
||||||
|
_ina228 = new WipperSnapper_I2C_Driver_INA228(this->_i2c, i2cAddress);
|
||||||
|
if (!_ina228->begin()) {
|
||||||
|
WS_DEBUG_PRINTLN("ERROR: Failed to initialize INA228");
|
||||||
|
_busStatusResponse =
|
||||||
|
wippersnapper_i2c_v1_BusResponse_BUS_RESPONSE_DEVICE_INIT_FAIL;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
_ina228->configureDriver(msgDeviceInitReq);
|
||||||
|
drivers.push_back(_ina228);
|
||||||
|
WS_DEBUG_PRINTLN("INA228 Initialized Successfully!");
|
||||||
} else if (strcmp("ina219", msgDeviceInitReq->i2c_device_name) == 0) {
|
} else if (strcmp("ina219", msgDeviceInitReq->i2c_device_name) == 0) {
|
||||||
_ina219 = new WipperSnapper_I2C_Driver_INA219(this->_i2c, i2cAddress);
|
_ina219 = new WipperSnapper_I2C_Driver_INA219(this->_i2c, i2cAddress);
|
||||||
if (!_ina219->begin()) {
|
if (!_ina219->begin()) {
|
||||||
|
|
@ -373,6 +445,17 @@ bool WipperSnapper_Component_I2C::initI2CDevice(
|
||||||
_ina219->configureDriver(msgDeviceInitReq);
|
_ina219->configureDriver(msgDeviceInitReq);
|
||||||
drivers.push_back(_ina219);
|
drivers.push_back(_ina219);
|
||||||
WS_DEBUG_PRINTLN("INA219 Initialized Successfully!");
|
WS_DEBUG_PRINTLN("INA219 Initialized Successfully!");
|
||||||
|
} else if (strcmp("ina260", msgDeviceInitReq->i2c_device_name) == 0) {
|
||||||
|
_ina260 = new WipperSnapper_I2C_Driver_INA260(this->_i2c, i2cAddress);
|
||||||
|
if (!_ina260->begin()) {
|
||||||
|
WS_DEBUG_PRINTLN("ERROR: Failed to initialize INA260");
|
||||||
|
_busStatusResponse =
|
||||||
|
wippersnapper_i2c_v1_BusResponse_BUS_RESPONSE_DEVICE_INIT_FAIL;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
_ina260->configureDriver(msgDeviceInitReq);
|
||||||
|
drivers.push_back(_ina260);
|
||||||
|
WS_DEBUG_PRINTLN("INA260 Initialized Successfully!");
|
||||||
} else if (strcmp("ltr390", msgDeviceInitReq->i2c_device_name) == 0) {
|
} else if (strcmp("ltr390", msgDeviceInitReq->i2c_device_name) == 0) {
|
||||||
_ltr390 = new WipperSnapper_I2C_Driver_LTR390(this->_i2c, i2cAddress);
|
_ltr390 = new WipperSnapper_I2C_Driver_LTR390(this->_i2c, i2cAddress);
|
||||||
if (!_ltr390->begin()) {
|
if (!_ltr390->begin()) {
|
||||||
|
|
@ -464,6 +547,33 @@ bool WipperSnapper_Component_I2C::initI2CDevice(
|
||||||
_mcp9808->configureDriver(msgDeviceInitReq);
|
_mcp9808->configureDriver(msgDeviceInitReq);
|
||||||
drivers.push_back(_mcp9808);
|
drivers.push_back(_mcp9808);
|
||||||
WS_DEBUG_PRINTLN("MCP9808 Initialized Successfully!");
|
WS_DEBUG_PRINTLN("MCP9808 Initialized Successfully!");
|
||||||
|
} else if (strcmp("mlx90632b", msgDeviceInitReq->i2c_device_name) == 0 ||
|
||||||
|
strcmp("mlx90632d_med", msgDeviceInitReq->i2c_device_name) == 0) {
|
||||||
|
_mlx90632d = new WipperSnapper_I2C_Driver_MLX90632D(this->_i2c, i2cAddress);
|
||||||
|
if (!_mlx90632d->begin()) {
|
||||||
|
WS_DEBUG_PRINTLN("ERROR: Failed to initialize MLX90632!");
|
||||||
|
_busStatusResponse =
|
||||||
|
wippersnapper_i2c_v1_BusResponse_BUS_RESPONSE_DEVICE_INIT_FAIL;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
_mlx90632d->configureDriver(msgDeviceInitReq);
|
||||||
|
drivers.push_back(_mlx90632d);
|
||||||
|
WS_DEBUG_PRINTLN("MLX90632 Initialized Successfully!");
|
||||||
|
} else if (strcmp("mlx90632d_ext", msgDeviceInitReq->i2c_device_name) == 0) {
|
||||||
|
_mlx90632d_ext =
|
||||||
|
new WipperSnapper_I2C_Driver_MLX90632D(this->_i2c, i2cAddress);
|
||||||
|
// set extended range
|
||||||
|
if (!_mlx90632d_ext->begin() ||
|
||||||
|
!_mlx90632d_ext->ConfigureAndPrintSensorInfo(true)) {
|
||||||
|
WS_DEBUG_PRINTLN(
|
||||||
|
"ERROR: Failed to initialize MLX90632D with extended range!");
|
||||||
|
_busStatusResponse =
|
||||||
|
wippersnapper_i2c_v1_BusResponse_BUS_RESPONSE_DEVICE_INIT_FAIL;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
_mlx90632d_ext->configureDriver(msgDeviceInitReq);
|
||||||
|
drivers.push_back(_mlx90632d_ext);
|
||||||
|
WS_DEBUG_PRINTLN("MLX90632D_EXT Initialized Successfully!");
|
||||||
} else if (strcmp("mpl115a2", msgDeviceInitReq->i2c_device_name) == 0) {
|
} else if (strcmp("mpl115a2", msgDeviceInitReq->i2c_device_name) == 0) {
|
||||||
_mpl115a2 = new WipperSnapper_I2C_Driver_MPL115A2(this->_i2c, i2cAddress);
|
_mpl115a2 = new WipperSnapper_I2C_Driver_MPL115A2(this->_i2c, i2cAddress);
|
||||||
if (!_mpl115a2->begin()) {
|
if (!_mpl115a2->begin()) {
|
||||||
|
|
@ -541,6 +651,17 @@ bool WipperSnapper_Component_I2C::initI2CDevice(
|
||||||
_vcnl4040->configureDriver(msgDeviceInitReq);
|
_vcnl4040->configureDriver(msgDeviceInitReq);
|
||||||
drivers.push_back(_vcnl4040);
|
drivers.push_back(_vcnl4040);
|
||||||
WS_DEBUG_PRINTLN("VCNL4040 Initialized Successfully!");
|
WS_DEBUG_PRINTLN("VCNL4040 Initialized Successfully!");
|
||||||
|
} else if (strcmp("vcnl4200", msgDeviceInitReq->i2c_device_name) == 0) {
|
||||||
|
_vcnl4200 = new WipperSnapper_I2C_Driver_VCNL4200(this->_i2c, i2cAddress);
|
||||||
|
if (!_vcnl4200->begin()) {
|
||||||
|
WS_DEBUG_PRINTLN("ERROR: Failed to initialize VCNL4200!");
|
||||||
|
_busStatusResponse =
|
||||||
|
wippersnapper_i2c_v1_BusResponse_BUS_RESPONSE_DEVICE_INIT_FAIL;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
_vcnl4200->configureDriver(msgDeviceInitReq);
|
||||||
|
drivers.push_back(_vcnl4200);
|
||||||
|
WS_DEBUG_PRINTLN("VCNL4200 Initialized Successfully!");
|
||||||
} else if (strcmp("veml7700", msgDeviceInitReq->i2c_device_name) == 0) {
|
} else if (strcmp("veml7700", msgDeviceInitReq->i2c_device_name) == 0) {
|
||||||
_veml7700 = new WipperSnapper_I2C_Driver_VEML7700(this->_i2c, i2cAddress);
|
_veml7700 = new WipperSnapper_I2C_Driver_VEML7700(this->_i2c, i2cAddress);
|
||||||
if (!_veml7700->begin()) {
|
if (!_veml7700->begin()) {
|
||||||
|
|
@ -577,6 +698,22 @@ bool WipperSnapper_Component_I2C::initI2CDevice(
|
||||||
_sen5x->configureDriver(msgDeviceInitReq);
|
_sen5x->configureDriver(msgDeviceInitReq);
|
||||||
drivers.push_back(_sen5x);
|
drivers.push_back(_sen5x);
|
||||||
WS_DEBUG_PRINTLN("SEN5X Initialized Successfully!");
|
WS_DEBUG_PRINTLN("SEN5X Initialized Successfully!");
|
||||||
|
} else if ((strcmp("sen6x", msgDeviceInitReq->i2c_device_name) == 0) ||
|
||||||
|
(strcmp("sen60", msgDeviceInitReq->i2c_device_name) == 0) ||
|
||||||
|
(strcmp("sen63C", msgDeviceInitReq->i2c_device_name) == 0) ||
|
||||||
|
(strcmp("sen65", msgDeviceInitReq->i2c_device_name) == 0) ||
|
||||||
|
(strcmp("sen66", msgDeviceInitReq->i2c_device_name) == 0) ||
|
||||||
|
(strcmp("sen68", msgDeviceInitReq->i2c_device_name) == 0)) {
|
||||||
|
_sen6x = new WipperSnapper_I2C_Driver_SEN6X(this->_i2c, i2cAddress);
|
||||||
|
if (!_sen6x->begin()) {
|
||||||
|
WS_DEBUG_PRINTLN("ERROR: Failed to initialize SEN6X!");
|
||||||
|
_busStatusResponse =
|
||||||
|
wippersnapper_i2c_v1_BusResponse_BUS_RESPONSE_DEVICE_INIT_FAIL;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
_sen6x->configureDriver(msgDeviceInitReq);
|
||||||
|
drivers.push_back(_sen6x);
|
||||||
|
WS_DEBUG_PRINTLN("SEN6X Initialized Successfully!");
|
||||||
} else if ((strcmp("sht40", msgDeviceInitReq->i2c_device_name) == 0) ||
|
} else if ((strcmp("sht40", msgDeviceInitReq->i2c_device_name) == 0) ||
|
||||||
(strcmp("sht41", msgDeviceInitReq->i2c_device_name) == 0) ||
|
(strcmp("sht41", msgDeviceInitReq->i2c_device_name) == 0) ||
|
||||||
(strcmp("sht45", msgDeviceInitReq->i2c_device_name) == 0)) {
|
(strcmp("sht45", msgDeviceInitReq->i2c_device_name) == 0)) {
|
||||||
|
|
@ -670,6 +807,17 @@ bool WipperSnapper_Component_I2C::initI2CDevice(
|
||||||
_lps25hb->configureDriver(msgDeviceInitReq);
|
_lps25hb->configureDriver(msgDeviceInitReq);
|
||||||
drivers.push_back(_lps25hb);
|
drivers.push_back(_lps25hb);
|
||||||
WS_DEBUG_PRINTLN("LPS25HB Sensor Initialized Successfully!");
|
WS_DEBUG_PRINTLN("LPS25HB Sensor Initialized Successfully!");
|
||||||
|
} else if (strcmp("lps28dfw", msgDeviceInitReq->i2c_device_name) == 0) {
|
||||||
|
_lps28hb = new WipperSnapper_I2C_Driver_LPS28DFW(this->_i2c, i2cAddress);
|
||||||
|
if (!_lps28hb->begin()) {
|
||||||
|
WS_DEBUG_PRINTLN("ERROR: Failed to initialize LPS28DFW Sensor!");
|
||||||
|
_busStatusResponse =
|
||||||
|
wippersnapper_i2c_v1_BusResponse_BUS_RESPONSE_DEVICE_INIT_FAIL;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
_lps28hb->configureDriver(msgDeviceInitReq);
|
||||||
|
drivers.push_back(_lps28hb);
|
||||||
|
WS_DEBUG_PRINTLN("LPS28HB Sensor Initialized Successfully!");
|
||||||
} else if ((strcmp("lps33hw", msgDeviceInitReq->i2c_device_name) == 0) ||
|
} else if ((strcmp("lps33hw", msgDeviceInitReq->i2c_device_name) == 0) ||
|
||||||
(strcmp("lps35hw", msgDeviceInitReq->i2c_device_name)) == 0) {
|
(strcmp("lps35hw", msgDeviceInitReq->i2c_device_name)) == 0) {
|
||||||
_lps3xhw = new WipperSnapper_I2C_Driver_LPS3XHW(this->_i2c, i2cAddress);
|
_lps3xhw = new WipperSnapper_I2C_Driver_LPS3XHW(this->_i2c, i2cAddress);
|
||||||
|
|
@ -771,6 +919,105 @@ bool WipperSnapper_Component_I2C::initI2CDevice(
|
||||||
_adt7410->configureDriver(msgDeviceInitReq);
|
_adt7410->configureDriver(msgDeviceInitReq);
|
||||||
drivers.push_back(_adt7410);
|
drivers.push_back(_adt7410);
|
||||||
WS_DEBUG_PRINTLN("ADT7410 Initialized Successfully!");
|
WS_DEBUG_PRINTLN("ADT7410 Initialized Successfully!");
|
||||||
|
} else if (strcmp("quadalphanum", msgDeviceInitReq->i2c_device_name) == 0) {
|
||||||
|
_quadAlphaNum =
|
||||||
|
new WipperSnapper_I2C_Driver_Out_QuadAlphaNum(this->_i2c, i2cAddress);
|
||||||
|
_quadAlphaNum->ConfigureI2CBackpack(
|
||||||
|
msgDeviceInitReq->i2c_output_add.config.led_backpack_config.brightness,
|
||||||
|
msgDeviceInitReq->i2c_output_add.config.led_backpack_config.alignment);
|
||||||
|
if (!_quadAlphaNum->begin()) {
|
||||||
|
WS_DEBUG_PRINTLN("ERROR: Failed to initialize Quad Alphanum. Display!");
|
||||||
|
_busStatusResponse =
|
||||||
|
wippersnapper_i2c_v1_BusResponse_BUS_RESPONSE_DEVICE_INIT_FAIL;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
_drivers_out.push_back(_quadAlphaNum);
|
||||||
|
WS_DEBUG_PRINTLN("Quad Alphanum. Display Initialized Successfully!");
|
||||||
|
} else if (strcmp("chardisplay16x2", msgDeviceInitReq->i2c_device_name) ==
|
||||||
|
0 ||
|
||||||
|
strcmp("chardisplay20x4", msgDeviceInitReq->i2c_device_name) ==
|
||||||
|
0) {
|
||||||
|
_charLcd = new WipperSnapper_I2C_Driver_Out_CharLcd(this->_i2c, i2cAddress);
|
||||||
|
_charLcd->ConfigureCharLcd(
|
||||||
|
msgDeviceInitReq->i2c_output_add.config.char_lcd_config.rows,
|
||||||
|
msgDeviceInitReq->i2c_output_add.config.char_lcd_config.columns);
|
||||||
|
if (!_charLcd->begin()) {
|
||||||
|
WS_DEBUG_PRINTLN("ERROR: Failed to initialize Character LCD!");
|
||||||
|
_busStatusResponse =
|
||||||
|
wippersnapper_i2c_v1_BusResponse_BUS_RESPONSE_DEVICE_INIT_FAIL;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
_drivers_out.push_back(_charLcd);
|
||||||
|
WS_DEBUG_PRINTLN("Char LCD Display Initialized Successfully!");
|
||||||
|
} else if (strcmp("7seg", msgDeviceInitReq->i2c_device_name) == 0) {
|
||||||
|
_sevenSeg = new WipperSnapper_I2C_Driver_Out_7Seg(this->_i2c, i2cAddress);
|
||||||
|
_sevenSeg->ConfigureI2CBackpack(
|
||||||
|
msgDeviceInitReq->i2c_output_add.config.led_backpack_config.brightness,
|
||||||
|
msgDeviceInitReq->i2c_output_add.config.led_backpack_config.alignment);
|
||||||
|
if (!_sevenSeg->begin()) {
|
||||||
|
WS_DEBUG_PRINTLN("ERROR: Failed to initialize 7-Segement LED Matrix!");
|
||||||
|
_busStatusResponse =
|
||||||
|
wippersnapper_i2c_v1_BusResponse_BUS_RESPONSE_DEVICE_INIT_FAIL;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
_drivers_out.push_back(_sevenSeg);
|
||||||
|
WS_DEBUG_PRINTLN("7-Segement LED Matrix Initialized Successfully!");
|
||||||
|
} else if (strcmp("fthrwingoled128x64", msgDeviceInitReq->i2c_device_name) ==
|
||||||
|
0 ||
|
||||||
|
strcmp("fthrwingoled128x64lg",
|
||||||
|
msgDeviceInitReq->i2c_device_name) == 0) {
|
||||||
|
WS_DEBUG_PRINTLN("SH1107 display detected!");
|
||||||
|
_sh1107 = new WipperSnapper_I2C_Driver_Out_SH1107(this->_i2c, i2cAddress);
|
||||||
|
WS_DEBUG_PRINTLN("Configuring SH1107 display...");
|
||||||
|
_sh1107->ConfigureSH1107(
|
||||||
|
(uint8_t)msgDeviceInitReq->i2c_output_add.config.ssd1306_config.width,
|
||||||
|
(uint8_t)msgDeviceInitReq->i2c_output_add.config.ssd1306_config.height,
|
||||||
|
(uint8_t)
|
||||||
|
msgDeviceInitReq->i2c_output_add.config.ssd1306_config.text_size,
|
||||||
|
OLED_128X64_WING_ROTATION_90); // fixed as currently the only screen is
|
||||||
|
// 128x64wing (needs a rotation of 1 / 90degrees and constructor w/h swap).
|
||||||
|
if (!_sh1107->begin()) {
|
||||||
|
WS_DEBUG_PRINTLN("ERROR: Failed to initialize sh1107!");
|
||||||
|
_busStatusResponse =
|
||||||
|
wippersnapper_i2c_v1_BusResponse_BUS_RESPONSE_DEVICE_INIT_FAIL;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
WS_DEBUG_PRINTLN("SH1107 display configured successfully!");
|
||||||
|
_drivers_out.push_back(_sh1107);
|
||||||
|
WS_DEBUG_PRINTLN("SH1107 display initialized Successfully!");
|
||||||
|
} else if (strcmp("oled32x64large", msgDeviceInitReq->i2c_device_name) == 0 ||
|
||||||
|
strcmp("oled64x32default", msgDeviceInitReq->i2c_device_name) ==
|
||||||
|
0 ||
|
||||||
|
strcmp("oled64x32large", msgDeviceInitReq->i2c_device_name) == 0 ||
|
||||||
|
strcmp("fthrwingoled128x32", msgDeviceInitReq->i2c_device_name) ==
|
||||||
|
0 ||
|
||||||
|
strcmp("fthrwingoled128x32lg",
|
||||||
|
msgDeviceInitReq->i2c_device_name) == 0 ||
|
||||||
|
strcmp("oled128x32default", msgDeviceInitReq->i2c_device_name) ==
|
||||||
|
0 ||
|
||||||
|
strcmp("oled128x32large", msgDeviceInitReq->i2c_device_name) ==
|
||||||
|
0 ||
|
||||||
|
strcmp("oled128x64default", msgDeviceInitReq->i2c_device_name) ==
|
||||||
|
0 ||
|
||||||
|
strcmp("oled128x64large", msgDeviceInitReq->i2c_device_name) ==
|
||||||
|
0) {
|
||||||
|
WS_DEBUG_PRINTLN("SSD1306 display detected!");
|
||||||
|
_ssd1306 = new WipperSnapper_I2C_Driver_Out_Ssd1306(this->_i2c, i2cAddress);
|
||||||
|
WS_DEBUG_PRINTLN("Configuring SSD1306 display...");
|
||||||
|
_ssd1306->ConfigureSSD1306(
|
||||||
|
(uint8_t)msgDeviceInitReq->i2c_output_add.config.ssd1306_config.width,
|
||||||
|
(uint8_t)msgDeviceInitReq->i2c_output_add.config.ssd1306_config.height,
|
||||||
|
(uint8_t)
|
||||||
|
msgDeviceInitReq->i2c_output_add.config.ssd1306_config.text_size);
|
||||||
|
if (!_ssd1306->begin()) {
|
||||||
|
WS_DEBUG_PRINTLN("ERROR: Failed to initialize ssd1306!");
|
||||||
|
_busStatusResponse =
|
||||||
|
wippersnapper_i2c_v1_BusResponse_BUS_RESPONSE_DEVICE_INIT_FAIL;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
WS_DEBUG_PRINTLN("SSD1306 display configured successfully!");
|
||||||
|
_drivers_out.push_back(_ssd1306);
|
||||||
|
WS_DEBUG_PRINTLN("SSD1306 display initialized Successfully!");
|
||||||
} else {
|
} else {
|
||||||
WS_DEBUG_PRINTLN("ERROR: I2C device type not found!")
|
WS_DEBUG_PRINTLN("ERROR: I2C device type not found!")
|
||||||
_busStatusResponse =
|
_busStatusResponse =
|
||||||
|
|
@ -819,8 +1066,9 @@ void WipperSnapper_Component_I2C::updateI2CDeviceProperties(
|
||||||
void WipperSnapper_Component_I2C::deinitI2CDevice(
|
void WipperSnapper_Component_I2C::deinitI2CDevice(
|
||||||
wippersnapper_i2c_v1_I2CDeviceDeinitRequest *msgDeviceDeinitReq) {
|
wippersnapper_i2c_v1_I2CDeviceDeinitRequest *msgDeviceDeinitReq) {
|
||||||
uint16_t deviceAddr = (uint16_t)msgDeviceDeinitReq->i2c_device_address;
|
uint16_t deviceAddr = (uint16_t)msgDeviceDeinitReq->i2c_device_address;
|
||||||
std::vector<WipperSnapper_I2C_Driver *>::iterator iter, end;
|
|
||||||
|
|
||||||
|
// Check input (sensor) drivers
|
||||||
|
std::vector<WipperSnapper_I2C_Driver *>::iterator iter, end;
|
||||||
for (iter = drivers.begin(), end = drivers.end(); iter != end; ++iter) {
|
for (iter = drivers.begin(), end = drivers.end(); iter != end; ++iter) {
|
||||||
if ((*iter)->getI2CAddress() == deviceAddr) {
|
if ((*iter)->getI2CAddress() == deviceAddr) {
|
||||||
// Delete the object that iter points to
|
// Delete the object that iter points to
|
||||||
|
|
@ -838,6 +1086,28 @@ void WipperSnapper_Component_I2C::deinitI2CDevice(
|
||||||
WS_DEBUG_PRINTLN("I2C Device De-initialized!");
|
WS_DEBUG_PRINTLN("I2C Device De-initialized!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check for output drivers
|
||||||
|
std::vector<WipperSnapper_I2C_Driver_Out *>::iterator out_iter, out_end;
|
||||||
|
for (out_iter = _drivers_out.begin(), out_end = _drivers_out.end();
|
||||||
|
out_iter != out_end; ++out_iter) {
|
||||||
|
if ((*out_iter)->getI2CAddress() == deviceAddr) {
|
||||||
|
// Set the driver to nullptr
|
||||||
|
*out_iter = nullptr;
|
||||||
|
// ESP-IDF, Erase–remove iter ptr from driver vector
|
||||||
|
#if defined(ARDUINO_ARCH_ESP32) || defined(ARDUINO_ARCH_ESP8266)
|
||||||
|
*out_iter = nullptr;
|
||||||
|
_drivers_out.erase(
|
||||||
|
remove(_drivers_out.begin(), _drivers_out.end(), nullptr),
|
||||||
|
_drivers_out.end());
|
||||||
|
#else
|
||||||
|
// Arduino can not erase-remove, erase only
|
||||||
|
_drivers_out.erase(out_iter);
|
||||||
|
#endif
|
||||||
|
WS_DEBUG_PRINTLN("I2C Device De-initialized!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
_busStatusResponse = wippersnapper_i2c_v1_BusResponse_BUS_RESPONSE_SUCCESS;
|
_busStatusResponse = wippersnapper_i2c_v1_BusResponse_BUS_RESPONSE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1006,6 +1276,51 @@ void WipperSnapper_Component_I2C::displayDeviceEventMessage(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************/
|
||||||
|
/*!
|
||||||
|
@brief Handles an I2CDeviceOutputWrite message.
|
||||||
|
@param msgDeviceWrite
|
||||||
|
A decoded I2CDeviceOutputWrite message.
|
||||||
|
@returns True if the message was handled successfully, false otherwise.
|
||||||
|
*/
|
||||||
|
/*******************************************************************************/
|
||||||
|
bool WipperSnapper_Component_I2C::Handle_I2cDeviceOutputWrite(
|
||||||
|
wippersnapper_i2c_v1_I2CDeviceOutputWrite *msgDeviceWrite) {
|
||||||
|
|
||||||
|
// Create a ptr to the base driver out
|
||||||
|
WipperSnapper_I2C_Driver_Out *driver_out = nullptr;
|
||||||
|
// Find the matching driver by address in the _drivers_out vector
|
||||||
|
for (size_t i = 0; i < _drivers_out.size(); i++) {
|
||||||
|
if (_drivers_out[i]->getI2CAddress() ==
|
||||||
|
msgDeviceWrite->i2c_device_address) {
|
||||||
|
driver_out = _drivers_out[i];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (driver_out == nullptr) {
|
||||||
|
WS_DEBUG_PRINTLN("ERROR: I2c output driver not found within drivers_out!");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Call the output_msg
|
||||||
|
if (msgDeviceWrite->which_output_msg ==
|
||||||
|
wippersnapper_i2c_v1_I2CDeviceOutputWrite_write_led_backpack_tag) {
|
||||||
|
driver_out->WriteLedBackpack(
|
||||||
|
&msgDeviceWrite->output_msg.write_led_backpack);
|
||||||
|
} else if (msgDeviceWrite->which_output_msg ==
|
||||||
|
wippersnapper_i2c_v1_I2CDeviceOutputWrite_write_char_lcd_tag) {
|
||||||
|
driver_out->WriteMessageCharLCD(&msgDeviceWrite->output_msg.write_char_lcd);
|
||||||
|
} else if (msgDeviceWrite->which_output_msg ==
|
||||||
|
wippersnapper_i2c_v1_I2CDeviceOutputWrite_write_ssd1306_tag) {
|
||||||
|
driver_out->WriteMessageSSD1306(
|
||||||
|
msgDeviceWrite->output_msg.write_ssd1306.message);
|
||||||
|
} else {
|
||||||
|
WS_DEBUG_PRINTLN("ERROR: Unknown i2c output message type!");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/*******************************************************************************/
|
/*******************************************************************************/
|
||||||
/*!
|
/*!
|
||||||
@brief Queries all I2C device drivers for new values. Fills and sends an
|
@brief Queries all I2C device drivers for new values. Fills and sends an
|
||||||
|
|
@ -1013,7 +1328,6 @@ void WipperSnapper_Component_I2C::displayDeviceEventMessage(
|
||||||
*/
|
*/
|
||||||
/*******************************************************************************/
|
/*******************************************************************************/
|
||||||
void WipperSnapper_Component_I2C::update() {
|
void WipperSnapper_Component_I2C::update() {
|
||||||
|
|
||||||
// Create response message
|
// Create response message
|
||||||
wippersnapper_signal_v1_I2CResponse msgi2cResponse =
|
wippersnapper_signal_v1_I2CResponse msgi2cResponse =
|
||||||
wippersnapper_signal_v1_I2CResponse_init_zero;
|
wippersnapper_signal_v1_I2CResponse_init_zero;
|
||||||
|
|
@ -1030,11 +1344,11 @@ void WipperSnapper_Component_I2C::update() {
|
||||||
|
|
||||||
std::vector<WipperSnapper_I2C_Driver *>::iterator iter, end;
|
std::vector<WipperSnapper_I2C_Driver *>::iterator iter, end;
|
||||||
for (iter = drivers.begin(), end = drivers.end(); iter != end; ++iter) {
|
for (iter = drivers.begin(), end = drivers.end(); iter != end; ++iter) {
|
||||||
// Number of events which occured for this driver
|
// Number of events which occurred for this driver
|
||||||
msgi2cResponse.payload.resp_i2c_device_event.sensor_event_count = 0;
|
msgi2cResponse.payload.resp_i2c_device_event.sensor_event_count = 0;
|
||||||
|
|
||||||
// Event struct
|
// Event struct - zero-initialise on each iteration
|
||||||
sensors_event_t event;
|
sensors_event_t event = {0};
|
||||||
|
|
||||||
// AMBIENT_TEMPERATURE sensor (°C)
|
// AMBIENT_TEMPERATURE sensor (°C)
|
||||||
sensorEventRead(
|
sensorEventRead(
|
||||||
|
|
|
||||||
|
|
@ -22,36 +22,52 @@
|
||||||
#include "drivers/WipperSnapper_I2C_Driver.h"
|
#include "drivers/WipperSnapper_I2C_Driver.h"
|
||||||
#include "drivers/WipperSnapper_I2C_Driver_ADT7410.h"
|
#include "drivers/WipperSnapper_I2C_Driver_ADT7410.h"
|
||||||
#include "drivers/WipperSnapper_I2C_Driver_AHTX0.h"
|
#include "drivers/WipperSnapper_I2C_Driver_AHTX0.h"
|
||||||
|
#include "drivers/WipperSnapper_I2C_Driver_AS5600.h"
|
||||||
#include "drivers/WipperSnapper_I2C_Driver_BH1750.h"
|
#include "drivers/WipperSnapper_I2C_Driver_BH1750.h"
|
||||||
#include "drivers/WipperSnapper_I2C_Driver_BME280.h"
|
#include "drivers/WipperSnapper_I2C_Driver_BME280.h"
|
||||||
#include "drivers/WipperSnapper_I2C_Driver_BME680.h"
|
#include "drivers/WipperSnapper_I2C_Driver_BME680.h"
|
||||||
#include "drivers/WipperSnapper_I2C_Driver_BMP280.h"
|
#include "drivers/WipperSnapper_I2C_Driver_BMP280.h"
|
||||||
#include "drivers/WipperSnapper_I2C_Driver_BMP3XX.h"
|
#include "drivers/WipperSnapper_I2C_Driver_BMP3XX.h"
|
||||||
|
#include "drivers/WipperSnapper_I2C_Driver_D6T1A.h"
|
||||||
#include "drivers/WipperSnapper_I2C_Driver_DPS310.h"
|
#include "drivers/WipperSnapper_I2C_Driver_DPS310.h"
|
||||||
#include "drivers/WipperSnapper_I2C_Driver_DS2484.h"
|
#include "drivers/WipperSnapper_I2C_Driver_DS2484.h"
|
||||||
#include "drivers/WipperSnapper_I2C_Driver_ENS160.h"
|
#include "drivers/WipperSnapper_I2C_Driver_ENS160.h"
|
||||||
|
#include "drivers/WipperSnapper_I2C_Driver_HDC302X.h"
|
||||||
#include "drivers/WipperSnapper_I2C_Driver_HTS221.h"
|
#include "drivers/WipperSnapper_I2C_Driver_HTS221.h"
|
||||||
#include "drivers/WipperSnapper_I2C_Driver_HTU21D.h"
|
#include "drivers/WipperSnapper_I2C_Driver_HTU21D.h"
|
||||||
#include "drivers/WipperSnapper_I2C_Driver_HTU31D.h"
|
#include "drivers/WipperSnapper_I2C_Driver_HTU31D.h"
|
||||||
#include "drivers/WipperSnapper_I2C_Driver_INA219.h"
|
#include "drivers/WipperSnapper_I2C_Driver_INA219.h"
|
||||||
|
#include "drivers/WipperSnapper_I2C_Driver_INA228.h"
|
||||||
|
#include "drivers/WipperSnapper_I2C_Driver_INA237.h"
|
||||||
|
#include "drivers/WipperSnapper_I2C_Driver_INA238.h"
|
||||||
|
#include "drivers/WipperSnapper_I2C_Driver_INA260.h"
|
||||||
#include "drivers/WipperSnapper_I2C_Driver_LC709203F.h"
|
#include "drivers/WipperSnapper_I2C_Driver_LC709203F.h"
|
||||||
#include "drivers/WipperSnapper_I2C_Driver_LPS22HB.h"
|
#include "drivers/WipperSnapper_I2C_Driver_LPS22HB.h"
|
||||||
#include "drivers/WipperSnapper_I2C_Driver_LPS25HB.h"
|
#include "drivers/WipperSnapper_I2C_Driver_LPS25HB.h"
|
||||||
|
#include "drivers/WipperSnapper_I2C_Driver_LPS28DFW.h"
|
||||||
#include "drivers/WipperSnapper_I2C_Driver_LPS3XHW.h"
|
#include "drivers/WipperSnapper_I2C_Driver_LPS3XHW.h"
|
||||||
#include "drivers/WipperSnapper_I2C_Driver_LTR329_LTR303.h"
|
#include "drivers/WipperSnapper_I2C_Driver_LTR329_LTR303.h"
|
||||||
#include "drivers/WipperSnapper_I2C_Driver_LTR390.h"
|
#include "drivers/WipperSnapper_I2C_Driver_LTR390.h"
|
||||||
#include "drivers/WipperSnapper_I2C_Driver_MAX17048.h"
|
#include "drivers/WipperSnapper_I2C_Driver_MAX17048.h"
|
||||||
#include "drivers/WipperSnapper_I2C_Driver_MCP3421.h"
|
#include "drivers/WipperSnapper_I2C_Driver_MCP3421.h"
|
||||||
#include "drivers/WipperSnapper_I2C_Driver_MCP9808.h"
|
#include "drivers/WipperSnapper_I2C_Driver_MCP9808.h"
|
||||||
|
#include "drivers/WipperSnapper_I2C_Driver_MLX90632D.h"
|
||||||
#include "drivers/WipperSnapper_I2C_Driver_MPL115A2.h"
|
#include "drivers/WipperSnapper_I2C_Driver_MPL115A2.h"
|
||||||
#include "drivers/WipperSnapper_I2C_Driver_MPRLS.h"
|
#include "drivers/WipperSnapper_I2C_Driver_MPRLS.h"
|
||||||
#include "drivers/WipperSnapper_I2C_Driver_MS8607.h"
|
#include "drivers/WipperSnapper_I2C_Driver_MS8607.h"
|
||||||
#include "drivers/WipperSnapper_I2C_Driver_NAU7802.h"
|
#include "drivers/WipperSnapper_I2C_Driver_NAU7802.h"
|
||||||
|
#include "drivers/WipperSnapper_I2C_Driver_Out.h"
|
||||||
|
#include "drivers/WipperSnapper_I2C_Driver_Out_7Seg.h"
|
||||||
|
#include "drivers/WipperSnapper_I2C_Driver_Out_CharLcd.h"
|
||||||
|
#include "drivers/WipperSnapper_I2C_Driver_Out_QuadAlphaNum.h"
|
||||||
|
#include "drivers/WipperSnapper_I2C_Driver_Out_Sh1107.h"
|
||||||
|
#include "drivers/WipperSnapper_I2C_Driver_Out_Ssd1306.h"
|
||||||
#include "drivers/WipperSnapper_I2C_Driver_PCT2075.h"
|
#include "drivers/WipperSnapper_I2C_Driver_PCT2075.h"
|
||||||
#include "drivers/WipperSnapper_I2C_Driver_PM25.h"
|
#include "drivers/WipperSnapper_I2C_Driver_PM25.h"
|
||||||
#include "drivers/WipperSnapper_I2C_Driver_SCD30.h"
|
#include "drivers/WipperSnapper_I2C_Driver_SCD30.h"
|
||||||
#include "drivers/WipperSnapper_I2C_Driver_SCD4X.h"
|
#include "drivers/WipperSnapper_I2C_Driver_SCD4X.h"
|
||||||
#include "drivers/WipperSnapper_I2C_Driver_SEN5X.h"
|
#include "drivers/WipperSnapper_I2C_Driver_SEN5X.h"
|
||||||
|
#include "drivers/WipperSnapper_I2C_Driver_SEN6X.h"
|
||||||
#include "drivers/WipperSnapper_I2C_Driver_SGP30.h"
|
#include "drivers/WipperSnapper_I2C_Driver_SGP30.h"
|
||||||
#include "drivers/WipperSnapper_I2C_Driver_SGP40.h"
|
#include "drivers/WipperSnapper_I2C_Driver_SGP40.h"
|
||||||
#include "drivers/WipperSnapper_I2C_Driver_SHT3X.h"
|
#include "drivers/WipperSnapper_I2C_Driver_SHT3X.h"
|
||||||
|
|
@ -63,6 +79,7 @@
|
||||||
#include "drivers/WipperSnapper_I2C_Driver_TSL2591.h"
|
#include "drivers/WipperSnapper_I2C_Driver_TSL2591.h"
|
||||||
#include "drivers/WipperSnapper_I2C_Driver_VCNL4020.h"
|
#include "drivers/WipperSnapper_I2C_Driver_VCNL4020.h"
|
||||||
#include "drivers/WipperSnapper_I2C_Driver_VCNL4040.h"
|
#include "drivers/WipperSnapper_I2C_Driver_VCNL4040.h"
|
||||||
|
#include "drivers/WipperSnapper_I2C_Driver_VCNL4200.h"
|
||||||
#include "drivers/WipperSnapper_I2C_Driver_VEML7700.h"
|
#include "drivers/WipperSnapper_I2C_Driver_VEML7700.h"
|
||||||
#include "drivers/WipperSnapper_I2C_Driver_VL53L0X.h"
|
#include "drivers/WipperSnapper_I2C_Driver_VL53L0X.h"
|
||||||
#include "drivers/WipperSnapper_I2C_Driver_VL53L1X.h"
|
#include "drivers/WipperSnapper_I2C_Driver_VL53L1X.h"
|
||||||
|
|
@ -74,6 +91,10 @@
|
||||||
|
|
||||||
// forward decl.
|
// forward decl.
|
||||||
class Wippersnapper;
|
class Wippersnapper;
|
||||||
|
class WipperSnapper_I2C_Driver_INA260;
|
||||||
|
class WipperSnapper_I2C_Driver_INA237;
|
||||||
|
class WipperSnapper_I2C_Driver_INA238;
|
||||||
|
class WipperSnapper_I2C_Driver_INA228;
|
||||||
|
|
||||||
/**************************************************************************/
|
/**************************************************************************/
|
||||||
/*!
|
/*!
|
||||||
|
|
@ -99,6 +120,9 @@ public:
|
||||||
|
|
||||||
void update();
|
void update();
|
||||||
|
|
||||||
|
bool Handle_I2cDeviceOutputWrite(
|
||||||
|
wippersnapper_i2c_v1_I2CDeviceOutputWrite *msgDeviceWrite);
|
||||||
|
|
||||||
void sensorEventRead(
|
void sensorEventRead(
|
||||||
std::vector<WipperSnapper_I2C_Driver *>::iterator &iter,
|
std::vector<WipperSnapper_I2C_Driver *>::iterator &iter,
|
||||||
unsigned long curTime,
|
unsigned long curTime,
|
||||||
|
|
@ -129,9 +153,14 @@ private:
|
||||||
int32_t _portNum;
|
int32_t _portNum;
|
||||||
TwoWire *_i2c = nullptr;
|
TwoWire *_i2c = nullptr;
|
||||||
wippersnapper_i2c_v1_BusResponse _busStatusResponse;
|
wippersnapper_i2c_v1_BusResponse _busStatusResponse;
|
||||||
std::vector<WipperSnapper_I2C_Driver *> drivers; ///< List of sensor drivers
|
std::vector<WipperSnapper_I2C_Driver *>
|
||||||
|
drivers; ///< List of i2c sensor drivers
|
||||||
|
std::vector<WipperSnapper_I2C_Driver_Out *>
|
||||||
|
_drivers_out; ///< List of i2c output drivers
|
||||||
// Sensor driver objects
|
// Sensor driver objects
|
||||||
WipperSnapper_I2C_Driver_AHTX0 *_ahtx0 = nullptr;
|
WipperSnapper_I2C_Driver_AHTX0 *_ahtx0 = nullptr;
|
||||||
|
WipperSnapper_I2C_Driver_AS5600 *_as5600 = nullptr;
|
||||||
|
WipperSnapper_I2C_Driver_D6T1A *_d6t1a = nullptr;
|
||||||
WipperSnapper_I2C_Driver_DPS310 *_dps310 = nullptr;
|
WipperSnapper_I2C_Driver_DPS310 *_dps310 = nullptr;
|
||||||
WipperSnapper_I2C_Driver_DS2484 *_ds2484 = nullptr;
|
WipperSnapper_I2C_Driver_DS2484 *_ds2484 = nullptr;
|
||||||
WipperSnapper_I2C_Driver_ENS160 *_ens160 = nullptr;
|
WipperSnapper_I2C_Driver_ENS160 *_ens160 = nullptr;
|
||||||
|
|
@ -141,14 +170,21 @@ private:
|
||||||
WipperSnapper_I2C_Driver_BMP280 *_bmp280 = nullptr;
|
WipperSnapper_I2C_Driver_BMP280 *_bmp280 = nullptr;
|
||||||
WipperSnapper_I2C_Driver_BMP3XX *_bmp3xx = nullptr;
|
WipperSnapper_I2C_Driver_BMP3XX *_bmp3xx = nullptr;
|
||||||
WipperSnapper_I2C_Driver_BME680 *_bme680 = nullptr;
|
WipperSnapper_I2C_Driver_BME680 *_bme680 = nullptr;
|
||||||
|
WipperSnapper_I2C_Driver_HDC302X *_hdc302x = nullptr;
|
||||||
WipperSnapper_I2C_Driver_HTS221 *_hts221 = nullptr;
|
WipperSnapper_I2C_Driver_HTS221 *_hts221 = nullptr;
|
||||||
WipperSnapper_I2C_Driver_HTU21D *_htu21d = nullptr;
|
WipperSnapper_I2C_Driver_HTU21D *_htu21d = nullptr;
|
||||||
WipperSnapper_I2C_Driver_HTU31D *_htu31d = nullptr;
|
WipperSnapper_I2C_Driver_HTU31D *_htu31d = nullptr;
|
||||||
WipperSnapper_I2C_Driver_INA219 *_ina219 = nullptr;
|
WipperSnapper_I2C_Driver_INA219 *_ina219 = nullptr;
|
||||||
|
WipperSnapper_I2C_Driver_INA237 *_ina237 = nullptr;
|
||||||
|
WipperSnapper_I2C_Driver_INA238 *_ina238 = nullptr;
|
||||||
|
WipperSnapper_I2C_Driver_INA228 *_ina228 = nullptr;
|
||||||
|
WipperSnapper_I2C_Driver_INA260 *_ina260 = nullptr;
|
||||||
WipperSnapper_I2C_Driver_LTR329_LTR303 *_ltr329 = nullptr;
|
WipperSnapper_I2C_Driver_LTR329_LTR303 *_ltr329 = nullptr;
|
||||||
WipperSnapper_I2C_Driver_LTR390 *_ltr390 = nullptr;
|
WipperSnapper_I2C_Driver_LTR390 *_ltr390 = nullptr;
|
||||||
WipperSnapper_I2C_Driver_MCP3421 *_mcp3421 = nullptr;
|
WipperSnapper_I2C_Driver_MCP3421 *_mcp3421 = nullptr;
|
||||||
WipperSnapper_I2C_Driver_MCP9808 *_mcp9808 = nullptr;
|
WipperSnapper_I2C_Driver_MCP9808 *_mcp9808 = nullptr;
|
||||||
|
WipperSnapper_I2C_Driver_MLX90632D *_mlx90632d = nullptr;
|
||||||
|
WipperSnapper_I2C_Driver_MLX90632D *_mlx90632d_ext = nullptr;
|
||||||
WipperSnapper_I2C_Driver_MPL115A2 *_mpl115a2 = nullptr;
|
WipperSnapper_I2C_Driver_MPL115A2 *_mpl115a2 = nullptr;
|
||||||
WipperSnapper_I2C_Driver_MPRLS *_mprls = nullptr;
|
WipperSnapper_I2C_Driver_MPRLS *_mprls = nullptr;
|
||||||
WipperSnapper_I2C_Driver_MS8607 *_ms8607 = nullptr;
|
WipperSnapper_I2C_Driver_MS8607 *_ms8607 = nullptr;
|
||||||
|
|
@ -157,9 +193,11 @@ private:
|
||||||
WipperSnapper_I2C_Driver_TSL2591 *_tsl2591 = nullptr;
|
WipperSnapper_I2C_Driver_TSL2591 *_tsl2591 = nullptr;
|
||||||
WipperSnapper_I2C_Driver_VCNL4020 *_vcnl4020 = nullptr;
|
WipperSnapper_I2C_Driver_VCNL4020 *_vcnl4020 = nullptr;
|
||||||
WipperSnapper_I2C_Driver_VCNL4040 *_vcnl4040 = nullptr;
|
WipperSnapper_I2C_Driver_VCNL4040 *_vcnl4040 = nullptr;
|
||||||
|
WipperSnapper_I2C_Driver_VCNL4200 *_vcnl4200 = nullptr;
|
||||||
WipperSnapper_I2C_Driver_VEML7700 *_veml7700 = nullptr;
|
WipperSnapper_I2C_Driver_VEML7700 *_veml7700 = nullptr;
|
||||||
WipperSnapper_I2C_Driver_SCD4X *_scd40 = nullptr;
|
WipperSnapper_I2C_Driver_SCD4X *_scd40 = nullptr;
|
||||||
WipperSnapper_I2C_Driver_SEN5X *_sen5x = nullptr;
|
WipperSnapper_I2C_Driver_SEN5X *_sen5x = nullptr;
|
||||||
|
WipperSnapper_I2C_Driver_SEN6X *_sen6x = nullptr;
|
||||||
WipperSnapper_I2C_Driver_SGP30 *_sgp30 = nullptr;
|
WipperSnapper_I2C_Driver_SGP30 *_sgp30 = nullptr;
|
||||||
WipperSnapper_I2C_Driver_SGP40 *_sgp40 = nullptr;
|
WipperSnapper_I2C_Driver_SGP40 *_sgp40 = nullptr;
|
||||||
WipperSnapper_I2C_Driver_PCT2075 *_pct2075 = nullptr;
|
WipperSnapper_I2C_Driver_PCT2075 *_pct2075 = nullptr;
|
||||||
|
|
@ -171,6 +209,7 @@ private:
|
||||||
WipperSnapper_I2C_Driver_LC709203F *_lc = nullptr;
|
WipperSnapper_I2C_Driver_LC709203F *_lc = nullptr;
|
||||||
WipperSnapper_I2C_Driver_LPS22HB *_lps22hb = nullptr;
|
WipperSnapper_I2C_Driver_LPS22HB *_lps22hb = nullptr;
|
||||||
WipperSnapper_I2C_Driver_LPS25HB *_lps25hb = nullptr;
|
WipperSnapper_I2C_Driver_LPS25HB *_lps25hb = nullptr;
|
||||||
|
WipperSnapper_I2C_Driver_LPS28DFW *_lps28hb = nullptr;
|
||||||
WipperSnapper_I2C_Driver_LPS3XHW *_lps3xhw = nullptr;
|
WipperSnapper_I2C_Driver_LPS3XHW *_lps3xhw = nullptr;
|
||||||
WipperSnapper_I2C_Driver_STEMMA_Soil_Sensor *_ss = nullptr;
|
WipperSnapper_I2C_Driver_STEMMA_Soil_Sensor *_ss = nullptr;
|
||||||
WipperSnapper_I2C_Driver_VL53L0X *_vl53l0x = nullptr;
|
WipperSnapper_I2C_Driver_VL53L0X *_vl53l0x = nullptr;
|
||||||
|
|
@ -180,6 +219,11 @@ private:
|
||||||
WipperSnapper_I2C_Driver_VL6180X *_vl6180x = nullptr;
|
WipperSnapper_I2C_Driver_VL6180X *_vl6180x = nullptr;
|
||||||
WipperSnapper_I2C_Driver_MAX17048 *_max17048 = nullptr;
|
WipperSnapper_I2C_Driver_MAX17048 *_max17048 = nullptr;
|
||||||
WipperSnapper_I2C_Driver_ADT7410 *_adt7410 = nullptr;
|
WipperSnapper_I2C_Driver_ADT7410 *_adt7410 = nullptr;
|
||||||
|
WipperSnapper_I2C_Driver_Out_QuadAlphaNum *_quadAlphaNum = nullptr;
|
||||||
|
WipperSnapper_I2C_Driver_Out_CharLcd *_charLcd = nullptr;
|
||||||
|
WipperSnapper_I2C_Driver_Out_7Seg *_sevenSeg = nullptr;
|
||||||
|
WipperSnapper_I2C_Driver_Out_SH1107 *_sh1107 = nullptr;
|
||||||
|
WipperSnapper_I2C_Driver_Out_Ssd1306 *_ssd1306 = nullptr;
|
||||||
};
|
};
|
||||||
extern Wippersnapper WS;
|
extern Wippersnapper WS;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,8 +16,10 @@
|
||||||
#ifndef WipperSnapper_I2C_Driver_H
|
#ifndef WipperSnapper_I2C_Driver_H
|
||||||
#define WipperSnapper_I2C_Driver_H
|
#define WipperSnapper_I2C_Driver_H
|
||||||
|
|
||||||
|
#include "wippersnapper/i2c/v1/i2c.pb.h"
|
||||||
#include <Adafruit_Sensor.h>
|
#include <Adafruit_Sensor.h>
|
||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
|
#include <Wire.h>
|
||||||
|
|
||||||
#define PERIOD_24HRS_AGO_MILLIS (millis() - (24 * 60 * 60 * 1000))
|
#define PERIOD_24HRS_AGO_MILLIS (millis() - (24 * 60 * 60 * 1000))
|
||||||
///< Used for last sensor read time, initially set 24hrs ago (max period)
|
///< Used for last sensor read time, initially set 24hrs ago (max period)
|
||||||
|
|
@ -1234,7 +1236,7 @@ public:
|
||||||
@brief Enables the device's proximity sensor, if it exists.
|
@brief Enables the device's proximity sensor, if it exists.
|
||||||
*/
|
*/
|
||||||
/*******************************************************************************/
|
/*******************************************************************************/
|
||||||
virtual void enableSensorProximity(){};
|
virtual void enableSensorProximity() {};
|
||||||
|
|
||||||
/*******************************************************************************/
|
/*******************************************************************************/
|
||||||
/*!
|
/*!
|
||||||
|
|
|
||||||
155
src/components/i2c/drivers/WipperSnapper_I2C_Driver_AS5600.h
Normal file
155
src/components/i2c/drivers/WipperSnapper_I2C_Driver_AS5600.h
Normal file
|
|
@ -0,0 +1,155 @@
|
||||||
|
/*!
|
||||||
|
* @file WipperSnapper_I2C_Driver_AS5600.h
|
||||||
|
*
|
||||||
|
* Device driver for the AS5600 Magnetic Angle sensor.
|
||||||
|
*
|
||||||
|
* Adafruit invests time and resources providing this open source code,
|
||||||
|
* please support Adafruit and open-source hardware by purchasing
|
||||||
|
* products from Adafruit!
|
||||||
|
*
|
||||||
|
* Copyright (c) Tyeth Gundry 2024 for Adafruit Industries.
|
||||||
|
*
|
||||||
|
* MIT license, all text here must be included in any redistribution.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef WipperSnapper_I2C_Driver_AS5600_H
|
||||||
|
#define WipperSnapper_I2C_Driver_AS5600_H
|
||||||
|
|
||||||
|
#include <Adafruit_AS5600.h>
|
||||||
|
|
||||||
|
#include "WipperSnapper_I2C_Driver.h"
|
||||||
|
#include "Wippersnapper.h"
|
||||||
|
|
||||||
|
/**************************************************************************/
|
||||||
|
/*!
|
||||||
|
@brief Class that provides a driver interface for a AS5600 sensor.
|
||||||
|
*/
|
||||||
|
/**************************************************************************/
|
||||||
|
class WipperSnapper_I2C_Driver_AS5600 : public WipperSnapper_I2C_Driver {
|
||||||
|
public:
|
||||||
|
/*******************************************************************************/
|
||||||
|
/*!
|
||||||
|
@brief Constructor for the AS5600 sensor.
|
||||||
|
@param i2c
|
||||||
|
The I2C interface.
|
||||||
|
@param sensorAddress
|
||||||
|
7-bit device address.
|
||||||
|
*/
|
||||||
|
/*******************************************************************************/
|
||||||
|
WipperSnapper_I2C_Driver_AS5600(TwoWire *i2c, uint16_t sensorAddress)
|
||||||
|
: WipperSnapper_I2C_Driver(i2c, sensorAddress) {
|
||||||
|
_as5600 = nullptr;
|
||||||
|
_angle = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************/
|
||||||
|
/*!
|
||||||
|
@brief Destructor for an AS5600 sensor.
|
||||||
|
*/
|
||||||
|
/*******************************************************************************/
|
||||||
|
~WipperSnapper_I2C_Driver_AS5600() {
|
||||||
|
if (_as5600) {
|
||||||
|
delete _as5600;
|
||||||
|
_as5600 = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************/
|
||||||
|
/*!
|
||||||
|
@brief Initializes the AS5600 sensor and begins I2C.
|
||||||
|
@returns True if initialized successfully, False otherwise.
|
||||||
|
*/
|
||||||
|
/*******************************************************************************/
|
||||||
|
bool begin() {
|
||||||
|
_as5600 = new Adafruit_AS5600();
|
||||||
|
if (!_as5600->begin((uint8_t)_sensorAddress, _i2c)) {
|
||||||
|
WS_DEBUG_PRINTLN("Failed to find AS5600 chip");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!configureSensor()) {
|
||||||
|
WS_DEBUG_PRINTLN("Failed to configure AS5600 sensor");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************/
|
||||||
|
/*!
|
||||||
|
@brief Configures the AS5600 sensor.
|
||||||
|
@returns True if the sensor was configured successfully, False otherwise.
|
||||||
|
*/
|
||||||
|
/*******************************************************************************/
|
||||||
|
bool configureSensor() {
|
||||||
|
return _as5600->enableWatchdog(false) &&
|
||||||
|
// Normal (high) power mode
|
||||||
|
_as5600->setPowerMode(AS5600_POWER_MODE_NOM) &&
|
||||||
|
// No Hysteresis
|
||||||
|
_as5600->setHysteresis(AS5600_HYSTERESIS_OFF) &&
|
||||||
|
// analog output (0-VCC for 0-360 degrees)
|
||||||
|
_as5600->setOutputStage(AS5600_OUTPUT_STAGE_ANALOG_FULL) &&
|
||||||
|
// setup filters
|
||||||
|
_as5600->setSlowFilter(AS5600_SLOW_FILTER_16X) &&
|
||||||
|
_as5600->setFastFilterThresh(AS5600_FAST_FILTER_THRESH_SLOW_ONLY) &&
|
||||||
|
// Reset position settings to defaults
|
||||||
|
_as5600->setZPosition(0) && _as5600->setMPosition(4095) &&
|
||||||
|
_as5600->setMaxAngle(4095);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************/
|
||||||
|
/*!
|
||||||
|
@brief Reads the Angle sensor.
|
||||||
|
@returns True if the sensor was read successfully, False otherwise.
|
||||||
|
*/
|
||||||
|
/*******************************************************************************/
|
||||||
|
bool readSensor() {
|
||||||
|
if (!_as5600->isMagnetDetected()) {
|
||||||
|
WS_DEBUG_PRINTLN("Magnet not detected!");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Continuously read and display angle values
|
||||||
|
uint16_t rawAngle = _as5600->getRawAngle();
|
||||||
|
uint16_t angle = _as5600->getAngle();
|
||||||
|
|
||||||
|
WS_DEBUG_PRINT("AS5600 Raw: ");
|
||||||
|
WS_DEBUG_PRINT(rawAngle);
|
||||||
|
WS_DEBUG_PRINT(" | Scaled: ");
|
||||||
|
WS_DEBUG_PRINT(angle);
|
||||||
|
|
||||||
|
// Check status conditions
|
||||||
|
if (_as5600->isAGCminGainOverflow()) {
|
||||||
|
WS_DEBUG_PRINTLN(" | MH: magnet too strong");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (_as5600->isAGCmaxGainOverflow()) {
|
||||||
|
WS_DEBUG_PRINTLN(" | ML: magnet too weak");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
_angle = ((float)angle / 4095.0) * 360.0;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************/
|
||||||
|
/*!
|
||||||
|
@brief Reads the Angle sensor with short wait for data.
|
||||||
|
@param rawEvent
|
||||||
|
Angle sensor reading
|
||||||
|
@returns True if the sensor event was obtained successfully, False
|
||||||
|
otherwise.
|
||||||
|
*/
|
||||||
|
/*******************************************************************************/
|
||||||
|
bool getEventRaw(sensors_event_t *rawEvent) {
|
||||||
|
if (!readSensor()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
rawEvent->data[0] = _angle;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
float _angle; ///< Current angle reading from the AS5600 sensor
|
||||||
|
Adafruit_AS5600 *_as5600; ///< Pointer to AS5600 sensor object
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // WipperSnapper_I2C_Driver_AS5600
|
||||||
|
|
@ -130,7 +130,7 @@ public:
|
||||||
bool getEventPressure(sensors_event_t *pressureEvent) {
|
bool getEventPressure(sensors_event_t *pressureEvent) {
|
||||||
if (!bmePerformReading())
|
if (!bmePerformReading())
|
||||||
return false;
|
return false;
|
||||||
pressureEvent->pressure = (float)_bme->pressure;
|
pressureEvent->pressure = (float)_bme->pressure / 100.0;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -172,4 +172,4 @@ protected:
|
||||||
Adafruit_BME680 *_bme; ///< BME680 object
|
Adafruit_BME680 *_bme; ///< BME680 object
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // WipperSnapper_I2C_Driver_BME680
|
#endif // WipperSnapper_I2C_Driver_BME680
|
||||||
|
|
|
||||||
142
src/components/i2c/drivers/WipperSnapper_I2C_Driver_D6T1A.h
Normal file
142
src/components/i2c/drivers/WipperSnapper_I2C_Driver_D6T1A.h
Normal file
|
|
@ -0,0 +1,142 @@
|
||||||
|
/*!
|
||||||
|
* @file WipperSnapper_I2C_Driver_D6T1A.h
|
||||||
|
*
|
||||||
|
* Device driver for a D6T1A thermal sensor.
|
||||||
|
*
|
||||||
|
* Adafruit invests time and resources providing this open source code,
|
||||||
|
* please support Adafruit and open-source hardware by purchasing
|
||||||
|
* products from Adafruit!
|
||||||
|
*
|
||||||
|
* Copyright (c) Tyeth Gundry 2025 for Adafruit Industries.
|
||||||
|
*
|
||||||
|
* MIT license, all text here must be included in any redistribution.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef WipperSnapper_I2C_Driver_D6T1A_H
|
||||||
|
#define WipperSnapper_I2C_Driver_D6T1A_H
|
||||||
|
|
||||||
|
#include <OmronD6T.h>
|
||||||
|
|
||||||
|
#include "WipperSnapper_I2C_Driver.h"
|
||||||
|
|
||||||
|
/**************************************************************************/
|
||||||
|
/*!
|
||||||
|
@brief Class that provides a sensor driver for the D6T1A temperature
|
||||||
|
and pressure sensor.
|
||||||
|
*/
|
||||||
|
/**************************************************************************/
|
||||||
|
class WipperSnapper_I2C_Driver_D6T1A : public WipperSnapper_I2C_Driver {
|
||||||
|
public:
|
||||||
|
/*******************************************************************************/
|
||||||
|
/*!
|
||||||
|
@brief Constructor for an D6T1A sensor.
|
||||||
|
@param i2c
|
||||||
|
The I2C interface.
|
||||||
|
@param sensorAddress
|
||||||
|
7-bit device address.
|
||||||
|
*/
|
||||||
|
/*******************************************************************************/
|
||||||
|
WipperSnapper_I2C_Driver_D6T1A(TwoWire *i2c, uint16_t sensorAddress)
|
||||||
|
: WipperSnapper_I2C_Driver(i2c, sensorAddress) {
|
||||||
|
_i2c = i2c;
|
||||||
|
_sensorAddress = sensorAddress;
|
||||||
|
_deviceTemp = NAN;
|
||||||
|
_objectTemp = NAN;
|
||||||
|
_lastRead = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************/
|
||||||
|
/*!
|
||||||
|
@brief Destructor for an D6T1A sensor.
|
||||||
|
*/
|
||||||
|
/*******************************************************************************/
|
||||||
|
~WipperSnapper_I2C_Driver_D6T1A() { delete _d6t1a; }
|
||||||
|
|
||||||
|
/*******************************************************************************/
|
||||||
|
/*!
|
||||||
|
@brief Initializes the D6T1A sensor and begins I2C.
|
||||||
|
@returns True if initialized successfully, False otherwise.
|
||||||
|
*/
|
||||||
|
/*******************************************************************************/
|
||||||
|
bool begin() {
|
||||||
|
_d6t1a = new OmronD6T(OmronD6T::D6T_1A, _i2c);
|
||||||
|
// attempt to initialize D6T1A
|
||||||
|
if (!_d6t1a->begin(_sensorAddress))
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************/
|
||||||
|
/*!
|
||||||
|
@brief Checks if sensor was read within last 1s, or is the first read.
|
||||||
|
@returns True if the sensor was recently read, False otherwise.
|
||||||
|
*/
|
||||||
|
/*******************************************************************************/
|
||||||
|
bool HasBeenReadInLast200ms() {
|
||||||
|
return _lastRead != 0 && millis() - _lastRead < 200;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************/
|
||||||
|
/*!
|
||||||
|
@brief Reads the sensor.
|
||||||
|
@returns True if the sensor was read successfully, False otherwise.
|
||||||
|
*/
|
||||||
|
/*******************************************************************************/
|
||||||
|
bool ReadSensorData() {
|
||||||
|
// dont read sensor more than once per 200ms
|
||||||
|
if (HasBeenReadInLast200ms()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
_d6t1a->read();
|
||||||
|
_deviceTemp = (float)_d6t1a->ambientTempC();
|
||||||
|
_objectTemp = (float)_d6t1a->objectTempC(0, 0);
|
||||||
|
_lastRead = millis();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************/
|
||||||
|
/*!
|
||||||
|
@brief Gets the D6T1A's current temperature.
|
||||||
|
@param tempEvent
|
||||||
|
Pointer to an Adafruit_Sensor event.
|
||||||
|
@returns True if the temperature was obtained successfully, False
|
||||||
|
otherwise.
|
||||||
|
*/
|
||||||
|
/*******************************************************************************/
|
||||||
|
bool getEventAmbientTemp(sensors_event_t *tempEvent) {
|
||||||
|
if (ReadSensorData() && _deviceTemp != NAN) {
|
||||||
|
// if the sensor was read recently, return the cached temperature
|
||||||
|
tempEvent->temperature = _deviceTemp;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false; // sensor not read recently, return false
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************/
|
||||||
|
/*!
|
||||||
|
@brief Gets the D6T1A's object temperature.
|
||||||
|
@param tempEvent
|
||||||
|
Pointer to an Adafruit_Sensor event.
|
||||||
|
@returns True if the temperature was obtained successfully, False
|
||||||
|
otherwise.
|
||||||
|
*/
|
||||||
|
/*******************************************************************************/
|
||||||
|
bool getEventObjectTemp(sensors_event_t *tempEvent) {
|
||||||
|
if (ReadSensorData() && _objectTemp != NAN) {
|
||||||
|
// if the sensor was read recently, return the cached temperature
|
||||||
|
tempEvent->temperature = _objectTemp;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false; // sensor not read recently, return false
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
float _deviceTemp; ///< Device temperature in Celsius
|
||||||
|
float _objectTemp; ///< Object temperature in Celsius
|
||||||
|
uint32_t _lastRead; ///< Last time the sensor was read in milliseconds
|
||||||
|
OmronD6T *_d6t1a = nullptr; ///< D6T1A object
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // WipperSnapper_I2C_Driver_D6T1A
|
||||||
130
src/components/i2c/drivers/WipperSnapper_I2C_Driver_HDC302X.h
Normal file
130
src/components/i2c/drivers/WipperSnapper_I2C_Driver_HDC302X.h
Normal file
|
|
@ -0,0 +1,130 @@
|
||||||
|
/*!
|
||||||
|
* @file WipperSnapper_I2C_Driver_HDC302X.h
|
||||||
|
*
|
||||||
|
* Device driver for an HDC302X Humidity and Temperature sensor.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef WipperSnapper_I2C_Driver_HDC302X_H
|
||||||
|
#define WipperSnapper_I2C_Driver_HDC302X_H
|
||||||
|
|
||||||
|
#include "WipperSnapper_I2C_Driver.h"
|
||||||
|
#include <Adafruit_HDC302x.h>
|
||||||
|
|
||||||
|
/**************************************************************************/
|
||||||
|
/*!
|
||||||
|
@brief Class that provides a sensor driver for the HDC302X humidity and
|
||||||
|
temperature sensor. This implementation uses the 1 Hz data rate.
|
||||||
|
*/
|
||||||
|
/**************************************************************************/
|
||||||
|
class WipperSnapper_I2C_Driver_HDC302X : public WipperSnapper_I2C_Driver {
|
||||||
|
|
||||||
|
public:
|
||||||
|
/*******************************************************************************/
|
||||||
|
/*!
|
||||||
|
@brief Constructor for an HDC302X sensor.
|
||||||
|
@param i2c
|
||||||
|
The I2C interface.
|
||||||
|
@param sensorAddress
|
||||||
|
7-bit device address.
|
||||||
|
*/
|
||||||
|
/*******************************************************************************/
|
||||||
|
WipperSnapper_I2C_Driver_HDC302X(TwoWire *i2c, uint16_t sensorAddress)
|
||||||
|
: WipperSnapper_I2C_Driver(i2c, sensorAddress) {
|
||||||
|
_i2c = i2c;
|
||||||
|
_sensorAddress = sensorAddress;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************/
|
||||||
|
/*!
|
||||||
|
@brief Destructor for an HDC302X sensor.
|
||||||
|
*/
|
||||||
|
/*******************************************************************************/
|
||||||
|
~WipperSnapper_I2C_Driver_HDC302X() { delete _hdc302x; }
|
||||||
|
|
||||||
|
/*******************************************************************************/
|
||||||
|
/*!
|
||||||
|
@brief Initializes the HDC302X sensor and begins I2C.
|
||||||
|
@returns True if initialized successfully, False otherwise.
|
||||||
|
|
||||||
|
*/
|
||||||
|
/*******************************************************************************/
|
||||||
|
bool begin() {
|
||||||
|
// attempt to initialize the HDC302X using the I2C interface
|
||||||
|
_hdc302x = new Adafruit_HDC302x();
|
||||||
|
if (!_hdc302x->begin(_sensorAddress, _i2c))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// set the HDC302X's data rate to 1 Hz lowest noise
|
||||||
|
_hdc302x->setAutoMode(EXIT_AUTO_MODE);
|
||||||
|
// discard first reading (It returned -45c for me once)
|
||||||
|
_hdc302x->readTemperatureHumidityOnDemand(_temp, _humidity,
|
||||||
|
TRIGGERMODE_LP0);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************/
|
||||||
|
/*!
|
||||||
|
@brief Reads the HDC302X's temperature and humidity data.
|
||||||
|
@returns True if the data was read successfully, False otherwise.
|
||||||
|
*/
|
||||||
|
/*******************************************************************************/
|
||||||
|
bool ReadSensorData() {
|
||||||
|
uint16_t status = _hdc302x->readStatus();
|
||||||
|
if (status & 0x0010) {
|
||||||
|
WS_DEBUG_PRINTLN(F("Device Reset Detected"));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status & 0x0001) {
|
||||||
|
WS_DEBUG_PRINTLN(
|
||||||
|
F("Checksum Verification Fail (incorrect checksum received)"));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!_hdc302x->readTemperatureHumidityOnDemand(_temp, _humidity,
|
||||||
|
TRIGGERMODE_LP0)) {
|
||||||
|
WS_DEBUG_PRINTLN(F("Failed to read temperature and humidity."));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************/
|
||||||
|
/*!
|
||||||
|
@brief Gets the HDC302X's current temperature.
|
||||||
|
@param tempEvent
|
||||||
|
Pointer to an Adafruit_Sensor event.
|
||||||
|
@returns True if the temperature was obtained successfully, False
|
||||||
|
otherwise.
|
||||||
|
*/
|
||||||
|
/*******************************************************************************/
|
||||||
|
bool getEventAmbientTemp(sensors_event_t *tempEvent) {
|
||||||
|
if (ReadSensorData() == false)
|
||||||
|
return false;
|
||||||
|
tempEvent->temperature = _temp;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************/
|
||||||
|
/*!
|
||||||
|
@brief Gets the HDC302X's current humidity.
|
||||||
|
@param humidEvent
|
||||||
|
Pointer to an Adafruit_Sensor event.
|
||||||
|
@returns True if the humidity was obtained successfully, False
|
||||||
|
otherwise.
|
||||||
|
*/
|
||||||
|
/*******************************************************************************/
|
||||||
|
bool getEventRelativeHumidity(sensors_event_t *humidEvent) {
|
||||||
|
if (ReadSensorData() == false)
|
||||||
|
return false;
|
||||||
|
humidEvent->relative_humidity = _humidity;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Adafruit_HDC302x *_hdc302x; ///< Pointer to an HDC302X object
|
||||||
|
double _temp = 0.0; ///< Holds data for the HDC302X's temperature sensor
|
||||||
|
double _humidity = 0.0; ///< Holds data for the HDC302X's humidity sensor
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // WipperSnapper_I2C_Driver_HDC302X
|
||||||
109
src/components/i2c/drivers/WipperSnapper_I2C_Driver_INA228.cpp
Normal file
109
src/components/i2c/drivers/WipperSnapper_I2C_Driver_INA228.cpp
Normal file
|
|
@ -0,0 +1,109 @@
|
||||||
|
/*!
|
||||||
|
* @file WipperSnapper_I2C_Driver_INA228.cpp
|
||||||
|
*
|
||||||
|
* Device driver implementation for the INA228 High Precision DC Current and
|
||||||
|
* Voltage Monitor (Avoids import conflict with INA260 typedef enum _mode etc)
|
||||||
|
*
|
||||||
|
* Adafruit invests time and resources providing this open source code,
|
||||||
|
* please support Adafruit and open-source hardware by purchasing
|
||||||
|
* products from Adafruit!
|
||||||
|
*
|
||||||
|
* Copyright (c) Tyeth Gundry 2025 for Adafruit Industries.
|
||||||
|
*
|
||||||
|
* MIT license, all text here must be included in any redistribution.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "WipperSnapper_I2C_Driver_INA228.h"
|
||||||
|
#include "Wippersnapper.h"
|
||||||
|
#include <Adafruit_INA228.h>
|
||||||
|
|
||||||
|
/*******************************************************************************/
|
||||||
|
/*!
|
||||||
|
@brief Constructor for a INA228 sensor.
|
||||||
|
@param i2c
|
||||||
|
The I2C interface.
|
||||||
|
@param sensorAddress
|
||||||
|
The 7-bit I2C address of the sensor.
|
||||||
|
*/
|
||||||
|
/*******************************************************************************/
|
||||||
|
WipperSnapper_I2C_Driver_INA228::WipperSnapper_I2C_Driver_INA228(
|
||||||
|
TwoWire *i2c, uint16_t sensorAddress)
|
||||||
|
: WipperSnapper_I2C_Driver(i2c, sensorAddress), _ina228(nullptr) {
|
||||||
|
_i2c = i2c;
|
||||||
|
_sensorAddress = sensorAddress;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************/
|
||||||
|
/*!
|
||||||
|
@brief Destructor for an INA228 sensor.
|
||||||
|
*/
|
||||||
|
/*******************************************************************************/
|
||||||
|
WipperSnapper_I2C_Driver_INA228::~WipperSnapper_I2C_Driver_INA228() {
|
||||||
|
delete _ina228;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************/
|
||||||
|
/*!
|
||||||
|
@brief Initializes the INA228 sensor and begins I2C.
|
||||||
|
@returns True if initialized successfully, False otherwise.
|
||||||
|
*/
|
||||||
|
/*******************************************************************************/
|
||||||
|
bool WipperSnapper_I2C_Driver_INA228::begin() {
|
||||||
|
_ina228 = new Adafruit_INA228();
|
||||||
|
if (!_ina228->begin(_sensorAddress, _i2c)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Default shunt: 0.015 ohm, 10A max current
|
||||||
|
_ina228->setShunt(0.015, 10.0);
|
||||||
|
|
||||||
|
_ina228->setAveragingCount(INA228_COUNT_16);
|
||||||
|
_ina228->setVoltageConversionTime(INA228_TIME_150_us);
|
||||||
|
_ina228->setCurrentConversionTime(INA228_TIME_280_us);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************/
|
||||||
|
/*!
|
||||||
|
@brief Reads a voltage sensor and converts the
|
||||||
|
reading into the expected SI unit.
|
||||||
|
@param voltageEvent
|
||||||
|
voltage sensor reading, in volts.
|
||||||
|
@returns True if the sensor event was obtained successfully, False
|
||||||
|
otherwise.
|
||||||
|
*/
|
||||||
|
/*******************************************************************************/
|
||||||
|
bool WipperSnapper_I2C_Driver_INA228::getEventVoltage(
|
||||||
|
sensors_event_t *voltageEvent) {
|
||||||
|
voltageEvent->voltage = _ina228->getBusVoltage_V();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the current sensor event.
|
||||||
|
*
|
||||||
|
* @param currentEvent Pointer to the current sensor event.
|
||||||
|
*
|
||||||
|
* @returns True if the sensor event was obtained successfully, False
|
||||||
|
* otherwise.
|
||||||
|
*/
|
||||||
|
bool WipperSnapper_I2C_Driver_INA228::getEventCurrent(
|
||||||
|
sensors_event_t *currentEvent) {
|
||||||
|
currentEvent->current = _ina228->getCurrent_mA();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the raw (power) sensor event.
|
||||||
|
*
|
||||||
|
* @param powerEvent Pointer to the power sensor event.
|
||||||
|
*
|
||||||
|
* @returns True if the sensor event was obtained successfully, False
|
||||||
|
* otherwise.
|
||||||
|
*/
|
||||||
|
bool WipperSnapper_I2C_Driver_INA228::getEventRaw(sensors_event_t *powerEvent) {
|
||||||
|
powerEvent->data[0] = _ina228->getPower_mW();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
43
src/components/i2c/drivers/WipperSnapper_I2C_Driver_INA228.h
Normal file
43
src/components/i2c/drivers/WipperSnapper_I2C_Driver_INA228.h
Normal file
|
|
@ -0,0 +1,43 @@
|
||||||
|
/*!
|
||||||
|
* @file WipperSnapper_I2C_Driver_INA228.h
|
||||||
|
*
|
||||||
|
* Device driver for the INA228 High Precision DC Current and Voltage Monitor
|
||||||
|
*
|
||||||
|
* Adafruit invests time and resources providing this open source code,
|
||||||
|
* please support Adafruit and open-source hardware by purchasing
|
||||||
|
* products from Adafruit!
|
||||||
|
*
|
||||||
|
* Copyright (c) Tyeth Gundry 2025 for Adafruit Industries.
|
||||||
|
*
|
||||||
|
* MIT license, all text here must be included in any redistribution.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef WipperSnapper_I2C_Driver_INA228_H
|
||||||
|
#define WipperSnapper_I2C_Driver_INA228_H
|
||||||
|
|
||||||
|
#include "WipperSnapper_I2C_Driver.h"
|
||||||
|
#include "Wippersnapper.h"
|
||||||
|
|
||||||
|
// Forward declaration
|
||||||
|
class Adafruit_INA228;
|
||||||
|
|
||||||
|
/**************************************************************************/
|
||||||
|
/*!
|
||||||
|
@brief Class that provides a driver interface for a INA228 sensor.
|
||||||
|
*/
|
||||||
|
/**************************************************************************/
|
||||||
|
class WipperSnapper_I2C_Driver_INA228 : public WipperSnapper_I2C_Driver {
|
||||||
|
public:
|
||||||
|
WipperSnapper_I2C_Driver_INA228(TwoWire *i2c, uint16_t sensorAddress);
|
||||||
|
~WipperSnapper_I2C_Driver_INA228();
|
||||||
|
|
||||||
|
bool begin();
|
||||||
|
bool getEventVoltage(sensors_event_t *voltageEvent);
|
||||||
|
bool getEventCurrent(sensors_event_t *currentEvent);
|
||||||
|
bool getEventRaw(sensors_event_t *powerEvent);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Adafruit_INA228 *_ina228; ///< Pointer to INA228 sensor object
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // WipperSnapper_I2C_Driver_INA228_H
|
||||||
114
src/components/i2c/drivers/WipperSnapper_I2C_Driver_INA237.cpp
Normal file
114
src/components/i2c/drivers/WipperSnapper_I2C_Driver_INA237.cpp
Normal file
|
|
@ -0,0 +1,114 @@
|
||||||
|
/*!
|
||||||
|
* @file WipperSnapper_I2C_Driver_INA237.cpp
|
||||||
|
*
|
||||||
|
* Device driver implementation for the INA237 DC Current and Voltage Monitor
|
||||||
|
* (Avoids import conflict with INA260 typedef enum _mode etc)
|
||||||
|
*
|
||||||
|
* Adafruit invests time and resources providing this open source code,
|
||||||
|
* please support Adafruit and open-source hardware by purchasing
|
||||||
|
* products from Adafruit!
|
||||||
|
*
|
||||||
|
* Copyright (c) Tyeth Gundry 2025 for Adafruit Industries.
|
||||||
|
*
|
||||||
|
* MIT license, all text here must be included in any redistribution.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "WipperSnapper_I2C_Driver_INA237.h"
|
||||||
|
#include "Wippersnapper.h"
|
||||||
|
#include <Adafruit_INA237.h>
|
||||||
|
|
||||||
|
/*******************************************************************************/
|
||||||
|
/*!
|
||||||
|
@brief Constructor for a INA237 sensor.
|
||||||
|
@param i2c
|
||||||
|
The I2C interface.
|
||||||
|
@param sensorAddress
|
||||||
|
The 7-bit I2C address of the sensor.
|
||||||
|
*/
|
||||||
|
/*******************************************************************************/
|
||||||
|
WipperSnapper_I2C_Driver_INA237::WipperSnapper_I2C_Driver_INA237(
|
||||||
|
TwoWire *i2c, uint16_t sensorAddress)
|
||||||
|
: WipperSnapper_I2C_Driver(i2c, sensorAddress), _ina237(nullptr) {
|
||||||
|
_i2c = i2c;
|
||||||
|
_sensorAddress = sensorAddress;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************/
|
||||||
|
/*!
|
||||||
|
@brief Destructor for an INA237 sensor.
|
||||||
|
*/
|
||||||
|
/*******************************************************************************/
|
||||||
|
WipperSnapper_I2C_Driver_INA237::~WipperSnapper_I2C_Driver_INA237() {
|
||||||
|
delete _ina237;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************/
|
||||||
|
/*!
|
||||||
|
@brief Initializes the INA237 sensor and begins I2C.
|
||||||
|
@returns True if initialized successfully, False otherwise.
|
||||||
|
*/
|
||||||
|
/*******************************************************************************/
|
||||||
|
bool WipperSnapper_I2C_Driver_INA237::begin() {
|
||||||
|
_ina237 = new Adafruit_INA237();
|
||||||
|
if (!_ina237->begin(_sensorAddress, _i2c)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Configuration based on INA237 example sketch
|
||||||
|
// Set default shunt resistance and maximum current
|
||||||
|
// Default 0.015 ohm shunt, 10A max current
|
||||||
|
_ina237->setShunt(0.015, 10.0);
|
||||||
|
|
||||||
|
// Set averaging for better accuracy (16 samples)
|
||||||
|
_ina237->setAveragingCount(INA2XX_COUNT_16);
|
||||||
|
|
||||||
|
// Set conversion times as per example
|
||||||
|
_ina237->setVoltageConversionTime(INA2XX_TIME_150_us);
|
||||||
|
_ina237->setCurrentConversionTime(INA2XX_TIME_280_us);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************/
|
||||||
|
/*!
|
||||||
|
@brief Reads a voltage sensor and converts the
|
||||||
|
reading into the expected SI unit.
|
||||||
|
@param voltageEvent
|
||||||
|
voltage sensor reading, in volts.
|
||||||
|
@returns True if the sensor event was obtained successfully, False
|
||||||
|
otherwise.
|
||||||
|
*/
|
||||||
|
/*******************************************************************************/
|
||||||
|
bool WipperSnapper_I2C_Driver_INA237::getEventVoltage(
|
||||||
|
sensors_event_t *voltageEvent) {
|
||||||
|
voltageEvent->voltage = _ina237->getBusVoltage_V();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the current sensor event.
|
||||||
|
*
|
||||||
|
* @param currentEvent Pointer to the current sensor event.
|
||||||
|
*
|
||||||
|
* @returns True if the sensor event was obtained successfully, False
|
||||||
|
* otherwise.
|
||||||
|
*/
|
||||||
|
bool WipperSnapper_I2C_Driver_INA237::getEventCurrent(
|
||||||
|
sensors_event_t *currentEvent) {
|
||||||
|
currentEvent->current = _ina237->getCurrent_mA();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the raw (power) sensor event.
|
||||||
|
*
|
||||||
|
* @param powerEvent Pointer to the power sensor event.
|
||||||
|
*
|
||||||
|
* @returns True if the sensor event was obtained successfully, False
|
||||||
|
* otherwise.
|
||||||
|
*/
|
||||||
|
bool WipperSnapper_I2C_Driver_INA237::getEventRaw(sensors_event_t *powerEvent) {
|
||||||
|
powerEvent->data[0] = _ina237->getPower_mW();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
45
src/components/i2c/drivers/WipperSnapper_I2C_Driver_INA237.h
Normal file
45
src/components/i2c/drivers/WipperSnapper_I2C_Driver_INA237.h
Normal file
|
|
@ -0,0 +1,45 @@
|
||||||
|
/*!
|
||||||
|
* @file WipperSnapper_I2C_Driver_INA237.h
|
||||||
|
*
|
||||||
|
* Device driver for the INA237 DC Current and Voltage Monitor
|
||||||
|
* 16-bit ADC with ±0.3% gain error, ±50µV offset voltage
|
||||||
|
* Cost-effective version, lower precision than INA238
|
||||||
|
*
|
||||||
|
* Adafruit invests time and resources providing this open source code,
|
||||||
|
* please support Adafruit and open-source hardware by purchasing
|
||||||
|
* products from Adafruit!
|
||||||
|
*
|
||||||
|
* Copyright (c) Tyeth Gundry 2025 for Adafruit Industries.
|
||||||
|
*
|
||||||
|
* MIT license, all text here must be included in any redistribution.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef WipperSnapper_I2C_Driver_INA237_H
|
||||||
|
#define WipperSnapper_I2C_Driver_INA237_H
|
||||||
|
|
||||||
|
#include "WipperSnapper_I2C_Driver.h"
|
||||||
|
#include "Wippersnapper.h"
|
||||||
|
|
||||||
|
// Forward declaration
|
||||||
|
class Adafruit_INA237;
|
||||||
|
|
||||||
|
/**************************************************************************/
|
||||||
|
/*!
|
||||||
|
@brief Class that provides a driver interface for a INA237 sensor.
|
||||||
|
*/
|
||||||
|
/**************************************************************************/
|
||||||
|
class WipperSnapper_I2C_Driver_INA237 : public WipperSnapper_I2C_Driver {
|
||||||
|
public:
|
||||||
|
WipperSnapper_I2C_Driver_INA237(TwoWire *i2c, uint16_t sensorAddress);
|
||||||
|
~WipperSnapper_I2C_Driver_INA237();
|
||||||
|
|
||||||
|
bool begin();
|
||||||
|
bool getEventVoltage(sensors_event_t *voltageEvent);
|
||||||
|
bool getEventCurrent(sensors_event_t *currentEvent);
|
||||||
|
bool getEventRaw(sensors_event_t *powerEvent);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Adafruit_INA237 *_ina237; ///< Pointer to INA237 sensor object
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // WipperSnapper_I2C_Driver_INA237
|
||||||
114
src/components/i2c/drivers/WipperSnapper_I2C_Driver_INA238.cpp
Normal file
114
src/components/i2c/drivers/WipperSnapper_I2C_Driver_INA238.cpp
Normal file
|
|
@ -0,0 +1,114 @@
|
||||||
|
/*!
|
||||||
|
* @file WipperSnapper_I2C_Driver_INA238.cpp
|
||||||
|
*
|
||||||
|
* Device driver implementation for the INA238 High-precision DC Current and
|
||||||
|
* Voltage Monitor (Avoids import conflict with INA260 typedef enum _mode etc)
|
||||||
|
*
|
||||||
|
* Adafruit invests time and resources providing this open source code,
|
||||||
|
* please support Adafruit and open-source hardware by purchasing
|
||||||
|
* products from Adafruit!
|
||||||
|
*
|
||||||
|
* Copyright (c) Tyeth Gundry 2025 for Adafruit Industries.
|
||||||
|
*
|
||||||
|
* MIT license, all text here must be included in any redistribution.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "WipperSnapper_I2C_Driver_INA238.h"
|
||||||
|
#include "Wippersnapper.h"
|
||||||
|
#include <Adafruit_INA238.h>
|
||||||
|
|
||||||
|
/*******************************************************************************/
|
||||||
|
/*!
|
||||||
|
@brief Constructor for a INA238 sensor.
|
||||||
|
@param i2c
|
||||||
|
The I2C interface.
|
||||||
|
@param sensorAddress
|
||||||
|
The 7-bit I2C address of the sensor.
|
||||||
|
*/
|
||||||
|
/*******************************************************************************/
|
||||||
|
WipperSnapper_I2C_Driver_INA238::WipperSnapper_I2C_Driver_INA238(
|
||||||
|
TwoWire *i2c, uint16_t sensorAddress)
|
||||||
|
: WipperSnapper_I2C_Driver(i2c, sensorAddress), _ina238(nullptr) {
|
||||||
|
_i2c = i2c;
|
||||||
|
_sensorAddress = sensorAddress;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************/
|
||||||
|
/*!
|
||||||
|
@brief Destructor for an INA238 sensor.
|
||||||
|
*/
|
||||||
|
/*******************************************************************************/
|
||||||
|
WipperSnapper_I2C_Driver_INA238::~WipperSnapper_I2C_Driver_INA238() {
|
||||||
|
delete _ina238;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************/
|
||||||
|
/*!
|
||||||
|
@brief Initializes the INA238 sensor and begins I2C.
|
||||||
|
@returns True if initialized successfully, False otherwise.
|
||||||
|
*/
|
||||||
|
/*******************************************************************************/
|
||||||
|
bool WipperSnapper_I2C_Driver_INA238::begin() {
|
||||||
|
_ina238 = new Adafruit_INA238();
|
||||||
|
if (!_ina238->begin(_sensorAddress, _i2c)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Configuration based on INA238 example sketch
|
||||||
|
// Set default shunt resistance and maximum current
|
||||||
|
// Default 0.015 ohm shunt, 10A max current
|
||||||
|
_ina238->setShunt(0.015, 10.0);
|
||||||
|
|
||||||
|
// Set averaging for better accuracy (16 samples)
|
||||||
|
_ina238->setAveragingCount(INA2XX_COUNT_16);
|
||||||
|
|
||||||
|
// Set conversion times as per example
|
||||||
|
_ina238->setVoltageConversionTime(INA2XX_TIME_150_us);
|
||||||
|
_ina238->setCurrentConversionTime(INA2XX_TIME_280_us);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************/
|
||||||
|
/*!
|
||||||
|
@brief Reads a voltage sensor and converts the
|
||||||
|
reading into the expected SI unit.
|
||||||
|
@param voltageEvent
|
||||||
|
voltage sensor reading, in volts.
|
||||||
|
@returns True if the sensor event was obtained successfully, False
|
||||||
|
otherwise.
|
||||||
|
*/
|
||||||
|
/*******************************************************************************/
|
||||||
|
bool WipperSnapper_I2C_Driver_INA238::getEventVoltage(
|
||||||
|
sensors_event_t *voltageEvent) {
|
||||||
|
voltageEvent->voltage = _ina238->getBusVoltage_V();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the current sensor event.
|
||||||
|
*
|
||||||
|
* @param currentEvent Pointer to the current sensor event.
|
||||||
|
*
|
||||||
|
* @returns True if the sensor event was obtained successfully, False
|
||||||
|
* otherwise.
|
||||||
|
*/
|
||||||
|
bool WipperSnapper_I2C_Driver_INA238::getEventCurrent(
|
||||||
|
sensors_event_t *currentEvent) {
|
||||||
|
currentEvent->current = _ina238->getCurrent_mA();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the Raw (power) sensor event.
|
||||||
|
*
|
||||||
|
* @param powerEvent Pointer to the power sensor event.
|
||||||
|
*
|
||||||
|
* @returns True if the sensor event was obtained successfully, False
|
||||||
|
* otherwise.
|
||||||
|
*/
|
||||||
|
bool WipperSnapper_I2C_Driver_INA238::getEventRaw(sensors_event_t *powerEvent) {
|
||||||
|
powerEvent->data[0] = _ina238->getPower_mW();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
44
src/components/i2c/drivers/WipperSnapper_I2C_Driver_INA238.h
Normal file
44
src/components/i2c/drivers/WipperSnapper_I2C_Driver_INA238.h
Normal file
|
|
@ -0,0 +1,44 @@
|
||||||
|
/*!
|
||||||
|
* @file WipperSnapper_I2C_Driver_INA238.h
|
||||||
|
*
|
||||||
|
* Device driver for the INA238 High-precision DC Current and Voltage Monitor
|
||||||
|
* 16-bit ADC with ±0.1% gain error, ±5µV offset voltage
|
||||||
|
* Higher precision version compared to INA237
|
||||||
|
*
|
||||||
|
* Adafruit invests time and resources providing this open source code,
|
||||||
|
* please support Adafruit and open-source hardware by purchasing
|
||||||
|
* products from Adafruit!
|
||||||
|
*
|
||||||
|
* Copyright (c) Tyeth Gundry 2025 for Adafruit Industries.
|
||||||
|
*
|
||||||
|
* MIT license, all text here must be included in any redistribution.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef WipperSnapper_I2C_Driver_INA238_H
|
||||||
|
#define WipperSnapper_I2C_Driver_INA238_H
|
||||||
|
|
||||||
|
#include "WipperSnapper_I2C_Driver.h"
|
||||||
|
|
||||||
|
// Forward declaration
|
||||||
|
class Adafruit_INA238;
|
||||||
|
|
||||||
|
/**************************************************************************/
|
||||||
|
/*!
|
||||||
|
@brief Class that provides a driver interface for a INA238 sensor.
|
||||||
|
*/
|
||||||
|
/**************************************************************************/
|
||||||
|
class WipperSnapper_I2C_Driver_INA238 : public WipperSnapper_I2C_Driver {
|
||||||
|
public:
|
||||||
|
WipperSnapper_I2C_Driver_INA238(TwoWire *i2c, uint16_t sensorAddress);
|
||||||
|
~WipperSnapper_I2C_Driver_INA238();
|
||||||
|
|
||||||
|
bool begin();
|
||||||
|
bool getEventVoltage(sensors_event_t *voltageEvent);
|
||||||
|
bool getEventCurrent(sensors_event_t *currentEvent);
|
||||||
|
bool getEventRaw(sensors_event_t *powerEvent);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Adafruit_INA238 *_ina238; ///< Pointer to INA238 sensor object
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // WipperSnapper_I2C_Driver_INA238
|
||||||
|
|
@ -0,0 +1,89 @@
|
||||||
|
/*!
|
||||||
|
* @file WipperSnapper_I2C_Driver_INA260.cpp
|
||||||
|
*
|
||||||
|
* Device driver implementation for the INA260 DC Current and Voltage Monitor
|
||||||
|
*
|
||||||
|
* Adafruit invests time and resources providing this open source code,
|
||||||
|
* please support Adafruit and open-source hardware by purchasing
|
||||||
|
* products from Adafruit!
|
||||||
|
*
|
||||||
|
* Copyright (c) Tyeth Gundry 2025 for Adafruit Industries.
|
||||||
|
*
|
||||||
|
* MIT license, all text here must be included in any redistribution.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "WipperSnapper_I2C_Driver_INA260.h"
|
||||||
|
#include "Wippersnapper.h"
|
||||||
|
#include <Adafruit_INA260.h>
|
||||||
|
|
||||||
|
/*******************************************************************************/
|
||||||
|
/*!
|
||||||
|
@brief Constructor for a INA260 sensor.
|
||||||
|
@param i2c
|
||||||
|
The I2C interface.
|
||||||
|
@param sensorAddress
|
||||||
|
The 7-bit I2C address of the sensor.
|
||||||
|
*/
|
||||||
|
/*******************************************************************************/
|
||||||
|
WipperSnapper_I2C_Driver_INA260::WipperSnapper_I2C_Driver_INA260(
|
||||||
|
TwoWire *i2c, uint16_t sensorAddress)
|
||||||
|
: WipperSnapper_I2C_Driver(i2c, sensorAddress), _ina260(nullptr) {
|
||||||
|
_i2c = i2c;
|
||||||
|
_sensorAddress = sensorAddress;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************/
|
||||||
|
/*!
|
||||||
|
@brief Destructor for an INA260 sensor.
|
||||||
|
*/
|
||||||
|
/*******************************************************************************/
|
||||||
|
WipperSnapper_I2C_Driver_INA260::~WipperSnapper_I2C_Driver_INA260() {
|
||||||
|
delete _ina260;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************/
|
||||||
|
/*!
|
||||||
|
@brief Initializes the INA260 sensor and begins I2C.
|
||||||
|
@returns True if initialized successfully, False otherwise.
|
||||||
|
*/
|
||||||
|
/*******************************************************************************/
|
||||||
|
bool WipperSnapper_I2C_Driver_INA260::begin() {
|
||||||
|
_ina260 = new Adafruit_INA260();
|
||||||
|
if (!_ina260->begin(_sensorAddress, _i2c)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// TODO: use setCalibration()
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************/
|
||||||
|
/*!
|
||||||
|
@brief Reads a voltage sensor and converts the
|
||||||
|
reading into the expected SI unit.
|
||||||
|
@param voltageEvent
|
||||||
|
voltage sensor reading, in volts.
|
||||||
|
@returns True if the sensor event was obtained successfully, False
|
||||||
|
otherwise.
|
||||||
|
*/
|
||||||
|
/*******************************************************************************/
|
||||||
|
bool WipperSnapper_I2C_Driver_INA260::getEventVoltage(
|
||||||
|
sensors_event_t *voltageEvent) {
|
||||||
|
voltageEvent->voltage = _ina260->readBusVoltage() / 1000.0f;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the current sensor event.
|
||||||
|
*
|
||||||
|
* @param currentEvent Pointer to the current sensor event.
|
||||||
|
*
|
||||||
|
* @returns True if the sensor event was obtained successfully, False
|
||||||
|
* otherwise.
|
||||||
|
*/
|
||||||
|
bool WipperSnapper_I2C_Driver_INA260::getEventCurrent(
|
||||||
|
sensors_event_t *currentEvent) {
|
||||||
|
currentEvent->current = _ina260->readCurrent();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
41
src/components/i2c/drivers/WipperSnapper_I2C_Driver_INA260.h
Normal file
41
src/components/i2c/drivers/WipperSnapper_I2C_Driver_INA260.h
Normal file
|
|
@ -0,0 +1,41 @@
|
||||||
|
/*!
|
||||||
|
* @file WipperSnapper_I2C_Driver_INA260.h
|
||||||
|
*
|
||||||
|
* Device driver for the INA260 DC Current and Voltage Monitor
|
||||||
|
*
|
||||||
|
* Adafruit invests time and resources providing this open source code,
|
||||||
|
* please support Adafruit and open-source hardware by purchasing
|
||||||
|
* products from Adafruit!
|
||||||
|
*
|
||||||
|
* Copyright (c) Tyeth Gundry 2025 for Adafruit Industries.
|
||||||
|
*
|
||||||
|
* MIT license, all text here must be included in any redistribution.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef WipperSnapper_I2C_Driver_INA260_H
|
||||||
|
#define WipperSnapper_I2C_Driver_INA260_H
|
||||||
|
|
||||||
|
#include "WipperSnapper_I2C_Driver.h"
|
||||||
|
|
||||||
|
// Forward declaration
|
||||||
|
class Adafruit_INA260;
|
||||||
|
|
||||||
|
/**************************************************************************/
|
||||||
|
/*!
|
||||||
|
@brief Class that provides a driver interface for a INA260 sensor.
|
||||||
|
*/
|
||||||
|
/**************************************************************************/
|
||||||
|
class WipperSnapper_I2C_Driver_INA260 : public WipperSnapper_I2C_Driver {
|
||||||
|
public:
|
||||||
|
WipperSnapper_I2C_Driver_INA260(TwoWire *i2c, uint16_t sensorAddress);
|
||||||
|
~WipperSnapper_I2C_Driver_INA260();
|
||||||
|
|
||||||
|
bool begin();
|
||||||
|
bool getEventVoltage(sensors_event_t *voltageEvent);
|
||||||
|
bool getEventCurrent(sensors_event_t *currentEvent);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Adafruit_INA260 *_ina260 = nullptr; ///< Pointer to INA260 sensor object
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // WipperSnapper_I2C_Driver_INA260
|
||||||
151
src/components/i2c/drivers/WipperSnapper_I2C_Driver_LPS28DFW.h
Normal file
151
src/components/i2c/drivers/WipperSnapper_I2C_Driver_LPS28DFW.h
Normal file
|
|
@ -0,0 +1,151 @@
|
||||||
|
/*!
|
||||||
|
* @file WipperSnapper_I2C_Driver_LPS28DFW.h
|
||||||
|
*
|
||||||
|
* Device driver for a LPS28DFW precision pressure sensor breakout.
|
||||||
|
*
|
||||||
|
* Adafruit invests time and resources providing this open source code,
|
||||||
|
* please support Adafruit and open-source hardware by purchasing
|
||||||
|
* products from Adafruit!
|
||||||
|
*
|
||||||
|
* Copyright (c) Tyeth Gundry 2025 for Adafruit Industries.
|
||||||
|
*
|
||||||
|
* MIT license, all text here must be included in any redistribution.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef WipperSnapper_I2C_Driver_LPS28DFW_H
|
||||||
|
#define WipperSnapper_I2C_Driver_LPS28DFW_H
|
||||||
|
|
||||||
|
#include "WipperSnapper_I2C_Driver.h"
|
||||||
|
#include <Adafruit_LPS28.h>
|
||||||
|
|
||||||
|
/**************************************************************************/
|
||||||
|
/*!
|
||||||
|
@brief Class that provides a sensor driver for the LPS28DFW temperature
|
||||||
|
and pressure sensor.
|
||||||
|
*/
|
||||||
|
/**************************************************************************/
|
||||||
|
class WipperSnapper_I2C_Driver_LPS28DFW : public WipperSnapper_I2C_Driver {
|
||||||
|
|
||||||
|
public:
|
||||||
|
/*******************************************************************************/
|
||||||
|
/*!
|
||||||
|
@brief Constructor for an LPS28DFW sensor.
|
||||||
|
@param i2c
|
||||||
|
The I2C interface.
|
||||||
|
@param sensorAddress
|
||||||
|
7-bit device address.
|
||||||
|
*/
|
||||||
|
/*******************************************************************************/
|
||||||
|
WipperSnapper_I2C_Driver_LPS28DFW(TwoWire *i2c, uint16_t sensorAddress)
|
||||||
|
: WipperSnapper_I2C_Driver(i2c, sensorAddress) {
|
||||||
|
_i2c = i2c;
|
||||||
|
_sensorAddress = sensorAddress;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************/
|
||||||
|
/*!
|
||||||
|
@brief Destructor for an LPS28DFW sensor.
|
||||||
|
*/
|
||||||
|
/*******************************************************************************/
|
||||||
|
~WipperSnapper_I2C_Driver_LPS28DFW() { delete _lps28; }
|
||||||
|
|
||||||
|
/*******************************************************************************/
|
||||||
|
/*!
|
||||||
|
@brief Initializes the LPS28DFW sensor and begins I2C.
|
||||||
|
@returns True if initialized successfully, False otherwise.
|
||||||
|
*/
|
||||||
|
/*******************************************************************************/
|
||||||
|
bool begin() {
|
||||||
|
_lps28 = new Adafruit_LPS28();
|
||||||
|
// attempt to initialize LPS28DFW
|
||||||
|
if (!_lps28->begin(_i2c, _sensorAddress))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Set up sample rate and filter initialization
|
||||||
|
if (!_lps28->setDataRate(LPS28_ODR_ONESHOT)) {
|
||||||
|
WS_DEBUG_PRINTLN("Failed to set data rate");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!_lps28->setAveraging(LPS28_AVG_512)) {
|
||||||
|
WS_DEBUG_PRINTLN("Failed to set averaging");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!_lps28->setFullScaleMode(true)) {
|
||||||
|
WS_DEBUG_PRINTLN("Failed to set 4060hPa max mode");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************/
|
||||||
|
/*!
|
||||||
|
@brief Reads the sensor and stores the data in the object.
|
||||||
|
@returns True if the sensor was read successfully, False otherwise.
|
||||||
|
*/
|
||||||
|
/*******************************************************************************/
|
||||||
|
bool readSensor() {
|
||||||
|
// grab one reading to seed the sensor
|
||||||
|
if (!_lps28->triggerOneShot()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wait (block up to 100ms) until data is ready
|
||||||
|
for (uint8_t i = 0; i < 100; i++) {
|
||||||
|
if (_lps28->getStatus() & LPS28_STATUS_PRESS_READY) {
|
||||||
|
if (_temp == NULL) {
|
||||||
|
_temp = _lps28->getTemperatureSensor();
|
||||||
|
}
|
||||||
|
if (_pressure == NULL) {
|
||||||
|
_pressure = _lps28->getPressureSensor();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
delay(1);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************/
|
||||||
|
/*!
|
||||||
|
@brief Gets the LPS28DFW's current temperature.
|
||||||
|
@param tempEvent
|
||||||
|
Pointer to an Adafruit_Sensor event.
|
||||||
|
@returns True if the temperature was obtained successfully, False
|
||||||
|
otherwise.
|
||||||
|
*/
|
||||||
|
/*******************************************************************************/
|
||||||
|
bool getEventAmbientTemp(sensors_event_t *tempEvent) {
|
||||||
|
if (!readSensor())
|
||||||
|
return false;
|
||||||
|
_temp->getEvent(tempEvent);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************/
|
||||||
|
/*!
|
||||||
|
@brief Reads a pressure sensor and converts
|
||||||
|
the reading into the expected SI unit.
|
||||||
|
@param pressureEvent
|
||||||
|
Pointer to an Adafruit_Sensor event.
|
||||||
|
@returns True if the sensor event was obtained successfully, False
|
||||||
|
otherwise.
|
||||||
|
*/
|
||||||
|
/*******************************************************************************/
|
||||||
|
bool getEventPressure(sensors_event_t *pressureEvent) {
|
||||||
|
if (!readSensor())
|
||||||
|
return false;
|
||||||
|
_pressure->getEvent(pressureEvent);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Adafruit_LPS28 *_lps28 = nullptr; ///< LPS28DFW object
|
||||||
|
Adafruit_Sensor *_temp =
|
||||||
|
NULL; ///< Ptr to an adafruit_sensor representing the temperature
|
||||||
|
Adafruit_Sensor *_pressure =
|
||||||
|
NULL; ///< Ptr to an adafruit_sensor representing the pressure
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // WipperSnapper_I2C_Driver_LPS28DFW
|
||||||
233
src/components/i2c/drivers/WipperSnapper_I2C_Driver_MLX90632D.h
Normal file
233
src/components/i2c/drivers/WipperSnapper_I2C_Driver_MLX90632D.h
Normal file
|
|
@ -0,0 +1,233 @@
|
||||||
|
/*!
|
||||||
|
* @file WipperSnapper_I2C_Driver_MLX90632D.h
|
||||||
|
*
|
||||||
|
* Device driver for a Melexis MLX90632-D (medical) thermal FIR sensor.
|
||||||
|
*
|
||||||
|
* Adafruit invests time and resources providing this open source code,
|
||||||
|
* please support Adafruit and open-source hardware by purchasing
|
||||||
|
* products from Adafruit!
|
||||||
|
*
|
||||||
|
* Copyright (c) Tyeth Gundry 2025 for Adafruit Industries.
|
||||||
|
*
|
||||||
|
* MIT license, all text here must be included in any redistribution.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef WipperSnapper_I2C_Driver_MLX90632D_H
|
||||||
|
#define WipperSnapper_I2C_Driver_MLX90632D_H
|
||||||
|
|
||||||
|
#include <Adafruit_MLX90632.h>
|
||||||
|
|
||||||
|
#include "WipperSnapper_I2C_Driver.h"
|
||||||
|
|
||||||
|
/**************************************************************************/
|
||||||
|
/*!
|
||||||
|
@brief Sensor driver for the Melexis MLX90632-D temperature sensor.
|
||||||
|
*/
|
||||||
|
/**************************************************************************/
|
||||||
|
class WipperSnapper_I2C_Driver_MLX90632D : public WipperSnapper_I2C_Driver {
|
||||||
|
public:
|
||||||
|
/*******************************************************************************/
|
||||||
|
/*!
|
||||||
|
@brief Constructor for an MLX90632 sensor.
|
||||||
|
@param i2c
|
||||||
|
The I2C interface.
|
||||||
|
@param sensorAddress
|
||||||
|
7-bit device address.
|
||||||
|
*/
|
||||||
|
/*******************************************************************************/
|
||||||
|
WipperSnapper_I2C_Driver_MLX90632D(TwoWire *i2c, uint16_t sensorAddress)
|
||||||
|
: WipperSnapper_I2C_Driver(i2c, sensorAddress) {
|
||||||
|
_i2c = i2c;
|
||||||
|
_sensorAddress = sensorAddress;
|
||||||
|
_mlx90632 = nullptr;
|
||||||
|
_deviceTemp = NAN;
|
||||||
|
_objectTemp = NAN;
|
||||||
|
_lastRead = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************/
|
||||||
|
/*!
|
||||||
|
@brief Destructor for an MLX90632 sensor.
|
||||||
|
*/
|
||||||
|
/*******************************************************************************/
|
||||||
|
~WipperSnapper_I2C_Driver_MLX90632D() {
|
||||||
|
if (_mlx90632) {
|
||||||
|
delete _mlx90632;
|
||||||
|
_mlx90632 = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************/
|
||||||
|
/*!
|
||||||
|
@brief Initializes the MLX90632 sensor and begins I2C.
|
||||||
|
@returns True if initialized successfully, False otherwise.
|
||||||
|
*/
|
||||||
|
/*******************************************************************************/
|
||||||
|
bool begin() {
|
||||||
|
if (_mlx90632) {
|
||||||
|
delete _mlx90632;
|
||||||
|
_mlx90632 = nullptr;
|
||||||
|
}
|
||||||
|
_mlx90632 = new Adafruit_MLX90632();
|
||||||
|
// attempt to initialize MLX90632
|
||||||
|
if (!_mlx90632->begin(_sensorAddress, _i2c))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return ConfigureAndPrintSensorInfo();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************/
|
||||||
|
/*!
|
||||||
|
@brief Configures the MLX90632 sensor and prints its information.
|
||||||
|
@param extendedInsteadOfMedicalRange
|
||||||
|
If true, configures the sensor for extended temperature
|
||||||
|
range/acc.
|
||||||
|
@returns True if configuration fetching and setting were successful.
|
||||||
|
*/
|
||||||
|
/*******************************************************************************/
|
||||||
|
bool ConfigureAndPrintSensorInfo(bool extendedInsteadOfMedicalRange = false) {
|
||||||
|
// Reset the device
|
||||||
|
if (!_mlx90632->reset()) {
|
||||||
|
WS_DEBUG_PRINTLN(F("Device reset failed"));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t productCode = _mlx90632->getProductCode();
|
||||||
|
// Decode product code bits
|
||||||
|
uint8_t fov = (productCode >> 8) & 0x3;
|
||||||
|
uint8_t package = (productCode >> 5) & 0x7;
|
||||||
|
uint8_t accuracy = productCode & 0x1F;
|
||||||
|
|
||||||
|
if (!_mlx90632->setMode(MLX90632_MODE_CONTINUOUS)) {
|
||||||
|
WS_DEBUG_PRINTLN(F("Failed to set mode"));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// set accuracy mode based on medical if detected
|
||||||
|
if (accuracy == 1) {
|
||||||
|
// Set and get measurement select (medical)
|
||||||
|
if (!extendedInsteadOfMedicalRange &&
|
||||||
|
!_mlx90632->setMeasurementSelect(MLX90632_MEAS_MEDICAL)) {
|
||||||
|
WS_DEBUG_PRINTLN(F("Failed to set measurement select to Medical"));
|
||||||
|
return false;
|
||||||
|
} else if (extendedInsteadOfMedicalRange &&
|
||||||
|
!_mlx90632->setMeasurementSelect(
|
||||||
|
MLX90632_MEAS_EXTENDED_RANGE)) {
|
||||||
|
WS_DEBUG_PRINTLN(
|
||||||
|
F("Failed to set measurement select to Extended Range"));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set and get refresh rate (default to 2Hz)
|
||||||
|
if (!_mlx90632->setRefreshRate(MLX90632_REFRESH_2HZ)) {
|
||||||
|
WS_DEBUG_PRINTLN(F("Failed to set refresh rate to 2Hz"));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!_mlx90632->resetNewData()) {
|
||||||
|
WS_DEBUG_PRINTLN(F("Failed to reset new data flag"));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************/
|
||||||
|
/*!
|
||||||
|
@brief Checks if sensor was read within last 1s, or is the first read.
|
||||||
|
@returns True if the sensor was recently read, False otherwise.
|
||||||
|
*/
|
||||||
|
/*******************************************************************************/
|
||||||
|
bool HasBeenReadInLast200ms() {
|
||||||
|
return _lastRead != 0 && millis() - _lastRead < 200;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************/
|
||||||
|
/*!
|
||||||
|
@brief Reads the sensor.
|
||||||
|
@returns True if the sensor was read successfully, False otherwise.
|
||||||
|
*/
|
||||||
|
/*******************************************************************************/
|
||||||
|
bool ReadSensorData() {
|
||||||
|
bool result = false;
|
||||||
|
if (HasBeenReadInLast200ms()) {
|
||||||
|
WS_DEBUG_PRINTLN(F("Sensor was read recently, using cached data"));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if we need to trigger a new measurement for step modes
|
||||||
|
mlx90632_mode_t currentMode = _mlx90632->getMode();
|
||||||
|
if (currentMode == MLX90632_MODE_STEP ||
|
||||||
|
currentMode == MLX90632_MODE_SLEEPING_STEP) {
|
||||||
|
// Trigger single measurement (SOC bit) for step modes
|
||||||
|
if (!_mlx90632->startSingleMeasurement()) {
|
||||||
|
WS_DEBUG_PRINTLN(F("Failed to start single measurement"));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
delay(510); // Wait for measurement to complete @ 2Hz
|
||||||
|
}
|
||||||
|
|
||||||
|
// Only check new data flag - much more efficient for continuous mode
|
||||||
|
if (_mlx90632->isNewData()) {
|
||||||
|
_deviceTemp = _mlx90632->getAmbientTemperature();
|
||||||
|
_objectTemp = _mlx90632->getObjectTemperature();
|
||||||
|
if (isnan(_objectTemp)) {
|
||||||
|
WS_DEBUG_PRINTLN(F("NaN (invalid cycle position)"));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
result = true;
|
||||||
|
_lastRead = millis();
|
||||||
|
// Reset new data flag after reading
|
||||||
|
if (!_mlx90632->resetNewData()) {
|
||||||
|
WS_DEBUG_PRINTLN(F("Failed to reset new data flag"));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
WS_DEBUG_PRINTLN(F("No new data available, skipping read"));
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************/
|
||||||
|
/*!
|
||||||
|
@brief Gets the MLX90632's current temperature.
|
||||||
|
@param tempEvent
|
||||||
|
Pointer to an Adafruit_Sensor event.
|
||||||
|
@returns True if the temperature was obtained successfully, False
|
||||||
|
otherwise.
|
||||||
|
*/
|
||||||
|
/*******************************************************************************/
|
||||||
|
bool getEventAmbientTemp(sensors_event_t *tempEvent) {
|
||||||
|
if (ReadSensorData() && _deviceTemp != NAN) {
|
||||||
|
tempEvent->temperature = _deviceTemp;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false; // sensor not read recently, return false
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************/
|
||||||
|
/*!
|
||||||
|
@brief Gets the MLX90632's object temperature.
|
||||||
|
@param tempEvent
|
||||||
|
Pointer to an Adafruit_Sensor event.
|
||||||
|
@returns True if the temperature was obtained successfully, False
|
||||||
|
otherwise.
|
||||||
|
*/
|
||||||
|
/*******************************************************************************/
|
||||||
|
bool getEventObjectTemp(sensors_event_t *tempEvent) {
|
||||||
|
if (ReadSensorData() && _objectTemp != NAN) {
|
||||||
|
tempEvent->temperature = _objectTemp;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false; // sensor not read recently, return false
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
double _deviceTemp; ///< Device temperature in Celsius
|
||||||
|
double _objectTemp; ///< Object temperature in Celsius
|
||||||
|
uint32_t _lastRead; ///< Last time the sensor was read in milliseconds
|
||||||
|
Adafruit_MLX90632 *_mlx90632 = nullptr; ///< MLX90632 object
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // WipperSnapper_I2C_Driver_MLX90632D_H
|
||||||
145
src/components/i2c/drivers/WipperSnapper_I2C_Driver_Out.h
Normal file
145
src/components/i2c/drivers/WipperSnapper_I2C_Driver_Out.h
Normal file
|
|
@ -0,0 +1,145 @@
|
||||||
|
/*!
|
||||||
|
* @file WipperSnapper_I2C_Driver_Out.h
|
||||||
|
*
|
||||||
|
* Derived class for I2C output driver components
|
||||||
|
*
|
||||||
|
* Adafruit invests time and resources providing this open source code,
|
||||||
|
* please support Adafruit and open-source hardware by purchasing
|
||||||
|
* products from Adafruit!
|
||||||
|
*
|
||||||
|
* Copyright (c) Brent Rubell 2025 for Adafruit Industries.
|
||||||
|
*
|
||||||
|
* MIT license, all text here must be included in any redistribution.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef WIPPERSNAPPER_I2C_DRIVER_OUT_H
|
||||||
|
#define WIPPERSNAPPER_I2C_DRIVER_OUT_H
|
||||||
|
|
||||||
|
#include "WipperSnapper_I2C_Driver.h"
|
||||||
|
#include <Arduino.h>
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@brief Derived class for I2C output component drivers.
|
||||||
|
*/
|
||||||
|
class WipperSnapper_I2C_Driver_Out : public WipperSnapper_I2C_Driver {
|
||||||
|
|
||||||
|
public:
|
||||||
|
/*!
|
||||||
|
@brief Creates a new I2C output component driver.
|
||||||
|
@param i2c
|
||||||
|
The I2C hardware interface, default is Wire.
|
||||||
|
@param sensorAddress
|
||||||
|
The I2C sensor's unique address.
|
||||||
|
*/
|
||||||
|
WipperSnapper_I2C_Driver_Out(TwoWire *i2c, uint16_t sensorAddress)
|
||||||
|
: WipperSnapper_I2C_Driver(i2c, sensorAddress) {
|
||||||
|
// No-op constructor
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@brief Destructor for an I2C output component.
|
||||||
|
*/
|
||||||
|
virtual ~WipperSnapper_I2C_Driver_Out() {
|
||||||
|
// No-op destructor
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@brief Writes a message to an i2c output device.
|
||||||
|
@param message
|
||||||
|
The message to be displayed.
|
||||||
|
*/
|
||||||
|
virtual void WriteMessage(const char *message) {
|
||||||
|
// noop
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@brief Configures a SSD1306 OLED display. Must be called before driver
|
||||||
|
begin()
|
||||||
|
@param width
|
||||||
|
The width of the display in pixels.
|
||||||
|
@param height
|
||||||
|
The height of the display in pixels.
|
||||||
|
@param text_size
|
||||||
|
The display's text size.
|
||||||
|
@param rotation
|
||||||
|
The rotation of the display in degrees, default is 0.
|
||||||
|
*/
|
||||||
|
virtual void ConfigureSSD1306(uint8_t width, uint8_t height,
|
||||||
|
uint8_t text_size, uint8_t rotation = 0) {
|
||||||
|
// noop
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@brief Writes a message to the SSD1306 display.
|
||||||
|
@param message
|
||||||
|
The message to be displayed.
|
||||||
|
*/
|
||||||
|
virtual void WriteMessageSSD1306(const char *message) {
|
||||||
|
// noop
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@brief Configures a LED backpack.
|
||||||
|
@param brightness
|
||||||
|
The brightness of the LED backpack.
|
||||||
|
@param alignment
|
||||||
|
The alignment of the LED backpack.
|
||||||
|
*/
|
||||||
|
virtual void ConfigureI2CBackpack(int32_t brightness, uint32_t alignment) {
|
||||||
|
// noop
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@brief Sets the brightness of the LED backpack.
|
||||||
|
@param b
|
||||||
|
The brightness value, from 0 (off) to 15 (full brightness).
|
||||||
|
*/
|
||||||
|
virtual void SetLedBackpackBrightness(uint8_t b) {
|
||||||
|
// noop
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@brief Writes a message to the LED backpack.
|
||||||
|
@param msg_write
|
||||||
|
Pointer to a wippersnapper_i2c_v1_LedBackpackWrite message.
|
||||||
|
*/
|
||||||
|
void WriteLedBackpack(wippersnapper_i2c_v1_LEDBackpackWrite *msg_write) {
|
||||||
|
WriteMessage(msg_write->message);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@brief Configures a character LCD.
|
||||||
|
@param rows
|
||||||
|
The number of rows in the LCD.
|
||||||
|
@param cols
|
||||||
|
The number of columns in the LCD.
|
||||||
|
*/
|
||||||
|
virtual void ConfigureCharLcd(uint32_t rows, uint32_t cols) {
|
||||||
|
// noop
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@brief Turns the character LCD backlight on or off.
|
||||||
|
@param enable
|
||||||
|
True to enable the backlight, false to disable it.
|
||||||
|
*/
|
||||||
|
void EnableCharLcdBacklight(bool enable) {
|
||||||
|
// noop
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@brief Writes a message to the LCD.
|
||||||
|
@param write_char_lcd
|
||||||
|
Points to a CharLCDWrite message.
|
||||||
|
@param enable_backlight
|
||||||
|
True if the backlight should be enabled, false otherwise.
|
||||||
|
*/
|
||||||
|
void WriteMessageCharLCD(wippersnapper_i2c_v1_CharLCDWrite *write_char_lcd,
|
||||||
|
bool enable_backlight = true) {
|
||||||
|
EnableCharLcdBacklight(enable_backlight);
|
||||||
|
WriteMessage(write_char_lcd->message);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // WIPPERSNAPPER_I2C_DRIVER_OUT_H
|
||||||
209
src/components/i2c/drivers/WipperSnapper_I2C_Driver_Out_7Seg.h
Normal file
209
src/components/i2c/drivers/WipperSnapper_I2C_Driver_Out_7Seg.h
Normal file
|
|
@ -0,0 +1,209 @@
|
||||||
|
/*!
|
||||||
|
* @file WipperSnapper_I2C_Driver_Out_7Seg.h
|
||||||
|
*
|
||||||
|
* Device driver designed specifically to work with the Adafruit LED 7-Segment
|
||||||
|
* I2C backpacks:
|
||||||
|
* ----> http://www.adafruit.com/products/881
|
||||||
|
* ----> http://www.adafruit.com/products/880
|
||||||
|
* ----> http://www.adafruit.com/products/879
|
||||||
|
* ----> http://www.adafruit.com/products/878
|
||||||
|
*
|
||||||
|
* Adafruit invests time and resources providing this open source code,
|
||||||
|
* please support Adafruit and open-source hardware by purchasing
|
||||||
|
* products from Adafruit!
|
||||||
|
*
|
||||||
|
* Copyright (c) Brent Rubell for Adafruit Industries 2025
|
||||||
|
*
|
||||||
|
* MIT license, all text here must be included in any redistribution.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef WIPPERSNAPPER_I2C_DRIVER_OUT_7SEG_H
|
||||||
|
#define WIPPERSNAPPER_I2C_DRIVER_OUT_7SEG_H
|
||||||
|
|
||||||
|
#include "WipperSnapper_I2C_Driver_Out.h"
|
||||||
|
#include <Adafruit_LEDBackpack.h>
|
||||||
|
#include <Arduino.h>
|
||||||
|
|
||||||
|
#define LED_BACKPACK_ALIGNMENT_UNSPECIFIED 0 ///< Unspecified alignment
|
||||||
|
#define LED_BACKPACK_ALIGNMENT_LEFT 1 ///< Left alignment
|
||||||
|
#define LED_BACKPACK_ALIGNMENT_RIGHT 2 ///< Right alignment
|
||||||
|
#define LED_BACKPACK_ALIGNMENT_DEFAULT \
|
||||||
|
LED_BACKPACK_ALIGNMENT_LEFT ///< Default alignment
|
||||||
|
#define LED_MAX_CHARS \
|
||||||
|
5 ///< Maximum characters for 7-segment display, including ':'
|
||||||
|
#define LED_BACKPACK_DEGREE_SYMBOL \
|
||||||
|
0b01100011 ///< Degree symbol for 7-segment display
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@brief Class that provides a driver interface for 7-Segment
|
||||||
|
Displays w/I2C Backpack
|
||||||
|
*/
|
||||||
|
class WipperSnapper_I2C_Driver_Out_7Seg : public WipperSnapper_I2C_Driver_Out {
|
||||||
|
|
||||||
|
public:
|
||||||
|
/*******************************************************************************/
|
||||||
|
/*!
|
||||||
|
@brief Constructor for a 7-Segment display driver.
|
||||||
|
@param i2c
|
||||||
|
The I2C interface.
|
||||||
|
@param sensorAddress
|
||||||
|
7-bit device address.
|
||||||
|
*/
|
||||||
|
/*******************************************************************************/
|
||||||
|
WipperSnapper_I2C_Driver_Out_7Seg(TwoWire *i2c, uint16_t sensorAddress)
|
||||||
|
: WipperSnapper_I2C_Driver_Out(i2c, sensorAddress) {
|
||||||
|
_i2c = i2c;
|
||||||
|
_sensorAddress = sensorAddress;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@brief Destructor for a 7-Segment display driver.
|
||||||
|
*/
|
||||||
|
~WipperSnapper_I2C_Driver_Out_7Seg() {
|
||||||
|
if (_matrix != nullptr) {
|
||||||
|
delete _matrix;
|
||||||
|
_matrix = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@brief Initializes the 7-segment LED matrix and begins I2C
|
||||||
|
communication.
|
||||||
|
@returns True if initialized successfully, False otherwise.
|
||||||
|
*/
|
||||||
|
bool begin() {
|
||||||
|
_matrix = new Adafruit_7segment();
|
||||||
|
bool did_begin = _matrix->begin(_sensorAddress, _i2c);
|
||||||
|
return did_begin;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@brief Configures the LED matrix's I2C backpack.
|
||||||
|
@param brightness
|
||||||
|
The brightness of the i2c backpack (0-15).
|
||||||
|
@param alignment
|
||||||
|
The alignment of the i2c backpack's LED matrix (left/right).
|
||||||
|
*/
|
||||||
|
void ConfigureI2CBackpack(int32_t brightness, uint32_t alignment) {
|
||||||
|
if (alignment == LED_BACKPACK_ALIGNMENT_RIGHT) {
|
||||||
|
_alignment = LED_BACKPACK_ALIGNMENT_RIGHT;
|
||||||
|
} else {
|
||||||
|
_alignment = LED_BACKPACK_ALIGNMENT_DEFAULT;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Note: Adafruit_LEDBackpack normalizes only > 15, but not < 0,
|
||||||
|
// so, here we're normalizing < 0 to 8 (median brightness)
|
||||||
|
if (brightness < 0) {
|
||||||
|
brightness = 8; // Set to median brightness if out of range
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@brief Sets the brightness of the LED backpack.
|
||||||
|
@param b
|
||||||
|
The brightness value, from 0 (off) to 15 (full brightness).
|
||||||
|
*/
|
||||||
|
void SetLedBackpackBrightness(uint8_t b) {
|
||||||
|
if (_matrix == nullptr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_matrix->setBrightness(b);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@brief Writes the first four characters of a message to the Adafruit
|
||||||
|
7-segment LED matrix.
|
||||||
|
@param message
|
||||||
|
The message to be displayed.
|
||||||
|
*/
|
||||||
|
void WriteMessage(const char *message) {
|
||||||
|
if (_matrix == nullptr || message == nullptr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clear before writing
|
||||||
|
_matrix->clear();
|
||||||
|
|
||||||
|
// Calculate the number of characters to display
|
||||||
|
size_t len_display = min(strlen(message), (size_t)LED_MAX_CHARS);
|
||||||
|
|
||||||
|
// Set the starting position based on alignment
|
||||||
|
int pos_start;
|
||||||
|
if (_alignment == LED_BACKPACK_ALIGNMENT_LEFT) {
|
||||||
|
pos_start = 0; // start at the leftmost position of the display
|
||||||
|
} else {
|
||||||
|
// Exclude decimal points from the character count because those get
|
||||||
|
// displayed on a "special" segment of the LED display
|
||||||
|
int seg_chars = 0;
|
||||||
|
for (size_t i = 0; i < len_display; i++) {
|
||||||
|
if (message[i] != '.') {
|
||||||
|
seg_chars++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// start at the rightmost position of the display
|
||||||
|
switch (seg_chars) {
|
||||||
|
case 4:
|
||||||
|
pos_start = 0;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
pos_start = 1;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
pos_start = 3; // if 2 characters, start at position 3 is required
|
||||||
|
// because ':' is position 2 and we need to skip it
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
pos_start = 4;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
pos_start = 0; // if no characters or overflow, start at position 0
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write to the display's buffer
|
||||||
|
int cur_idx = pos_start;
|
||||||
|
for (size_t i = 0; i < len_display; i++) {
|
||||||
|
|
||||||
|
// skip position 2
|
||||||
|
if (cur_idx == 2) {
|
||||||
|
cur_idx++;
|
||||||
|
}
|
||||||
|
// Save the character because if there's a decimal, we need to skip it in
|
||||||
|
// the buffer
|
||||||
|
char ch = message[i];
|
||||||
|
|
||||||
|
// Look-ahead for a decimal point to attach to the current character
|
||||||
|
bool display_dot = false;
|
||||||
|
if (i + 1 < len_display && message[i + 1] == '.') {
|
||||||
|
display_dot = true;
|
||||||
|
i++;
|
||||||
|
len_display++;
|
||||||
|
} else if (message[i] == 0xC2 && message[i + 1] == 0xB0 &&
|
||||||
|
i + 1 < strlen(message)) {
|
||||||
|
// Write degree symbol
|
||||||
|
_matrix->writeDigitRaw(cur_idx, LED_BACKPACK_DEGREE_SYMBOL);
|
||||||
|
i++;
|
||||||
|
cur_idx++;
|
||||||
|
continue; // skip to next character
|
||||||
|
}
|
||||||
|
// Write the character to the display buffer
|
||||||
|
_matrix->writeDigitAscii(cur_idx, ch, display_dot);
|
||||||
|
cur_idx++;
|
||||||
|
}
|
||||||
|
// Issue the buffered data in RAM to the display
|
||||||
|
_matrix->writeDisplay();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Adafruit_7segment *_matrix =
|
||||||
|
nullptr; ///< ptr to a 7-segment LED matrix object
|
||||||
|
int32_t _brightness; ///< Brightness of the LED backpack, from 0 (off) to 15
|
||||||
|
///< (full brightness)
|
||||||
|
uint32_t _alignment =
|
||||||
|
LED_BACKPACK_ALIGNMENT_DEFAULT; ///< Determines L/R alignment of the
|
||||||
|
///< message displayed
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // WIPPERSNAPPER_I2C_DRIVER_OUT_7SEG_H
|
||||||
|
|
@ -0,0 +1,163 @@
|
||||||
|
/*!
|
||||||
|
* @file WipperSnapper_I2C_Driver_Out_CharLcd.h
|
||||||
|
*
|
||||||
|
* Device driver for I2C Character LCDs (HD44780)
|
||||||
|
*
|
||||||
|
* Adafruit invests time and resources providing this open source code,
|
||||||
|
* please support Adafruit and open-source hardware by purchasing
|
||||||
|
* products from Adafruit!
|
||||||
|
*
|
||||||
|
* Copyright (c) Brent Rubell for Adafruit Industries 2025
|
||||||
|
*
|
||||||
|
* MIT license, all text here must be included in any redistribution.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef WIPPERSNAPPER_I2C_DRIVER_OUT_CHARLCD_H
|
||||||
|
#define WIPPERSNAPPER_I2C_DRIVER_OUT_CHARLCD_H
|
||||||
|
|
||||||
|
#include "WipperSnapper_I2C_Driver_Out.h"
|
||||||
|
#include <Adafruit_LiquidCrystal.h>
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@brief Class that provides a driver interface for a lcd character display.
|
||||||
|
This class is a wrapper around the Adafruit_LiquidCrystal library.
|
||||||
|
*/
|
||||||
|
class WipperSnapper_I2C_Driver_Out_CharLcd
|
||||||
|
: public WipperSnapper_I2C_Driver_Out {
|
||||||
|
|
||||||
|
public:
|
||||||
|
/*!
|
||||||
|
@brief Constructor for a LCD character display.
|
||||||
|
@param i2c
|
||||||
|
The I2C interface.
|
||||||
|
@param sensorAddress
|
||||||
|
7-bit device address.
|
||||||
|
*/
|
||||||
|
WipperSnapper_I2C_Driver_Out_CharLcd(TwoWire *i2c, uint16_t sensorAddress)
|
||||||
|
: WipperSnapper_I2C_Driver_Out(i2c, sensorAddress) {
|
||||||
|
_i2c = i2c;
|
||||||
|
_sensorAddress = sensorAddress;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@brief Destructor for an MS8607 sensor.
|
||||||
|
*/
|
||||||
|
~WipperSnapper_I2C_Driver_Out_CharLcd() {
|
||||||
|
if (_lcd != nullptr) {
|
||||||
|
delete _lcd;
|
||||||
|
_lcd = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@brief Initializes the drvOutQuadAlphaNum component and begins I2C.
|
||||||
|
@returns True if initialized successfully, False otherwise.
|
||||||
|
*/
|
||||||
|
bool begin() {
|
||||||
|
_lcd = new Adafruit_LiquidCrystal(_sensorAddress, _i2c);
|
||||||
|
bool did_begin = _lcd->begin(_cols, _rows);
|
||||||
|
if (did_begin) {
|
||||||
|
_lcd->setBacklight(HIGH);
|
||||||
|
}
|
||||||
|
return did_begin;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@brief Writes a message to the LCD.
|
||||||
|
@note MUST be called prior to begin() to configure the LCD's size
|
||||||
|
@param rows
|
||||||
|
The number of rows in the LCD.
|
||||||
|
@param cols
|
||||||
|
The number of columns in the LCD.
|
||||||
|
*/
|
||||||
|
void ConfigureCharLcd(uint8_t rows, uint8_t cols) {
|
||||||
|
_rows = rows;
|
||||||
|
_cols = cols;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@brief Turns the character LCD backlight on or off.
|
||||||
|
@param enable
|
||||||
|
True to enable the backlight, false to disable it.
|
||||||
|
*/
|
||||||
|
void EnableCharLcdBacklight(bool enable = true) {
|
||||||
|
if (_lcd == nullptr)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (enable) {
|
||||||
|
_lcd->setBacklight(HIGH);
|
||||||
|
} else {
|
||||||
|
_lcd->setBacklight(LOW);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@brief Writes a message to the LCD.
|
||||||
|
@param message
|
||||||
|
The message to be displayed.
|
||||||
|
*/
|
||||||
|
void WriteMessage(const char *message) {
|
||||||
|
if (_lcd == nullptr)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Before writing, let's clear the display
|
||||||
|
_lcd->clear();
|
||||||
|
|
||||||
|
size_t message_length = strlen(message);
|
||||||
|
size_t cur_idx = 0; // Current index in the message
|
||||||
|
|
||||||
|
// Write each row until it hits: \n, or the end of the message, or the last
|
||||||
|
// column/row position
|
||||||
|
for (int cur_row = 0; cur_row < _rows && cur_idx < message_length;
|
||||||
|
cur_row++) {
|
||||||
|
// Write each row out at the beginning of the row
|
||||||
|
_lcd->setCursor(0, cur_row);
|
||||||
|
for (int cur_col = 0; cur_col < _cols && cur_idx < message_length;
|
||||||
|
cur_col++) {
|
||||||
|
char c = message[cur_idx];
|
||||||
|
if (c == '\\' && cur_idx + 1 < message_length &&
|
||||||
|
(message[cur_idx + 1] == 'n' || message[cur_idx + 1] == 'r')) {
|
||||||
|
// Handle \r\n sequence as a single newline
|
||||||
|
if (message[cur_idx + 1] == 'r' && cur_idx + 3 < message_length &&
|
||||||
|
message[cur_idx + 2] == '\\' && message[cur_idx + 3] == 'n') {
|
||||||
|
cur_idx += 4; // Skip \r\n and don't move the cursor two rows
|
||||||
|
break; // Move to the next row
|
||||||
|
} else {
|
||||||
|
if (message[cur_idx + 1] == 'r') {
|
||||||
|
_lcd->write('\\');
|
||||||
|
_lcd->write('r');
|
||||||
|
cur_idx += 2; // Skip the \r
|
||||||
|
} else {
|
||||||
|
cur_idx += 2; // Skip the \n
|
||||||
|
break; // Move to the next row
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if ((c == 0x0A || c == 0x0D) && cur_idx + 1 < message_length) {
|
||||||
|
if (c == 0x0A && cur_idx + 1 < message_length &&
|
||||||
|
message[cur_idx + 1] == 0x0D) {
|
||||||
|
cur_idx += 2; // Skip both LF and CR characters
|
||||||
|
} else {
|
||||||
|
cur_idx += 1; // Skip single newline character
|
||||||
|
}
|
||||||
|
break; // and move to the next row
|
||||||
|
} else if (c == 194 && cur_idx + 1 < message_length &&
|
||||||
|
message[cur_idx + 1] == 176) {
|
||||||
|
cur_idx += 2; // Skip the degree symbol sequence in the buffer
|
||||||
|
_lcd->write(0xDF); // and write the degree symbol
|
||||||
|
} else {
|
||||||
|
_lcd->write(c);
|
||||||
|
cur_idx++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Adafruit_LiquidCrystal *_lcd =
|
||||||
|
nullptr; ///< Pointer to the Adafruit_LiquidCrystal object
|
||||||
|
uint8_t _rows; ///< Number of rows in the display
|
||||||
|
uint8_t _cols; ///< Number of columns in the display
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // WIPPERSNAPPER_I2C_DRIVER_OUT_CHARLCD_H
|
||||||
|
|
@ -0,0 +1,178 @@
|
||||||
|
/*!
|
||||||
|
* @file WipperSnapper_I2C_Driver_Out_QuadAlphaNum.h
|
||||||
|
*
|
||||||
|
* Device driver for Quad Alphanumeric Displays w/I2C Backpack
|
||||||
|
*
|
||||||
|
* Adafruit invests time and resources providing this open source code,
|
||||||
|
* please support Adafruit and open-source hardware by purchasing
|
||||||
|
* products from Adafruit!
|
||||||
|
*
|
||||||
|
* Copyright (c) Brent Rubell for Adafruit Industries 2025
|
||||||
|
*
|
||||||
|
* MIT license, all text here must be included in any redistribution.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef WIPPERSNAPPER_I2C_DRIVER_OUT_QUADALPHANUM_H
|
||||||
|
#define WIPPERSNAPPER_I2C_DRIVER_OUT_QUADALPHANUM_H
|
||||||
|
|
||||||
|
#include "WipperSnapper_I2C_Driver_Out.h"
|
||||||
|
#include <Adafruit_LEDBackpack.h>
|
||||||
|
#include <Arduino.h>
|
||||||
|
|
||||||
|
#define LED_BACKPACK_ALIGNMENT_UNSPECIFIED 0 ///< Unspecified alignment
|
||||||
|
#define LED_BACKPACK_ALIGNMENT_LEFT 1 ///< Left alignment
|
||||||
|
#define LED_BACKPACK_ALIGNMENT_RIGHT 2 ///< Right alignment
|
||||||
|
#define LED_BACKPACK_ALIGNMENT_DEFAULT \
|
||||||
|
LED_BACKPACK_ALIGNMENT_LEFT ///< Default alignment
|
||||||
|
#define LED_MAX_CHARS \
|
||||||
|
4 ///< Maximum number of characters to display on the alphanumeric display
|
||||||
|
#define ALPHANUM_DEGREE_SYMBOL \
|
||||||
|
0b0000000011100011 ///< Degree symbol for alphanumeric display
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@brief Class that provides a driver interface for Quad Alphanumeric
|
||||||
|
Displays w/I2C Backpack
|
||||||
|
*/
|
||||||
|
class WipperSnapper_I2C_Driver_Out_QuadAlphaNum
|
||||||
|
: public WipperSnapper_I2C_Driver_Out {
|
||||||
|
|
||||||
|
public:
|
||||||
|
/*******************************************************************************/
|
||||||
|
/*!
|
||||||
|
@brief Constructor for an MS8607 sensor.
|
||||||
|
@param i2c
|
||||||
|
The I2C interface.
|
||||||
|
@param sensorAddress
|
||||||
|
7-bit device address.
|
||||||
|
*/
|
||||||
|
/*******************************************************************************/
|
||||||
|
WipperSnapper_I2C_Driver_Out_QuadAlphaNum(TwoWire *i2c,
|
||||||
|
uint16_t sensorAddress)
|
||||||
|
: WipperSnapper_I2C_Driver_Out(i2c, sensorAddress) {
|
||||||
|
_i2c = i2c;
|
||||||
|
_sensorAddress = sensorAddress;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@brief Destructor for an MS8607 sensor.
|
||||||
|
*/
|
||||||
|
~WipperSnapper_I2C_Driver_Out_QuadAlphaNum() {
|
||||||
|
if (_alpha4 != nullptr) {
|
||||||
|
delete _alpha4;
|
||||||
|
_alpha4 = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@brief Initializes the drvOutQuadAlphaNum component and begins I2C.
|
||||||
|
@returns True if initialized successfully, False otherwise.
|
||||||
|
*/
|
||||||
|
bool begin() {
|
||||||
|
_alpha4 = new Adafruit_AlphaNum4();
|
||||||
|
bool did_begin = _alpha4->begin(_sensorAddress, _i2c);
|
||||||
|
_alpha4->setBrightness(_brightness);
|
||||||
|
return did_begin;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@brief Configures a LED backpack.
|
||||||
|
@param brightness
|
||||||
|
The brightness of the LED backpack.
|
||||||
|
@param alignment
|
||||||
|
The alignment of the LED backpack.
|
||||||
|
*/
|
||||||
|
void ConfigureI2CBackpack(int32_t brightness, uint32_t alignment) {
|
||||||
|
if (alignment == LED_BACKPACK_ALIGNMENT_RIGHT) {
|
||||||
|
_alignment = LED_BACKPACK_ALIGNMENT_RIGHT;
|
||||||
|
} else {
|
||||||
|
_alignment = LED_BACKPACK_ALIGNMENT_DEFAULT;
|
||||||
|
}
|
||||||
|
_brightness = brightness;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@brief Sets the brightness of the LED backpack.
|
||||||
|
@param b
|
||||||
|
The brightness value, from 0 (off) to 15 (full brightness).
|
||||||
|
*/
|
||||||
|
void SetLedBackpackBrightness(uint8_t b) {
|
||||||
|
if (_alpha4 == nullptr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_alpha4->setBrightness(b);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@brief Writes the first four characters of a message to the quad
|
||||||
|
alphanumeric display.
|
||||||
|
@param message
|
||||||
|
The message to be displayed.
|
||||||
|
*/
|
||||||
|
void WriteMessage(const char *message) {
|
||||||
|
if (_alpha4 == nullptr || message == nullptr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Clear before writing
|
||||||
|
_alpha4->clear();
|
||||||
|
|
||||||
|
// Calculate the number of characters to display
|
||||||
|
size_t len_display = min(strlen(message), (size_t)LED_MAX_CHARS);
|
||||||
|
|
||||||
|
// Set the starting position based on alignment
|
||||||
|
int pos_start;
|
||||||
|
if (_alignment == LED_BACKPACK_ALIGNMENT_LEFT) {
|
||||||
|
pos_start = 0; // start at the leftmost position of the display
|
||||||
|
} else {
|
||||||
|
// Exclude decimal points from the character count because those get
|
||||||
|
// displayed on a "special" segment of the LED display
|
||||||
|
int seg_chars = 0;
|
||||||
|
for (size_t i = 0; i < len_display; i++) {
|
||||||
|
if (message[i] != '.') {
|
||||||
|
seg_chars++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// start at the rightmost position of the display
|
||||||
|
pos_start = LED_MAX_CHARS - seg_chars;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write to the display's buffer
|
||||||
|
int cur_idx = pos_start;
|
||||||
|
for (size_t i = 0; i < len_display; i++) {
|
||||||
|
// Save the character because if there's a decimal, we need to skip it in
|
||||||
|
// the buffer
|
||||||
|
char ch = message[i];
|
||||||
|
|
||||||
|
// Look-ahead for a decimal point to attach to the current character
|
||||||
|
bool display_dot = false;
|
||||||
|
if (i + 1 < len_display && message[i + 1] == '.') {
|
||||||
|
display_dot = true;
|
||||||
|
i++;
|
||||||
|
len_display++;
|
||||||
|
} else if (message[i] == 0xC2 && message[i + 1] == 0xB0 &&
|
||||||
|
i + 1 < strlen(message)) {
|
||||||
|
// Write the degree symbol
|
||||||
|
_alpha4->writeDigitRaw(cur_idx, ALPHANUM_DEGREE_SYMBOL);
|
||||||
|
i++;
|
||||||
|
cur_idx++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// Write the character to the display buffer
|
||||||
|
_alpha4->writeDigitAscii(cur_idx, ch, display_dot);
|
||||||
|
cur_idx++;
|
||||||
|
}
|
||||||
|
// Issue the buffered data in RAM to the display
|
||||||
|
_alpha4->writeDisplay();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Adafruit_AlphaNum4 *_alpha4 =
|
||||||
|
nullptr; ///< ptr to a 4-digit alphanumeric display object
|
||||||
|
int32_t _brightness; ///< Brightness of the LED backpack, from 0 (off) to 15
|
||||||
|
///< (full brightness)
|
||||||
|
uint32_t _alignment =
|
||||||
|
LED_BACKPACK_ALIGNMENT_DEFAULT; ///< Determines L/R alignment of the
|
||||||
|
///< message displayed
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // WIPPERSNAPPER_I2C_DRIVER_OUT_QUADALPHANUM_H
|
||||||
208
src/components/i2c/drivers/WipperSnapper_I2C_Driver_Out_Sh1107.h
Normal file
208
src/components/i2c/drivers/WipperSnapper_I2C_Driver_Out_Sh1107.h
Normal file
|
|
@ -0,0 +1,208 @@
|
||||||
|
/*!
|
||||||
|
* @file WipperSnapper_I2C_Driver_Out_SH1107.h
|
||||||
|
*
|
||||||
|
* Device driver for a SH1107 OLED Display
|
||||||
|
*
|
||||||
|
* Adafruit invests time and resources providing this open source code,
|
||||||
|
* please support Adafruit and open-source hardware by purchasing
|
||||||
|
* products from Adafruit!
|
||||||
|
*
|
||||||
|
* Copyright (c) Tyeth Gundry for Adafruit Industries 2025
|
||||||
|
*
|
||||||
|
* MIT license, all text here must be included in any redistribution.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef WIPPERSNAPPER_I2C_DRIVER_OUT_SH1107_H
|
||||||
|
#define WIPPERSNAPPER_I2C_DRIVER_OUT_SH1107_H
|
||||||
|
|
||||||
|
#include "WipperSnapper_I2C_Driver_Out.h"
|
||||||
|
#include <Adafruit_GFX.h>
|
||||||
|
#include <Adafruit_SH110X.h>
|
||||||
|
#include <Arduino.h>
|
||||||
|
|
||||||
|
#define WS_SH1107_DEFAULT_WIDTH \
|
||||||
|
128 ///< Default width for a sh1107 128x64 display
|
||||||
|
#define WS_SH1107_DEFAULT_HEIGHT \
|
||||||
|
64 ///< Default height for a sh1107 128x64 display
|
||||||
|
|
||||||
|
#define OLED_128X64_WING_WIDTH 128 ///< Width of the 128x64 OLED FeatherWing
|
||||||
|
#define OLED_128X64_WING_HEIGHT 64 ///< Height of the 128x64 OLED FeatherWing
|
||||||
|
#define OLED_128X64_WING_ROTATION_90 1 ///< Rotation of OLED FeatherWing 0-3
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@brief Class that provides a driver interface for a SH1107
|
||||||
|
OLED Display
|
||||||
|
*/
|
||||||
|
class WipperSnapper_I2C_Driver_Out_SH1107
|
||||||
|
: public WipperSnapper_I2C_Driver_Out {
|
||||||
|
|
||||||
|
public:
|
||||||
|
/*******************************************************************************/
|
||||||
|
/*!
|
||||||
|
@brief Constructor for an SH1107 OLED display.
|
||||||
|
@param i2c
|
||||||
|
The I2C interface.
|
||||||
|
@param sensorAddress
|
||||||
|
7-bit device address.
|
||||||
|
*/
|
||||||
|
/*******************************************************************************/
|
||||||
|
WipperSnapper_I2C_Driver_Out_SH1107(TwoWire *i2c, uint16_t sensorAddress)
|
||||||
|
: WipperSnapper_I2C_Driver_Out(i2c, sensorAddress) {
|
||||||
|
_i2c = i2c;
|
||||||
|
_sensorAddress = sensorAddress;
|
||||||
|
_width = WS_SH1107_DEFAULT_WIDTH;
|
||||||
|
_height = WS_SH1107_DEFAULT_HEIGHT;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@brief Destructor for a SH1107 OLED display.
|
||||||
|
*/
|
||||||
|
~WipperSnapper_I2C_Driver_Out_SH1107() {
|
||||||
|
if (_display != nullptr) {
|
||||||
|
_display->clearDisplay();
|
||||||
|
_display->display();
|
||||||
|
_display->oled_command(SH110X_DISPLAYOFF);
|
||||||
|
delete _display;
|
||||||
|
_display = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@brief Initializes the SH1107 display and begins I2C.
|
||||||
|
@returns True if initialized successfully, False otherwise.
|
||||||
|
*/
|
||||||
|
bool begin() {
|
||||||
|
if (_width == OLED_128X64_WING_WIDTH &&
|
||||||
|
_height == OLED_128X64_WING_HEIGHT &&
|
||||||
|
_rotation == OLED_128X64_WING_ROTATION_90) {
|
||||||
|
// featherwing needs to be rotated 90 degrees and swap w/h ctor args
|
||||||
|
_display = new Adafruit_SH1107(_height, _width, _i2c);
|
||||||
|
} else {
|
||||||
|
_display = new Adafruit_SH1107(_width, _height, _i2c);
|
||||||
|
}
|
||||||
|
if (!_display->begin(_sensorAddress, true))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Clear the buffer.
|
||||||
|
_display->clearDisplay();
|
||||||
|
_display->display();
|
||||||
|
_display->setRotation(_rotation); // 0-3, not degrees for SH1107
|
||||||
|
|
||||||
|
// Configure the text size and color
|
||||||
|
_display->setTextSize(_text_sz);
|
||||||
|
_display->setTextColor(SH110X_WHITE);
|
||||||
|
_display->setCursor(0, 0);
|
||||||
|
// Clear the buffer
|
||||||
|
_display->clearDisplay();
|
||||||
|
_display->display();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@brief Configures a SH1107 OLED display. Must be called before driver
|
||||||
|
begin()
|
||||||
|
@param width
|
||||||
|
The width of the display in pixels.
|
||||||
|
@param height
|
||||||
|
The height of the display in pixels.
|
||||||
|
@param text_size
|
||||||
|
The magnification factor for the text size.
|
||||||
|
@param rotation
|
||||||
|
The rotation of the display in degrees, default is 0.
|
||||||
|
*/
|
||||||
|
void ConfigureSH1107(uint8_t width, uint8_t height, uint8_t text_size,
|
||||||
|
uint8_t rotation) {
|
||||||
|
_width = width;
|
||||||
|
_height = height;
|
||||||
|
_text_sz = text_size;
|
||||||
|
_rotation =
|
||||||
|
rotation % 90; // SH1107 requires rotation to be 0-3, not degrees
|
||||||
|
}
|
||||||
|
/*!
|
||||||
|
@brief Configures a SSD1306 OLED display. Must be called before driver
|
||||||
|
begin() - This is a fake function to match the SSD1306 interface.
|
||||||
|
@param width
|
||||||
|
The width of the display in pixels.
|
||||||
|
@param height
|
||||||
|
The height of the display in pixels.
|
||||||
|
@param text_size
|
||||||
|
The magnification factor for the text size.
|
||||||
|
@param rotation
|
||||||
|
The rotation of the display in degrees, default is 0.
|
||||||
|
*/
|
||||||
|
void ConfigureSSD1306(uint8_t width, uint8_t height, uint8_t text_size,
|
||||||
|
uint8_t rotation) {
|
||||||
|
// This is a SH1107, not a SSD1306, so we don't need to do anything here.
|
||||||
|
ConfigureSH1107(width, height, text_size, rotation);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@brief Writes a message to the SH1107 display.
|
||||||
|
@param message
|
||||||
|
The message to be displayed.
|
||||||
|
*/
|
||||||
|
void WriteMessageSH1107(const char *message) {
|
||||||
|
if (_display == nullptr)
|
||||||
|
return;
|
||||||
|
// Start with a fresh display buffer
|
||||||
|
// and settings
|
||||||
|
int16_t y_idx = 0;
|
||||||
|
_display->clearDisplay();
|
||||||
|
_display->setTextSize(_text_sz);
|
||||||
|
_display->setTextColor(SH110X_WHITE);
|
||||||
|
_display->setCursor(0, y_idx);
|
||||||
|
_display->display();
|
||||||
|
|
||||||
|
// Calculate the line height based on the text size (NOTE: base height is
|
||||||
|
// 8px)
|
||||||
|
int16_t line_height = 8 * _text_sz;
|
||||||
|
uint16_t c_idx = 0;
|
||||||
|
size_t msg_size = strlen(message);
|
||||||
|
for (size_t i = 0; i < msg_size && c_idx < msg_size; i++) {
|
||||||
|
if (message[i] == '\\' && i + 1 < msg_size &&
|
||||||
|
(message[i + 1] == 'n' || message[i + 1] == 'r')) {
|
||||||
|
// Handle \r\n sequence as a single newline
|
||||||
|
if (message[i + 1] == 'r' && i + 3 < msg_size &&
|
||||||
|
message[i + 2] == '\\' && message[i + 3] == 'n') {
|
||||||
|
// Skip to the next line
|
||||||
|
y_idx += line_height;
|
||||||
|
_display->setCursor(0, y_idx);
|
||||||
|
i += 3;
|
||||||
|
} else if (message[i + 1] == 'n') {
|
||||||
|
// Skip to the next line
|
||||||
|
y_idx += line_height;
|
||||||
|
_display->setCursor(0, y_idx);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
} else if (message[i] == 0xC2 && message[i + 1] == 0xB0) {
|
||||||
|
_display->write(char(248));
|
||||||
|
_display->display();
|
||||||
|
i++;
|
||||||
|
} else {
|
||||||
|
_display->print(message[i]);
|
||||||
|
_display->display();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@brief Writes a message to the fake "SSD1306" SH1107 display.
|
||||||
|
@param message
|
||||||
|
The message to be displayed.
|
||||||
|
*/
|
||||||
|
void WriteMessageSSD1306(const char *message) {
|
||||||
|
// This is a SH1107, not a SSD1306, so we just call the SH1107 write
|
||||||
|
WriteMessageSH1107(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Adafruit_SH1107 *_display =
|
||||||
|
nullptr; ///< Pointer to the Adafruit_SH1107 object
|
||||||
|
uint8_t _width; ///< Width of the display in pixels
|
||||||
|
uint8_t _height; ///< Height of the display in pixels
|
||||||
|
uint8_t _rotation; ///< Rotation of the display (0-3)
|
||||||
|
uint8_t _text_sz; ///< Text size of the display
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // WIPPERSNAPPER_I2C_DRIVER_OUT_SH1107_H
|
||||||
|
|
@ -0,0 +1,166 @@
|
||||||
|
/*!
|
||||||
|
* @file WipperSnapper_I2C_Driver_Out_Ssd1306.h
|
||||||
|
*
|
||||||
|
* Device driver for a SSD1306 OLED Display
|
||||||
|
*
|
||||||
|
* Adafruit invests time and resources providing this open source code,
|
||||||
|
* please support Adafruit and open-source hardware by purchasing
|
||||||
|
* products from Adafruit!
|
||||||
|
*
|
||||||
|
* Copyright (c) Brent Rubell for Adafruit Industries 2025
|
||||||
|
*
|
||||||
|
* MIT license, all text here must be included in any redistribution.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef WIPPERSNAPPER_I2C_DRIVER_OUT_SSD1306_H
|
||||||
|
#define WIPPERSNAPPER_I2C_DRIVER_OUT_SSD1306_H
|
||||||
|
|
||||||
|
#include "WipperSnapper_I2C_Driver_Out.h"
|
||||||
|
#include <Adafruit_SSD1306.h>
|
||||||
|
#include <Arduino.h>
|
||||||
|
|
||||||
|
#define WS_SSD1306_DEFAULT_WIDTH \
|
||||||
|
128 ///< Default width for a ssd1306 128x64 display
|
||||||
|
#define WS_SSD1306_DEFAULT_HEIGHT \
|
||||||
|
64 ///< Default height for a ssd1306 128x64 display
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@brief Class that provides a driver interface for a SSD1306
|
||||||
|
OLED Display
|
||||||
|
*/
|
||||||
|
class WipperSnapper_I2C_Driver_Out_Ssd1306
|
||||||
|
: public WipperSnapper_I2C_Driver_Out {
|
||||||
|
|
||||||
|
public:
|
||||||
|
/*******************************************************************************/
|
||||||
|
/*!
|
||||||
|
@brief Constructor for a SSD1306 OLED display.
|
||||||
|
@param i2c
|
||||||
|
The I2C interface.
|
||||||
|
@param sensorAddress
|
||||||
|
7-bit device address.
|
||||||
|
*/
|
||||||
|
/*******************************************************************************/
|
||||||
|
WipperSnapper_I2C_Driver_Out_Ssd1306(TwoWire *i2c, uint16_t sensorAddress)
|
||||||
|
: WipperSnapper_I2C_Driver_Out(i2c, sensorAddress) {
|
||||||
|
_i2c = i2c;
|
||||||
|
_sensorAddress = sensorAddress;
|
||||||
|
_width = WS_SSD1306_DEFAULT_WIDTH;
|
||||||
|
_height = WS_SSD1306_DEFAULT_HEIGHT;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@brief Destructor for a SSD1306 OLED display.
|
||||||
|
*/
|
||||||
|
~WipperSnapper_I2C_Driver_Out_Ssd1306() {
|
||||||
|
if (_display != nullptr) {
|
||||||
|
_display->clearDisplay();
|
||||||
|
_display->display();
|
||||||
|
_display->ssd1306_command(SSD1306_DISPLAYOFF);
|
||||||
|
delete _display;
|
||||||
|
_display = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@brief Initializes the SSD1306 display and begins I2C.
|
||||||
|
@returns True if initialized successfully, False otherwise.
|
||||||
|
*/
|
||||||
|
bool begin() {
|
||||||
|
// Attempt to create and allocate a SSD1306 obj.
|
||||||
|
_display = new Adafruit_SSD1306(_width, _height, _i2c);
|
||||||
|
if (!_display->begin(SSD1306_SWITCHCAPVCC, _sensorAddress))
|
||||||
|
return false;
|
||||||
|
// Configure the rotation, text size and color
|
||||||
|
_display->setRotation(_rotation);
|
||||||
|
_display->setTextSize(_text_sz);
|
||||||
|
_display->setTextColor(SSD1306_WHITE);
|
||||||
|
// Use full 256 char 'Code Page 437' font
|
||||||
|
_display->cp437(true);
|
||||||
|
// Clear the buffer
|
||||||
|
_display->clearDisplay();
|
||||||
|
_display->display();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@brief Configures a SSD1306 OLED display. Must be called before driver
|
||||||
|
begin()
|
||||||
|
@param width
|
||||||
|
The width of the display in pixels.
|
||||||
|
@param height
|
||||||
|
The height of the display in pixels.
|
||||||
|
@param text_size
|
||||||
|
The magnification factor for the text size.
|
||||||
|
@param rotation
|
||||||
|
The rotation of the display in degrees, default is 0.
|
||||||
|
*/
|
||||||
|
void ConfigureSSD1306(uint8_t width, uint8_t height, uint8_t text_size,
|
||||||
|
uint8_t rotation = 0) {
|
||||||
|
_width = width;
|
||||||
|
_height = height;
|
||||||
|
_text_sz = text_size;
|
||||||
|
_rotation = rotation;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@brief Writes a message to the SSD1306 display.
|
||||||
|
@param message
|
||||||
|
The message to be displayed.
|
||||||
|
*/
|
||||||
|
void WriteMessageSSD1306(const char *message) {
|
||||||
|
if (_display == nullptr)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Start with a fresh display buffer
|
||||||
|
// and settings
|
||||||
|
int16_t y_idx = 0;
|
||||||
|
_display->clearDisplay();
|
||||||
|
_display->setTextSize(_text_sz);
|
||||||
|
_display->setTextColor(SSD1306_WHITE);
|
||||||
|
_display->setCursor(0, y_idx);
|
||||||
|
_display->display();
|
||||||
|
|
||||||
|
// Calculate the line height based on the text size (NOTE: base height is
|
||||||
|
// 8px)
|
||||||
|
int16_t line_height = 8 * _text_sz;
|
||||||
|
uint16_t c_idx = 0;
|
||||||
|
size_t msg_size = strlen(message);
|
||||||
|
for (size_t i = 0; i < msg_size && c_idx < msg_size; i++) {
|
||||||
|
if (message[i] == '\\' && i + 1 < msg_size &&
|
||||||
|
(message[i + 1] == 'n' || message[i + 1] == 'r')) {
|
||||||
|
// Handle \r\n sequence as a single newline
|
||||||
|
if (message[i + 1] == 'r' && i + 3 < msg_size &&
|
||||||
|
message[i + 2] == '\\' && message[i + 3] == 'n') {
|
||||||
|
// Skip to the next line
|
||||||
|
y_idx += line_height;
|
||||||
|
_display->setCursor(0, y_idx);
|
||||||
|
i += 3;
|
||||||
|
} else if (message[i + 1] == 'n') {
|
||||||
|
// Skip to the next line
|
||||||
|
y_idx += line_height;
|
||||||
|
_display->setCursor(0, y_idx);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
} else if (message[i] == 0xC2 && message[i + 1] == 0xB0) {
|
||||||
|
_display->write(char(248));
|
||||||
|
_display->display();
|
||||||
|
i++;
|
||||||
|
} else {
|
||||||
|
_display->print(message[i]);
|
||||||
|
_display->display();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Adafruit_SSD1306 *_display =
|
||||||
|
nullptr; ///< Pointer to the Adafruit_SSD1306 object
|
||||||
|
uint8_t _width; ///< Width of the display in pixels
|
||||||
|
uint8_t _height; ///< Height of the display in pixels
|
||||||
|
uint8_t _rotation; ///< Rotation of the display in degrees
|
||||||
|
uint8_t _text_sz; ///< Text size of the display
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // WIPPERSNAPPER_I2C_DRIVER_OUT_SSD1306_H
|
||||||
|
|
@ -71,7 +71,7 @@ public:
|
||||||
*/
|
*/
|
||||||
/*******************************************************************************/
|
/*******************************************************************************/
|
||||||
bool getEventPM10_STD(sensors_event_t *pm10StdEvent) {
|
bool getEventPM10_STD(sensors_event_t *pm10StdEvent) {
|
||||||
PM25_AQI_Data data;
|
PM25_AQI_Data data = {0};
|
||||||
if (!_pm25->read(&data))
|
if (!_pm25->read(&data))
|
||||||
return false; // couldn't read data
|
return false; // couldn't read data
|
||||||
|
|
||||||
|
|
@ -89,7 +89,7 @@ public:
|
||||||
*/
|
*/
|
||||||
/*******************************************************************************/
|
/*******************************************************************************/
|
||||||
bool getEventPM25_STD(sensors_event_t *pm25StdEvent) {
|
bool getEventPM25_STD(sensors_event_t *pm25StdEvent) {
|
||||||
PM25_AQI_Data data;
|
PM25_AQI_Data data = {0};
|
||||||
if (!_pm25->read(&data))
|
if (!_pm25->read(&data))
|
||||||
return false; // couldn't read data
|
return false; // couldn't read data
|
||||||
|
|
||||||
|
|
@ -107,7 +107,7 @@ public:
|
||||||
*/
|
*/
|
||||||
/*******************************************************************************/
|
/*******************************************************************************/
|
||||||
bool getEventPM100_STD(sensors_event_t *pm100StdEvent) {
|
bool getEventPM100_STD(sensors_event_t *pm100StdEvent) {
|
||||||
PM25_AQI_Data data;
|
PM25_AQI_Data data = {0};
|
||||||
if (!_pm25->read(&data))
|
if (!_pm25->read(&data))
|
||||||
return false; // couldn't read data
|
return false; // couldn't read data
|
||||||
|
|
||||||
|
|
@ -116,7 +116,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Adafruit_PM25AQI *_pm25; ///< PM25 driver object
|
Adafruit_PM25AQI *_pm25 = nullptr; ///< PM25 driver object
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // WipperSnapper_I2C_Driver_PM25
|
#endif // WipperSnapper_I2C_Driver_PM25
|
||||||
|
|
@ -53,6 +53,56 @@ public:
|
||||||
return _scd->begin((uint8_t)_sensorAddress, _i2c);
|
return _scd->begin((uint8_t)_sensorAddress, _i2c);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************/
|
||||||
|
/*!
|
||||||
|
@brief Checks if sensor was read within last 1s, or is the first read.
|
||||||
|
@returns True if the sensor was recently read, False otherwise.
|
||||||
|
*/
|
||||||
|
bool HasBeenReadInLastSecond() {
|
||||||
|
return _lastRead != 0 && millis() - _lastRead < 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************/
|
||||||
|
/*!
|
||||||
|
@brief Checks if the sensor is ready to be read
|
||||||
|
@returns True if the sensor is ready, False otherwise.
|
||||||
|
*/
|
||||||
|
/*******************************************************************************/
|
||||||
|
bool IsSensorReady() {
|
||||||
|
if (!_scd->dataReady()) {
|
||||||
|
// failed, one more quick attempt
|
||||||
|
delay(100);
|
||||||
|
if (!_scd->dataReady()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************/
|
||||||
|
/*!
|
||||||
|
@brief Reads the SCD30 sensor.
|
||||||
|
@returns True if the sensor was read successfully, False otherwise.
|
||||||
|
*/
|
||||||
|
/*******************************************************************************/
|
||||||
|
bool ReadSensorData() {
|
||||||
|
// dont read sensor more than once per second
|
||||||
|
if (HasBeenReadInLastSecond()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!IsSensorReady()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!_scd->getEvent(&_humidity, &_temperature)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
_CO2.CO2 = _scd->CO2;
|
||||||
|
_lastRead = millis();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/*******************************************************************************/
|
/*******************************************************************************/
|
||||||
/*!
|
/*!
|
||||||
@brief Gets the SCD30's current temperature.
|
@brief Gets the SCD30's current temperature.
|
||||||
|
|
@ -64,14 +114,11 @@ public:
|
||||||
/*******************************************************************************/
|
/*******************************************************************************/
|
||||||
bool getEventAmbientTemp(sensors_event_t *tempEvent) {
|
bool getEventAmbientTemp(sensors_event_t *tempEvent) {
|
||||||
// check if sensor is enabled and data is available
|
// check if sensor is enabled and data is available
|
||||||
if (_tempSensorPeriod != 0 && (!_scd->dataReady()))
|
if (!ReadSensorData()) {
|
||||||
return false;
|
|
||||||
|
|
||||||
// attempt to get temperature data
|
|
||||||
sensors_event_t humidEvent;
|
|
||||||
if (!_scd->getEvent(&humidEvent, tempEvent))
|
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
*tempEvent = _temperature;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -86,14 +133,11 @@ public:
|
||||||
/*******************************************************************************/
|
/*******************************************************************************/
|
||||||
bool getEventRelativeHumidity(sensors_event_t *humidEvent) {
|
bool getEventRelativeHumidity(sensors_event_t *humidEvent) {
|
||||||
// check if sensor is enabled and data is available
|
// check if sensor is enabled and data is available
|
||||||
if (_humidSensorPeriod != 0 && (!_scd->dataReady()))
|
if (!ReadSensorData()) {
|
||||||
return false;
|
|
||||||
|
|
||||||
// attempt to get temperature data
|
|
||||||
sensors_event_t tempEvent;
|
|
||||||
if (!_scd->getEvent(humidEvent, &tempEvent))
|
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
*humidEvent = _humidity;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -108,15 +152,20 @@ public:
|
||||||
/*******************************************************************************/
|
/*******************************************************************************/
|
||||||
bool getEventCO2(sensors_event_t *co2Event) {
|
bool getEventCO2(sensors_event_t *co2Event) {
|
||||||
// check if sensor is enabled and data is available
|
// check if sensor is enabled and data is available
|
||||||
if (_CO2SensorPeriod != 0 && (!_scd->dataReady()))
|
if (!ReadSensorData()) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
co2Event->CO2 = _scd->CO2;
|
*co2Event = _CO2;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Adafruit_SCD30 *_scd; ///< SCD30 driver object
|
Adafruit_SCD30 *_scd = nullptr; ///< SCD30 driver object
|
||||||
|
ulong _lastRead = 0uL; ///< Last time the sensor was read
|
||||||
|
sensors_event_t _temperature = {0}; ///< Temperature
|
||||||
|
sensors_event_t _humidity = {0}; ///< Relative Humidity
|
||||||
|
sensors_event_t _CO2 = {0}; ///< CO2
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // WipperSnapper_I2C_Driver_SCD30
|
#endif // WipperSnapper_I2C_Driver_SCD30
|
||||||
|
|
@ -18,7 +18,7 @@
|
||||||
#define WipperSnapper_I2C_Driver_SCD4X_H
|
#define WipperSnapper_I2C_Driver_SCD4X_H
|
||||||
|
|
||||||
#include "WipperSnapper_I2C_Driver.h"
|
#include "WipperSnapper_I2C_Driver.h"
|
||||||
#include <SensirionI2CScd4x.h>
|
#include <SensirionI2cScd4x.h>
|
||||||
#include <Wire.h>
|
#include <Wire.h>
|
||||||
|
|
||||||
/**************************************************************************/
|
/**************************************************************************/
|
||||||
|
|
@ -51,42 +51,78 @@ public:
|
||||||
*/
|
*/
|
||||||
/*******************************************************************************/
|
/*******************************************************************************/
|
||||||
bool begin() {
|
bool begin() {
|
||||||
_scd = new SensirionI2CScd4x();
|
_scd = new SensirionI2cScd4x();
|
||||||
_scd->begin(*_i2c);
|
_scd->begin(*_i2c, _sensorAddress);
|
||||||
|
|
||||||
// stop previously started measurement
|
// stop previously started measurement
|
||||||
if (_scd->stopPeriodicMeasurement())
|
if (_scd->stopPeriodicMeasurement() != 0) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// start measurements
|
// start measurements
|
||||||
if (_scd->startPeriodicMeasurement())
|
if (_scd->startPeriodicMeasurement() != 0) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/********************************************************************************/
|
/*******************************************************************************/
|
||||||
/*!
|
/*!
|
||||||
@brief Attempts to read the SCD4x's sensor measurements
|
@brief Checks if sensor was read within last 1s, or is the first read.
|
||||||
@returns True if the measurements were read without errors, False
|
@returns True if the sensor was recently read, False otherwise.
|
||||||
if read errors occured or if sensor did not have data ready.
|
|
||||||
*/
|
*/
|
||||||
/********************************************************************************/
|
/*******************************************************************************/
|
||||||
bool readSensorMeasurements() {
|
bool HasBeenReadInLastSecond() {
|
||||||
uint16_t error;
|
return _lastRead != 0 && millis() - _lastRead < 1000;
|
||||||
bool isDataReady = false;
|
}
|
||||||
delay(100);
|
|
||||||
|
|
||||||
// Check if data is ready
|
/*******************************************************************************/
|
||||||
error = _scd->getDataReadyFlag(isDataReady);
|
/*!
|
||||||
if (error || !isDataReady)
|
@brief Checks if the sensor is ready to be read
|
||||||
|
@returns True if the sensor is ready, False otherwise.
|
||||||
|
*/
|
||||||
|
/*******************************************************************************/
|
||||||
|
bool IsSensorReady() {
|
||||||
|
bool isDataReady = false;
|
||||||
|
for (int i = 0; i < 2; i++) {
|
||||||
|
uint16_t error = _scd->getDataReadyStatus(isDataReady);
|
||||||
|
if (error == 0 && isDataReady) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
delay(100);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************/
|
||||||
|
/*!
|
||||||
|
@brief Reads the sensor.
|
||||||
|
@returns True if the sensor was read successfully, False otherwise.
|
||||||
|
*/
|
||||||
|
/*******************************************************************************/
|
||||||
|
bool ReadSensorData() {
|
||||||
|
// dont read sensor more than once per second
|
||||||
|
if (HasBeenReadInLastSecond()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!IsSensorReady()) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// Read SCD4x measurement
|
// Read SCD4x measurement
|
||||||
error = _scd->readMeasurement(_co2, _temperature, _humidity);
|
uint16_t co2 = 0;
|
||||||
if (error || _co2 == 0)
|
float temperature = 0;
|
||||||
|
float humidity = 0;
|
||||||
|
int16_t error = _scd->readMeasurement(co2, temperature, humidity);
|
||||||
|
if (error != 0 || co2 == 0) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
_CO2.CO2 = co2;
|
||||||
|
_temperature.temperature = temperature;
|
||||||
|
_humidity.relative_humidity = humidity;
|
||||||
|
_lastRead = millis();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -101,10 +137,11 @@ public:
|
||||||
/*******************************************************************************/
|
/*******************************************************************************/
|
||||||
bool getEventAmbientTemp(sensors_event_t *tempEvent) {
|
bool getEventAmbientTemp(sensors_event_t *tempEvent) {
|
||||||
// read all sensor measurements
|
// read all sensor measurements
|
||||||
if (!readSensorMeasurements())
|
if (!ReadSensorData()) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
tempEvent->temperature = _temperature;
|
*tempEvent = _temperature;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -119,10 +156,11 @@ public:
|
||||||
/*******************************************************************************/
|
/*******************************************************************************/
|
||||||
bool getEventRelativeHumidity(sensors_event_t *humidEvent) {
|
bool getEventRelativeHumidity(sensors_event_t *humidEvent) {
|
||||||
// read all sensor measurements
|
// read all sensor measurements
|
||||||
if (!readSensorMeasurements())
|
if (!ReadSensorData()) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
humidEvent->relative_humidity = _humidity;
|
*humidEvent = _humidity;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -137,18 +175,20 @@ public:
|
||||||
/*******************************************************************************/
|
/*******************************************************************************/
|
||||||
bool getEventCO2(sensors_event_t *co2Event) {
|
bool getEventCO2(sensors_event_t *co2Event) {
|
||||||
// read all sensor measurements
|
// read all sensor measurements
|
||||||
if (!readSensorMeasurements())
|
if (!ReadSensorData()) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
co2Event->CO2 = (float)_co2;
|
*co2Event = _CO2;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
SensirionI2CScd4x *_scd; ///< SCD4x driver object
|
SensirionI2cScd4x *_scd = nullptr; ///< SCD4x driver object
|
||||||
uint16_t _co2; ///< SCD4x co2 reading
|
sensors_event_t _temperature = {0}; ///< Temperature
|
||||||
float _temperature; ///< SCD4x temperature reading
|
sensors_event_t _humidity = {0}; ///< Relative Humidity
|
||||||
float _humidity; ///< SCD4x humidity reading
|
sensors_event_t _CO2 = {0}; ///< CO2
|
||||||
|
ulong _lastRead = 0uL; ///< Last time the sensor was read
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // WipperSnapper_I2C_Driver_SCD4X
|
#endif // WipperSnapper_I2C_Driver_SCD4X_H
|
||||||
|
|
@ -1,14 +1,13 @@
|
||||||
/*!
|
/*!
|
||||||
* @file WipperSnapper_I2C_Driver_SEN5X.h
|
* @file WipperSnapper_I2C_Driver_SEN5X.h
|
||||||
*
|
*
|
||||||
* Device driver for the SEN5X CO2, Temperature, and Humidity sensor.
|
* Device driver for the SEN5X air quality sensors.
|
||||||
* TEMPORARY HACK
|
|
||||||
*
|
*
|
||||||
* Adafruit invests time and resources providing this open source code,
|
* Adafruit invests time and resources providing this open source code,
|
||||||
* please support Adafruit and open-source hardware by purchasing
|
* please support Adafruit and open-source hardware by purchasing
|
||||||
* products from Adafruit!
|
* products from Adafruit!
|
||||||
*
|
*
|
||||||
* Copyright (c) Marni Brewster 2022 for Adafruit Industries.
|
* Copyright (c) Tyeth Gundry 2022 for Adafruit Industries.
|
||||||
*
|
*
|
||||||
* MIT license, all text here must be included in any redistribution.
|
* MIT license, all text here must be included in any redistribution.
|
||||||
*
|
*
|
||||||
|
|
@ -44,6 +43,14 @@ public:
|
||||||
: WipperSnapper_I2C_Driver(i2c, sensorAddress) {
|
: WipperSnapper_I2C_Driver(i2c, sensorAddress) {
|
||||||
_i2c = i2c;
|
_i2c = i2c;
|
||||||
_sensorAddress = sensorAddress;
|
_sensorAddress = sensorAddress;
|
||||||
|
_massConcentrationPm1p0 = NAN;
|
||||||
|
_massConcentrationPm2p5 = NAN;
|
||||||
|
_massConcentrationPm4p0 = NAN;
|
||||||
|
_massConcentrationPm10p0 = NAN;
|
||||||
|
_ambientHumidity = NAN;
|
||||||
|
_ambientTemperature = NAN;
|
||||||
|
_vocIndex = NAN;
|
||||||
|
_noxIndex = NAN;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*******************************************************************************/
|
/*******************************************************************************/
|
||||||
|
|
@ -69,6 +76,60 @@ public:
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************/
|
||||||
|
/*!
|
||||||
|
@brief Checks if sensor was read within last 1s, or is the first read.
|
||||||
|
@returns True if the sensor was recently read, False otherwise.
|
||||||
|
*/
|
||||||
|
bool HasBeenReadInLastSecond() {
|
||||||
|
return _lastRead != 0 && millis() - _lastRead < 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************/
|
||||||
|
/*!
|
||||||
|
@brief Checks if the sensor is ready to be read
|
||||||
|
@returns True if the sensor is ready, False otherwise.
|
||||||
|
*/
|
||||||
|
/*******************************************************************************/
|
||||||
|
bool IsSensorReady() {
|
||||||
|
bool isDataReady = false;
|
||||||
|
for (int i = 0; i < 2; i++) {
|
||||||
|
uint16_t error = _sen->readDataReady(isDataReady);
|
||||||
|
if (error == 0 && isDataReady) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
delay(100);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************/
|
||||||
|
/*!
|
||||||
|
@brief Reads the sensor.
|
||||||
|
@returns True if the sensor was read successfully, False otherwise.
|
||||||
|
*/
|
||||||
|
/*******************************************************************************/
|
||||||
|
bool ReadSensorData() {
|
||||||
|
// dont read sensor more than once per second
|
||||||
|
if (HasBeenReadInLastSecond()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!IsSensorReady()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t error = _sen->readMeasuredValues(
|
||||||
|
_massConcentrationPm1p0, _massConcentrationPm2p5,
|
||||||
|
_massConcentrationPm4p0, _massConcentrationPm10p0, _ambientHumidity,
|
||||||
|
_ambientTemperature, _vocIndex, _noxIndex);
|
||||||
|
if (error != 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
_lastRead = millis();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/*******************************************************************************/
|
/*******************************************************************************/
|
||||||
/*!
|
/*!
|
||||||
@brief Gets the SEN5X's current temperature.
|
@brief Gets the SEN5X's current temperature.
|
||||||
|
|
@ -79,20 +140,10 @@ public:
|
||||||
*/
|
*/
|
||||||
/*******************************************************************************/
|
/*******************************************************************************/
|
||||||
bool getEventAmbientTemp(sensors_event_t *tempEvent) {
|
bool getEventAmbientTemp(sensors_event_t *tempEvent) {
|
||||||
float massConcentrationPm1p0, massConcentrationPm2p5,
|
if (!ReadSensorData() || _ambientTemperature == NAN) {
|
||||||
massConcentrationPm4p0, massConcentrationPm10p0, ambientHumidity,
|
|
||||||
ambientTemperature, vocIndex, noxIndex;
|
|
||||||
uint16_t error;
|
|
||||||
|
|
||||||
error = _sen->readMeasuredValues(
|
|
||||||
massConcentrationPm1p0, massConcentrationPm2p5, massConcentrationPm4p0,
|
|
||||||
massConcentrationPm10p0, ambientHumidity, ambientTemperature, vocIndex,
|
|
||||||
noxIndex);
|
|
||||||
if ((_tempSensorPeriod != 0 && error != 0) || ambientTemperature == NAN) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
tempEvent->temperature = _ambientTemperature;
|
||||||
tempEvent->temperature = ambientTemperature;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -106,20 +157,10 @@ public:
|
||||||
*/
|
*/
|
||||||
/*******************************************************************************/
|
/*******************************************************************************/
|
||||||
bool getEventRelativeHumidity(sensors_event_t *humidEvent) {
|
bool getEventRelativeHumidity(sensors_event_t *humidEvent) {
|
||||||
float massConcentrationPm1p0, massConcentrationPm2p5,
|
if (!ReadSensorData() || _ambientHumidity == NAN) {
|
||||||
massConcentrationPm4p0, massConcentrationPm10p0, ambientHumidity,
|
|
||||||
ambientTemperature, vocIndex, noxIndex;
|
|
||||||
uint16_t error;
|
|
||||||
|
|
||||||
error = _sen->readMeasuredValues(
|
|
||||||
massConcentrationPm1p0, massConcentrationPm2p5, massConcentrationPm4p0,
|
|
||||||
massConcentrationPm10p0, ambientHumidity, ambientTemperature, vocIndex,
|
|
||||||
noxIndex);
|
|
||||||
if ((_humidSensorPeriod != 0 && error != 0) || ambientHumidity == NAN) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
humidEvent->relative_humidity = _ambientHumidity;
|
||||||
humidEvent->relative_humidity = ambientHumidity;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -136,20 +177,10 @@ public:
|
||||||
*/
|
*/
|
||||||
/*******************************************************************************/
|
/*******************************************************************************/
|
||||||
bool getEventNOxIndex(sensors_event_t *noxIndexEvent) {
|
bool getEventNOxIndex(sensors_event_t *noxIndexEvent) {
|
||||||
float massConcentrationPm1p0, massConcentrationPm2p5,
|
if (!ReadSensorData() || _noxIndex == NAN) {
|
||||||
massConcentrationPm4p0, massConcentrationPm10p0, ambientHumidity,
|
|
||||||
ambientTemperature, vocIndex, noxIndex;
|
|
||||||
uint16_t error;
|
|
||||||
|
|
||||||
error = _sen->readMeasuredValues(
|
|
||||||
massConcentrationPm1p0, massConcentrationPm2p5, massConcentrationPm4p0,
|
|
||||||
massConcentrationPm10p0, ambientHumidity, ambientTemperature, vocIndex,
|
|
||||||
noxIndex);
|
|
||||||
if ((_NOxIndexPeriod != 0 && error != 0) || noxIndex == NAN) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
noxIndexEvent->nox_index = _noxIndex;
|
||||||
noxIndexEvent->nox_index = noxIndex;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -163,20 +194,10 @@ public:
|
||||||
*/
|
*/
|
||||||
/*******************************************************************************/
|
/*******************************************************************************/
|
||||||
bool getEventVOCIndex(sensors_event_t *vocIndexEvent) {
|
bool getEventVOCIndex(sensors_event_t *vocIndexEvent) {
|
||||||
float massConcentrationPm1p0, massConcentrationPm2p5,
|
if (!ReadSensorData() || _vocIndex == NAN) {
|
||||||
massConcentrationPm4p0, massConcentrationPm10p0, ambientHumidity,
|
|
||||||
ambientTemperature, vocIndex, noxIndex;
|
|
||||||
uint16_t error;
|
|
||||||
|
|
||||||
error = _sen->readMeasuredValues(
|
|
||||||
massConcentrationPm1p0, massConcentrationPm2p5, massConcentrationPm4p0,
|
|
||||||
massConcentrationPm10p0, ambientHumidity, ambientTemperature, vocIndex,
|
|
||||||
noxIndex);
|
|
||||||
if ((_VOCIndexPeriod != 0 && error != 0) || vocIndex == NAN) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
vocIndexEvent->voc_index = _vocIndex;
|
||||||
vocIndexEvent->voc_index = vocIndex;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -190,22 +211,11 @@ public:
|
||||||
*/
|
*/
|
||||||
/*******************************************************************************/
|
/*******************************************************************************/
|
||||||
bool getEventPM10_STD(sensors_event_t *pm10StdEvent) {
|
bool getEventPM10_STD(sensors_event_t *pm10StdEvent) {
|
||||||
float massConcentrationPm1p0, massConcentrationPm2p5,
|
if (!ReadSensorData() || _massConcentrationPm1p0 == NAN ||
|
||||||
massConcentrationPm4p0, massConcentrationPm10p0, ambientHumidity,
|
_massConcentrationPm1p0 == OVERFLOW_SEN55) {
|
||||||
ambientTemperature, vocIndex, noxIndex;
|
|
||||||
uint16_t error;
|
|
||||||
|
|
||||||
error = _sen->readMeasuredValues(
|
|
||||||
massConcentrationPm1p0, massConcentrationPm2p5, massConcentrationPm4p0,
|
|
||||||
massConcentrationPm10p0, ambientHumidity, ambientTemperature, vocIndex,
|
|
||||||
noxIndex);
|
|
||||||
if ((_PM10SensorPeriod != 0 && error != 0) ||
|
|
||||||
massConcentrationPm1p0 == NAN ||
|
|
||||||
massConcentrationPm1p0 == OVERFLOW_SEN55) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
pm10StdEvent->pm10_std = _massConcentrationPm1p0;
|
||||||
pm10StdEvent->pm10_std = massConcentrationPm1p0;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -219,22 +229,11 @@ public:
|
||||||
*/
|
*/
|
||||||
/*******************************************************************************/
|
/*******************************************************************************/
|
||||||
bool getEventPM25_STD(sensors_event_t *pm25StdEvent) {
|
bool getEventPM25_STD(sensors_event_t *pm25StdEvent) {
|
||||||
float massConcentrationPm1p0, massConcentrationPm2p5,
|
if (!ReadSensorData() || _massConcentrationPm2p5 == NAN ||
|
||||||
massConcentrationPm4p0, massConcentrationPm10p0, ambientHumidity,
|
_massConcentrationPm2p5 == OVERFLOW_SEN55) {
|
||||||
ambientTemperature, vocIndex, noxIndex;
|
|
||||||
uint16_t error;
|
|
||||||
|
|
||||||
error = _sen->readMeasuredValues(
|
|
||||||
massConcentrationPm1p0, massConcentrationPm2p5, massConcentrationPm4p0,
|
|
||||||
massConcentrationPm10p0, ambientHumidity, ambientTemperature, vocIndex,
|
|
||||||
noxIndex);
|
|
||||||
if ((_PM25SensorPeriod != 0 && error != 0) ||
|
|
||||||
massConcentrationPm2p5 == NAN ||
|
|
||||||
massConcentrationPm2p5 == OVERFLOW_SEN55) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
pm25StdEvent->pm25_std = _massConcentrationPm2p5;
|
||||||
pm25StdEvent->pm25_std = massConcentrationPm2p5;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -248,22 +247,11 @@ public:
|
||||||
*/
|
*/
|
||||||
/*******************************************************************************/
|
/*******************************************************************************/
|
||||||
bool getEventPM40_STD(sensors_event_t *pm40StdEvent) {
|
bool getEventPM40_STD(sensors_event_t *pm40StdEvent) {
|
||||||
float massConcentrationPm1p0, massConcentrationPm2p5,
|
if (!ReadSensorData() || _massConcentrationPm4p0 == NAN ||
|
||||||
massConcentrationPm4p0, massConcentrationPm10p0, ambientHumidity,
|
_massConcentrationPm4p0 == OVERFLOW_SEN55) {
|
||||||
ambientTemperature, vocIndex, noxIndex;
|
|
||||||
uint16_t error;
|
|
||||||
|
|
||||||
error = _sen->readMeasuredValues(
|
|
||||||
massConcentrationPm1p0, massConcentrationPm2p5, massConcentrationPm4p0,
|
|
||||||
massConcentrationPm10p0, ambientHumidity, ambientTemperature, vocIndex,
|
|
||||||
noxIndex);
|
|
||||||
if ((_PM25SensorPeriod != 0 && error != 0) ||
|
|
||||||
massConcentrationPm4p0 == NAN ||
|
|
||||||
massConcentrationPm4p0 == OVERFLOW_SEN55) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
pm40StdEvent->data[0] = _massConcentrationPm4p0;
|
||||||
pm40StdEvent->data[0] = massConcentrationPm4p0;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -277,27 +265,25 @@ public:
|
||||||
*/
|
*/
|
||||||
/*******************************************************************************/
|
/*******************************************************************************/
|
||||||
bool getEventPM100_STD(sensors_event_t *pm100StdEvent) {
|
bool getEventPM100_STD(sensors_event_t *pm100StdEvent) {
|
||||||
float massConcentrationPm1p0, massConcentrationPm2p5,
|
if (!ReadSensorData() || _massConcentrationPm10p0 == NAN ||
|
||||||
massConcentrationPm4p0, massConcentrationPm10p0, ambientHumidity,
|
_massConcentrationPm10p0 == OVERFLOW_SEN55) {
|
||||||
ambientTemperature, vocIndex, noxIndex;
|
|
||||||
uint16_t error;
|
|
||||||
|
|
||||||
error = _sen->readMeasuredValues(
|
|
||||||
massConcentrationPm1p0, massConcentrationPm2p5, massConcentrationPm4p0,
|
|
||||||
massConcentrationPm10p0, ambientHumidity, ambientTemperature, vocIndex,
|
|
||||||
noxIndex);
|
|
||||||
if ((_PM100SensorPeriod != 0 && error != 0) ||
|
|
||||||
massConcentrationPm10p0 == NAN ||
|
|
||||||
massConcentrationPm10p0 == OVERFLOW_SEN55) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
pm100StdEvent->pm100_std = _massConcentrationPm10p0;
|
||||||
pm100StdEvent->pm100_std = massConcentrationPm10p0;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
SensirionI2CSen5x *_sen; ///< SEN5X driver object
|
SensirionI2CSen5x *_sen = nullptr; ///< SEN5X driver object
|
||||||
|
float _massConcentrationPm1p0; ///< PM1.0 mass concentration
|
||||||
|
float _massConcentrationPm2p5; ///< PM2.5 mass concentration
|
||||||
|
float _massConcentrationPm4p0; ///< PM4.0 mass concentration
|
||||||
|
float _massConcentrationPm10p0; ///< PM10.0 mass concentration
|
||||||
|
float _ambientHumidity; ///< Ambient humidity
|
||||||
|
float _ambientTemperature; ///< Ambient temperature
|
||||||
|
float _vocIndex; ///< VOC index
|
||||||
|
float _noxIndex; ///< NOx index
|
||||||
|
ulong _lastRead = 0uL; ///< Last time the sensor was read
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // WipperSnapper_I2C_Driver_SEN5X
|
#endif // WipperSnapper_I2C_Driver_SEN5X
|
||||||
|
|
|
||||||
311
src/components/i2c/drivers/WipperSnapper_I2C_Driver_SEN6X.h
Normal file
311
src/components/i2c/drivers/WipperSnapper_I2C_Driver_SEN6X.h
Normal file
|
|
@ -0,0 +1,311 @@
|
||||||
|
/*!
|
||||||
|
* @file WipperSnapper_I2C_Driver_SEN6X.h
|
||||||
|
*
|
||||||
|
* Device driver for the SEN66 Particulate Matter, Temperature, Humidity, VOC,
|
||||||
|
* NOX, and CO2 sensor.
|
||||||
|
*
|
||||||
|
* Adafruit invests time and resources providing this open source code,
|
||||||
|
* please support Adafruit and open-source hardware by purchasing
|
||||||
|
* products from Adafruit!
|
||||||
|
*
|
||||||
|
* Copyright (c) Tyeth Gundry 2022 for Adafruit Industries.
|
||||||
|
* Modified (c) by Martin Ebner 2024 https://github.com/MartinEbnerSensirion
|
||||||
|
*
|
||||||
|
* MIT license, all text here must be included in any redistribution.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef WipperSnapper_I2C_Driver_SEN6X_H
|
||||||
|
#define WipperSnapper_I2C_Driver_SEN6X_H
|
||||||
|
|
||||||
|
#include "WipperSnapper_I2C_Driver.h"
|
||||||
|
#include <SensirionI2cSen66.h>
|
||||||
|
#include <Wire.h>
|
||||||
|
|
||||||
|
/**************************************************************************/
|
||||||
|
/*!
|
||||||
|
@brief Class that provides a driver interface for the SEN6X sensor.
|
||||||
|
*/
|
||||||
|
/**************************************************************************/
|
||||||
|
class WipperSnapper_I2C_Driver_SEN6X : public WipperSnapper_I2C_Driver {
|
||||||
|
|
||||||
|
const float OVERFLOW_SEN6X = (0xFFFF / 10); // maxes out at u_int16 / 10
|
||||||
|
|
||||||
|
public:
|
||||||
|
/*******************************************************************************/
|
||||||
|
/*!
|
||||||
|
@brief Constructor for a SEN6X sensor.
|
||||||
|
@param i2c
|
||||||
|
The I2C interface.
|
||||||
|
@param sensorAddress
|
||||||
|
7-bit device address.
|
||||||
|
*/
|
||||||
|
/*******************************************************************************/
|
||||||
|
WipperSnapper_I2C_Driver_SEN6X(TwoWire *i2c, uint16_t sensorAddress)
|
||||||
|
: WipperSnapper_I2C_Driver(i2c, sensorAddress) {
|
||||||
|
_i2c = i2c;
|
||||||
|
_sensorAddress = sensorAddress;
|
||||||
|
_massConcentrationPm1p0 = NAN;
|
||||||
|
_massConcentrationPm2p5 = NAN;
|
||||||
|
_massConcentrationPm4p0 = NAN;
|
||||||
|
_massConcentrationPm10p0 = NAN;
|
||||||
|
_ambientHumidity = NAN;
|
||||||
|
_ambientTemperature = NAN;
|
||||||
|
_vocIndex = NAN;
|
||||||
|
_noxIndex = NAN;
|
||||||
|
_co2 = 0uL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************/
|
||||||
|
/*!
|
||||||
|
@brief Initializes the SEN6X sensor and begins I2C.
|
||||||
|
@returns True if initialized successfully, False otherwise.
|
||||||
|
*/
|
||||||
|
/*******************************************************************************/
|
||||||
|
bool begin() {
|
||||||
|
_sen = new SensirionI2cSen66();
|
||||||
|
_sen->begin(*_i2c, (uint8_t)_sensorAddress);
|
||||||
|
u_int16_t error_stop = _sen->deviceReset();
|
||||||
|
if (error_stop != 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// Wait 1 second for sensors to start recording + 100ms for reset command
|
||||||
|
delay(1100);
|
||||||
|
u_int16_t error_start = _sen->startContinuousMeasurement();
|
||||||
|
if (error_start != 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************/
|
||||||
|
/*!
|
||||||
|
@brief Checks if sensor was read within last 1s, or is the first read.
|
||||||
|
@returns True if the sensor was recently read, False otherwise.
|
||||||
|
*/
|
||||||
|
bool HasBeenReadInLastSecond() {
|
||||||
|
return _lastRead != 0 && millis() - _lastRead < 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************/
|
||||||
|
/*!
|
||||||
|
@brief Checks if the sensor is ready to be read
|
||||||
|
@returns True if the sensor is ready, False otherwise.
|
||||||
|
*/
|
||||||
|
/*******************************************************************************/
|
||||||
|
bool IsSensorReady() {
|
||||||
|
bool isDataReady = false;
|
||||||
|
uint8_t padding = 0x0;
|
||||||
|
for (int i = 0; i < 2; i++) {
|
||||||
|
uint16_t error = _sen->getDataReady(padding, isDataReady);
|
||||||
|
if (error == 0 && isDataReady) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
delay(100);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************/
|
||||||
|
/*!
|
||||||
|
@brief Reads the sensor.
|
||||||
|
@returns True if the sensor was read successfully, False otherwise.
|
||||||
|
*/
|
||||||
|
/*******************************************************************************/
|
||||||
|
bool ReadSensorData() {
|
||||||
|
// dont read sensor more than once per second
|
||||||
|
if (HasBeenReadInLastSecond()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!IsSensorReady()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t error = _sen->readMeasuredValues(
|
||||||
|
_massConcentrationPm1p0, _massConcentrationPm2p5,
|
||||||
|
_massConcentrationPm4p0, _massConcentrationPm10p0, _ambientHumidity,
|
||||||
|
_ambientTemperature, _vocIndex, _noxIndex, _co2);
|
||||||
|
if (error != 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
_lastRead = millis();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************/
|
||||||
|
/*!
|
||||||
|
@brief Gets the SEN6X's current temperature.
|
||||||
|
@param tempEvent
|
||||||
|
Pointer to an Adafruit_Sensor event.
|
||||||
|
@returns True if the temperature was obtained successfully, False
|
||||||
|
otherwise.
|
||||||
|
*/
|
||||||
|
/*******************************************************************************/
|
||||||
|
bool getEventAmbientTemp(sensors_event_t *tempEvent) {
|
||||||
|
if (!ReadSensorData() || _ambientTemperature == NAN) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
tempEvent->temperature = _ambientTemperature;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************/
|
||||||
|
/*!
|
||||||
|
@brief Gets the SEN6X's current relative humidity reading.
|
||||||
|
@param humidEvent
|
||||||
|
Pointer to an Adafruit_Sensor event.
|
||||||
|
@returns True if the humidity was obtained successfully, False
|
||||||
|
otherwise.
|
||||||
|
*/
|
||||||
|
/*******************************************************************************/
|
||||||
|
bool getEventRelativeHumidity(sensors_event_t *humidEvent) {
|
||||||
|
if (!ReadSensorData() || _ambientHumidity == NAN) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
humidEvent->relative_humidity = _ambientHumidity;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************/
|
||||||
|
/*!
|
||||||
|
@brief Gets the SEN6X's current NOX reading.
|
||||||
|
Note: If this value is unknown, which is true for SEN54,
|
||||||
|
NAN is returned. During the first 10..11 seconds after
|
||||||
|
power-on or device reset, this value will be NAN as well.
|
||||||
|
@param noxIndexEvent
|
||||||
|
Adafruit Sensor event for NOx Index (0-500, 1 is normal)
|
||||||
|
@returns True if the sensor value was obtained successfully, False
|
||||||
|
otherwise.
|
||||||
|
*/
|
||||||
|
/*******************************************************************************/
|
||||||
|
bool getEventNOxIndex(sensors_event_t *noxIndexEvent) {
|
||||||
|
if (!ReadSensorData() || _noxIndex == NAN) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
noxIndexEvent->nox_index = _noxIndex;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************/
|
||||||
|
/*!
|
||||||
|
@brief Gets the SEN6X's current VOC reading.
|
||||||
|
@param vocIndexEvent
|
||||||
|
Adafruit Sensor event for VOC Index (1-500, 100 is normal)
|
||||||
|
@returns True if the sensor value was obtained successfully, False
|
||||||
|
otherwise.
|
||||||
|
*/
|
||||||
|
/*******************************************************************************/
|
||||||
|
bool getEventVOCIndex(sensors_event_t *vocIndexEvent) {
|
||||||
|
if (!ReadSensorData() || _vocIndex == NAN) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
vocIndexEvent->voc_index = _vocIndex;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************/
|
||||||
|
/*!
|
||||||
|
@brief Gets the SEN6X sensor's PM1.0 STD reading.
|
||||||
|
@param pm10StdEvent
|
||||||
|
Adafruit Sensor event for PM1.0
|
||||||
|
@returns True if the sensor value was obtained successfully, False
|
||||||
|
otherwise.
|
||||||
|
*/
|
||||||
|
/*******************************************************************************/
|
||||||
|
bool getEventPM10_STD(sensors_event_t *pm10StdEvent) {
|
||||||
|
if (!ReadSensorData() || _massConcentrationPm1p0 == NAN ||
|
||||||
|
_massConcentrationPm1p0 == OVERFLOW_SEN6X) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
pm10StdEvent->pm10_std = _massConcentrationPm1p0;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************/
|
||||||
|
/*!
|
||||||
|
@brief Gets the SEN6X sensor's PM2.5 STD reading.
|
||||||
|
@param pm25StdEvent
|
||||||
|
Adafruit Sensor event for PM2.5
|
||||||
|
@returns True if the sensor value was obtained successfully, False
|
||||||
|
otherwise.
|
||||||
|
*/
|
||||||
|
/*******************************************************************************/
|
||||||
|
bool getEventPM25_STD(sensors_event_t *pm25StdEvent) {
|
||||||
|
if (!ReadSensorData() || _massConcentrationPm2p5 == NAN ||
|
||||||
|
_massConcentrationPm2p5 == OVERFLOW_SEN6X) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
pm25StdEvent->pm25_std = _massConcentrationPm2p5;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************/
|
||||||
|
/*!
|
||||||
|
@brief Gets the SEN6X sensor's PM4.0 STD reading.
|
||||||
|
@param pm40StdEvent
|
||||||
|
Adafruit Sensor event for PM4.0
|
||||||
|
@returns True if the sensor value was obtained successfully, False
|
||||||
|
otherwise.
|
||||||
|
*/
|
||||||
|
/*******************************************************************************/
|
||||||
|
bool getEventPM40_STD(sensors_event_t *pm40StdEvent) {
|
||||||
|
if (!ReadSensorData() || _massConcentrationPm4p0 == NAN ||
|
||||||
|
_massConcentrationPm4p0 == OVERFLOW_SEN6X) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
pm40StdEvent->data[0] = _massConcentrationPm4p0;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************/
|
||||||
|
/*!
|
||||||
|
@brief Gets the SEN6X sensor's PM10.0 STD reading.
|
||||||
|
@param pm100StdEvent
|
||||||
|
Adafruit Sensor event for PM10.0
|
||||||
|
@returns True if the sensor value was obtained successfully, False
|
||||||
|
otherwise.
|
||||||
|
*/
|
||||||
|
/*******************************************************************************/
|
||||||
|
bool getEventPM100_STD(sensors_event_t *pm100StdEvent) {
|
||||||
|
if (!ReadSensorData() || _massConcentrationPm10p0 == NAN ||
|
||||||
|
_massConcentrationPm10p0 == OVERFLOW_SEN6X) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
pm100StdEvent->pm100_std = _massConcentrationPm10p0;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************/
|
||||||
|
/*!
|
||||||
|
@brief Gets the SEN6X sensor's CO2 reading.
|
||||||
|
@param co2Event
|
||||||
|
Adafruit Sensor event for CO2
|
||||||
|
@returns True if the sensor value was obtained successfully, False
|
||||||
|
otherwise.
|
||||||
|
*/
|
||||||
|
/*******************************************************************************/
|
||||||
|
bool getEventCO2(sensors_event_t *co2Event) {
|
||||||
|
if (!ReadSensorData() || _co2 == 0xFFFF) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
co2Event->CO2 = _co2;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
SensirionI2cSen66 *_sen = nullptr; ///< SEN6X driver object
|
||||||
|
float _massConcentrationPm1p0; ///< PM1.0 mass concentration
|
||||||
|
float _massConcentrationPm2p5; ///< PM2.5 mass concentration
|
||||||
|
float _massConcentrationPm4p0; ///< PM4.0 mass concentration
|
||||||
|
float _massConcentrationPm10p0; ///< PM10.0 mass concentration
|
||||||
|
float _ambientHumidity; ///< Ambient humidity
|
||||||
|
float _ambientTemperature; ///< Ambient temperature
|
||||||
|
float _vocIndex; ///< VOC index
|
||||||
|
float _noxIndex; ///< NOx index
|
||||||
|
uint16_t _co2; ///< CO2 value
|
||||||
|
ulong _lastRead; ///< Last time the sensor was read
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // WipperSnapper_I2C_Driver_SEN6X
|
||||||
|
|
@ -44,11 +44,7 @@ public:
|
||||||
/*******************************************************************************/
|
/*******************************************************************************/
|
||||||
bool begin() {
|
bool begin() {
|
||||||
_sgp30 = new Adafruit_SGP30();
|
_sgp30 = new Adafruit_SGP30();
|
||||||
bool isInit = _sgp30->begin(_i2c);
|
return _sgp30->begin(_i2c);
|
||||||
if (isInit) {
|
|
||||||
_sgp30->IAQinit();
|
|
||||||
}
|
|
||||||
return isInit;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool getEventECO2(sensors_event_t *senseEvent) {
|
bool getEventECO2(sensors_event_t *senseEvent) {
|
||||||
|
|
|
||||||
107
src/components/i2c/drivers/WipperSnapper_I2C_Driver_VCNL4200.h
Normal file
107
src/components/i2c/drivers/WipperSnapper_I2C_Driver_VCNL4200.h
Normal file
|
|
@ -0,0 +1,107 @@
|
||||||
|
/*!
|
||||||
|
* @file WipperSnapper_I2C_Driver_VCNL4200.h
|
||||||
|
*
|
||||||
|
* Device driver for the VCNL4200 light + proximity sensor.
|
||||||
|
*
|
||||||
|
* Adafruit invests time and resources providing this open source code,
|
||||||
|
* please support Adafruit and open-source hardware by purchasing
|
||||||
|
* products from Adafruit!
|
||||||
|
*
|
||||||
|
* Copyright (c) Tyeth Gundry 2024 for Adafruit Industries.
|
||||||
|
*
|
||||||
|
* MIT license, all text here must be included in any redistribution.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef WipperSnapper_I2C_Driver_VCNL4200_H
|
||||||
|
#define WipperSnapper_I2C_Driver_VCNL4200_H
|
||||||
|
|
||||||
|
#include "WipperSnapper_I2C_Driver.h"
|
||||||
|
#include <Adafruit_VCNL4200.h>
|
||||||
|
|
||||||
|
/**************************************************************************/
|
||||||
|
/*!
|
||||||
|
@brief Class that provides a driver interface for a VCNL4200 sensor.
|
||||||
|
*/
|
||||||
|
/**************************************************************************/
|
||||||
|
class WipperSnapper_I2C_Driver_VCNL4200 : public WipperSnapper_I2C_Driver {
|
||||||
|
public:
|
||||||
|
/*******************************************************************************/
|
||||||
|
/*!
|
||||||
|
@brief Constructor for a VCNL4200 sensor.
|
||||||
|
@param i2c
|
||||||
|
The I2C interface.
|
||||||
|
@param sensorAddress
|
||||||
|
The 7-bit I2C address of the sensor.
|
||||||
|
*/
|
||||||
|
/*******************************************************************************/
|
||||||
|
WipperSnapper_I2C_Driver_VCNL4200(TwoWire *i2c, uint16_t sensorAddress)
|
||||||
|
: WipperSnapper_I2C_Driver(i2c, sensorAddress) {
|
||||||
|
_i2c = i2c;
|
||||||
|
_sensorAddress = sensorAddress;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************/
|
||||||
|
/*!
|
||||||
|
@brief Destructor for an VCNL4200 sensor.
|
||||||
|
*/
|
||||||
|
/*******************************************************************************/
|
||||||
|
~WipperSnapper_I2C_Driver_VCNL4200() { delete _vcnl4200; }
|
||||||
|
|
||||||
|
/*******************************************************************************/
|
||||||
|
/*!
|
||||||
|
@brief Initializes the VCNL4200 sensor and begins I2C.
|
||||||
|
@returns True if initialized successfully, False otherwise.
|
||||||
|
*/
|
||||||
|
/*******************************************************************************/
|
||||||
|
bool begin() {
|
||||||
|
_vcnl4200 = new Adafruit_VCNL4200();
|
||||||
|
bool status = false;
|
||||||
|
// Attempt to initialize and configure VCNL4200
|
||||||
|
if (!_vcnl4200->begin(_sensorAddress, _i2c)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
status = _vcnl4200->setALSshutdown(false);
|
||||||
|
status &= _vcnl4200->setProxShutdown(false);
|
||||||
|
status &= _vcnl4200->setProxHD(true); // 16bit instead of 12bit
|
||||||
|
status &= _vcnl4200->setALSIntegrationTime(VCNL4200_ALS_IT_400MS);
|
||||||
|
status &= _vcnl4200->setProxDuty(VCNL4200_PS_DUTY_1_160);
|
||||||
|
status &= _vcnl4200->setProxLEDCurrent(VCNL4200_LED_I_200MA);
|
||||||
|
status &= _vcnl4200->setProxIntegrationTime(VCNL4200_PS_IT_9T);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************/
|
||||||
|
/*!
|
||||||
|
@brief Performs a light sensor read using the Adafruit
|
||||||
|
Unified Sensor API.
|
||||||
|
@param lightEvent
|
||||||
|
Light sensor reading, in lux.
|
||||||
|
@returns True if the sensor event was obtained successfully, False
|
||||||
|
otherwise.
|
||||||
|
*/
|
||||||
|
/*******************************************************************************/
|
||||||
|
bool getEventLight(sensors_event_t *lightEvent) {
|
||||||
|
// Get sensor event populated in lux via AUTO integration and gain
|
||||||
|
lightEvent->light = _vcnl4200->readALSdata();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************/
|
||||||
|
/*!
|
||||||
|
@brief Reads the VCNL4200's proximity value into an event (no unit).
|
||||||
|
@param proximityEvent
|
||||||
|
Pointer to an Adafruit_Sensor event.
|
||||||
|
@returns True if the proximity was obtained successfully, False
|
||||||
|
otherwise.
|
||||||
|
*/
|
||||||
|
/*******************************************************************************/
|
||||||
|
bool getEventProximity(sensors_event_t *proximityEvent) {
|
||||||
|
proximityEvent->data[0] = (float)_vcnl4200->readProxData();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Adafruit_VCNL4200 *_vcnl4200; ///< Pointer to VCNL4200 light sensor object
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // WipperSnapper_I2C_Driver_VCNL4200
|
||||||
|
|
@ -112,7 +112,7 @@ public:
|
||||||
/*******************************************************************************/
|
/*******************************************************************************/
|
||||||
bool getEventProximity(sensors_event_t *proximityEvent) {
|
bool getEventProximity(sensors_event_t *proximityEvent) {
|
||||||
uint8_t NewDataReady = 0;
|
uint8_t NewDataReady = 0;
|
||||||
VL53L4CD_Result_t results;
|
VL53L4CD_Result_t results = {0};
|
||||||
uint8_t status;
|
uint8_t status;
|
||||||
// Start fresh reading, seemed to be accepting stale value
|
// Start fresh reading, seemed to be accepting stale value
|
||||||
_VL53L4CD->VL53L4CD_ClearInterrupt();
|
_VL53L4CD->VL53L4CD_ClearInterrupt();
|
||||||
|
|
|
||||||
|
|
@ -129,7 +129,7 @@ public:
|
||||||
*/
|
*/
|
||||||
/*******************************************************************************/
|
/*******************************************************************************/
|
||||||
bool getProximity(sensors_event_t *proximityEvent, int whichObject = 0) {
|
bool getProximity(sensors_event_t *proximityEvent, int whichObject = 0) {
|
||||||
VL53L4CX_MultiRangingData_t MultiRangingData;
|
VL53L4CX_MultiRangingData_t MultiRangingData = {0};
|
||||||
VL53L4CX_MultiRangingData_t *pMultiRangingData = &MultiRangingData;
|
VL53L4CX_MultiRangingData_t *pMultiRangingData = &MultiRangingData;
|
||||||
uint8_t NewDataReady = 0;
|
uint8_t NewDataReady = 0;
|
||||||
int status;
|
int status;
|
||||||
|
|
|
||||||
|
|
@ -54,7 +54,8 @@ bool ws_ledc::analogWrite(uint8_t pin, int value) {
|
||||||
|
|
||||||
// Calculate duty cycle for the `value` passed in
|
// Calculate duty cycle for the `value` passed in
|
||||||
// (assumes 12-bit resolution, 2^12)
|
// (assumes 12-bit resolution, 2^12)
|
||||||
uint32_t dutyCycle = (4095 / 255) * min(value, 255);
|
uint32_t dutyCycle =
|
||||||
|
(uint32_t)(((double)4095 / 255.0) * min((uint32_t)value, (uint32_t)255));
|
||||||
|
|
||||||
// Call duty cycle write
|
// Call duty cycle write
|
||||||
return setDuty(pin, dutyCycle);
|
return setDuty(pin, dutyCycle);
|
||||||
|
|
|
||||||
|
|
@ -64,12 +64,19 @@ int16_t ws_pixels::allocateStrand() {
|
||||||
*/
|
*/
|
||||||
/**************************************************************************/
|
/**************************************************************************/
|
||||||
void ws_pixels::deallocateStrand(int16_t strandIdx) {
|
void ws_pixels::deallocateStrand(int16_t strandIdx) {
|
||||||
|
|
||||||
// delete the pixel object
|
// delete the pixel object
|
||||||
if (strands[strandIdx].neoPixelPtr != nullptr)
|
if (strands[strandIdx].neoPixelPtr != nullptr) {
|
||||||
|
// Fill with "off"
|
||||||
|
strands[strandIdx].neoPixelPtr->clear();
|
||||||
|
strands[strandIdx].neoPixelPtr->show();
|
||||||
|
// Delete the NeoPixel object
|
||||||
delete strands[strandIdx].neoPixelPtr;
|
delete strands[strandIdx].neoPixelPtr;
|
||||||
if ((strands[strandIdx].dotStarPtr != nullptr))
|
} else if ((strands[strandIdx].dotStarPtr != nullptr)) {
|
||||||
|
// Fill with "off"
|
||||||
|
strands[strandIdx].dotStarPtr->clear();
|
||||||
|
strands[strandIdx].dotStarPtr->show();
|
||||||
delete strands[strandIdx].dotStarPtr;
|
delete strands[strandIdx].dotStarPtr;
|
||||||
|
}
|
||||||
|
|
||||||
// re-initialize status pixel (if pixel was prvsly used)
|
// re-initialize status pixel (if pixel was prvsly used)
|
||||||
if (strands[strandIdx].pinNeoPixel == getStatusNeoPixelPin() ||
|
if (strands[strandIdx].pinNeoPixel == getStatusNeoPixelPin() ||
|
||||||
|
|
@ -243,6 +250,7 @@ bool ws_pixels::addStrand(
|
||||||
releaseStatusLED(); // release it!
|
releaseStatusLED(); // release it!
|
||||||
|
|
||||||
// Create a new strand of NeoPixels
|
// Create a new strand of NeoPixels
|
||||||
|
WS_DEBUG_PRINTLN("Setting up new NeoPixel Strand...");
|
||||||
strands[strandIdx].neoPixelPtr = new Adafruit_NeoPixel(
|
strands[strandIdx].neoPixelPtr = new Adafruit_NeoPixel(
|
||||||
pixelsCreateReqMsg->pixels_num, strands[strandIdx].pinNeoPixel,
|
pixelsCreateReqMsg->pixels_num, strands[strandIdx].pinNeoPixel,
|
||||||
getNeoPixelStrandOrder(pixelsCreateReqMsg->pixels_ordering));
|
getNeoPixelStrandOrder(pixelsCreateReqMsg->pixels_ordering));
|
||||||
|
|
|
||||||
|
|
@ -55,7 +55,7 @@ bool Wippersnapper::encodePubRegistrationReq() {
|
||||||
if (!_status)
|
if (!_status)
|
||||||
return _status;
|
return _status;
|
||||||
|
|
||||||
// pubish message
|
// publish message
|
||||||
WS.publish(WS._topic_description, _message_buffer, _message_len, 1);
|
WS.publish(WS._topic_description, _message_buffer, _message_len, 1);
|
||||||
WS_DEBUG_PRINTLN("Published!");
|
WS_DEBUG_PRINTLN("Published!");
|
||||||
WS._boardStatus = WS_BOARD_DEF_SENT;
|
WS._boardStatus = WS_BOARD_DEF_SENT;
|
||||||
|
|
|
||||||
|
|
@ -72,7 +72,7 @@ bool ws_servo::servo_attach(int pin, int minPulseWidth, int maxPulseWidth,
|
||||||
#ifdef ARDUINO_ARCH_ESP32
|
#ifdef ARDUINO_ARCH_ESP32
|
||||||
rc = servo->attach(pin, minPulseWidth, maxPulseWidth, freq);
|
rc = servo->attach(pin, minPulseWidth, maxPulseWidth, freq);
|
||||||
#else
|
#else
|
||||||
(void)freq; // supress warning when we don't use the frequency parameter
|
(void)freq; // suppress warning when we don't use the frequency parameter
|
||||||
rc = servo->attach(pin, minPulseWidth, maxPulseWidth);
|
rc = servo->attach(pin, minPulseWidth, maxPulseWidth);
|
||||||
#endif
|
#endif
|
||||||
if (rc == ERR_SERVO_ATTACH)
|
if (rc == ERR_SERVO_ATTACH)
|
||||||
|
|
|
||||||
|
|
@ -51,6 +51,7 @@ void initStatusLED() {
|
||||||
statusPixel = new Adafruit_NeoPixel(
|
statusPixel = new Adafruit_NeoPixel(
|
||||||
STATUS_NEOPIXEL_NUM, STATUS_NEOPIXEL_PIN, NEO_GRB + NEO_KHZ800);
|
STATUS_NEOPIXEL_NUM, STATUS_NEOPIXEL_PIN, NEO_GRB + NEO_KHZ800);
|
||||||
statusPixel->begin();
|
statusPixel->begin();
|
||||||
|
statusPixel->clear();
|
||||||
statusPixel->show(); // turn OFF all pixels
|
statusPixel->show(); // turn OFF all pixels
|
||||||
WS.lockStatusNeoPixel = true;
|
WS.lockStatusNeoPixel = true;
|
||||||
}
|
}
|
||||||
|
|
@ -69,6 +70,7 @@ void initStatusLED() {
|
||||||
STATUS_DOTSTAR_PIN_CLK, STATUS_DOTSTAR_COLOR_ORDER)
|
STATUS_DOTSTAR_PIN_CLK, STATUS_DOTSTAR_COLOR_ORDER)
|
||||||
#endif
|
#endif
|
||||||
statusPixelDotStar->begin();
|
statusPixelDotStar->begin();
|
||||||
|
statusPixelDotStar->clear();
|
||||||
statusPixelDotStar->show(); // turn OFF all pixels
|
statusPixelDotStar->show(); // turn OFF all pixels
|
||||||
WS.lockStatusDotStar = true;
|
WS.lockStatusDotStar = true;
|
||||||
}
|
}
|
||||||
|
|
@ -83,7 +85,7 @@ void initStatusLED() {
|
||||||
#elif defined(ARDUINO_ARCH_ESP32)
|
#elif defined(ARDUINO_ARCH_ESP32)
|
||||||
WS._pwmComponent->attach(STATUS_LED_PIN, LEDC_BASE_FREQ, LEDC_TIMER_12_BIT);
|
WS._pwmComponent->attach(STATUS_LED_PIN, LEDC_BASE_FREQ, LEDC_TIMER_12_BIT);
|
||||||
WS._pwmComponent->writeDutyCycle(STATUS_LED_PIN, 0); // turn OFF
|
WS._pwmComponent->writeDutyCycle(STATUS_LED_PIN, 0); // turn OFF
|
||||||
#elif defined(ARDUINO_RASPBERRY_PI_PICO_W)
|
#elif defined(ARDUINO_ARCH_RP2040)
|
||||||
digitalWrite(STATUS_LED_PIN, 0);
|
digitalWrite(STATUS_LED_PIN, 0);
|
||||||
#else
|
#else
|
||||||
analogWrite(STATUS_LED_PIN, 0);
|
analogWrite(STATUS_LED_PIN, 0);
|
||||||
|
|
@ -99,10 +101,12 @@ void initStatusLED() {
|
||||||
*/
|
*/
|
||||||
/****************************************************************************/
|
/****************************************************************************/
|
||||||
void releaseStatusLED() {
|
void releaseStatusLED() {
|
||||||
|
WS_DEBUG_PRINTLN("Releasing status LED");
|
||||||
#ifdef USE_STATUS_NEOPIXEL
|
#ifdef USE_STATUS_NEOPIXEL
|
||||||
delete statusPixel; // Deallocate Adafruit_NeoPixel object, set data pin back
|
// Deallocate Adafruit_NeoPixel object, set data pin back to INPUT,
|
||||||
// to INPUT.
|
// and unlock pixel for use by pixels component
|
||||||
WS.lockStatusNeoPixel = false; // unlock
|
delete statusPixel;
|
||||||
|
WS.lockStatusNeoPixel = false;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_STATUS_DOTSTAR
|
#ifdef USE_STATUS_DOTSTAR
|
||||||
|
|
@ -177,7 +181,7 @@ void setStatusLEDColor(uint32_t color) {
|
||||||
#ifdef USE_STATUS_LED
|
#ifdef USE_STATUS_LED
|
||||||
if (!WS.lockStatusLED)
|
if (!WS.lockStatusLED)
|
||||||
return; // status pixel is in-use elsewhere
|
return; // status pixel is in-use elsewhere
|
||||||
#ifdef ARDUINO_RASPBERRY_PI_PICO_W
|
#ifdef ARDUINO_ARCH_RP2040
|
||||||
digitalWrite(STATUS_LED_PIN, color > 0);
|
digitalWrite(STATUS_LED_PIN, color > 0);
|
||||||
#else
|
#else
|
||||||
if (color != BLACK)
|
if (color != BLACK)
|
||||||
|
|
@ -236,7 +240,7 @@ void setStatusLEDColor(uint32_t color, int brightness) {
|
||||||
if (!WS.lockStatusLED)
|
if (!WS.lockStatusLED)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
#ifdef ARDUINO_RASPBERRY_PI_PICO_W
|
#ifdef ARDUINO_ARCH_RP2040
|
||||||
digitalWrite(STATUS_LED_PIN, color > 0);
|
digitalWrite(STATUS_LED_PIN, color > 0);
|
||||||
#else
|
#else
|
||||||
if (color != BLACK) {
|
if (color != BLACK) {
|
||||||
|
|
|
||||||
|
|
@ -160,7 +160,7 @@ public:
|
||||||
@brief Reads the UART device's data then packs and sends it to IO.
|
@brief Reads the UART device's data then packs and sends it to IO.
|
||||||
*/
|
*/
|
||||||
/*******************************************************************************/
|
/*******************************************************************************/
|
||||||
virtual void send_data(){};
|
virtual void send_data() {};
|
||||||
|
|
||||||
const char *uartTopic = nullptr; ///< UART device's MQTT topic
|
const char *uartTopic = nullptr; ///< UART device's MQTT topic
|
||||||
Adafruit_MQTT *mqttClient = nullptr; ///< Pointer to MQTT client object
|
Adafruit_MQTT *mqttClient = nullptr; ///< Pointer to MQTT client object
|
||||||
|
|
|
||||||
|
|
@ -81,14 +81,17 @@ public:
|
||||||
/*******************************************************************************/
|
/*******************************************************************************/
|
||||||
bool begin() override {
|
bool begin() override {
|
||||||
_aqi = new Adafruit_PM25AQI();
|
_aqi = new Adafruit_PM25AQI();
|
||||||
|
bool is_pm1006 = (strcmp(getDriverID(), "pm1006") == 0);
|
||||||
#ifdef USE_SW_UART
|
#ifdef USE_SW_UART
|
||||||
if (!_aqi->begin_UART(
|
if (!_aqi->begin_UART(
|
||||||
_swSerial)) { // connect to the sensor over software serial
|
_swSerial, // connect to the sensor over software serial
|
||||||
|
is_pm1006)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
if (!_aqi->begin_UART(
|
if (!_aqi->begin_UART(
|
||||||
_hwSerial)) { // connect to the sensor over hardware serial
|
_hwSerial, // connect to the sensor over hardware serial
|
||||||
|
is_pm1006)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@
|
||||||
* please support Adafruit and open-source hardware by purchasing
|
* please support Adafruit and open-source hardware by purchasing
|
||||||
* products from Adafruit!
|
* products from Adafruit!
|
||||||
*
|
*
|
||||||
* Copyright (c) Brent Rubell 2020-2021 for Adafruit Industries.
|
* Copyright (c) Brent Rubell 2020-2025 for Adafruit Industries.
|
||||||
*
|
*
|
||||||
* MIT license, all text here must be included in any redistribution.
|
* MIT license, all text here must be included in any redistribution.
|
||||||
*
|
*
|
||||||
|
|
@ -32,7 +32,9 @@
|
||||||
#define AIRLIFT_CONNECT_TIMEOUT_MS 20000 /*!< Connection timeout (in ms) */
|
#define AIRLIFT_CONNECT_TIMEOUT_MS 20000 /*!< Connection timeout (in ms) */
|
||||||
#define AIRLIFT_CONNECT_RETRY_DELAY_MS 200 /*!< delay time between retries. */
|
#define AIRLIFT_CONNECT_RETRY_DELAY_MS 200 /*!< delay time between retries. */
|
||||||
|
|
||||||
|
#ifndef SPIWIFI
|
||||||
#define SPIWIFI SPI /*!< Instance of SPI interface used by an AirLift. */
|
#define SPIWIFI SPI /*!< Instance of SPI interface used by an AirLift. */
|
||||||
|
#endif
|
||||||
|
|
||||||
extern Wippersnapper WS;
|
extern Wippersnapper WS;
|
||||||
/****************************************************************************/
|
/****************************************************************************/
|
||||||
|
|
@ -49,9 +51,13 @@ public:
|
||||||
*/
|
*/
|
||||||
/**************************************************************************/
|
/**************************************************************************/
|
||||||
Wippersnapper_AIRLIFT() : Wippersnapper() {
|
Wippersnapper_AIRLIFT() : Wippersnapper() {
|
||||||
_ssPin = SPIWIFI_SS; // 10;
|
_ssPin = SPIWIFI_SS;
|
||||||
_ackPin = SPIWIFI_ACK; // 7;
|
_ackPin = SPIWIFI_ACK;
|
||||||
_rstPin = SPIWIFI_RESET; // 5; // should be 7 on PyPortals
|
#ifdef ESP32_RESETN
|
||||||
|
_rstPin = ESP32_RESETN; // FruitJam
|
||||||
|
#else
|
||||||
|
_rstPin = SPIWIFI_RESET;
|
||||||
|
#endif // ESP32_RESETN
|
||||||
#ifdef ESP32_GPIO0
|
#ifdef ESP32_GPIO0
|
||||||
_gpio0Pin = ESP32_GPIO0;
|
_gpio0Pin = ESP32_GPIO0;
|
||||||
#else
|
#else
|
||||||
|
|
@ -103,8 +109,8 @@ public:
|
||||||
|
|
||||||
/***********************************************************/
|
/***********************************************************/
|
||||||
/*!
|
/*!
|
||||||
@brief Performs a scan of local WiFi networks.
|
@brief Performs a scan of local WiFi networks.
|
||||||
@returns True if `_network_ssid` is found, False otherwise.
|
@returns True if `_network_ssid` is found, False otherwise.
|
||||||
*/
|
*/
|
||||||
/***********************************************************/
|
/***********************************************************/
|
||||||
bool check_valid_ssid() {
|
bool check_valid_ssid() {
|
||||||
|
|
@ -119,26 +125,33 @@ public:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Was the network within secrets.json found?
|
bool foundNetwork = false;
|
||||||
for (int i = 0; i < n; ++i) {
|
|
||||||
if (strcmp(_ssid, WiFi.SSID(i)) == 0) {
|
WS_DEBUG_PRINTLN("WipperSnapper found these WiFi networks:");
|
||||||
WS_DEBUG_PRINT("SSID found! RSSI: ");
|
for (uint8_t i = 0; i < n; i++) {
|
||||||
WS_DEBUG_PRINTLN(WiFi.RSSI(i));
|
if (!foundNetwork && strcmp(WiFi.SSID(i), _ssid) == 0) {
|
||||||
return true;
|
foundNetwork = true;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// User-set network not found, print scan results to serial console
|
|
||||||
WS_DEBUG_PRINTLN("ERROR: Your requested WiFi network was not found!");
|
|
||||||
WS_DEBUG_PRINTLN("WipperSnapper found these WiFi networks: ");
|
|
||||||
for (int i = 0; i < n; ++i) {
|
|
||||||
WS_DEBUG_PRINT(WiFi.SSID(i));
|
WS_DEBUG_PRINT(WiFi.SSID(i));
|
||||||
WS_DEBUG_PRINT(" ");
|
WS_DEBUG_PRINT(" (");
|
||||||
|
uint8_t BSSID[WL_MAC_ADDR_LENGTH];
|
||||||
|
WiFi.BSSID(i, BSSID);
|
||||||
|
for (int m = 0; m < WL_MAC_ADDR_LENGTH; m++) {
|
||||||
|
if (m != 0)
|
||||||
|
WS_DEBUG_PRINT(":");
|
||||||
|
WS_DEBUG_PRINTHEX(BSSID[m]);
|
||||||
|
}
|
||||||
|
WS_DEBUG_PRINT(") ");
|
||||||
WS_DEBUG_PRINT(WiFi.RSSI(i));
|
WS_DEBUG_PRINT(WiFi.RSSI(i));
|
||||||
WS_DEBUG_PRINTLN("dB");
|
WS_DEBUG_PRINT("dB (ch");
|
||||||
|
WS_DEBUG_PRINT(WiFi.channel(i))
|
||||||
|
WS_DEBUG_PRINTLN(")");
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
if (!foundNetwork) {
|
||||||
|
WS_DEBUG_PRINTLN("ERROR: Your requested WiFi network was not found!");
|
||||||
|
}
|
||||||
|
return foundNetwork;
|
||||||
}
|
}
|
||||||
|
|
||||||
/********************************************************/
|
/********************************************************/
|
||||||
|
|
@ -229,7 +242,7 @@ public:
|
||||||
*/
|
*/
|
||||||
/********************************************************/
|
/********************************************************/
|
||||||
void getMacAddr() {
|
void getMacAddr() {
|
||||||
uint8_t mac[6] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
byte mac[6] = {0};
|
||||||
WiFi.macAddress(mac);
|
WiFi.macAddress(mac);
|
||||||
memcpy(WS._macAddr, mac, sizeof(mac));
|
memcpy(WS._macAddr, mac, sizeof(mac));
|
||||||
}
|
}
|
||||||
|
|
@ -323,6 +336,7 @@ protected:
|
||||||
|
|
||||||
// validate co-processor's firmware version
|
// validate co-processor's firmware version
|
||||||
if (!firmwareCheck()) {
|
if (!firmwareCheck()) {
|
||||||
|
// TODO: see if there's a way to add to bootlog without usb reattach
|
||||||
WS_DEBUG_PRINTLN("Please upgrade the firmware on the ESP module to the "
|
WS_DEBUG_PRINTLN("Please upgrade the firmware on the ESP module to the "
|
||||||
"latest version.");
|
"latest version.");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -103,6 +103,17 @@ public:
|
||||||
WiFi.disconnect();
|
WiFi.disconnect();
|
||||||
delay(100);
|
delay(100);
|
||||||
|
|
||||||
|
// For boards with a "3D Antenna", we need to reduce the TX power
|
||||||
|
// to prevent flaky operation.
|
||||||
|
// NOTE: This is a known issue with the QT Py series of boards.
|
||||||
|
#if defined(ARDUINO_ADAFRUIT_QTPY_ESP32S2) || \
|
||||||
|
defined(ARDUINO_ADAFRUIT_QTPY_ESP32S3_NOPSRAM) || \
|
||||||
|
defined(ARDUINO_ADAFRUIT_QTPY_ESP32S3_N4R2) || \
|
||||||
|
defined(ARDUINO_ADAFRUIT_QTPY_ESP32C3) || \
|
||||||
|
defined(ARDUINO_ADAFRUIT_QTPY_ESP32_PICO)
|
||||||
|
WiFi.setTxPower(WIFI_POWER_15dBm);
|
||||||
|
#endif
|
||||||
|
|
||||||
// Perform a network scan
|
// Perform a network scan
|
||||||
int n = WiFi.scanNetworks();
|
int n = WiFi.scanNetworks();
|
||||||
if (n == 0) {
|
if (n == 0) {
|
||||||
|
|
@ -110,40 +121,40 @@ public:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Was the network within secrets.json found?
|
bool foundNetwork = false;
|
||||||
for (int i = 0; i < n; ++i) {
|
|
||||||
if (strcmp(_ssid, WiFi.SSID(i).c_str()) == 0) {
|
WS_DEBUG_PRINTLN("WipperSnapper found these WiFi networks:");
|
||||||
WS_DEBUG_PRINT("SSID (");
|
for (uint8_t i = 0; i < n; i++) {
|
||||||
WS_DEBUG_PRINT(_ssid);
|
if (!foundNetwork && strcmp(WiFi.SSID(i).c_str(), _ssid) == 0) {
|
||||||
WS_DEBUG_PRINT(") found! RSSI: ");
|
foundNetwork = true;
|
||||||
WS_DEBUG_PRINTLN(WiFi.RSSI(i));
|
} else if (!foundNetwork && WS._isWiFiMulti) {
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (WS._isWiFiMulti) {
|
|
||||||
// multi network mode
|
// multi network mode
|
||||||
for (int j = 0; j < WS_MAX_ALT_WIFI_NETWORKS; j++) {
|
for (int j = 0; j < WS_MAX_ALT_WIFI_NETWORKS; j++) {
|
||||||
if (strcmp(WS._multiNetworks[j].ssid, WiFi.SSID(i).c_str()) == 0) {
|
if (strcmp(WS._multiNetworks[j].ssid, WiFi.SSID(i).c_str()) == 0) {
|
||||||
WS_DEBUG_PRINT("SSID (");
|
foundNetwork = true;
|
||||||
WS_DEBUG_PRINT(WS._multiNetworks[j].ssid);
|
|
||||||
WS_DEBUG_PRINT(") found! RSSI: ");
|
|
||||||
WS_DEBUG_PRINTLN(WiFi.RSSI(i));
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// User-set network not found, print scan results to serial console
|
|
||||||
WS_DEBUG_PRINTLN("ERROR: Your requested WiFi network was not found!");
|
|
||||||
WS_DEBUG_PRINTLN("WipperSnapper found these WiFi networks: ");
|
|
||||||
for (int i = 0; i < n; ++i) {
|
|
||||||
WS_DEBUG_PRINT(WiFi.SSID(i));
|
WS_DEBUG_PRINT(WiFi.SSID(i));
|
||||||
WS_DEBUG_PRINT(" ");
|
WS_DEBUG_PRINT(" (");
|
||||||
|
uint8_t BSSID[WL_MAC_ADDR_LENGTH];
|
||||||
|
WiFi.BSSID(i, BSSID);
|
||||||
|
for (int m = 0; m < WL_MAC_ADDR_LENGTH; m++) {
|
||||||
|
if (m != 0)
|
||||||
|
WS_DEBUG_PRINT(":");
|
||||||
|
WS_DEBUG_PRINTHEX(BSSID[m]);
|
||||||
|
}
|
||||||
|
WS_DEBUG_PRINT(") ");
|
||||||
WS_DEBUG_PRINT(WiFi.RSSI(i));
|
WS_DEBUG_PRINT(WiFi.RSSI(i));
|
||||||
WS_DEBUG_PRINTLN("dB");
|
WS_DEBUG_PRINT("dB (ch");
|
||||||
|
WS_DEBUG_PRINT(WiFi.channel(i))
|
||||||
|
WS_DEBUG_PRINTLN(")");
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
if (!foundNetwork) {
|
||||||
|
WS_DEBUG_PRINTLN("ERROR: Your requested WiFi network was not found!");
|
||||||
|
}
|
||||||
|
return foundNetwork;
|
||||||
}
|
}
|
||||||
|
|
||||||
/********************************************************/
|
/********************************************************/
|
||||||
|
|
@ -232,30 +243,35 @@ protected:
|
||||||
|
|
||||||
const char *_aio_root_ca_staging =
|
const char *_aio_root_ca_staging =
|
||||||
"-----BEGIN CERTIFICATE-----\n"
|
"-----BEGIN CERTIFICATE-----\n"
|
||||||
"MIIEVzCCAj+gAwIBAgIRALBXPpFzlydw27SHyzpFKzgwDQYJKoZIhvcNAQELBQAw\n"
|
"MIIFazCCA1OgAwIBAgIRAIIQz7DSQONZRGPgu2OCiwAwDQYJKoZIhvcNAQELBQAw\n"
|
||||||
"TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh\n"
|
"TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh\n"
|
||||||
"cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMjQwMzEzMDAwMDAw\n"
|
"cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMTUwNjA0MTEwNDM4\n"
|
||||||
"WhcNMjcwMzEyMjM1OTU5WjAyMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNTGV0J3Mg\n"
|
"WhcNMzUwNjA0MTEwNDM4WjBPMQswCQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJu\n"
|
||||||
"RW5jcnlwdDELMAkGA1UEAxMCRTYwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAATZ8Z5G\n"
|
"ZXQgU2VjdXJpdHkgUmVzZWFyY2ggR3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBY\n"
|
||||||
"h/ghcWCoJuuj+rnq2h25EqfUJtlRFLFhfHWWvyILOR/VvtEKRqotPEoJhC6+QJVV\n"
|
"MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK3oJHP0FDfzm54rVygc\n"
|
||||||
"6RlAN2Z17TJOdwRJ+HB7wxjnzvdxEP6sdNgA1O1tHHMWMxCcOrLqbGL0vbijgfgw\n"
|
"h77ct984kIxuPOZXoHj3dcKi/vVqbvYATyjb3miGbESTtrFj/RQSa78f0uoxmyF+\n"
|
||||||
"gfUwDgYDVR0PAQH/BAQDAgGGMB0GA1UdJQQWMBQGCCsGAQUFBwMCBggrBgEFBQcD\n"
|
"0TM8ukj13Xnfs7j/EvEhmkvBioZxaUpmZmyPfjxwv60pIgbz5MDmgK7iS4+3mX6U\n"
|
||||||
"ATASBgNVHRMBAf8ECDAGAQH/AgEAMB0GA1UdDgQWBBSTJ0aYA6lRaI6Y1sRCSNsj\n"
|
"A5/TR5d8mUgjU+g4rk8Kb4Mu0UlXjIB0ttov0DiNewNwIRt18jA8+o+u3dpjq+sW\n"
|
||||||
"v1iU0jAfBgNVHSMEGDAWgBR5tFnme7bl5AFzgAiIyBpY9umbbjAyBggrBgEFBQcB\n"
|
"T8KOEUt+zwvo/7V3LvSye0rgTBIlDHCNAymg4VMk7BPZ7hm/ELNKjD+Jo2FR3qyH\n"
|
||||||
"AQQmMCQwIgYIKwYBBQUHMAKGFmh0dHA6Ly94MS5pLmxlbmNyLm9yZy8wEwYDVR0g\n"
|
"B5T0Y3HsLuJvW5iB4YlcNHlsdu87kGJ55tukmi8mxdAQ4Q7e2RCOFvu396j3x+UC\n"
|
||||||
"BAwwCjAIBgZngQwBAgEwJwYDVR0fBCAwHjAcoBqgGIYWaHR0cDovL3gxLmMubGVu\n"
|
"B5iPNgiV5+I3lg02dZ77DnKxHZu8A/lJBdiB3QW0KtZB6awBdpUKD9jf1b0SHzUv\n"
|
||||||
"Y3Iub3JnLzANBgkqhkiG9w0BAQsFAAOCAgEAfYt7SiA1sgWGCIpunk46r4AExIRc\n"
|
"KBds0pjBqAlkd25HN7rOrFleaJ1/ctaJxQZBKT5ZPt0m9STJEadao0xAH0ahmbWn\n"
|
||||||
"MxkKgUhNlrrv1B21hOaXN/5miE+LOTbrcmU/M9yvC6MVY730GNFoL8IhJ8j8vrOL\n"
|
"OlFuhjuefXKnEgV4We0+UXgVCwOPjdAvBbI+e0ocS3MFEvzG6uBQE3xDk3SzynTn\n"
|
||||||
"pMY22OP6baS1k9YMrtDTlwJHoGby04ThTUeBDksS9RiuHvicZqBedQdIF65pZuhp\n"
|
"jh8BCNAw1FtxNrQHusEwMFxIt4I7mKZ9YIqioymCzLq9gwQbooMDQaHWBfEbwrbw\n"
|
||||||
"eDcGBcLiYasQr/EO5gxxtLyTmgsHSOVSBcFOn9lgv7LECPq9i7mfH3mpxgrRKSxH\n"
|
"qHyGO0aoSCqI3Haadr8faqU9GY/rOPNk3sgrDQoo//fb4hVC1CLQJ13hef4Y53CI\n"
|
||||||
"pOoZ0KXMcB+hHuvlklHntvcI0mMMQ0mhYj6qtMFStkF1RpCG3IPdIwpVCQqu8GV7\n"
|
"rU7m2Ys6xt0nUW7/vGT1M0NPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV\n"
|
||||||
"s8ubknRzs+3C/Bm19RFOoiPpDkwvyNfvmQ14XkyqqKK5oZ8zhD32kFRQkxa8uZSu\n"
|
"HRMBAf8EBTADAQH/MB0GA1UdDgQWBBR5tFnme7bl5AFzgAiIyBpY9umbbjANBgkq\n"
|
||||||
"h4aTImFxknu39waBxIRXE4jKxlAmQc4QjFZoq1KmQqQg0J/1JF8RlFvJas1VcjLv\n"
|
"hkiG9w0BAQsFAAOCAgEAVR9YqbyyqFDQDLHYGmkgJykIrGF1XIpu+ILlaS/V9lZL\n"
|
||||||
"YlvUB2t6npO6oQjB3l+PNf0DpQH7iUx3Wz5AjQCi6L25FjyE06q6BZ/QlmtYdl/8\n"
|
"ubhzEFnTIZd+50xx+7LSYK05qAvqFyFWhfFQDlnrzuBZ6brJFe+GnY+EgPbk6ZGQ\n"
|
||||||
"ZYao4SRqPEs/6cAiF+Qf5zg2UkaWtDphl1LKMuTNLotvsX99HP69V2faNyegodQ0\n"
|
"3BebYhtF8GaV0nxvwuo77x/Py9auJ/GpsMiu/X1+mvoiBOv/2X/qkSsisRcOj/KK\n"
|
||||||
"LyTApr/vT01YPE46vNsDLgK+4cL6TrzC/a4WcmF5SRJ938zrv/duJHLXQIku5v0+\n"
|
"NFtY2PwByVS5uCbMiogziUwthDyC3+6WVwW6LLv3xLfHTjuCvjHIInNzktHCgKQ5\n"
|
||||||
"EwOy59Hdm0PT/Er/84dDV0CSjdR/2XuZM3kpysSKLgD1cKiDA+IRguODCxfO9cyY\n"
|
"ORAzI4JMPJ+GslWYHb4phowim57iaztXOoJwTdwJx4nLCgdNbOhdjsnvzqvHu7Ur\n"
|
||||||
"Ig46v9mFmBvyH04=\n"
|
"TkXWStAmzOVyyghqpZXjFaH3pO3JLF+l+/+sKAIuvtd7u+Nxe5AW0wdeRlN8NwdC\n"
|
||||||
|
"jNPElpzVmbUq4JUagEiuTDkHzsxHpFKVK7q4+63SM1N95R1NbdWhscdCb+ZAJzVc\n"
|
||||||
|
"oyi3B43njTOQ5yOf+1CceWxG1bQVs5ZufpsMljq4Ui0/1lvh+wjChP4kqKOJ2qxq\n"
|
||||||
|
"4RgqsahDYVvTH9w7jXbyLeiNdd8XM2w9U/t7y0Ff/9yi0GE44Za4rF2LN9d11TPA\n"
|
||||||
|
"mRGunUHBcnWEvgJBQl9nJEiU0Zsnvgc/ubhPgXRR4Xq37Z0j4r7g1SgEEzwxA57d\n"
|
||||||
|
"emyPxgcYxn/eR44/KJ4EBs+lVDR3veyJm+kXQ99b21/+jh5Xos1AnX5iItreGCc=\n"
|
||||||
"-----END CERTIFICATE-----\n"; ///< Root certificate for io.adafruit.us
|
"-----END CERTIFICATE-----\n"; ///< Root certificate for io.adafruit.us
|
||||||
|
|
||||||
const char *_aio_root_ca_prod =
|
const char *_aio_root_ca_prod =
|
||||||
|
|
|
||||||
|
|
@ -29,13 +29,15 @@
|
||||||
* important - please switch to using the modern ESP32 (and related models)
|
* important - please switch to using the modern ESP32 (and related models)
|
||||||
* instead of the ESP8266 to avoid updating the SSL fingerprint every year.
|
* instead of the ESP8266 to avoid updating the SSL fingerprint every year.
|
||||||
*
|
*
|
||||||
|
* The commented-out fingerprint below was last updated on 07/14/2025.
|
||||||
|
*
|
||||||
* If you've read through this and still want to use "Secure MQTT" with your
|
* If you've read through this and still want to use "Secure MQTT" with your
|
||||||
* ESP8266 project, we've left the "WiFiClientSecure" lines commented out. To
|
* ESP8266 project, we've left the "WiFiClientSecure" lines commented out. To
|
||||||
* use them, uncomment the commented out lines within this file and re-compile
|
* use them, uncomment the commented out lines within this file and re-compile
|
||||||
* the library.
|
* the library.
|
||||||
*/
|
*/
|
||||||
// static const char *fingerprint PROGMEM = "4E C1 52 73 24 A8 36 D6 7A 4C 67
|
// static const char *fingerprint PROGMEM = "47 D2 CB 14 DF 38 97 59 C6 65 1A
|
||||||
// C7 91 0C 0A 22 B9 2D 5B CA";
|
// 1F 3E 00 1E 53 CC A5 17 E0";
|
||||||
|
|
||||||
extern Wippersnapper WS;
|
extern Wippersnapper WS;
|
||||||
|
|
||||||
|
|
@ -133,40 +135,40 @@ public:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Was the network within secrets.json found?
|
bool foundNetwork = false;
|
||||||
for (int i = 0; i < n; ++i) {
|
|
||||||
if (strcmp(_ssid, WiFi.SSID(i).c_str()) == 0) {
|
WS_DEBUG_PRINTLN("WipperSnapper found these WiFi networks:");
|
||||||
WS_DEBUG_PRINT("SSID (");
|
for (uint8_t i = 0; i < n; i++) {
|
||||||
WS_DEBUG_PRINT(_ssid);
|
if (!foundNetwork && strcmp(WiFi.SSID(i).c_str(), _ssid) == 0) {
|
||||||
WS_DEBUG_PRINT(") found! RSSI: ");
|
foundNetwork = true;
|
||||||
WS_DEBUG_PRINTLN(WiFi.RSSI(i));
|
} else if (!foundNetwork && WS._isWiFiMulti) {
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (WS._isWiFiMulti) {
|
|
||||||
// multi network mode
|
// multi network mode
|
||||||
for (int j = 0; j < WS_MAX_ALT_WIFI_NETWORKS; j++) {
|
for (int j = 0; j < WS_MAX_ALT_WIFI_NETWORKS; j++) {
|
||||||
if (strcmp(WS._multiNetworks[j].ssid, WiFi.SSID(i).c_str()) == 0) {
|
if (strcmp(WS._multiNetworks[j].ssid, WiFi.SSID(i).c_str()) == 0) {
|
||||||
WS_DEBUG_PRINT("SSID (");
|
foundNetwork = true;
|
||||||
WS_DEBUG_PRINT(WS._multiNetworks[j].ssid);
|
|
||||||
WS_DEBUG_PRINT(") found! RSSI: ");
|
|
||||||
WS_DEBUG_PRINTLN(WiFi.RSSI(i));
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// User-set network not found, print scan results to serial console
|
|
||||||
WS_DEBUG_PRINTLN("ERROR: Your requested WiFi network was not found!");
|
|
||||||
WS_DEBUG_PRINTLN("WipperSnapper found these WiFi networks: ");
|
|
||||||
for (int i = 0; i < n; ++i) {
|
|
||||||
WS_DEBUG_PRINT(WiFi.SSID(i));
|
WS_DEBUG_PRINT(WiFi.SSID(i));
|
||||||
WS_DEBUG_PRINT(" ");
|
WS_DEBUG_PRINT(" (");
|
||||||
|
uint8_t BSSID[WL_MAC_ADDR_LENGTH];
|
||||||
|
memcpy(BSSID, WiFi.BSSID(i), WL_MAC_ADDR_LENGTH);
|
||||||
|
for (int m = 0; m < WL_MAC_ADDR_LENGTH; m++) {
|
||||||
|
if (m != 0)
|
||||||
|
WS_DEBUG_PRINT(":");
|
||||||
|
WS_DEBUG_PRINTHEX(BSSID[m]);
|
||||||
|
}
|
||||||
|
WS_DEBUG_PRINT(") ");
|
||||||
WS_DEBUG_PRINT(WiFi.RSSI(i));
|
WS_DEBUG_PRINT(WiFi.RSSI(i));
|
||||||
WS_DEBUG_PRINTLN("dB");
|
WS_DEBUG_PRINT("dB (ch");
|
||||||
|
WS_DEBUG_PRINT(WiFi.channel(i))
|
||||||
|
WS_DEBUG_PRINTLN(")");
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
if (!foundNetwork) {
|
||||||
|
WS_DEBUG_PRINTLN("ERROR: Your requested WiFi network was not found!");
|
||||||
|
}
|
||||||
|
return foundNetwork;
|
||||||
}
|
}
|
||||||
|
|
||||||
/********************************************************/
|
/********************************************************/
|
||||||
|
|
@ -260,7 +262,6 @@ protected:
|
||||||
delay(100);
|
delay(100);
|
||||||
// ESP8266 MUST be in STA mode to avoid device acting as client/server
|
// ESP8266 MUST be in STA mode to avoid device acting as client/server
|
||||||
WiFi.mode(WIFI_STA);
|
WiFi.mode(WIFI_STA);
|
||||||
WiFi.begin(_ssid, _pass);
|
|
||||||
_status = WS_NET_DISCONNECTED;
|
_status = WS_NET_DISCONNECTED;
|
||||||
delay(100);
|
delay(100);
|
||||||
|
|
||||||
|
|
@ -274,38 +275,28 @@ protected:
|
||||||
WS._multiNetworks[i].pass);
|
WS._multiNetworks[i].pass);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// add default network
|
|
||||||
if (_wifiMulti.existsAP(_ssid) == false) {
|
|
||||||
_wifiMulti.addAP(_ssid, _pass);
|
|
||||||
}
|
|
||||||
long startRetry = millis();
|
|
||||||
WS_DEBUG_PRINTLN("CONNECTING");
|
|
||||||
while (_wifiMulti.run(5000) != WL_CONNECTED &&
|
|
||||||
millis() - startRetry < 10000) {
|
|
||||||
// ESP8266 WDT requires yield() during a busy-loop so it doesn't bite
|
|
||||||
yield();
|
|
||||||
}
|
|
||||||
if (WiFi.status() == WL_CONNECTED) {
|
|
||||||
_status = WS_NET_CONNECTED;
|
|
||||||
} else {
|
|
||||||
_status = WS_NET_DISCONNECTED;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// single network mode
|
|
||||||
|
|
||||||
// wait for a connection to be established
|
|
||||||
long startRetry = millis();
|
|
||||||
WS_DEBUG_PRINTLN("CONNECTING");
|
|
||||||
while (WiFi.status() != WL_CONNECTED && millis() - startRetry < 10000) {
|
|
||||||
// ESP8266 WDT requires yield() during a busy-loop so it doesn't bite
|
|
||||||
yield();
|
|
||||||
}
|
|
||||||
if (WiFi.status() == WL_CONNECTED) {
|
|
||||||
_status = WS_NET_CONNECTED;
|
|
||||||
} else {
|
|
||||||
_status = WS_NET_DISCONNECTED;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// add default network
|
||||||
|
if (_wifiMulti.existsAP(_ssid) == false) {
|
||||||
|
_wifiMulti.addAP(_ssid, _pass);
|
||||||
|
}
|
||||||
|
|
||||||
|
long startRetry = millis();
|
||||||
|
WS_DEBUG_PRINTLN("CONNECTING");
|
||||||
|
|
||||||
|
while (_wifiMulti.run(5000) != WL_CONNECTED &&
|
||||||
|
millis() - startRetry < 10000) {
|
||||||
|
// ESP8266 WDT requires yield() during a busy-loop so it doesn't bite
|
||||||
|
yield();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (WiFi.status() == WL_CONNECTED) {
|
||||||
|
_status = WS_NET_CONNECTED;
|
||||||
|
} else {
|
||||||
|
_status = WS_NET_DISCONNECTED;
|
||||||
|
}
|
||||||
|
|
||||||
WS.feedWDT();
|
WS.feedWDT();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,286 +0,0 @@
|
||||||
/*!
|
|
||||||
* @file Wippersnapper_WIFININA.h
|
|
||||||
*
|
|
||||||
* Network interface for the ublox wifi module on the
|
|
||||||
* Arduino MKR WiFi 1010, Arduino Nano 33 IoT and Arduino UNO WiFi Rev.2.
|
|
||||||
*
|
|
||||||
* Adafruit invests time and resources providing this open source code,
|
|
||||||
* please support Adafruit and open-source hardware by purchasing
|
|
||||||
* products from Adafruit!
|
|
||||||
*
|
|
||||||
* Copyright (c) Brent Rubell 2021 for Adafruit Industries.
|
|
||||||
*
|
|
||||||
* MIT license, all text here must be included in any redistribution.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef WIPPERSNAPPER_WIFININA_H
|
|
||||||
#define WIPPERSNAPPER_WIFININA_H
|
|
||||||
#include <Adafruit_MQTT.h>
|
|
||||||
#include <Adafruit_MQTT_Client.h>
|
|
||||||
#include <Arduino.h>
|
|
||||||
#include <SPI.h>
|
|
||||||
#include <WiFiNINA.h>
|
|
||||||
|
|
||||||
#include "Wippersnapper.h"
|
|
||||||
|
|
||||||
#define SPIWIFI \
|
|
||||||
SPI /*!< Instance of SPI interface used by an external uBlox module. */
|
|
||||||
|
|
||||||
extern Wippersnapper WS;
|
|
||||||
/****************************************************************************/
|
|
||||||
/*!
|
|
||||||
@brief Class for using the AirLift Co-Processor network iface.
|
|
||||||
*/
|
|
||||||
/****************************************************************************/
|
|
||||||
class Wippersnapper_WIFININA : public Wippersnapper {
|
|
||||||
|
|
||||||
public:
|
|
||||||
/**************************************************************************/
|
|
||||||
/*!
|
|
||||||
@brief Initializes the Adafruit IO class for ublox devices.
|
|
||||||
@param aioUsername
|
|
||||||
Adafruit IO username
|
|
||||||
@param aioKey
|
|
||||||
Adafruit IO key
|
|
||||||
@param netSSID
|
|
||||||
Wireless Network SSID
|
|
||||||
@param netPass
|
|
||||||
Wireless Network password
|
|
||||||
*/
|
|
||||||
/**************************************************************************/
|
|
||||||
Wippersnapper_WIFININA(const char *aioUsername, const char *aioKey,
|
|
||||||
const char *netSSID, const char *netPass)
|
|
||||||
: Wippersnapper() {
|
|
||||||
_ssid = netSSID;
|
|
||||||
_pass = netPass;
|
|
||||||
_username = aioUsername;
|
|
||||||
_key = aioKey;
|
|
||||||
|
|
||||||
_wifi = &SPIWIFI;
|
|
||||||
_mqtt_client = new WiFiSSLClient;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**************************************************************************/
|
|
||||||
/*!
|
|
||||||
@brief Destructor for the Adafruit IO ublox class.
|
|
||||||
*/
|
|
||||||
/**************************************************************************/
|
|
||||||
~Wippersnapper_WIFININA() {
|
|
||||||
if (_mqtt)
|
|
||||||
delete _mqtt;
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************************************/
|
|
||||||
/*!
|
|
||||||
@brief Configures the device's Adafruit IO credentials. This method
|
|
||||||
should be used only if filesystem-backed provisioning is
|
|
||||||
not avaliable.
|
|
||||||
*/
|
|
||||||
/****************************************************************************/
|
|
||||||
void set_user_key() {
|
|
||||||
strlcpy(WS._config.aio_user, _username, sizeof(WS._config.aio_user));
|
|
||||||
strlcpy(WS._config.aio_key, _key, sizeof(WS._config.aio_key));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**********************************************************/
|
|
||||||
/*!
|
|
||||||
@brief Sets the WiFi client's ssid and password.
|
|
||||||
@param ssid
|
|
||||||
Wireless network's SSID.
|
|
||||||
@param ssidPassword
|
|
||||||
Wireless network's password.
|
|
||||||
*/
|
|
||||||
/**********************************************************/
|
|
||||||
void set_ssid_pass(const char *ssid, const char *ssidPassword) {
|
|
||||||
strlcpy(WS._config.network.ssid, ssid, sizeof(WS._config.network.ssid));
|
|
||||||
strlcpy(WS._config.network.pass, ssidPassword,
|
|
||||||
sizeof(WS._config.network.pass));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**********************************************************/
|
|
||||||
/*!
|
|
||||||
@brief Sets the WiFi client's ssid and password from the
|
|
||||||
header file's credentials.
|
|
||||||
*/
|
|
||||||
/**********************************************************/
|
|
||||||
void set_ssid_pass() {
|
|
||||||
strlcpy(WS._config.network.ssid, _ssid, sizeof(WS._config.network.ssid));
|
|
||||||
strlcpy(WS._config.network.pass, _pass, sizeof(WS._config.network.pass));
|
|
||||||
}
|
|
||||||
|
|
||||||
/***********************************************************/
|
|
||||||
/*!
|
|
||||||
@brief Performs a scan of local WiFi networks.
|
|
||||||
@returns True if `_network_ssid` is found, False otherwise.
|
|
||||||
*/
|
|
||||||
/***********************************************************/
|
|
||||||
bool check_valid_ssid() {
|
|
||||||
// Set WiFi to station mode and disconnect from an AP if it was previously
|
|
||||||
// connected
|
|
||||||
WiFi.disconnect();
|
|
||||||
delay(100);
|
|
||||||
|
|
||||||
// Perform a network scan
|
|
||||||
int n = WiFi.scanNetworks();
|
|
||||||
if (n == 0) {
|
|
||||||
WS_DEBUG_PRINTLN("ERROR: No WiFi networks found!");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Was the network within secrets.json found?
|
|
||||||
for (int i = 0; i < n; ++i) {
|
|
||||||
if (strcmp(_ssid, WiFi.SSID(i)) == 0) {
|
|
||||||
WS_DEBUG_PRINT("SSID found! RSSI: ");
|
|
||||||
WS_DEBUG_PRINTLN(WiFi.RSSI(i));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// User-set network not found, print scan results to serial console
|
|
||||||
WS_DEBUG_PRINTLN("ERROR: Your requested WiFi network was not found!");
|
|
||||||
WS_DEBUG_PRINTLN("WipperSnapper found these WiFi networks: ");
|
|
||||||
for (int i = 0; i < n; ++i) {
|
|
||||||
WS_DEBUG_PRINT(WiFi.SSID(i));
|
|
||||||
WS_DEBUG_PRINT(" ");
|
|
||||||
WS_DEBUG_PRINT(WiFi.RSSI(i));
|
|
||||||
WS_DEBUG_PRINTLN("dB");
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/********************************************************/
|
|
||||||
/*!
|
|
||||||
@brief Sets the WiFi client.
|
|
||||||
@param wifi
|
|
||||||
Instance of SPIClass.
|
|
||||||
*/
|
|
||||||
/********************************************************/
|
|
||||||
void set_wifi(SPIClass *wifi) {
|
|
||||||
_wifi = wifi;
|
|
||||||
_mqtt_client = new WiFiSSLClient;
|
|
||||||
}
|
|
||||||
|
|
||||||
/***********************************************************/
|
|
||||||
/*!
|
|
||||||
@brief Checks the nina-fw version on the module.
|
|
||||||
@return True if firmware on the ublox module matches
|
|
||||||
the latest version of the library, False otherwise.
|
|
||||||
*/
|
|
||||||
/***********************************************************/
|
|
||||||
bool firmwareCheck() {
|
|
||||||
String fv = WiFi.firmwareVersion();
|
|
||||||
if (fv < WIFI_FIRMWARE_LATEST_VERSION)
|
|
||||||
return false;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/********************************************************/
|
|
||||||
/*!
|
|
||||||
@brief Gets the ESP32's unique client identifier.
|
|
||||||
@note For the ESP32, the UID is the MAC address.
|
|
||||||
*/
|
|
||||||
/********************************************************/
|
|
||||||
void getMacAddr() {
|
|
||||||
uint8_t mac[6] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
|
||||||
WiFi.macAddress(mac);
|
|
||||||
memcpy(WS._macAddr, mac, sizeof(mac));
|
|
||||||
}
|
|
||||||
|
|
||||||
/********************************************************/
|
|
||||||
/*!
|
|
||||||
@brief Gets the current network RSSI value
|
|
||||||
@return int32_t RSSI value
|
|
||||||
*/
|
|
||||||
/********************************************************/
|
|
||||||
int32_t getRSSI() { return WiFi.RSSI(); }
|
|
||||||
|
|
||||||
/********************************************************/
|
|
||||||
/*!
|
|
||||||
@brief Initializes the MQTT client.
|
|
||||||
@param clientID
|
|
||||||
MQTT client identifier
|
|
||||||
*/
|
|
||||||
/********************************************************/
|
|
||||||
void setupMQTTClient(const char *clientID) {
|
|
||||||
WS._mqtt = new Adafruit_MQTT_Client(
|
|
||||||
_mqtt_client, WS._config.aio_url, WS._config.io_port, clientID,
|
|
||||||
WS._config.aio_user, WS._config.aio_key);
|
|
||||||
}
|
|
||||||
|
|
||||||
/********************************************************/
|
|
||||||
/*!
|
|
||||||
@brief Returns the network status of an ESP32 module.
|
|
||||||
@return ws_status_t
|
|
||||||
*/
|
|
||||||
/********************************************************/
|
|
||||||
ws_status_t networkStatus() {
|
|
||||||
switch (WiFi.status()) {
|
|
||||||
case WL_CONNECTED:
|
|
||||||
return WS_NET_CONNECTED;
|
|
||||||
case WL_CONNECT_FAILED:
|
|
||||||
return WS_NET_CONNECT_FAILED;
|
|
||||||
case WL_IDLE_STATUS:
|
|
||||||
return WS_IDLE;
|
|
||||||
default:
|
|
||||||
return WS_NET_DISCONNECTED;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*******************************************************************/
|
|
||||||
/*!
|
|
||||||
@brief Returns the type of network connection used by Wippersnapper
|
|
||||||
@return AIRLIFT
|
|
||||||
*/
|
|
||||||
/*******************************************************************/
|
|
||||||
const char *connectionType() { return "AIRLIFT"; }
|
|
||||||
|
|
||||||
protected:
|
|
||||||
const char *_ssid; /*!< Network SSID. */
|
|
||||||
const char *_pass; /*!< Network password. */
|
|
||||||
const char *_username; /*!< Adafruit IO username. */
|
|
||||||
const char *_key; /*!< Adafruit IO key. */
|
|
||||||
|
|
||||||
WiFiSSLClient *_mqtt_client; /*!< Instance of a secure WiFi client. */
|
|
||||||
SPIClass *_wifi; /*!< Instance of the SPI bus used by the ublox. */
|
|
||||||
|
|
||||||
/**************************************************************************/
|
|
||||||
/*!
|
|
||||||
@brief Establishes a connection with the wireless network.
|
|
||||||
*/
|
|
||||||
/**************************************************************************/
|
|
||||||
void _connect() {
|
|
||||||
|
|
||||||
// check if co-processor connected first
|
|
||||||
if (WiFi.status() == WL_NO_MODULE)
|
|
||||||
errorWriteHang("No WiFi Module Detected!");
|
|
||||||
|
|
||||||
// validate the nina-fw version
|
|
||||||
if (!firmwareCheck())
|
|
||||||
errorWriteHang("Please upgrade the firmware on the ESP module to the "
|
|
||||||
"latest version.");
|
|
||||||
|
|
||||||
if (strlen(_ssid) == 0) {
|
|
||||||
_status = WS_SSID_INVALID;
|
|
||||||
} else {
|
|
||||||
// disconnect from possible previous connection
|
|
||||||
_disconnect();
|
|
||||||
|
|
||||||
WiFi.begin(_ssid, _pass);
|
|
||||||
_status = WS_NET_DISCONNECTED;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**************************************************************************/
|
|
||||||
/*!
|
|
||||||
@brief Disconnects from the wireless network.
|
|
||||||
*/
|
|
||||||
/**************************************************************************/
|
|
||||||
void _disconnect() {
|
|
||||||
WiFi.disconnect();
|
|
||||||
delay(500);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // WIPPERSNAPPER_WIFININA_H
|
|
||||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue