mirror of
https://github.com/letscontrolit/ESPEasy.git
synced 2026-07-28 04:07:47 +00:00
Compare commits
686
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
da54ddda78 | ||
|
|
c24205713d | ||
|
|
ae077de72b | ||
|
|
e713da5d79 | ||
|
|
edc261ca2b | ||
|
|
8f4a52a6f1 | ||
|
|
c04b80b2f1 | ||
|
|
cdbc2498c1 | ||
|
|
78997b4329 | ||
|
|
2bece45712 | ||
|
|
10c73a001a | ||
|
|
790a946cf6 | ||
|
|
69c5be6489 | ||
|
|
233ca2bf43 | ||
|
|
3de400fc91 | ||
|
|
edeea02f71 | ||
|
|
6fae1f79d8 | ||
|
|
1222e04caf | ||
|
|
f38973aad6 | ||
|
|
b31b1d913f | ||
|
|
fa3d4af8cb | ||
|
|
29320aab90 | ||
|
|
3bc8609611 | ||
|
|
c43d6b3769 | ||
|
|
e9e2ea32ed | ||
|
|
24b7d1f438 | ||
|
|
4febf08501 | ||
|
|
7f4eae19f4 | ||
|
|
c13952d04c | ||
|
|
3032463917 | ||
|
|
bbb97bfc7e | ||
|
|
e51f7683a5 | ||
|
|
e747756dd2 | ||
|
|
1ad6fd6ea0 | ||
|
|
d2ec15a4bf | ||
|
|
f23d9fa3d3 | ||
|
|
3cea522ec4 | ||
|
|
5c4defdf6e | ||
|
|
e58ea2a3fe | ||
|
|
a93a078c0b | ||
|
|
0e0e7be95a | ||
|
|
2b7a61469f | ||
|
|
ce02c9e039 | ||
|
|
1e9dc1d14c | ||
|
|
9a6f7360da | ||
|
|
e3cd057ad8 | ||
|
|
fec069ba00 | ||
|
|
d835ef679c | ||
|
|
9144e7901b | ||
|
|
858ce397c3 | ||
|
|
78c9ff70be | ||
|
|
b2db97e808 | ||
|
|
40eb3e7ceb | ||
|
|
d7134e6b87 | ||
|
|
8dc1924059 | ||
|
|
a7b77b6008 | ||
|
|
88320d25fc | ||
|
|
649305a2dd | ||
|
|
d49197a621 | ||
|
|
2371b0f315 | ||
|
|
9abdd097c9 | ||
|
|
f8849cb601 | ||
|
|
b293e8fee0 | ||
|
|
11b1c8505a | ||
|
|
9cb3ceed83 | ||
|
|
2ac1df9482 | ||
|
|
59b7768722 | ||
|
|
d4e5742b1c | ||
|
|
f815564dc7 | ||
|
|
b320c2a1e2 | ||
|
|
2b51a4d7c4 | ||
|
|
01d0723424 | ||
|
|
b85010006b | ||
|
|
aec539be43 | ||
|
|
749c8cd931 | ||
|
|
eb2dbb5b90 | ||
|
|
e49f31121c | ||
|
|
bd874c4a13 | ||
|
|
d87cd7eafe | ||
|
|
58bb62cc1a | ||
|
|
6b8ea6c15b | ||
|
|
a62dd5ce8f | ||
|
|
92889b6cf1 | ||
|
|
b5479575eb | ||
|
|
201d013230 | ||
|
|
6fead68f34 | ||
|
|
9a77b1727c | ||
|
|
2f26cd13bc | ||
|
|
f0d35527df | ||
|
|
3a9ef290e8 | ||
|
|
9cbaa4d7e7 | ||
|
|
af4ad9fbcb | ||
|
|
36a9bdae72 | ||
|
|
ebfa0a45a6 | ||
|
|
c2e70360c4 | ||
|
|
8bdfa656de | ||
|
|
952bf68b93 | ||
|
|
712a5e80d0 | ||
|
|
a44069ae26 | ||
|
|
13f73c0156 | ||
|
|
bb88225cab | ||
|
|
3089b288b2 | ||
|
|
6abea46eb5 | ||
|
|
ffa73aee59 | ||
|
|
f4b7e97997 | ||
|
|
b32212b061 | ||
|
|
66d0de684a | ||
|
|
cae3baf71e | ||
|
|
27db33f1bd | ||
|
|
23d5709957 | ||
|
|
b96e12f217 | ||
|
|
16eb08afa0 | ||
|
|
ad8e229c06 | ||
|
|
b9b7ceccb6 | ||
|
|
5c4bf52b66 | ||
|
|
34369d268e | ||
|
|
0ec7085022 | ||
|
|
913cd67eee | ||
|
|
3292051bae | ||
|
|
2586b94e28 | ||
|
|
d492347f31 | ||
|
|
b811b13483 | ||
|
|
56f9bc9c3a | ||
|
|
c149888bed | ||
|
|
82cea3db2e | ||
|
|
8aea298854 | ||
|
|
5617fbe0a0 | ||
|
|
6a643da8ee | ||
|
|
2f32799b67 | ||
|
|
ee568a76c1 | ||
|
|
beaf077b06 | ||
|
|
fd5da94f9c | ||
|
|
0694fcc5fb | ||
|
|
e36a9f163e | ||
|
|
17f0f6637a | ||
|
|
bc91939757 | ||
|
|
eb743f95cf | ||
|
|
0ec770fc51 | ||
|
|
ed4cdc3d90 | ||
|
|
9da5f465d1 | ||
|
|
8e72ace3b5 | ||
|
|
5230a4fe4f | ||
|
|
b236887718 | ||
|
|
2527cbe097 | ||
|
|
cbca4c3efa | ||
|
|
5b0e9d934c | ||
|
|
19429e8507 | ||
|
|
a67f92176f | ||
|
|
3922827fad | ||
|
|
0c637da19f | ||
|
|
48f168da9d | ||
|
|
3357eb287c | ||
|
|
5da1c54b70 | ||
|
|
c5bbdb401a | ||
|
|
f69b84d24b | ||
|
|
1250e09fef | ||
|
|
fbf22ba7af | ||
|
|
5c26d50227 | ||
|
|
47be037be9 | ||
|
|
bc4f7d390c | ||
|
|
9fe64834f9 | ||
|
|
4d943c2386 | ||
|
|
4b298d6e31 | ||
|
|
c0c65364e5 | ||
|
|
51b76682cf | ||
|
|
5f89698308 | ||
|
|
400ee82686 | ||
|
|
485f97bdc2 | ||
|
|
5821377b6c | ||
|
|
e6e3c1ddee | ||
|
|
a6ea35ef9c | ||
|
|
fe9a579dc3 | ||
|
|
017aad051e | ||
|
|
8a30659015 | ||
|
|
ed7f597b3d | ||
|
|
6700030d7c | ||
|
|
f45c7650de | ||
|
|
a36ee65865 | ||
|
|
b61c638f0a | ||
|
|
dfb5b8a4c5 | ||
|
|
09e5d6abcd | ||
|
|
2aafbb57a8 | ||
|
|
9d3dd49e9d | ||
|
|
744f22112b | ||
|
|
b38edfb672 | ||
|
|
a73875a2e2 | ||
|
|
0833029c82 | ||
|
|
71cf207bf7 | ||
|
|
f7ea185f80 | ||
|
|
3d3a035822 | ||
|
|
11a94aae25 | ||
|
|
af3bf5217d | ||
|
|
11f47f26e6 | ||
|
|
57c6fbbaab | ||
|
|
f7b37306aa | ||
|
|
8b3d8f6ad4 | ||
|
|
7a9726063d | ||
|
|
d6680b604f | ||
|
|
25ef1803e0 | ||
|
|
2bc72151bc | ||
|
|
93ceae3bef | ||
|
|
b5cad22afd | ||
|
|
2bf31a1985 | ||
|
|
5796f50439 | ||
|
|
36415d424e | ||
|
|
76be5dd8d9 | ||
|
|
407dae03ca | ||
|
|
6e760cd25b | ||
|
|
69c03cafb9 | ||
|
|
c17e683834 | ||
|
|
311abeabd0 | ||
|
|
b20d4a10ba | ||
|
|
548bf8b867 | ||
|
|
0b68e16894 | ||
|
|
33e46addbb | ||
|
|
04f27e0d03 | ||
|
|
628ff925b7 | ||
|
|
6fddf25a39 | ||
|
|
84e58285af | ||
|
|
fc5103de8d | ||
|
|
14b6345277 | ||
|
|
9a70037e32 | ||
|
|
3a8323faab | ||
|
|
fe1944922c | ||
|
|
7ea0c767fa | ||
|
|
ec18e5c530 | ||
|
|
885781850b | ||
|
|
443b46f383 | ||
|
|
8ce1aa0092 | ||
|
|
801a591282 | ||
|
|
740efcb763 | ||
|
|
67fa39f4ed | ||
|
|
7a8bb7c0e0 | ||
|
|
961b1106aa | ||
|
|
9dc549e62d | ||
|
|
c1a11ff6e4 | ||
|
|
151bf18cc6 | ||
|
|
d2e2522c07 | ||
|
|
4a212302e0 | ||
|
|
993dd7ade3 | ||
|
|
e4d68b9d0e | ||
|
|
b5e093bc80 | ||
|
|
d544fc84e8 | ||
|
|
e6dba4456c | ||
|
|
a0a0c31a49 | ||
|
|
d2777a9b15 | ||
|
|
c7d12bb798 | ||
|
|
901d87ad1d | ||
|
|
ef912a4484 | ||
|
|
b4debd9559 | ||
|
|
d7277649dd | ||
|
|
f177ff9e11 | ||
|
|
53a2008a0a | ||
|
|
2525b0e502 | ||
|
|
b7e7c0bb0b | ||
|
|
a397796188 | ||
|
|
33ec7e5240 | ||
|
|
d62b692b3b | ||
|
|
493bfd56b9 | ||
|
|
0f0bc30052 | ||
|
|
abbfa24ca6 | ||
|
|
fae1edc859 | ||
|
|
a9a741f775 | ||
|
|
c0d482e4fc | ||
|
|
2b256389dd | ||
|
|
b5cabdc775 | ||
|
|
e103cc38f7 | ||
|
|
c71a43c3a6 | ||
|
|
cd01283ac6 | ||
|
|
7ce1077bd6 | ||
|
|
f9701d1c7b | ||
|
|
e764830113 | ||
|
|
28eceffedf | ||
|
|
57a1b0dd6f | ||
|
|
9646457b50 | ||
|
|
7346e55e0d | ||
|
|
ae38a8cb4f | ||
|
|
df46a4a5fc | ||
|
|
a0b546e416 | ||
|
|
7c6797a141 | ||
|
|
83abac8c5e | ||
|
|
5ba6b2f335 | ||
|
|
64caeac9ee | ||
|
|
0d4ba7c6f1 | ||
|
|
a1fc351183 | ||
|
|
3131a075f5 | ||
|
|
33a6c39fc4 | ||
|
|
f853f6ef25 | ||
|
|
7a2d114360 | ||
|
|
0157f387ee | ||
|
|
3418f2b708 | ||
|
|
5a0f588344 | ||
|
|
d362446451 | ||
|
|
c23be231e1 | ||
|
|
00f5c36919 | ||
|
|
c960175ec1 | ||
|
|
e456604436 | ||
|
|
ac4657e77f | ||
|
|
3817427e79 | ||
|
|
0200b3c63e | ||
|
|
972a1a5703 | ||
|
|
73c22176b8 | ||
|
|
4db036f350 | ||
|
|
52223f0a20 | ||
|
|
907ad0faf6 | ||
|
|
887e10c947 | ||
|
|
b4c463e452 | ||
|
|
66ba9b1f46 | ||
|
|
7db50811ba | ||
|
|
17d20705ff | ||
|
|
e3bd782a42 | ||
|
|
b073379fff | ||
|
|
b89d8ff946 | ||
|
|
22ad971c8e | ||
|
|
ab06cc3703 | ||
|
|
8a5cc5f2bd | ||
|
|
6919baf23c | ||
|
|
ddedb215c4 | ||
|
|
3dc5f1e160 | ||
|
|
08d4d817f6 | ||
|
|
e8bdcfbaf2 | ||
|
|
743fb4494e | ||
|
|
0a4bc7fad6 | ||
|
|
49d0b16324 | ||
|
|
de479d6188 | ||
|
|
3fd3e13dc7 | ||
|
|
d7d913d439 | ||
|
|
5c4ae3820b | ||
|
|
38774a20c6 | ||
|
|
9fc58bb4df | ||
|
|
ca936ca42f | ||
|
|
840fb6b647 | ||
|
|
34f54c51e4 | ||
|
|
cda973a54f | ||
|
|
8d77c29d75 | ||
|
|
c80b5d6d78 | ||
|
|
0454926d68 | ||
|
|
40067c514f | ||
|
|
77e5d8f00e | ||
|
|
e33f9c1709 | ||
|
|
31ba3aad85 | ||
|
|
3c591f146e | ||
|
|
35f82ea616 | ||
|
|
60f5bdb069 | ||
|
|
7be9f321a2 | ||
|
|
00998a8d3e | ||
|
|
1f5d0f1968 | ||
|
|
ec83cf39cd | ||
|
|
7c8487632d | ||
|
|
e6bd9adc03 | ||
|
|
6f0c10dcd7 | ||
|
|
ddb3d1a0dd | ||
|
|
c187e7edc3 | ||
|
|
9735e33e51 | ||
|
|
4eeb22110d | ||
|
|
b190a43e7e | ||
|
|
20b95c425e | ||
|
|
5ba05ff769 | ||
|
|
051f7c9f52 | ||
|
|
0fa7817b2a | ||
|
|
95d5dd3c68 | ||
|
|
56fd1e0203 | ||
|
|
890487fcae | ||
|
|
9b9dce0aaf | ||
|
|
139ae36d3e | ||
|
|
da6edeab86 | ||
|
|
cdcf041073 | ||
|
|
ec99795c1e | ||
|
|
0bc8570b4a | ||
|
|
2d8e14eb87 | ||
|
|
4917dab1d3 | ||
|
|
42e1eb33ef | ||
|
|
c2fdd50655 | ||
|
|
a643596c48 | ||
|
|
04465454f4 | ||
|
|
190783f382 | ||
|
|
e51c5d8504 | ||
|
|
3849befeaf | ||
|
|
05c61879f9 | ||
|
|
71f6b58dd7 | ||
|
|
c30074afc5 | ||
|
|
5aef196306 | ||
|
|
e09f5ca0a1 | ||
|
|
716ae30d9d | ||
|
|
116c653db5 | ||
|
|
dcfc1e3689 | ||
|
|
7ba981eaea | ||
|
|
ede5ed8b0d | ||
|
|
b8877c53ed | ||
|
|
296271007b | ||
|
|
d49a91c4a2 | ||
|
|
2b567f5578 | ||
|
|
8469188f75 | ||
|
|
2409df4f5b | ||
|
|
c5c33cf6b6 | ||
|
|
cea1d8b825 | ||
|
|
982ed4d677 | ||
|
|
d424803cac | ||
|
|
6cd3f514a6 | ||
|
|
b5d4b96f14 | ||
|
|
f9ce235b32 | ||
|
|
491fa5c0a2 | ||
|
|
1bbbaa18f7 | ||
|
|
eff68b2173 | ||
|
|
8b6adac269 | ||
|
|
e0edd56413 | ||
|
|
c95d04aa6b | ||
|
|
9a88269e28 | ||
|
|
d5847f9ea1 | ||
|
|
b3a75c0105 | ||
|
|
3ba2f38408 | ||
|
|
b455a676d8 | ||
|
|
e5dbb3c680 | ||
|
|
7d236e8564 | ||
|
|
ae18a47bc9 | ||
|
|
5dd4d49517 | ||
|
|
d708d6a057 | ||
|
|
c3db03ea5e | ||
|
|
b65812ebf3 | ||
|
|
698299f918 | ||
|
|
277d12205d | ||
|
|
52b3c2e962 | ||
|
|
f6cadc43f3 | ||
|
|
e393d66283 | ||
|
|
10e33de018 | ||
|
|
842dc38805 | ||
|
|
52ef5c06fd | ||
|
|
1c63589b3d | ||
|
|
3e230310b9 | ||
|
|
ce249aaa4a | ||
|
|
bd216674d4 | ||
|
|
32c4b1d614 | ||
|
|
1847746077 | ||
|
|
56741b425c | ||
|
|
4f3a8e6acb | ||
|
|
f40d8c3cf4 | ||
|
|
d7a3c74ad9 | ||
|
|
b5049cd9ca | ||
|
|
55536cc4b3 | ||
|
|
cbbec517d6 | ||
|
|
db2624d49d | ||
|
|
d7116735e9 | ||
|
|
43ba235e68 | ||
|
|
2c3c8f6e0d | ||
|
|
6dc816869f | ||
|
|
5fff3c6ce7 | ||
|
|
fe85b0908c | ||
|
|
612742f669 | ||
|
|
8d2303db5f | ||
|
|
97b90a09db | ||
|
|
dcdf095575 | ||
|
|
9ecfce472d | ||
|
|
20e5bc0081 | ||
|
|
5136d4757c | ||
|
|
2729e341c8 | ||
|
|
6d0399c6c7 | ||
|
|
72d07bc303 | ||
|
|
c55bb28038 | ||
|
|
0a746d017e | ||
|
|
de4517f614 | ||
|
|
0dcd89a653 | ||
|
|
f70970c6f3 | ||
|
|
4d28d2b837 | ||
|
|
b63e76adfe | ||
|
|
77eedf5d6c | ||
|
|
01ff98be05 | ||
|
|
6222041a30 | ||
|
|
302e0d7fa7 | ||
|
|
894e9c3ff6 | ||
|
|
66bda6d531 | ||
|
|
f3c7c68248 | ||
|
|
093767f2b1 | ||
|
|
50f6c403e8 | ||
|
|
3c41155ee4 | ||
|
|
dcc2dbf0c6 | ||
|
|
fd1da876a4 | ||
|
|
93fc1b6140 | ||
|
|
80fb17ca05 | ||
|
|
ee0069ffa4 | ||
|
|
b1bd7d63f6 | ||
|
|
ef8059cf56 | ||
|
|
8d246947c1 | ||
|
|
8bcf29fa11 | ||
|
|
4b900daa67 | ||
|
|
a84567c14e | ||
|
|
d4420b9e36 | ||
|
|
6daa9a1e3c | ||
|
|
6a4f8a6942 | ||
|
|
41974d12e5 | ||
|
|
ea5168c08a | ||
|
|
d07bb3574a | ||
|
|
fb83badfce | ||
|
|
1a9eedc6d6 | ||
|
|
b26b4a1a93 | ||
|
|
f3e7dffec4 | ||
|
|
9341bde0da | ||
|
|
e10a6e6f55 | ||
|
|
f0ed209ba6 | ||
|
|
2672558bfe | ||
|
|
ffe2f3f775 | ||
|
|
92816f1a9f | ||
|
|
43ef90f688 | ||
|
|
2c6096dd31 | ||
|
|
1cefa5eb1b | ||
|
|
a8e39b1899 | ||
|
|
b1a47e4c3a | ||
|
|
b7d881d136 | ||
|
|
67c3a166f5 | ||
|
|
060b72e88b | ||
|
|
36550511f5 | ||
|
|
fb8188b14b | ||
|
|
436564ba51 | ||
|
|
9016f1b53e | ||
|
|
0404a871f2 | ||
|
|
1413c92678 | ||
|
|
28208ac7a2 | ||
|
|
168a2c343c | ||
|
|
a873e920d4 | ||
|
|
10838d544c | ||
|
|
ab48fc0dfd | ||
|
|
bcf6521ef9 | ||
|
|
6f8d7d1ada | ||
|
|
c6f03551c5 | ||
|
|
b2a9679488 | ||
|
|
b66d983060 | ||
|
|
2b16ddedbf | ||
|
|
dbd89deb7b | ||
|
|
6c52721ed1 | ||
|
|
03fbe8fcca | ||
|
|
9e0af20343 | ||
|
|
aa0b4d0fce | ||
|
|
a9f6605065 | ||
|
|
26b073ba34 | ||
|
|
27bba1b628 | ||
|
|
6131ebca73 | ||
|
|
01b42a6dfb | ||
|
|
23be929f72 | ||
|
|
b536770a07 | ||
|
|
792982262b | ||
|
|
541d50e6bb | ||
|
|
c8d88140f7 | ||
|
|
d3fdf27746 | ||
|
|
afb6860156 | ||
|
|
48563bade6 | ||
|
|
017019e122 | ||
|
|
8e0d78af7b | ||
|
|
66531d46bd | ||
|
|
83dbb63d13 | ||
|
|
771f981c13 | ||
|
|
9d5afd1e2a | ||
|
|
33ac272804 | ||
|
|
30a1e4c7c3 | ||
|
|
1d97f08b34 | ||
|
|
752a741e60 | ||
|
|
9eaf88abad | ||
|
|
f5ffcf5454 | ||
|
|
e8c5a02ead | ||
|
|
5c9d00c0a9 | ||
|
|
9b8d5bba4c | ||
|
|
5f8e2a70d0 | ||
|
|
19b1316205 | ||
|
|
b9f47d3cf2 | ||
|
|
75067cd33f | ||
|
|
25477a1232 | ||
|
|
4b9b3f5a37 | ||
|
|
c0d147f3df | ||
|
|
228f782762 | ||
|
|
e952bb8731 | ||
|
|
32dc1e69e5 | ||
|
|
9e53288ca4 | ||
|
|
6ca0e5416c | ||
|
|
686d862024 | ||
|
|
60f1c79e2a | ||
|
|
25240591a3 | ||
|
|
75b28225a6 | ||
|
|
4e3fa4243a | ||
|
|
56a313f941 | ||
|
|
7a197f516c | ||
|
|
48497a0786 | ||
|
|
9badfe8fed | ||
|
|
8f67ebe16f | ||
|
|
b52c5a884f | ||
|
|
24e4f8c1fd | ||
|
|
84c50f4863 | ||
|
|
4d7e602155 | ||
|
|
8d47f10519 | ||
|
|
3c616348f7 | ||
|
|
abe5ccec5d | ||
|
|
916de7909f | ||
|
|
ff720188f7 | ||
|
|
d1180e4e47 | ||
|
|
4e52fdeaab | ||
|
|
67e2cff541 | ||
|
|
1d9286419a | ||
|
|
b6c1510365 | ||
|
|
323255143e | ||
|
|
d0eedce248 | ||
|
|
76fca12d1a | ||
|
|
70f7888905 | ||
|
|
1f65f16d09 | ||
|
|
541bc4e868 | ||
|
|
bd3310ab0c | ||
|
|
8054930597 | ||
|
|
b51d65c8cd | ||
|
|
e49c32ea01 | ||
|
|
73a0136556 | ||
|
|
27ee456413 | ||
|
|
6f1a0c8dc7 | ||
|
|
93710e2268 | ||
|
|
14fb8e9738 | ||
|
|
24a2b62840 | ||
|
|
d35889f9ae | ||
|
|
29fd1312cd | ||
|
|
9a13b3cbdd | ||
|
|
5b90077df0 | ||
|
|
fdb755a9c4 | ||
|
|
39edb76ee0 | ||
|
|
1e70ce91e7 | ||
|
|
bafee423b2 | ||
|
|
d2a38c5f34 | ||
|
|
73d3be972d | ||
|
|
01be80ca8c | ||
|
|
6d9c7de7c0 | ||
|
|
64c6970696 | ||
|
|
7fa3150921 | ||
|
|
268f99c5e3 | ||
|
|
988d0bbcb2 | ||
|
|
2268a2115b | ||
|
|
f624c5737a | ||
|
|
9c66f83fab | ||
|
|
65b78ee753 | ||
|
|
6097708952 | ||
|
|
7941bc6158 | ||
|
|
d15139501c | ||
|
|
d9674925d0 | ||
|
|
027313872c | ||
|
|
57c351a4d3 | ||
|
|
07b6642823 | ||
|
|
e44464f532 | ||
|
|
43c8317c99 | ||
|
|
16aceaac73 | ||
|
|
cbf7ba59d4 | ||
|
|
1464c00fb0 | ||
|
|
3f489fd32b | ||
|
|
6534d89cd7 | ||
|
|
5d56d00fa2 | ||
|
|
2cabe08eb8 | ||
|
|
1e5a43ae6d | ||
|
|
fbd7fa83b6 | ||
|
|
6de51645b3 | ||
|
|
cfc3af3510 | ||
|
|
a4f8e0178f | ||
|
|
b3edbdf225 | ||
|
|
1d1d69a13f | ||
|
|
dca6871a4e | ||
|
|
9d3b119448 | ||
|
|
45ad68cd61 | ||
|
|
9402fb73a9 | ||
|
|
853ddb0d38 | ||
|
|
fbdc78e46d | ||
|
|
c0da3a1831 | ||
|
|
d7f32b1cb1 | ||
|
|
e9aec70ba9 | ||
|
|
750658be10 | ||
|
|
510bd22533 | ||
|
|
85de1ba4ac | ||
|
|
3bdabc8974 | ||
|
|
bb45183df3 | ||
|
|
0a1f9d5e47 | ||
|
|
1a92890e4e | ||
|
|
bfc0dbc131 | ||
|
|
05bde80ffd | ||
|
|
b3aa5f4bc6 | ||
|
|
80ae38e196 | ||
|
|
9535482dbf | ||
|
|
e2862cef05 | ||
|
|
8b97538382 | ||
|
|
cc4addec9f | ||
|
|
0461f5bd96 | ||
|
|
09e95cd1ff | ||
|
|
8a02f2cbd2 | ||
|
|
63f1bb9a9e | ||
|
|
ea1c033402 | ||
|
|
ce1f35e5ff | ||
|
|
b5131b3fac | ||
|
|
66852bdc8d |
@@ -0,0 +1,22 @@
|
||||
# cmd: "cd {PROJECT_PATH}; platformio"
|
||||
cmd: "platformio"
|
||||
name: "Build with error highlighting (dev_ESP8266_4096)"
|
||||
args:
|
||||
- run --environment dev_ESP8266_4096
|
||||
sh: true
|
||||
cwd: "{PROJECT_PATH}"
|
||||
# env:
|
||||
# VARIABLE1: "VALUE1"
|
||||
# VARIABLE2: "VALUE2"
|
||||
errorMatch:
|
||||
- "(?<file>[\\/0-9a-zA-Z\\._]+):(?<line>\\d+):(?<col>\\d+):\\s+error:\\s+(?<message>.+)"
|
||||
|
||||
warningMatch:
|
||||
- "(?<file>[\\/0-9a-zA-Z\\._]+):(?<line>\\d+):(?<col>\\d+):\\s+warning:\\s+(?<message>.+)"
|
||||
# keymap: <keymap string>
|
||||
# atomCommandName: namespace:command
|
||||
# targets:
|
||||
# extraTargetName:
|
||||
# cmd: "<command to execute>"
|
||||
# args:
|
||||
# # (any previous options are viable here except `targets` itself)
|
||||
@@ -0,0 +1,33 @@
|
||||
# Contributing to ESPEasy
|
||||
|
||||
:+1::tada: First off, thanks for taking the time to contribute! :tada::+1:
|
||||
|
||||
## Issue tracker
|
||||
|
||||
* The issue tracker is NOT a support forum. For support questions go to our forum: https://www.letscontrolit.com/forum/viewforum.php?f=1
|
||||
|
||||
* Only post an issue if you're 100% sure you've hit a bug. If your not sure, post on the forum first to see if anyone can confirm it.
|
||||
|
||||
This way we keep the issue tracker as short as possible, which saves our developers a lot of time.
|
||||
|
||||
Also there are more people on the forum that can help you with support.
|
||||
|
||||
## Pull requests
|
||||
|
||||
* Make sure your code compiles.
|
||||
|
||||
* Make sure your code does not have warnings. (Warnings will be treated as errors by our Travis system.)
|
||||
|
||||
* Try to create different pull requests for different features/fixes.
|
||||
|
||||
* Dont combine a lot of different stuff in one huge pull request.
|
||||
|
||||
* The v2.0 branch should get only fixes, new stuff should go into the mega-branch. (We will merge those fixes from v2.0 to mega)
|
||||
|
||||
* Incomplete or unstable plugins should have a PLUGIN_BUILD_DEV #ifdef around them. Also add [DEVELOPMENT] to the name.
|
||||
|
||||
* Do not modify any of the variables passed to your PLUGIN_WRITE handler.
|
||||
|
||||
* New plugins that seem to be working correctly should have a PLUGIN_BUILD_TESTING around until they are tested enough. Also add [TESTING] to the name
|
||||
|
||||
* Also see our general guidelines at: https://www.letscontrolit.com/wiki/index.php/ESPEasyDevelopmentGuidelines
|
||||
@@ -0,0 +1,18 @@
|
||||
**NOTE: This is not a support forum! For questions and support go here: https://www.letscontrolit.com/forum/viewforum.php?f=1**
|
||||
|
||||
### Steps to reproduce
|
||||
How can we trigger this problem?
|
||||
|
||||
Does the problem presist after powering off and on? (just resetting isnt enough sometimes)
|
||||
|
||||
### Expected behavior
|
||||
Tell us what should happen?
|
||||
|
||||
### Actual behavior
|
||||
Tell us what happens instead?
|
||||
|
||||
### System configuration
|
||||
|
||||
Hardware:
|
||||
|
||||
Software or git version:
|
||||
@@ -2,3 +2,6 @@
|
||||
.clang_complete
|
||||
.gcc-flags.json
|
||||
.piolibdeps
|
||||
|
||||
lib/readme.txt
|
||||
src/Custom.h
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
[submodule "lib/Adafruit_NeoPixel"]
|
||||
path = lib/Adafruit_NeoPixel
|
||||
url = https://github.com/adafruit/Adafruit_NeoPixel.git
|
||||
[submodule "lib/ArduinoJson"]
|
||||
path = lib/ArduinoJson
|
||||
url = https://github.com/bblanchon/ArduinoJson.git
|
||||
[submodule "lib/IRremoteESP8266"]
|
||||
path = lib/IRremoteESP8266
|
||||
url = https://github.com/sebastienwarin/IRremoteESP8266.git
|
||||
|
||||
+26
-3
@@ -1,15 +1,38 @@
|
||||
language: python
|
||||
python:
|
||||
- '2.7'
|
||||
- '2.7'
|
||||
|
||||
#we want a newer cppcheck, so use trusty
|
||||
dist: trusty
|
||||
|
||||
sudo: false
|
||||
|
||||
cache:
|
||||
directories:
|
||||
- "~/.platformio"
|
||||
- "./.pioenvs"
|
||||
|
||||
|
||||
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- cppcheck
|
||||
|
||||
|
||||
|
||||
install:
|
||||
- pip install -U platformio
|
||||
- pip install -U platformio
|
||||
|
||||
script:
|
||||
- platformio run
|
||||
# - cppcheck --enable=warning src/*.ino -q --force -I src --include=src/ESPEasy.ino --error-exitcode=1
|
||||
# - ./memanalyzer.py ~/.platformio/packages/toolchain-xtensa/bin/xtensa-lx106-elf-objdump
|
||||
- PLATFORMIO_BUILD_FLAGS="-D CONTINUOUS_INTEGRATION" platformio run -s
|
||||
|
||||
# patch platformio core libs for PUYA bug (https://github.com/letscontrolit/ESPEasy/issues/650)
|
||||
- cd patches; ./check_puya_patch; cd ..
|
||||
- PLATFORMIO_BUILD_FLAGS="-D CONTINUOUS_INTEGRATION" platformio run -s --environment dev_ESP8266PUYA_1024
|
||||
|
||||
|
||||
before_deploy:
|
||||
- ./before_deploy
|
||||
|
||||
@@ -1,11 +1,39 @@
|
||||
# ESPEasy (mega branch)
|
||||
# ESPEasy (development branch)
|
||||
|
||||
Build status: [](https://travis-ci.org/letscontrolit/ESPEasy)
|
||||
|
||||
This is the development branch for the next upcoming release (2.0.0). This is also known as ESPEasyMega.
|
||||
Introduction and wiki: https://www.letscontrolit.com/wiki/index.php/ESPEasy#Introduction
|
||||
|
||||
**MEGA**
|
||||
:warning:This is the development branch of ESPEasy. All new untested features go into this branch. If you want to do a bugfix, do it on the stable branch, we will merge the fix to the development branch as well.:warning:
|
||||
|
||||
Next stable branch: https://github.com/letscontrolit/ESPEasy/tree/v2.0 (bug fixes only, since oct 2017))
|
||||
|
||||
Check here to learn how to use this branch and help us improving ESPEasy: http://www.letscontrolit.com/wiki/index.php/ESPEasy#Source_code_development
|
||||
|
||||
Binary development releases are here: https://github.com/letscontrolit/ESPEasy/releases
|
||||
|
||||
Details and discussion are on the Experimental forum: http://www.letscontrolit.com/forum/viewtopic.php?f=18&t=2257&p=13600#p13600
|
||||
## Automated binary releases
|
||||
|
||||
Every night our build-bot will build a new binary release: https://github.com/letscontrolit/ESPEasy/releases
|
||||
|
||||
The releases are named something like 'mega-20180102' (last number is the build date)
|
||||
|
||||
Depending on your needs, we release different types of files:
|
||||
|
||||
Firmware name | Hardware | Included plugins |
|
||||
----------------------------------------------|-------------------------|-----------------------------|
|
||||
ESPEasy_mega-20180102_normal_ESP8266_1024.bin | ESP8266 with 1Mb flash | Stable |
|
||||
ESPEasy_mega-20180102_test_ESP8266_1024.bin | ESP8266 with 1Mb flash | Stable + Test |
|
||||
ESPEasy_mega-20180102_dev_ESP8266_1024.bin | ESP8266 with 1Mb flash | Stable + Test + Development |
|
||||
ESPEasy_mega-20180102_normal_ESP8266_4096.bin | ESP8266 with 4Mb flash | Stable |
|
||||
ESPEasy_mega-20180102_test_ESP8266_4096.bin | ESP8266 with 4Mb flash | Stable + Test |
|
||||
ESPEasy_mega-20180102_dev_ESP8266_4096.bin | ESP8266 with 4Mb flash | Stable + Test + Development |
|
||||
ESPEasy_mega-20180102_normal_ESP8285_1024.bin | ESP8285 with 1Mb flash | Stable |
|
||||
ESPEasy_mega-20180102_test_ESP8285_1024.bin | ESP8285 with 1Mb flash | Stable + Test |
|
||||
ESPEasy_mega-20180102_dev_ESP8285_1024.bin | ESP8285 with 1Mb flash | Stable + Test + Development |
|
||||
|
||||
## More info
|
||||
|
||||
Details and discussion are on the Experimental forum: https://www.letscontrolit.com/forum/viewforum.php?f=18
|
||||
|
||||
We're also on IRC: #ESPEasy @freenode
|
||||
|
||||
+24
-9
@@ -1,18 +1,30 @@
|
||||
#!/bin/bash
|
||||
|
||||
VERSION=$(git describe)
|
||||
echo "Creating release archives for $VERSION ..."
|
||||
#binaries
|
||||
# cp .pioenvs/mini_512/firmware.bin dist/"ESPEasy_$VERSION""_mini_512.bin"
|
||||
|
||||
cp .pioenvs/normal_1024/firmware.bin dist/"ESPEasy_$VERSION""_normal_1024.bin"
|
||||
cp .pioenvs/normal_4096/firmware.bin dist/"ESPEasy_$VERSION""_normal_4096.bin"
|
||||
#Naming convention:
|
||||
# ESP_Easy_[github version]_[plugin set]_[chip type]_[flash memory].bin
|
||||
|
||||
cp .pioenvs/test_1024/firmware.bin dist/"ESPEasy_$VERSION""_test_1024.bin"
|
||||
cp .pioenvs/test_4096/firmware.bin dist/"ESPEasy_$VERSION""_test_4096.bin"
|
||||
|
||||
cp .pioenvs/dev_1024/firmware.bin dist/"ESPEasy_$VERSION""_dev_1024.bin"
|
||||
cp .pioenvs/dev_4096/firmware.bin dist/"ESPEasy_$VERSION""_dev_4096.bin"
|
||||
for ENV in \
|
||||
normal_ESP8266_1024 \
|
||||
normal_ESP8266_4096 \
|
||||
normal_ESP8285_1024 \
|
||||
test_ESP8266_1024\
|
||||
test_ESP8266_4096\
|
||||
test_ESP8285_1024\
|
||||
dev_ESP8266_1024\
|
||||
dev_ESP8266_4096\
|
||||
dev_ESP8285_1024\
|
||||
dev_ESP8266PUYA_1024;\
|
||||
do
|
||||
echo
|
||||
echo "### Deploying environment $ENV for version $VERSION"
|
||||
BIN=.pioenvs/$ENV/firmware.bin
|
||||
python2 crc2.py $BIN
|
||||
cp $BIN dist/"ESP_Easy_$VERSION""_$ENV.bin"
|
||||
done
|
||||
|
||||
|
||||
#create a source structure that is the same as the original ESPEasy project (and works with the howto on the wiki)
|
||||
rm -rf dist/Source 2>/dev/null
|
||||
@@ -22,4 +34,7 @@ cp -r src dist/Source/
|
||||
cp platformio.ini dist/Source/
|
||||
|
||||
cd dist
|
||||
|
||||
echo
|
||||
echo "### Creating zip archive"
|
||||
zip ../ESPEasy_$VERSION.zip -r .
|
||||
|
||||
@@ -0,0 +1,116 @@
|
||||
|
||||
import sys
|
||||
import binascii
|
||||
import struct
|
||||
import md5
|
||||
import os
|
||||
MD5DUMMY = "MD5_MD5_MD5_MD5_BoundariesOfTheSegmentsGoHere..." #48 chars
|
||||
FILENAMEDUMMY = "ThisIsTheDummyPlaceHolderForTheBinaryFilename..." #48 chars
|
||||
|
||||
MemorySegmentStart,MemorySegmentEnd,MemoryContent=[],[],[]
|
||||
|
||||
##################################################################
|
||||
# this subroutine shows the segments of a part
|
||||
##################################################################
|
||||
def showSegments (fileContent,offset):
|
||||
global MemorySegmentStart, MemorySegmentEnd, MemoryContent
|
||||
header = struct.unpack("ii", fileContent[offset:offset+8])
|
||||
herestr =""
|
||||
herestr2 =""
|
||||
MemorySegmentStart.append(struct.pack("I",header[0]))
|
||||
MemorySegmentEnd.append(struct.pack("I",header[0]+header[1]))
|
||||
MemoryContent.append(fileContent[offset+8:offset+8+header[1]])
|
||||
if fileContent.find( MD5DUMMY, offset+8, offset+8+header[1]) >0 :
|
||||
herestr= " <-- CRC is here."
|
||||
if fileContent.find( FILENAMEDUMMY, offset+8, offset+8+header[1]) >0 :
|
||||
herestr2= " <-- filename is here."
|
||||
print ("SEGMENT "+ str(len(MemorySegmentStart)-1)+ ": memory position: " + hex(header[0])+" to " + hex(header[0]+header[1]) + " length: " + hex(header[1])+herestr+herestr2)
|
||||
#print ("first byte positoin in file: " + hex( offset+8))
|
||||
#print ("last byte postion in file: " + hex(offset+8+header[1]-1))
|
||||
return (8+offset+ header[1]); # return start of next segment
|
||||
|
||||
##################################################################
|
||||
# this subroutine shows the parts of a binary file
|
||||
##################################################################
|
||||
def showParts(fileContent, offset):
|
||||
header = struct.unpack("BBBBi", fileContent[offset:offset+8])
|
||||
print ('\n\nBINARY PART\nSegments: ') + (hex(header[1]))
|
||||
nextpos =offset+8
|
||||
for x in range (0,header[1]):
|
||||
nextpos = showSegments(fileContent,nextpos)
|
||||
nextSegmentOffset = (fileContent.find("\xe9", nextpos))
|
||||
return nextSegmentOffset
|
||||
|
||||
##################################################################
|
||||
# MAIN
|
||||
##################################################################
|
||||
|
||||
#if len(sys.argv) !=2 :
|
||||
# print ("please give a filename")
|
||||
# k=input("press close to exit")
|
||||
# sys.exit(1)
|
||||
FileName = sys.argv[1]#"C:/ArduinoPortable/sketchbooks/build/sketch_jan15a.ino.bin"
|
||||
#FileName = "C:/ArduinoPortable/sketchbooks/build/sketch_jan15a.ino.bin"
|
||||
print( "\n\nReplacing dummy MD5 checksum in .bin file")
|
||||
|
||||
|
||||
|
||||
with open(FileName, mode='rb') as file: # b is important -> binary
|
||||
nextpos =0;
|
||||
fileContent = file.read()
|
||||
while nextpos >=0:
|
||||
nextpos = showParts(fileContent,nextpos)
|
||||
|
||||
startArray,endArray,hashString = "","",""
|
||||
includeStr = "hash includes segments:"
|
||||
# memory sections:
|
||||
# 0: bootloader (not readable)
|
||||
# 1: program memory (SPI flash)
|
||||
# 2: unknown but stable
|
||||
# 3: RAM (initialized by bin file. Can be read but changes as you go :-( )
|
||||
# 4: RAM
|
||||
|
||||
for i in (1,2 ): # use only stable segments, must be 4 in total. We use 2.
|
||||
startArray =startArray + MemorySegmentStart[i]
|
||||
endArray = endArray + MemorySegmentEnd[i]
|
||||
hashString =hashString + MemoryContent[i]
|
||||
with open(FileName+str(i), mode='wb') as file: # b is important -> binary
|
||||
file.write(MemoryContent[i])
|
||||
includeStr = includeStr +" "+ str(i)
|
||||
print (includeStr)
|
||||
# IMPORTANT: pad array with zeros if you use only 3 segments (see above)
|
||||
while len(startArray) < 16 :
|
||||
startArray =startArray + struct.pack("I",0)
|
||||
endArray = endArray + struct.pack("I",0)
|
||||
# debug print (binascii.hexlify(startArray))
|
||||
# debug print (binascii.hexlify(endArray))
|
||||
if (len(endArray) + len (startArray)) != 32 :
|
||||
print("ERROR: please make sure you add / remove padding if you change the semgents.")
|
||||
|
||||
BinaryFileName = "";
|
||||
if fileContent.find( FILENAMEDUMMY) < 0:
|
||||
print("ERROR: FILENAMEDUMMY dummy not found in binary")
|
||||
else:
|
||||
BinaryFileName=os.path.basename(FileName) +"\0"
|
||||
if len(BinaryFileName) >48: # check that filename is <48 chars
|
||||
BinaryFileName=BinaryFileName[0:48] # truncate if necessary. 49th char in ESP is zero already
|
||||
else:
|
||||
BinaryFileName= BinaryFileName.ljust(48,'\0'); # pad with zeros.
|
||||
|
||||
|
||||
if fileContent.find( MD5DUMMY) < 0:
|
||||
print("ERROR: MD5 dummy not found in binary")
|
||||
else:
|
||||
hashString=hashString.replace (MD5DUMMY,"",1)
|
||||
m = md5.new()
|
||||
m.update (hashString) #use segment 1
|
||||
md5hash = m.digest()
|
||||
print("MD5 hash: "+ m.hexdigest())
|
||||
print("\nwriting output file:\n" + FileName)
|
||||
|
||||
fileContent=fileContent.replace(MD5DUMMY,md5hash+startArray+endArray)
|
||||
fileContent=fileContent.replace(FILENAMEDUMMY,BinaryFileName)
|
||||
|
||||
with open(FileName, mode='wb') as file: # b is important -> binary
|
||||
file.write(fileContent)
|
||||
#k=input("press close to exit")
|
||||
Vendored
+63
@@ -0,0 +1,63 @@
|
||||
plugin |cache IRAM |init RAM |r.o. RAM |uninit RAM |Flash ROM
|
||||
src/_C001.ino |0 |0 |272 |0 |3520
|
||||
src/_C002.ino |0 |4 |528 |32 |6064
|
||||
src/_C003.ino |0 |0 |64 |0 |1072
|
||||
src/_C004.ino |0 |0 |56 |8 |1280
|
||||
src/_C005.ino |0 |4 |56 |8 |1424
|
||||
src/_C006.ino |0 |0 |64 |0 |1296
|
||||
src/_C007.ino |0 |4 |32 |0 |1664
|
||||
src/_C008.ino |0 |0 |80 |0 |2272
|
||||
src/_C009.ino |0 |4 |352 |16 |4896
|
||||
src/_C010.ino |0 |0 |48 |0 |1136
|
||||
src/_C011.ino |0 |0 |152 |8 |5248
|
||||
src/_N001_Email.ino |0 |0 |72 |8 |1808
|
||||
src/_N002_Buzzer.ino |288 |12 |8 |264 |1184
|
||||
src/_P001_Switch.ino |1028 |8 |104 |280 |7248
|
||||
src/_P002_ADC.ino |0 |0 |16 |0 |336
|
||||
src/_P003_Pulse.ino |167 |0 |144 |192 |2544
|
||||
src/_P004_Dallas.ino |0 |0 |64 |16 |2496
|
||||
src/_P005_DHT.ino |0 |0 |56 |8 |1520
|
||||
src/_P006_BMP085.ino |0 |4 |48 |8 |2112
|
||||
src/_P007_PCF8591.ino |0 |0 |8 |8 |400
|
||||
src/_P008_RFID.ino |101 |0 |56 |8 |624
|
||||
src/_P009_MCP.ino |0 |0 |104 |24 |3232
|
||||
src/_P010_BH1750.ino |0 |0 |56 |8 |2688
|
||||
src/_P011_PME.ino |0 |4 |96 |0 |3040
|
||||
src/_P012_LCD.ino |0 |4 |120 |8 |3520
|
||||
src/_P013_HCSR04.ino |90 |0 |64 |16 |1552
|
||||
src/_P014_SI7021.ino |0 |4 |48 |0 |1824
|
||||
src/_P015_TSL2561.ino |0 |0 |56 |8 |3488
|
||||
src/_P016_IR.ino |288 |0 |72 |480 |3600
|
||||
src/_P017_PN532.ino |0 |0 |88 |72 |2016
|
||||
src/_P018_Dust.ino |0 |0 |56 |8 |512
|
||||
src/_P019_PCF8574.ino |0 |0 |104 |24 |2848
|
||||
src/_P020_Ser2Net.ino |0 |0 |88 |40 |3456
|
||||
src/_P021_Level.ino |0 |4 |136 |24 |1872
|
||||
src/_P022_PCA9685.ino |0 |4 |32 |0 |1216
|
||||
src/_P023_OLED.ino |0 |4 |80 |0 |4448
|
||||
src/_P024_MLX90614.ino |0 |4 |56 |8 |992
|
||||
src/_P025_ADS1115.ino |0 |0 |72 |8 |1184
|
||||
src/_P026_Sysinfo.ino |0 |0 |72 |8 |864
|
||||
src/_P027_INA219.ino |0 |0 |56 |24 |1840
|
||||
src/_P028_BME280.ino |128 |0 |48 |80 |3488
|
||||
src/_P029_Output.ino |0 |4 |8 |8 |256
|
||||
src/_P030_BMP280.ino |128 |0 |48 |48 |3024
|
||||
src/_P031_SHT1X.ino |0 |0 |100 |0 |2176
|
||||
src/_P032_MS5611.ino |0 |4 |88 |56 |2592
|
||||
src/_P033_Dummy.ino |0 |4 |48 |0 |1168
|
||||
src/_P034_DHT12.ino |0 |0 |16 |0 |656
|
||||
src/_P035_IRTX.ino |0 |4 |64 |-8 |3840
|
||||
src/_P036_FrameOLED.ino |0 |4 |96 |0 |33600
|
||||
src/_P037_MQTTImport.ino |0 |0 |24 |40 |3536
|
||||
src/_P038_NeoPixel.ino |128 |0 |56 |8 |1712
|
||||
src/_P039_Thermocouple.ino |0 |0 |104 |8 |1536
|
||||
src/_P040_ID12.ino |0 |4 |72 |8 |640
|
||||
src/_P041_NeoClock.ino |128 |4 |128 |0 |3344
|
||||
src/_P042_Candle.ino |128 |8 |160 |32 |8048
|
||||
src/_P043_ClkOutput.ino |0 |0 |80 |0 |1456
|
||||
src/_P044_P1WifiGateway.ino |0 |0 |80 |64 |4032
|
||||
src/_P045_MPU6050.ino |0 |4 |216 |72 |4496
|
||||
src/_P046_VentusW266.ino |325 |4 |184 |88 |3920
|
||||
src/_P047_i2c-soil-moisture-so|0 |4 |216 |8 |2144
|
||||
src/_P048_Motorshield_v2.ino |0 |32 |208 |0 |5952
|
||||
src/_P049_MHZ19.ino |380 |80 |184 |88 |3792
|
||||
Vendored
+1272
File diff suppressed because it is too large
Load Diff
Vendored
BIN
Binary file not shown.
@@ -0,0 +1,59 @@
|
||||
#include "AM2320.h"
|
||||
#include <Wire.h>
|
||||
//
|
||||
// AM2321 Temperature & Humidity Sensor library for Arduino
|
||||
// Сделана Тимофеевым Е.Н. из AM2320-master
|
||||
|
||||
unsigned int CRC16(byte *ptr, byte length)
|
||||
{
|
||||
unsigned int crc = 0xFFFF;
|
||||
uint8_t s = 0x00;
|
||||
|
||||
while(length--) {
|
||||
crc ^= *ptr++;
|
||||
for(s = 0; s < 8; s++) {
|
||||
if((crc & 0x01) != 0) {
|
||||
crc >>= 1;
|
||||
crc ^= 0xA001;
|
||||
} else crc >>= 1;
|
||||
}
|
||||
}
|
||||
return crc;
|
||||
}
|
||||
|
||||
AM2320::AM2320()
|
||||
{
|
||||
}
|
||||
|
||||
int AM2320::Read()
|
||||
{
|
||||
byte buf[8];
|
||||
for(int s = 0; s < 8; s++) buf[s] = 0x00;
|
||||
|
||||
Wire.beginTransmission(AM2320_address);
|
||||
Wire.endTransmission();
|
||||
// запрос 4 байт (температуры и влажности)
|
||||
Wire.beginTransmission(AM2320_address);
|
||||
Wire.write(0x03);// запрос
|
||||
Wire.write(0x00); // с 0-го адреса
|
||||
Wire.write(0x04); // 4 байта
|
||||
if (Wire.endTransmission(1) != 0) return 1;
|
||||
delayMicroseconds(1600); //>1.5ms
|
||||
// считываем результаты запроса
|
||||
Wire.requestFrom(AM2320_address, 0x08);
|
||||
for (int i = 0; i < 0x08; i++) buf[i] = Wire.read();
|
||||
|
||||
// CRC check
|
||||
unsigned int Rcrc = buf[7] << 8;
|
||||
Rcrc += buf[6];
|
||||
if (Rcrc == CRC16(buf, 6)) {
|
||||
unsigned int temperature = ((buf[4] & 0x7F) << 8) + buf[5];
|
||||
t = temperature / 10.0;
|
||||
t = ((buf[4] & 0x80) >> 7) == 1 ? t * (-1) : t;
|
||||
|
||||
unsigned int humidity = (buf[2] << 8) + buf[3];
|
||||
h = humidity / 10.0;
|
||||
return 0;
|
||||
}
|
||||
return 2;
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
#ifndef AM2320_H
|
||||
#define AM2320_H
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
#define AM2320_address (0xB8 >> 1)
|
||||
|
||||
class AM2320
|
||||
{
|
||||
public:
|
||||
AM2320();
|
||||
float t;
|
||||
float h;
|
||||
int Read(void);
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,29 @@
|
||||
#include <Wire.h>
|
||||
#include <AM2320.h>
|
||||
|
||||
AM2320 th;
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
Wire.begin();
|
||||
}
|
||||
|
||||
void loop() {
|
||||
switch(th.Read()) {
|
||||
case 2:
|
||||
Serial.println("CRC failed");
|
||||
break;
|
||||
case 1:
|
||||
Serial.println("Sensor offline");
|
||||
break;
|
||||
case 0:
|
||||
Serial.print("humidity: ");
|
||||
Serial.print(th.h);
|
||||
Serial.print("%, temperature: ");
|
||||
Serial.print(th.t);
|
||||
Serial.println("*C");
|
||||
break;
|
||||
}
|
||||
|
||||
delay(200);
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
AM2320 KEYWORD1
|
||||
getTemperature KEYWORD2
|
||||
getHumidity KEYWORD2
|
||||
CRCCheck KEYWORD2
|
||||
@@ -0,0 +1,13 @@
|
||||
# Compiled Object files
|
||||
*.slo
|
||||
*.lo
|
||||
*.o
|
||||
|
||||
# Compiled Dynamic libraries
|
||||
*.so
|
||||
*.dylib
|
||||
|
||||
# Compiled Static libraries
|
||||
*.lai
|
||||
*.la
|
||||
*.a
|
||||
@@ -0,0 +1,476 @@
|
||||
/*
|
||||
This is a (Arduino) library for the BH1750FVI Digital Light Sensor.
|
||||
|
||||
Description:
|
||||
http://www.rohm.com/web/global/products/-/product/BH1750FVI
|
||||
|
||||
Datasheet:
|
||||
http://rohmfs.rohm.com/en/products/databook/datasheet/ic/sensor/light/bh1750fvi-e.pdf
|
||||
|
||||
Copyright (c) 2013 Alexander Schulz. All right reserved.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include "AS_BH1750.h"
|
||||
|
||||
// Debug-Flag
|
||||
#define BH1750_DEBUG 0
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
* Erlaubt die I2C-Adresse des Sensors zu ändern.
|
||||
* Standardadresse: 0x23, Alternativadresse: 0x5C.
|
||||
* Es sind entsprechende Konstanten definiert: BH1750_DEFAULT_I2CADDR und BH1750_SECOND_I2CADDR.
|
||||
* Bei Nichtangabe wird die Standardadresse verwendet.
|
||||
* Um die Alternativadresse zu nutzen, muss der Sensorpin 'ADR' des Chips auf VCC gelegt werden.
|
||||
*/
|
||||
AS_BH1750::AS_BH1750(uint8_t address) {
|
||||
_address = address;
|
||||
_hardwareMode = 255;
|
||||
}
|
||||
|
||||
/**
|
||||
* Führt die anfängliche Initialisierung des Sensors.
|
||||
* Mögliche Parameter:
|
||||
* - Modus für die Sensorauflösung:
|
||||
* -- RESOLUTION_LOW: Physische Sensormodus mit 4 lx Auflösung. Messzeit ca. 16ms. Bereich 0-54612.
|
||||
* -- RESOLUTION_NORMAL: Physische Sensormodus mit 1 lx Auflösung. Messzeit ca. 120ms. Bereich 0-54612.
|
||||
* -- RESOLUTION_HIGH: Physische Sensormodus mit 0,5 lx Auflösung. Messzeit ca. 120ms. Bereich 0-54612.
|
||||
* (Die Messbereiche können durch Änderung des MTreg verschoben werden.)
|
||||
* -- RESOLUTION_AUTO_HIGH: Die Werte im MTreg werden je nach Helligkeit automatisch so angepasst,
|
||||
* dass eine maximalmögliche Auflösung und Messbereich erziehlt werden.
|
||||
* Die messbaren Werte fangen von 0,11 lx und gehen bis über 100000 lx.
|
||||
* (ich weis nicht, wie genau die Werte in Grenzbereichen sind,
|
||||
* besonders bei hohen Werte habe ich da meine Zweifel.
|
||||
* Die Werte scheinen jedoch weitgehend linear mit der steigenden Helligkeit zu wachsen.)
|
||||
* Auflösung im Unteren Bereich ca. 0,13 lx, im mittleren 0,5 lx, im oberen etwa 1-2 lx.
|
||||
* Die Messzeiten verlängern sich durch mehrfache Messungen und
|
||||
* die Änderungen von Measurement Time (MTreg) bis max. ca. 500 ms.
|
||||
*
|
||||
* - AutoPowerDown: true = Der Sensor wird nach der Messung in den Stromsparmodus versetzt.
|
||||
* Das spätere Aufwecken wird ggf. automatisch vorgenommen, braucht jedoch geringfügig mehr Zeit.
|
||||
*
|
||||
* Defaultwerte: RESOLUTION_AUTO_HIGH, true
|
||||
*
|
||||
*/
|
||||
bool AS_BH1750::begin(sensors_resolution_t mode, bool autoPowerDown) {
|
||||
#if BH1750_DEBUG == 1
|
||||
Serial.print(" sensors_resolution_mode (virtual): ");
|
||||
Serial.println(mode, DEC);
|
||||
#endif
|
||||
_virtualMode = mode;
|
||||
_autoPowerDown = autoPowerDown;
|
||||
|
||||
Wire.begin();
|
||||
|
||||
defineMTReg(BH1750_MTREG_DEFAULT); // eigentlich normalerweise unnötig, da standard
|
||||
|
||||
// Hardware-Modus zum gewünschten VitrualModus ermitteltn
|
||||
switch (_virtualMode) {
|
||||
case RESOLUTION_LOW:
|
||||
_hardwareMode = autoPowerDown?BH1750_ONE_TIME_LOW_RES_MODE:BH1750_CONTINUOUS_LOW_RES_MODE;
|
||||
break;
|
||||
case RESOLUTION_NORMAL:
|
||||
_hardwareMode = autoPowerDown?BH1750_ONE_TIME_HIGH_RES_MODE:BH1750_CONTINUOUS_HIGH_RES_MODE;
|
||||
break;
|
||||
case RESOLUTION_HIGH:
|
||||
_hardwareMode = autoPowerDown?BH1750_ONE_TIME_HIGH_RES_MODE_2:BH1750_CONTINUOUS_HIGH_RES_MODE_2;
|
||||
break;
|
||||
case RESOLUTION_AUTO_HIGH:
|
||||
_hardwareMode = BH1750_CONTINUOUS_LOW_RES_MODE;
|
||||
break;
|
||||
default:
|
||||
// darf eigentlich nicht passieren...
|
||||
_hardwareMode = 255;
|
||||
break;
|
||||
}
|
||||
|
||||
#if BH1750_DEBUG == 1
|
||||
Serial.print("hardware mode: ");
|
||||
Serial.println(_hardwareMode, DEC);
|
||||
#endif
|
||||
|
||||
if(_hardwareMode==255) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Versuchen, den gewählten Hardwaremodus zu aktivieren
|
||||
if(selectResolutionMode(_hardwareMode)){
|
||||
#if BH1750_DEBUG == 1
|
||||
Serial.print("hardware mode defined successfully");
|
||||
Serial.println(_hardwareMode, DEC);
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
// Initialisierung fehlgeschlagen
|
||||
#if BH1750_DEBUG == 1
|
||||
Serial.print("failure to aktivate hardware mode ");
|
||||
Serial.println(_hardwareMode, DEC);
|
||||
#endif
|
||||
_hardwareMode = 255;
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Erlaub eine Prüfung, ob ein (ansprechbarer) BH1750-Sensor vorhanden ist.
|
||||
*/
|
||||
bool AS_BH1750::isPresent() {
|
||||
// Check I2C Adresse
|
||||
Wire.beginTransmission(_address);
|
||||
if(Wire.endTransmission()!=0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check device: ist es ein BH1750
|
||||
if(!isInitialized()) {
|
||||
// zuvor inaktiv, daher zu Testen schnelltes einmal-Mode aktivieren
|
||||
//write8(BH1750_POWER_ON);
|
||||
selectResolutionMode(BH1750_ONE_TIME_LOW_RES_MODE);
|
||||
_hardwareMode=255;
|
||||
}
|
||||
else {
|
||||
// falls einmal-modus aktiv war, muss der Sensor geweckt werden
|
||||
powerOn();
|
||||
}
|
||||
|
||||
// Prüfen, ob Werte auch wirklich geliefert werden (letztes Modus, ggf. wird auto-PowerDown ausgeführt)
|
||||
return (readLightLevel()>=0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Weckt ein im PowerDown-Modus befindlichen Sensor auf (schadet auch dem 'wachen' Sensor nicht).
|
||||
* Funktionier nur, wenn der Sensor bereits initialisiert wurde.
|
||||
*/
|
||||
void AS_BH1750::powerOn() {
|
||||
if(!isInitialized()) {
|
||||
#if BH1750_DEBUG == 1
|
||||
Serial.println("sensor not initialized");
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
_valueReaded=false;
|
||||
//write8(BH1750_POWER_ON); //
|
||||
//fDelayPtr(10); // Nötig?
|
||||
// Scheinbar reicht das Setzen von HardwareMode auch ohne PowerON-Befehl aus
|
||||
selectResolutionMode(_hardwareMode); // letzten Modus wieder aktivieren
|
||||
}
|
||||
|
||||
/**
|
||||
* Schickt den Sensor in Stromsparmodus.
|
||||
* Funktionier nur, wenn der Sensor bereits initialisiert wurde.
|
||||
*/
|
||||
void AS_BH1750::powerDown() {
|
||||
if(!isInitialized()) {
|
||||
#if BH1750_DEBUG == 1
|
||||
Serial.println("sensor not initialized");
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
write8(BH1750_POWER_DOWN);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sendet zum Sensor ein Befehl zum Auswahl von HardwareMode.
|
||||
*
|
||||
* Parameter:
|
||||
* - mode: s.o.
|
||||
* - DelayFuncPtr: delay(n) Möglichkeit, eigene Delay-Funktion mitzugeben (z.B. um sleep-Modus zu verwenden).
|
||||
*
|
||||
* Defaultwerte: delay()
|
||||
*
|
||||
*/
|
||||
bool AS_BH1750::selectResolutionMode(uint8_t mode, DelayFuncPtr fDelayPtr) {
|
||||
#if BH1750_DEBUG == 1
|
||||
Serial.print("selectResolutionMode: ");
|
||||
Serial.println(mode, DEC);
|
||||
#endif
|
||||
if(!isInitialized()) {
|
||||
return false;
|
||||
#if BH1750_DEBUG == 1
|
||||
Serial.println("sensor not initialized");
|
||||
#endif
|
||||
}
|
||||
|
||||
_hardwareMode=mode;
|
||||
_valueReaded=false;
|
||||
|
||||
// Prüfen, ob ein valides Modus vorliegt und im positiven Fall das gewünschte Modus aktivieren
|
||||
switch (mode) {
|
||||
case BH1750_CONTINUOUS_HIGH_RES_MODE:
|
||||
case BH1750_CONTINUOUS_HIGH_RES_MODE_2:
|
||||
case BH1750_CONTINUOUS_LOW_RES_MODE:
|
||||
case BH1750_ONE_TIME_HIGH_RES_MODE:
|
||||
case BH1750_ONE_TIME_HIGH_RES_MODE_2:
|
||||
case BH1750_ONE_TIME_LOW_RES_MODE:
|
||||
// Modus aktivieren
|
||||
if(write8(mode)) {
|
||||
// Kurze pause nötig, sonst wird das Modus nicht sicher Aktiviert
|
||||
// (z.B. liefert Sensor im AutoHigh Modus abwechselnd übersteuerte Werte, etwa so: 54612.5, 68123.4, 54612.5, 69345.3,..)
|
||||
fDelayPtr(5);
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
// Invalid measurement mode
|
||||
#if BH1750_DEBUG == 1
|
||||
Serial.println("Invalid measurement mode");
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert aktuell gemessenen Wert für Helligkeit in lux (lx).
|
||||
* Falls sich der Sensorf in Stromsparmodus befindet, wird er automatisch geweckt.
|
||||
*
|
||||
* Wurde der Sensor (noch) nicht initialisiert (begin), wird der Wert -1 geliefert.
|
||||
*/
|
||||
float AS_BH1750::readLightLevel(DelayFuncPtr fDelayPtr) {
|
||||
#if BH1750_DEBUG == 1
|
||||
Serial.print("call: readLightLevel. virtualMode: ");
|
||||
Serial.println(_virtualMode, DEC);
|
||||
#endif
|
||||
|
||||
if(!isInitialized()) {
|
||||
#if BH1750_DEBUG == 1
|
||||
Serial.println("sensor not initialized");
|
||||
#endif
|
||||
return -1;
|
||||
}
|
||||
|
||||
// ggf. PowerOn
|
||||
if(_autoPowerDown && _valueReaded){
|
||||
powerOn();
|
||||
}
|
||||
|
||||
// Das Automatische Modus benötigt eine Sonderbehandlung.
|
||||
// Zuerst wird die Helligkeit im LowRes-Modus gelesen,
|
||||
// je nach Bereich (dunkel, normal, sehr hell) werden die Werte von MTreg gesetzt und
|
||||
// danach wird die eigentliche Messung vorgenommen.
|
||||
/*
|
||||
Die feste Grenzwerte verursachen möglicherweise einen 'Sprung' in der Messkurve.
|
||||
In diesem Fall wäre eine laufende Anpassung von MTreg in Grenzbereichen vermutlich besser.
|
||||
Für meine Zwecke ist das jedoch ohne Bedeutung.
|
||||
*/
|
||||
if(_virtualMode==RESOLUTION_AUTO_HIGH) {
|
||||
defineMTReg(BH1750_MTREG_DEFAULT);
|
||||
selectResolutionMode(BH1750_CONTINUOUS_LOW_RES_MODE, fDelayPtr);
|
||||
fDelayPtr(16); // Lesezeit in LowResMode
|
||||
uint16_t level = readRawLevel();
|
||||
#if BH1750_DEBUG == 1
|
||||
Serial.print("AutoHighMode: check level read: ");
|
||||
Serial.println(level, DEC);
|
||||
#endif
|
||||
if(level<10) {
|
||||
#if BH1750_DEBUG == 1
|
||||
Serial.println("level 0: dark");
|
||||
#endif
|
||||
// Dunkel, Empfindlichkeit auf Maximum.
|
||||
// Der Wert ist zufällig. Ab ca. 16000 wäre diese Vorgehnsweise möglich.
|
||||
// Ich brauche diese Genauigkeit aber nur in den ganz dunklen Bereichen (zu erkennen, wann wirklich 'dunkel' ist).
|
||||
defineMTReg(BH1750_MTREG_MAX);
|
||||
selectResolutionMode(_autoPowerDown?BH1750_ONE_TIME_HIGH_RES_MODE_2:BH1750_CONTINUOUS_HIGH_RES_MODE_2, fDelayPtr);
|
||||
fDelayPtr(120*3.68); // TODO: Wert prüfen
|
||||
//fDelayPtr(122);
|
||||
}
|
||||
else if(level<32767) {
|
||||
#if BH1750_DEBUG == 1
|
||||
Serial.println("level 1: normal");
|
||||
#endif
|
||||
// Bis hierher reicht die 0,5 lx Modus. Normale Empfindlichkeit.
|
||||
defineMTReg(BH1750_MTREG_DEFAULT);
|
||||
selectResolutionMode(_autoPowerDown?BH1750_ONE_TIME_HIGH_RES_MODE_2:BH1750_CONTINUOUS_HIGH_RES_MODE_2, fDelayPtr);
|
||||
fDelayPtr(120); // TODO: Wert prüfen
|
||||
}
|
||||
else if(level<60000) {
|
||||
#if BH1750_DEBUG == 1
|
||||
Serial.println("level 2: bright");
|
||||
#endif
|
||||
// hoher Bereich, 1 lx Modus, normale Empfindlichkeit. Der Wert von 60000 ist mehr oder weniger zufällig, es mus einfach ein hoher Wert, nah an der Grenze sein.
|
||||
defineMTReg(BH1750_MTREG_DEFAULT);
|
||||
selectResolutionMode(_autoPowerDown?BH1750_ONE_TIME_HIGH_RES_MODE:BH1750_CONTINUOUS_HIGH_RES_MODE, fDelayPtr);
|
||||
fDelayPtr(120); // TODO: Wert prüfen
|
||||
}
|
||||
else {
|
||||
#if BH1750_DEBUG == 1
|
||||
Serial.println("level 3: very bright");
|
||||
#endif
|
||||
// sehr hoher Bereich, Empfindlichkeit verringern
|
||||
defineMTReg(32); // Min+1, bei dem Minimum aus Doku spielt der Sensor (zumindest meiner) verrückt: Die Werte sind ca. 1/10 von den Erwarteten.
|
||||
selectResolutionMode(_autoPowerDown?BH1750_ONE_TIME_HIGH_RES_MODE:BH1750_CONTINUOUS_HIGH_RES_MODE, fDelayPtr);
|
||||
fDelayPtr(120); // TODO: Wert prüfen
|
||||
}
|
||||
}
|
||||
|
||||
// Hardware Wert lesen und in Lux umrechnen.
|
||||
uint16_t raw = readRawLevel();
|
||||
if(raw==65535) {
|
||||
// Wert verdächtig hoch. Sensor prüfen.
|
||||
// Check I2C Adresse
|
||||
Wire.beginTransmission(_address);
|
||||
if(Wire.endTransmission()!=0) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return convertRawValue(raw);
|
||||
}
|
||||
|
||||
/**
|
||||
* Roh-Wert der Helligkeit auslesen.
|
||||
* Wertebereich 0-65535.
|
||||
*/
|
||||
uint16_t AS_BH1750::readRawLevel(void) {
|
||||
uint16_t level;
|
||||
Wire.beginTransmission(_address);
|
||||
Wire.requestFrom(_address, 2);
|
||||
#if (ARDUINO >= 100)
|
||||
level = Wire.read();
|
||||
level <<= 8;
|
||||
level |= Wire.read();
|
||||
#else
|
||||
level = Wire.receive();
|
||||
level <<= 8;
|
||||
level |= Wire.receive();
|
||||
#endif
|
||||
if(Wire.endTransmission()!=0) {
|
||||
#if BH1750_DEBUG == 1
|
||||
Serial.println("I2C read error");
|
||||
#endif
|
||||
return 65535; // Error marker
|
||||
}
|
||||
|
||||
#if BH1750_DEBUG == 1
|
||||
Serial.print("Raw light level: ");
|
||||
Serial.println(level);
|
||||
#endif
|
||||
|
||||
_valueReaded=true;
|
||||
|
||||
return level;
|
||||
}
|
||||
|
||||
/**
|
||||
* Rechnet Roh-Werte in Lux um.
|
||||
*/
|
||||
float AS_BH1750::convertRawValue(uint16_t raw) {
|
||||
// Basisumrechnung
|
||||
float flevel = raw/1.2;
|
||||
|
||||
#if BH1750_DEBUG == 1
|
||||
Serial.print("convert light level (1): ");
|
||||
Serial.println(flevel);
|
||||
#endif
|
||||
|
||||
// MTreg-Einfluss berechnen
|
||||
if(_MTreg!=BH1750_MTREG_DEFAULT) { // bei 69 ist der Faktor = 1
|
||||
flevel = flevel * _MTregFactor;
|
||||
#if BH1750_DEBUG == 1
|
||||
Serial.print("convert light level (2): ");
|
||||
Serial.println(flevel);
|
||||
#endif
|
||||
}
|
||||
|
||||
// je nach Modus ist eine weitere Umrechnung nötig
|
||||
switch (_hardwareMode) {
|
||||
case BH1750_CONTINUOUS_HIGH_RES_MODE_2:
|
||||
case BH1750_ONE_TIME_HIGH_RES_MODE_2:
|
||||
flevel = flevel/2;
|
||||
#if BH1750_DEBUG == 1
|
||||
Serial.print("convert light level (3): ");
|
||||
Serial.println(flevel);
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
// nothing to do
|
||||
break;
|
||||
}
|
||||
|
||||
#if BH1750_DEBUG == 1
|
||||
Serial.print("Light level: ");
|
||||
Serial.println(flevel);
|
||||
#endif
|
||||
|
||||
return flevel;
|
||||
}
|
||||
|
||||
/**
|
||||
* MTreg setzen. Definiert Empfindlichkeit des Sensors.
|
||||
* Min.Wert (BH1750_MTREG_MIN) = 31 (Empfindlichkeit: default*0,45)
|
||||
* Max.Wert (BH1750_MTREG_MAX) = 254 (Empfindlichkeit: default*3,68)
|
||||
* Default (BH1750_MTREG_DEFAULT) = 69.
|
||||
* Mit der Empfindlichkeit verändert sich die Lesezeit (höhere Empfindlichkeit bedeutet längere Zeitspanne).
|
||||
*/
|
||||
void AS_BH1750::defineMTReg(uint8_t val) {
|
||||
if(val<BH1750_MTREG_MIN) {
|
||||
val = BH1750_MTREG_MIN;
|
||||
}
|
||||
if(val>BH1750_MTREG_MAX) {
|
||||
val = BH1750_MTREG_MAX;
|
||||
}
|
||||
if(val!=_MTreg) {
|
||||
_MTreg = val;
|
||||
_MTregFactor = (float)BH1750_MTREG_DEFAULT / _MTreg;
|
||||
|
||||
// Change Measurement time
|
||||
// Übertragung in zwei Schritten: 3 Bit und 5 Bit, jeweils mit einem Prefix.
|
||||
// High bit: 01000_MT[7,6,5]
|
||||
// Low bit: 011_MT[4,3,2,1,0]
|
||||
uint8_t hiByte = val>>5;
|
||||
hiByte |= 0b01000000;
|
||||
#if BH1750_DEBUG == 1
|
||||
Serial.print("MGTreg high byte: ");
|
||||
Serial.println(hiByte, BIN);
|
||||
#endif
|
||||
write8(hiByte);
|
||||
//fDelayPtr(10);
|
||||
// Pause nötig?
|
||||
uint8_t loByte = val&0b00011111;
|
||||
loByte |= 0b01100000;
|
||||
#if BH1750_DEBUG == 1
|
||||
Serial.print("MGTreg low byte: ");
|
||||
Serial.println(loByte, BIN);
|
||||
#endif
|
||||
write8(hiByte);
|
||||
//fDelayPtr(10);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gibt an, ob der Sensor initialisiert ist.
|
||||
*/
|
||||
bool AS_BH1750::isInitialized() {
|
||||
return _hardwareMode!=255;
|
||||
}
|
||||
|
||||
/**
|
||||
* Schreibt ein Byte auf I2C Bus (auf die Adresse des Sensors).
|
||||
*/
|
||||
bool AS_BH1750::write8(uint8_t d) {
|
||||
Wire.beginTransmission(_address);
|
||||
#if (ARDUINO >= 100)
|
||||
Wire.write(d);
|
||||
#else
|
||||
Wire.send(d);
|
||||
#endif
|
||||
return (Wire.endTransmission()==0);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,183 @@
|
||||
/*
|
||||
This is a (Arduino) library for the BH1750FVI Digital Light Sensor.
|
||||
|
||||
Description:
|
||||
http://www.rohm.com/web/global/products/-/product/BH1750FVI
|
||||
|
||||
Datasheet:
|
||||
http://rohmfs.rohm.com/en/products/databook/datasheet/ic/sensor/light/bh1750fvi-e.pdf
|
||||
|
||||
Copyright (c) 2013 Alexander Schulz. All right reserved.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef AS_BH1750_h
|
||||
#define AS_BH1750_h
|
||||
|
||||
#if (ARDUINO >= 100)
|
||||
#include <Arduino.h>
|
||||
#else
|
||||
#include <WProgram.h>
|
||||
#endif
|
||||
#include "Wire.h"
|
||||
|
||||
// Mögliche I2C Adressen
|
||||
#define BH1750_DEFAULT_I2CADDR 0x23
|
||||
#define BH1750_SECOND_I2CADDR 0x5C
|
||||
|
||||
// MTreg Werte
|
||||
// Default
|
||||
#define BH1750_MTREG_DEFAULT 69
|
||||
// Sensitivity : default = 0.45
|
||||
#define BH1750_MTREG_MIN 31
|
||||
// Sensitivity : default = 3.68
|
||||
#define BH1750_MTREG_MAX 254
|
||||
|
||||
// Hardware Modi
|
||||
// No active state
|
||||
#define BH1750_POWER_DOWN 0x00
|
||||
|
||||
// Wating for measurment command
|
||||
#define BH1750_POWER_ON 0x01
|
||||
|
||||
// Reset data register value - not accepted in POWER_DOWN mode
|
||||
#define BH1750_RESET 0x07
|
||||
|
||||
// Start measurement at 1lx resolution. Measurement time is approx 120ms.
|
||||
#define BH1750_CONTINUOUS_HIGH_RES_MODE 0x10
|
||||
|
||||
// Start measurement at 0.5lx resolution. Measurement time is approx 120ms.
|
||||
#define BH1750_CONTINUOUS_HIGH_RES_MODE_2 0x11
|
||||
|
||||
// Start measurement at 4lx resolution. Measurement time is approx 16ms.
|
||||
#define BH1750_CONTINUOUS_LOW_RES_MODE 0x13
|
||||
|
||||
// Start measurement at 1lx resolution. Measurement time is approx 120ms.
|
||||
// Device is automatically set to Power Down after measurement.
|
||||
#define BH1750_ONE_TIME_HIGH_RES_MODE 0x20
|
||||
|
||||
// Start measurement at 0.5lx resolution. Measurement time is approx 120ms.
|
||||
// Device is automatically set to Power Down after measurement.
|
||||
#define BH1750_ONE_TIME_HIGH_RES_MODE_2 0x21
|
||||
|
||||
// Start measurement at 1lx resolution. Measurement time is approx 120ms.
|
||||
// Device is automatically set to Power Down after measurement.
|
||||
#define BH1750_ONE_TIME_LOW_RES_MODE 0x23
|
||||
|
||||
/** Virtual Modi */
|
||||
typedef enum
|
||||
{
|
||||
RESOLUTION_LOW = (1), /** 4lx resolution. Measurement time is approx 16ms. */
|
||||
RESOLUTION_NORMAL = (2), /** 1lx resolution. Measurement time is approx 120ms. */
|
||||
RESOLUTION_HIGH = (3), /** 0,5lx resolution. Measurement time is approx 120ms. */
|
||||
RESOLUTION_AUTO_HIGH = (99) /** 0,11-1lx resolution. Measurement time is above 250ms. */
|
||||
}
|
||||
sensors_resolution_t;
|
||||
|
||||
typedef void (*DelayFuncPtr)(unsigned long);
|
||||
typedef unsigned long (*TimeFuncPtr)(void);
|
||||
|
||||
/**
|
||||
* BH1750 driver class.
|
||||
*/
|
||||
class AS_BH1750 {
|
||||
public:
|
||||
/**
|
||||
* Constructor.
|
||||
* Erlaubt die I2C-Adresse des Sensors zu ändern.
|
||||
* Standardadresse: 0x23, Alternativadresse: 0x5C.
|
||||
* Es sind entsprechende Konstanten definiert: BH1750_DEFAULT_I2CADDR und BH1750_SECOND_I2CADDR.
|
||||
* Bei Nichtangabe wird die Standardadresse verwendet.
|
||||
* Um die Alternativadresse zu nutzen, muss der Sensorpin 'ADR' des Chips auf VCC gelegt werden.
|
||||
*/
|
||||
AS_BH1750(uint8_t address = BH1750_DEFAULT_I2CADDR);
|
||||
|
||||
/**
|
||||
* Führt die anfängliche Initialisierung des Sensors.
|
||||
* Mögliche Parameter:
|
||||
* - Modus für die Sensorauflösung:
|
||||
* -- RESOLUTION_LOW: Physische Sensormodus mit 4 lx Auflösung. Messzeit ca. 16ms. Bereich 0-54612.
|
||||
* -- RESOLUTION_NORMAL: Physische Sensormodus mit 1 lx Auflösung. Messzeit ca. 120ms. Bereich 0-54612.
|
||||
* -- RESOLUTION_HIGH: Physische Sensormodus mit 0,5 lx Auflösung. Messzeit ca. 120ms. Bereich 0-54612.
|
||||
* (Die Messbereiche können durch Änderung des MTreg verschoben werden.)
|
||||
* -- RESOLUTION_AUTO_HIGH: Die Werte im MTreg werden je nach Helligkeit automatisch so angepasst,
|
||||
* dass eine maximalmögliche Auflösung und Messbereich erziehlt werden.
|
||||
* Die messbaren Werte fangen von 0,11 lx und gehen bis über 100000 lx.
|
||||
* (ich weis nicht, wie genau die Werte in Grenzbereichen sind,
|
||||
* besonders bei hohen Werte habe ich meine Zweifel.)
|
||||
* Auflösung im Unteren Bereich 0,13 lx, im mittleren 0,5 lx, im oberen 1-2 lx.
|
||||
* Die Messzeiten verlängern sich durch mehrfache Messungen und
|
||||
* die Änderungen von Measurement Time (MTreg) bis max. ca. 500 ms.
|
||||
*
|
||||
* - AutoPowerDown: true = Der Sensor wird nach der Messung in den Stromsparmodus versetzt.
|
||||
* Das spätere Aufwecken wird ggf. automatisch vorgenommen, braucht jedoch geringfügig mehr Zeit.
|
||||
*
|
||||
* Defaultwerte: RESOLUTION_AUTO_HIGH, true, delay()
|
||||
*
|
||||
*/
|
||||
bool begin(sensors_resolution_t mode = RESOLUTION_AUTO_HIGH, bool autoPowerDown = true);
|
||||
|
||||
/**
|
||||
* Erlaub eine Prüfung, ob ein (ansprechbarer) BH1750-Sensor vorhanden ist.
|
||||
*/
|
||||
bool isPresent(void);
|
||||
|
||||
/**
|
||||
* Liefert aktuell gemessenen Wert für Helligkeit in lux (lx).
|
||||
* Falls sich der Sensorf in Stromsparmodus befindet, wird er automatisch geweckt.
|
||||
*
|
||||
* Wurde der Sensor (noch) nicht initialisiert (begin), wird der Wert -1 geliefert.
|
||||
*
|
||||
* Mögliche Parameter:
|
||||
*
|
||||
* - DelayFuncPtr: delay(n) Möglichkeit, eigene Delay-Funktion mitzugeben (z.B. um sleep-Modus zu verwenden).
|
||||
*
|
||||
* Defaultwerte: delay()
|
||||
*
|
||||
*/
|
||||
float readLightLevel(DelayFuncPtr fDelayPtr = &delay);
|
||||
|
||||
/**
|
||||
* Schickt den Sensor in Stromsparmodus.
|
||||
* Funktionier nur, wenn der Sensor bereits initialisiert wurde.
|
||||
*/
|
||||
void powerDown(void);
|
||||
|
||||
private:
|
||||
int _address;
|
||||
uint8_t _hardwareMode;
|
||||
|
||||
uint8_t _MTreg;
|
||||
float _MTregFactor;
|
||||
|
||||
sensors_resolution_t _virtualMode;
|
||||
bool _autoPowerDown;
|
||||
|
||||
bool _valueReaded;
|
||||
|
||||
bool selectResolutionMode(uint8_t mode, DelayFuncPtr fDelayPtr = &delay);
|
||||
void defineMTReg(uint8_t val);
|
||||
void powerOn(void);
|
||||
void reset(void);
|
||||
uint16_t readRawLevel(void);
|
||||
float convertRawValue(uint16_t raw);
|
||||
bool isInitialized();
|
||||
bool write8(uint8_t data);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -0,0 +1,705 @@
|
||||
/*
|
||||
This is a (Arduino) library for the BH1750FVI Digital Light Sensor.
|
||||
|
||||
Description:
|
||||
http://www.rohm.com/web/global/products/-/product/BH1750FVI
|
||||
|
||||
Datasheet:
|
||||
http://rohmfs.rohm.com/en/products/databook/datasheet/ic/sensor/light/bh1750fvi-e.pdf
|
||||
|
||||
Copyright (c) 2013 Alexander Schulz. All right reserved.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include "AS_BH1750A.h"
|
||||
|
||||
// Debug-Flag
|
||||
#define BH1750_DEBUG 0
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
* Erlaubt die I2C-Adresse des Sensors zu ändern.
|
||||
* Standardadresse: 0x23, Alternativadresse: 0x5C.
|
||||
* Es sind entsprechende Konstanten definiert: BH1750_DEFAULT_I2CADDR und BH1750_SECOND_I2CADDR.
|
||||
* Bei Nichtangabe wird die Standardadresse verwendet.
|
||||
* Um die Alternativadresse zu nutzen, muss der Sensorpin 'ADR' des Chips auf VCC gelegt werden.
|
||||
*/
|
||||
AS_BH1750A::AS_BH1750A(uint8_t address) {
|
||||
_address = address;
|
||||
_hardwareMode = 255;
|
||||
}
|
||||
|
||||
/**
|
||||
* Führt die anfängliche Initialisierung des Sensors.
|
||||
* Mögliche Parameter:
|
||||
* - Modus für die Sensorauflösung:
|
||||
* -- RESOLUTION_LOW: Physische Sensormodus mit 4 lx Auflösung. Messzeit ca. 16ms. Bereich 0-54612.
|
||||
* -- RESOLUTION_NORMAL: Physische Sensormodus mit 1 lx Auflösung. Messzeit ca. 120ms. Bereich 0-54612.
|
||||
* -- RESOLUTION_HIGH: Physische Sensormodus mit 0,5 lx Auflösung. Messzeit ca. 120ms. Bereich 0-54612.
|
||||
* (Die Messbereiche können durch Änderung des MTreg verschoben werden.)
|
||||
* -- RESOLUTION_AUTO_HIGH: Die Werte im MTreg werden je nach Helligkeit automatisch so angepasst,
|
||||
* dass eine maximalmögliche Auflösung und Messbereich erziehlt werden.
|
||||
* Die messbaren Werte fangen von 0,11 lx und gehen bis über 100000 lx.
|
||||
* (ich weis nicht, wie genau die Werte in Grenzbereichen sind,
|
||||
* besonders bei hohen Werte habe ich da meine Zweifel.
|
||||
* Die Werte scheinen jedoch weitgehend linear mit der steigenden Helligkeit zu wachsen.)
|
||||
* Auflösung im Unteren Bereich ca. 0,13 lx, im mittleren 0,5 lx, im oberen etwa 1-2 lx.
|
||||
* Die Messzeiten verlängern sich durch mehrfache Messungen und
|
||||
* die Änderungen von Measurement Time (MTreg) bis max. ca. 500 ms.
|
||||
*
|
||||
* - AutoPowerDown: true = Der Sensor wird nach der Messung in den Stromsparmodus versetzt.
|
||||
* Das spätere Aufwecken wird ggf. automatisch vorgenommen, braucht jedoch geringfügig mehr Zeit.
|
||||
*
|
||||
* Defaultwerte: RESOLUTION_AUTO_HIGH, true
|
||||
*
|
||||
*/
|
||||
bool AS_BH1750A::begin(sensors_resolution_t mode, bool autoPowerDown) {
|
||||
#if BH1750_DEBUG == 1
|
||||
Serial.print(" sensors_resolution_mode (virtual): ");
|
||||
Serial.println(mode, DEC);
|
||||
#endif
|
||||
_virtualMode = mode;
|
||||
_autoPowerDown = autoPowerDown;
|
||||
|
||||
Wire.begin();
|
||||
|
||||
defineMTReg(BH1750_MTREG_DEFAULT); // eigentlich normalerweise unnötig, da standard
|
||||
|
||||
// Hardware-Modus zum gewünschten VitrualModus ermitteltn
|
||||
switch (_virtualMode) {
|
||||
case RESOLUTION_LOW:
|
||||
_hardwareMode = autoPowerDown?BH1750_ONE_TIME_LOW_RES_MODE:BH1750_CONTINUOUS_LOW_RES_MODE;
|
||||
break;
|
||||
case RESOLUTION_NORMAL:
|
||||
_hardwareMode = autoPowerDown?BH1750_ONE_TIME_HIGH_RES_MODE:BH1750_CONTINUOUS_HIGH_RES_MODE;
|
||||
break;
|
||||
case RESOLUTION_HIGH:
|
||||
_hardwareMode = autoPowerDown?BH1750_ONE_TIME_HIGH_RES_MODE_2:BH1750_CONTINUOUS_HIGH_RES_MODE_2;
|
||||
break;
|
||||
case RESOLUTION_AUTO_HIGH:
|
||||
_hardwareMode = BH1750_CONTINUOUS_LOW_RES_MODE;
|
||||
break;
|
||||
default:
|
||||
// darf eigentlich nicht passieren...
|
||||
_hardwareMode = 255;
|
||||
break;
|
||||
}
|
||||
|
||||
#if BH1750_DEBUG == 1
|
||||
Serial.print("hardware mode: ");
|
||||
Serial.println(_hardwareMode, DEC);
|
||||
#endif
|
||||
|
||||
if(_hardwareMode==255) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Versuchen, den gewählten Hardwaremodus zu aktivieren
|
||||
if(selectResolutionMode(_hardwareMode)){
|
||||
#if BH1750_DEBUG == 1
|
||||
Serial.print("hardware mode defined successfully");
|
||||
Serial.println(_hardwareMode, DEC);
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
// Initialisierung fehlgeschlagen
|
||||
#if BH1750_DEBUG == 1
|
||||
Serial.print("failure to aktivate hardware mode ");
|
||||
Serial.println(_hardwareMode, DEC);
|
||||
#endif
|
||||
_hardwareMode = 255;
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Erlaub eine Prüfung, ob ein (ansprechbarer) BH1750-Sensor vorhanden ist.
|
||||
*/
|
||||
bool AS_BH1750A::isPresent() {
|
||||
// Check I2C Adresse
|
||||
Wire.beginTransmission(_address);
|
||||
if(Wire.endTransmission()!=0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check device: ist es ein BH1750
|
||||
if(!isInitialized()) {
|
||||
// zuvor inaktiv, daher zu Testen schnelltes einmal-Mode aktivieren
|
||||
//write8(BH1750_POWER_ON);
|
||||
selectResolutionMode(BH1750_ONE_TIME_LOW_RES_MODE);
|
||||
delay(5);// Hier muss man in jedem Fall warten, daher die kurze Pause erstmal ok
|
||||
_hardwareMode=255;
|
||||
}
|
||||
else {
|
||||
// falls einmal-modus aktiv war, muss der Sensor geweckt werden
|
||||
powerOn();
|
||||
unsigned long dd = getModeDelay(); if(dd>0) {delay(dd);}
|
||||
//delay(getModeDelay()); // s.o.
|
||||
}
|
||||
|
||||
// Prüfen, ob Werte auch wirklich geliefert werden (letztes Modus, ggf. wird auto-PowerDown ausgeführt)
|
||||
return (readLightLevel()>=0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Weckt ein im PowerDown-Modus befindlichen Sensor auf (schadet auch dem 'wachen' Sensor nicht).
|
||||
* Funktionier nur, wenn der Sensor bereits initialisiert wurde.
|
||||
*/
|
||||
void AS_BH1750A::powerOn() {
|
||||
if(!isInitialized()) {
|
||||
#if BH1750_DEBUG == 1
|
||||
Serial.println("sensor not initialized");
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
_valueReaded=false;
|
||||
//write8(BH1750_POWER_ON); //
|
||||
//fDelayPtr(10); // Nötig?
|
||||
// Scheinbar reicht das Setzen von HardwareMode auch ohne PowerON-Befehl aus
|
||||
selectResolutionMode(_hardwareMode); // letzten Modus wieder aktivieren
|
||||
}
|
||||
|
||||
/**
|
||||
* Schickt den Sensor in Stromsparmodus.
|
||||
* Funktionier nur, wenn der Sensor bereits initialisiert wurde.
|
||||
*/
|
||||
void AS_BH1750A::powerDown() {
|
||||
if(!isInitialized()) {
|
||||
#if BH1750_DEBUG == 1
|
||||
Serial.println("sensor not initialized");
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
write8(BH1750_POWER_DOWN);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sendet zum Sensor ein Befehl zum Auswahl von HardwareMode.
|
||||
*
|
||||
* Parameter:
|
||||
* - mode: s.o.
|
||||
* - DelayFuncPtr: delay(n) Möglichkeit, eigene Delay-Funktion mitzugeben (z.B. um sleep-Modus zu verwenden).
|
||||
*
|
||||
* Defaultwerte: delay()
|
||||
*
|
||||
*/
|
||||
bool AS_BH1750A::selectResolutionMode(uint8_t mode) {
|
||||
#if BH1750_DEBUG == 1
|
||||
Serial.print("selectResolutionMode: ");
|
||||
Serial.println(mode, DEC);
|
||||
#endif
|
||||
if(!isInitialized()) {
|
||||
return false;
|
||||
#if BH1750_DEBUG == 1
|
||||
Serial.println("sensor not initialized");
|
||||
#endif
|
||||
}
|
||||
|
||||
_hardwareMode=mode;
|
||||
_valueReaded=false;
|
||||
|
||||
// Prüfen, ob ein valides Modus vorliegt und im positiven Fall das gewünschte Modus aktivieren
|
||||
switch (mode) {
|
||||
case BH1750_CONTINUOUS_HIGH_RES_MODE:
|
||||
case BH1750_CONTINUOUS_HIGH_RES_MODE_2:
|
||||
case BH1750_CONTINUOUS_LOW_RES_MODE:
|
||||
case BH1750_ONE_TIME_HIGH_RES_MODE:
|
||||
case BH1750_ONE_TIME_HIGH_RES_MODE_2:
|
||||
case BH1750_ONE_TIME_LOW_RES_MODE:
|
||||
// Modus aktivieren
|
||||
if(write8(mode)) {
|
||||
// Kurze pause nötig, sonst wird das Modus nicht sicher Aktiviert
|
||||
// (z.B. liefert Sensor im AutoHigh Modus abwechselnd übersteuerte Werte, etwa so: 54612.5, 68123.4, 54612.5, 69345.3,..)
|
||||
//fDelayPtr(5); => Aufrufer soll 5ms extra warten
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
// Invalid measurement mode
|
||||
#if BH1750_DEBUG == 1
|
||||
Serial.println("Invalid measurement mode");
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert aktuell gemessenen Wert für Helligkeit in lux (lx).
|
||||
* Falls sich der Sensorf in Stromsparmodus befindet, wird er automatisch geweckt.
|
||||
*
|
||||
* Wurde der Sensor (noch) nicht initialisiert (begin), wird der Wert -1 geliefert.
|
||||
*/
|
||||
/*float AS_BH1750A::readLightLevel_alt(DelayFuncPtr fDelayPtr) {
|
||||
#if BH1750_DEBUG == 1
|
||||
Serial.print("call: readLightLevel. virtualMode: ");
|
||||
Serial.println(_virtualMode, DEC);
|
||||
#endif
|
||||
|
||||
if(!isInitialized()) {
|
||||
#if BH1750_DEBUG == 1
|
||||
Serial.println("sensor not initialized");
|
||||
#endif
|
||||
return -1;
|
||||
}
|
||||
|
||||
// ggf. PowerOn
|
||||
if(_autoPowerDown && _valueReaded){
|
||||
powerOn();
|
||||
unsigned long dd = getModeDelay(); if(dd>0) {delay(dd);}
|
||||
}
|
||||
|
||||
// Das Automatische Modus benötigt eine Sonderbehandlung.
|
||||
// Zuerst wird die Helligkeit im LowRes-Modus gelesen,
|
||||
// je nach Bereich (dunkel, normal, sehr hell) werden die Werte von MTreg gesetzt und
|
||||
// danach wird die eigentliche Messung vorgenommen.
|
||||
|
||||
// Die feste Grenzwerte verursachen möglicherweise einen 'Sprung' in der Messkurve.
|
||||
// In diesem Fall wäre eine laufende Anpassung von MTreg in Grenzbereichen vermutlich besser.
|
||||
// Für meine Zwecke ist das jedoch ohne Bedeutung.
|
||||
|
||||
if(_virtualMode==RESOLUTION_AUTO_HIGH) {
|
||||
defineMTReg(BH1750_MTREG_DEFAULT);
|
||||
selectResolutionMode(BH1750_CONTINUOUS_LOW_RES_MODE);
|
||||
//fDelayPtr(16+5); // Lesezeit in LowResMode
|
||||
fDelayPtr(getModeDelay());
|
||||
uint16_t level = readRawLevel();
|
||||
#if BH1750_DEBUG == 1
|
||||
Serial.print("AutoHighMode: check level read: ");
|
||||
Serial.println(level, DEC);
|
||||
#endif
|
||||
if(level<10) {
|
||||
#if BH1750_DEBUG == 1
|
||||
Serial.println("level 0: dark");
|
||||
#endif
|
||||
// Dunkel, Empfindlichkeit auf Maximum.
|
||||
// Der Wert ist zufällig. Ab ca. 16000 wäre diese Vorgehnsweise möglich.
|
||||
// Ich brauche diese Genauigkeit aber nur in den ganz dunklen Bereichen (zu erkennen, wann wirklich 'dunkel' ist).
|
||||
defineMTReg(BH1750_MTREG_MAX);
|
||||
selectResolutionMode(_autoPowerDown?BH1750_ONE_TIME_HIGH_RES_MODE_2:BH1750_CONTINUOUS_HIGH_RES_MODE_2);
|
||||
//fDelayPtr(120*3.68+5); // TODO: Wert prüfen
|
||||
fDelayPtr(getModeDelay());
|
||||
//fDelayPtr(122);
|
||||
}
|
||||
else if(level<32767) {
|
||||
#if BH1750_DEBUG == 1
|
||||
Serial.println("level 1: normal");
|
||||
#endif
|
||||
// Bis hierher reicht die 0,5 lx Modus. Normale Empfindlichkeit.
|
||||
defineMTReg(BH1750_MTREG_DEFAULT);
|
||||
selectResolutionMode(_autoPowerDown?BH1750_ONE_TIME_HIGH_RES_MODE_2:BH1750_CONTINUOUS_HIGH_RES_MODE_2);
|
||||
//fDelayPtr(120+5); // TODO: Wert prüfen
|
||||
fDelayPtr(getModeDelay());
|
||||
}
|
||||
else if(level<60000) {
|
||||
#if BH1750_DEBUG == 1
|
||||
Serial.println("level 2: bright");
|
||||
#endif
|
||||
// hoher Bereich, 1 lx Modus, normale Empfindlichkeit. Der Wert von 60000 ist mehr oder weniger zufällig, es mus einfach ein hoher Wert, nah an der Grenze sein.
|
||||
defineMTReg(BH1750_MTREG_DEFAULT);
|
||||
selectResolutionMode(_autoPowerDown?BH1750_ONE_TIME_HIGH_RES_MODE:BH1750_CONTINUOUS_HIGH_RES_MODE);
|
||||
//fDelayPtr(120+5); // TODO: Wert prüfen
|
||||
fDelayPtr(getModeDelay());
|
||||
}
|
||||
else {
|
||||
#if BH1750_DEBUG == 1
|
||||
Serial.println("level 3: very bright");
|
||||
#endif
|
||||
// sehr hoher Bereich, Empfindlichkeit verringern
|
||||
defineMTReg(32); // Min+1, bei dem Minimum aus Doku spielt der Sensor (zumindest meiner) verrückt: Die Werte sind ca. 1/10 von den Erwarteten.
|
||||
selectResolutionMode(_autoPowerDown?BH1750_ONE_TIME_HIGH_RES_MODE:BH1750_CONTINUOUS_HIGH_RES_MODE);
|
||||
//fDelayPtr(120+5); // TODO: Wert prüfen
|
||||
fDelayPtr(getModeDelay());
|
||||
}
|
||||
}
|
||||
|
||||
// Hardware Wert lesen und in Lux umrechnen.
|
||||
uint16_t raw = readRawLevel();
|
||||
if(raw==65535) {
|
||||
// Wert verdächtig hoch. Sensor prüfen.
|
||||
// Check I2C Adresse
|
||||
Wire.beginTransmission(_address);
|
||||
if(Wire.endTransmission()!=0) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return convertRawValue(raw);
|
||||
}*/
|
||||
|
||||
/**
|
||||
* Roh-Wert der Helligkeit auslesen.
|
||||
* Wertebereich 0-65535.
|
||||
*/
|
||||
uint16_t AS_BH1750A::readRawLevel(void) {
|
||||
uint16_t level;
|
||||
Wire.beginTransmission(_address);
|
||||
Wire.requestFrom(_address, 2);
|
||||
#if (ARDUINO >= 100)
|
||||
level = Wire.read();
|
||||
level <<= 8;
|
||||
level |= Wire.read();
|
||||
#else
|
||||
level = Wire.receive();
|
||||
level <<= 8;
|
||||
level |= Wire.receive();
|
||||
#endif
|
||||
if(Wire.endTransmission()!=0) {
|
||||
#if BH1750_DEBUG == 1
|
||||
Serial.println("I2C read error");
|
||||
#endif
|
||||
return 65535; // Error marker
|
||||
}
|
||||
|
||||
#if BH1750_DEBUG == 1
|
||||
Serial.print("Raw light level: ");
|
||||
Serial.println(level);
|
||||
#endif
|
||||
|
||||
_valueReaded=true;
|
||||
|
||||
return level;
|
||||
}
|
||||
|
||||
/**
|
||||
* Rechnet Roh-Werte in Lux um.
|
||||
*/
|
||||
float AS_BH1750A::convertRawValue(uint16_t raw) {
|
||||
// Basisumrechnung
|
||||
float flevel = raw/1.2;
|
||||
|
||||
#if BH1750_DEBUG == 1
|
||||
Serial.print("convert light level (1): ");
|
||||
Serial.println(flevel);
|
||||
#endif
|
||||
|
||||
// MTreg-Einfluss berechnen
|
||||
if(_MTreg!=BH1750_MTREG_DEFAULT) { // bei 69 ist der Faktor = 1
|
||||
flevel = flevel * _MTregFactor;
|
||||
#if BH1750_DEBUG == 1
|
||||
Serial.print("convert light level (2): ");
|
||||
Serial.println(flevel);
|
||||
#endif
|
||||
}
|
||||
|
||||
// je nach Modus ist eine weitere Umrechnung nötig
|
||||
switch (_hardwareMode) {
|
||||
case BH1750_CONTINUOUS_HIGH_RES_MODE_2:
|
||||
case BH1750_ONE_TIME_HIGH_RES_MODE_2:
|
||||
flevel = flevel/2;
|
||||
#if BH1750_DEBUG == 1
|
||||
Serial.print("convert light level (3): ");
|
||||
Serial.println(flevel);
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
// nothing to do
|
||||
break;
|
||||
}
|
||||
|
||||
#if BH1750_DEBUG == 1
|
||||
Serial.print("Light level: ");
|
||||
Serial.println(flevel);
|
||||
#endif
|
||||
|
||||
return flevel;
|
||||
}
|
||||
|
||||
/**
|
||||
* MTreg setzen. Definiert Empfindlichkeit des Sensors.
|
||||
* Min.Wert (BH1750_MTREG_MIN) = 31 (Empfindlichkeit: default*0,45)
|
||||
* Max.Wert (BH1750_MTREG_MAX) = 254 (Empfindlichkeit: default*3,68)
|
||||
* Default (BH1750_MTREG_DEFAULT) = 69.
|
||||
* Mit der Empfindlichkeit verändert sich die Lesezeit (höhere Empfindlichkeit bedeutet längere Zeitspanne).
|
||||
*/
|
||||
void AS_BH1750A::defineMTReg(uint8_t val) {
|
||||
if(val<BH1750_MTREG_MIN) {
|
||||
val = BH1750_MTREG_MIN;
|
||||
}
|
||||
if(val>BH1750_MTREG_MAX) {
|
||||
val = BH1750_MTREG_MAX;
|
||||
}
|
||||
if(val!=_MTreg) {
|
||||
_MTreg = val;
|
||||
_MTregFactor = (float)BH1750_MTREG_DEFAULT / _MTreg;
|
||||
|
||||
// Change Measurement time
|
||||
// Übertragung in zwei Schritten: 3 Bit und 5 Bit, jeweils mit einem Prefix.
|
||||
// High bit: 01000_MT[7,6,5]
|
||||
// Low bit: 011_MT[4,3,2,1,0]
|
||||
uint8_t hiByte = val>>5;
|
||||
hiByte |= 0b01000000;
|
||||
#if BH1750_DEBUG == 1
|
||||
Serial.print("MGTreg high byte: ");
|
||||
Serial.println(hiByte, BIN);
|
||||
#endif
|
||||
write8(hiByte);
|
||||
//fDelayPtr(10);
|
||||
// Pause nötig?
|
||||
uint8_t loByte = val&0b00011111;
|
||||
loByte |= 0b01100000;
|
||||
#if BH1750_DEBUG == 1
|
||||
Serial.print("MGTreg low byte: ");
|
||||
Serial.println(loByte, BIN);
|
||||
#endif
|
||||
write8(hiByte);
|
||||
//fDelayPtr(10);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gibt an, ob der Sensor initialisiert ist.
|
||||
*/
|
||||
bool AS_BH1750A::isInitialized() {
|
||||
return _hardwareMode!=255;
|
||||
}
|
||||
|
||||
/**
|
||||
* Schreibt ein Byte auf I2C Bus (auf die Adresse des Sensors).
|
||||
*/
|
||||
bool AS_BH1750A::write8(uint8_t d) {
|
||||
Wire.beginTransmission(_address);
|
||||
#if (ARDUINO >= 100)
|
||||
Wire.write(d);
|
||||
#else
|
||||
Wire.send(d);
|
||||
#endif
|
||||
return (Wire.endTransmission()==0);
|
||||
}
|
||||
|
||||
|
||||
float AS_BH1750A::readLightLevel(DelayFuncPtr fDelayPtr, TimeFuncPtr fTimePtr) {
|
||||
startMeasurementAsync(fTimePtr);
|
||||
while(!isMeasurementReady()) {
|
||||
fDelayPtr(_nextDelay);
|
||||
}
|
||||
return readLightLevelAsync();
|
||||
}
|
||||
|
||||
/*float AS_BH1750A::checkAndReadLightLevelAsync(TimeFuncPtr fTimePtr) {
|
||||
//Serial.print("--stage: ");
|
||||
//Serial.println(_stage);
|
||||
if(_stage==0 || _stage>=100) {
|
||||
if(startMeasurementAsync(fTimePtr)) return -100;
|
||||
return -1; // Marker "nicht vorhanden"
|
||||
} else if(_stage==99) {
|
||||
_stage=100;
|
||||
return readLightLevelAsync();
|
||||
}
|
||||
return readLightLevelAsync();
|
||||
}*/
|
||||
|
||||
unsigned long AS_BH1750A::nextDelay(void) {
|
||||
return _nextDelay;
|
||||
}
|
||||
//void AS_BH1750A::reset(void) {
|
||||
//_stage==0;
|
||||
//}
|
||||
|
||||
bool AS_BH1750A::startMeasurementAsync(TimeFuncPtr fTimePtr) {
|
||||
_fTimePtr = fTimePtr;
|
||||
_stage = 0;
|
||||
_nextDelay = 0;
|
||||
int _lastResult = -1;
|
||||
_lastTimestamp=fTimePtr();
|
||||
return readLightLevelAsync()!=-1;
|
||||
}
|
||||
|
||||
bool AS_BH1750A::isMeasurementReady(void) {
|
||||
return readLightLevelAsync() >= -1; // -1 ist 'not initialized'-Marker (prevent hangs)
|
||||
}
|
||||
|
||||
bool AS_BH1750A::delayExpired() {
|
||||
unsigned long timestamp = _fTimePtr();
|
||||
|
||||
// Zeitdifferenz
|
||||
unsigned long delayTime = 0;
|
||||
// Auf Ueberlauf pruefen
|
||||
if (timestamp < _lastTimestamp)
|
||||
{
|
||||
// Ueberlauf: Delay ist Zeit zum MaxWert plus Zeit ab Null
|
||||
delayTime = MAX_U_LONG - _lastTimestamp + timestamp;
|
||||
} else {
|
||||
// Kein Ueberlauf: einfache Differenz
|
||||
delayTime = timestamp - _lastTimestamp;
|
||||
}
|
||||
|
||||
return (delayTime >= _nextDelay);
|
||||
}
|
||||
|
||||
float AS_BH1750A::readLightLevelAsync() {
|
||||
if(_stage>=99) return _lastResult;
|
||||
|
||||
if(_stage==0) {
|
||||
#if BH1750_DEBUG == 1
|
||||
Serial.print("call: readLightLevel. virtualMode: ");
|
||||
Serial.println(_virtualMode, DEC);
|
||||
#endif
|
||||
|
||||
if(!isInitialized()) {
|
||||
#if BH1750_DEBUG == 1
|
||||
Serial.println("sensor not initialized");
|
||||
#endif
|
||||
return -1;
|
||||
}
|
||||
|
||||
// ggf. PowerOn
|
||||
if(_autoPowerDown && _valueReaded){
|
||||
powerOn();
|
||||
_nextDelay = getModeDelay();
|
||||
// TEST delay(getModeDelay());_stage=99;
|
||||
return -100;
|
||||
} else {
|
||||
_nextDelay = 0;
|
||||
}
|
||||
_stage++;
|
||||
|
||||
}
|
||||
|
||||
// Das Automatische Modus benötigt eine Sonderbehandlung.
|
||||
// Zuerst wird die Helligkeit im LowRes-Modus gelesen,
|
||||
// je nach Bereich (dunkel, normal, sehr hell) werden die Werte von MTreg gesetzt und
|
||||
// danach wird die eigentliche Messung vorgenommen.
|
||||
/*
|
||||
Die feste Grenzwerte verursachen möglicherweise einen 'Sprung' in der Messkurve.
|
||||
In diesem Fall wäre eine laufende Anpassung von MTreg in Grenzbereichen vermutlich besser.
|
||||
Für meine Zwecke ist das jedoch ohne Bedeutung.
|
||||
*/
|
||||
if(_virtualMode==RESOLUTION_AUTO_HIGH) {
|
||||
selectAutoMode();
|
||||
} else {
|
||||
if(delayExpired()) {_stage=99;} // Fertig
|
||||
}
|
||||
if(_stage<99) return -100; // Marker: wait for next step
|
||||
|
||||
// Hardware Wert lesen und in Lux umrechnen.
|
||||
uint16_t raw = readRawLevel();
|
||||
if(raw==65535) {
|
||||
// Wert verdächtig hoch. Sensor prüfen.
|
||||
// Check I2C Adresse
|
||||
Wire.beginTransmission(_address);
|
||||
if(Wire.endTransmission()!=0) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
_lastResult = convertRawValue(raw);
|
||||
return _lastResult;
|
||||
}
|
||||
|
||||
void AS_BH1750A::selectAutoMode() {
|
||||
|
||||
//if(!delayExpired()) return;
|
||||
|
||||
if(_stage==1) {
|
||||
defineMTReg(BH1750_MTREG_DEFAULT);
|
||||
selectResolutionMode(BH1750_CONTINUOUS_LOW_RES_MODE);
|
||||
//fDelayPtr(16+5); // Lesezeit in LowResMode
|
||||
//fDelayPtr(getModeDelay());
|
||||
_nextDelay=getModeDelay();
|
||||
_stage++;
|
||||
return;
|
||||
}
|
||||
|
||||
if(!delayExpired()) return;
|
||||
|
||||
if(_stage==2) {
|
||||
uint16_t level = readRawLevel();
|
||||
#if BH1750_DEBUG == 1
|
||||
Serial.print("AutoHighMode: check level read: ");
|
||||
Serial.println(level, DEC);
|
||||
#endif
|
||||
if(level<10) {
|
||||
#if BH1750_DEBUG == 1
|
||||
Serial.println("level 0: dark");
|
||||
#endif
|
||||
// Dunkel, Empfindlichkeit auf Maximum.
|
||||
// Der Wert ist zufällig. Ab ca. 16000 wäre diese Vorgehnsweise möglich.
|
||||
// Ich brauche diese Genauigkeit aber nur in den ganz dunklen Bereichen (zu erkennen, wann wirklich 'dunkel' ist).
|
||||
defineMTReg(BH1750_MTREG_MAX);
|
||||
selectResolutionMode(_autoPowerDown?BH1750_ONE_TIME_HIGH_RES_MODE_2:BH1750_CONTINUOUS_HIGH_RES_MODE_2);
|
||||
//fDelayPtr(120*3.68+5); // TODO: Wert prüfen
|
||||
//fDelayPtr(getModeDelay());
|
||||
_nextDelay=getModeDelay();
|
||||
//fDelayPtr(122);
|
||||
} else if(level<32767) {
|
||||
#if BH1750_DEBUG == 1
|
||||
Serial.println("level 1: normal");
|
||||
#endif
|
||||
// Bis hierher reicht die 0,5 lx Modus. Normale Empfindlichkeit.
|
||||
defineMTReg(BH1750_MTREG_DEFAULT);
|
||||
selectResolutionMode(_autoPowerDown?BH1750_ONE_TIME_HIGH_RES_MODE_2:BH1750_CONTINUOUS_HIGH_RES_MODE_2);
|
||||
//fDelayPtr(120+5); // TODO: Wert prüfen
|
||||
//fDelayPtr(getModeDelay());
|
||||
_nextDelay=getModeDelay();
|
||||
} else if(level<60000) {
|
||||
#if BH1750_DEBUG == 1
|
||||
Serial.println("level 2: bright");
|
||||
#endif
|
||||
// hoher Bereich, 1 lx Modus, normale Empfindlichkeit. Der Wert von 60000 ist mehr oder weniger zufällig, es mus einfach ein hoher Wert, nah an der Grenze sein.
|
||||
defineMTReg(BH1750_MTREG_DEFAULT);
|
||||
selectResolutionMode(_autoPowerDown?BH1750_ONE_TIME_HIGH_RES_MODE:BH1750_CONTINUOUS_HIGH_RES_MODE);
|
||||
//fDelayPtr(120+5); // TODO: Wert prüfen
|
||||
//fDelayPtr(getModeDelay());
|
||||
_nextDelay=getModeDelay();
|
||||
} else {
|
||||
#if BH1750_DEBUG == 1
|
||||
Serial.println("level 3: very bright");
|
||||
#endif
|
||||
// sehr hoher Bereich, Empfindlichkeit verringern
|
||||
defineMTReg(32); // Min+1, bei dem Minimum aus Doku spielt der Sensor (zumindest meiner) verrückt: Die Werte sind ca. 1/10 von den Erwarteten.
|
||||
selectResolutionMode(_autoPowerDown?BH1750_ONE_TIME_HIGH_RES_MODE:BH1750_CONTINUOUS_HIGH_RES_MODE);
|
||||
//fDelayPtr(120+5); // TODO: Wert prüfen
|
||||
//fDelayPtr(getModeDelay());
|
||||
_nextDelay=getModeDelay();
|
||||
}
|
||||
|
||||
_stage++;
|
||||
return;
|
||||
}
|
||||
|
||||
_stage = 99; // fertig
|
||||
|
||||
}
|
||||
|
||||
unsigned long AS_BH1750A::getModeDelay() {
|
||||
|
||||
float ml;
|
||||
|
||||
if(_MTreg<=BH1750_MTREG_MIN+1) { ml = 0.45; }
|
||||
else if(_MTreg<=BH1750_MTREG_DEFAULT+1) { ml = 1.0; }
|
||||
else { ml = 3.68; }
|
||||
|
||||
switch (_hardwareMode) {
|
||||
case BH1750_CONTINUOUS_HIGH_RES_MODE:
|
||||
case BH1750_ONE_TIME_HIGH_RES_MODE:
|
||||
return ml*120+5;
|
||||
|
||||
case BH1750_ONE_TIME_HIGH_RES_MODE_2:
|
||||
case BH1750_CONTINUOUS_HIGH_RES_MODE_2:
|
||||
return ml*120+5;
|
||||
|
||||
case BH1750_CONTINUOUS_LOW_RES_MODE:
|
||||
case BH1750_ONE_TIME_LOW_RES_MODE:
|
||||
return ml*16+5;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,207 @@
|
||||
/*
|
||||
This is a (Arduino) library for the BH1750FVI Digital Light Sensor.
|
||||
|
||||
Description:
|
||||
http://www.rohm.com/web/global/products/-/product/BH1750FVI
|
||||
|
||||
Datasheet:
|
||||
http://rohmfs.rohm.com/en/products/databook/datasheet/ic/sensor/light/bh1750fvi-e.pdf
|
||||
|
||||
Copyright (c) 2013 Alexander Schulz. All right reserved.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef AS_BH1750A_h
|
||||
#define AS_BH1750A_h
|
||||
|
||||
#if (ARDUINO >= 100)
|
||||
#include <Arduino.h>
|
||||
#else
|
||||
#include <WProgram.h>
|
||||
#endif
|
||||
#include "Wire.h"
|
||||
|
||||
// Mögliche I2C Adressen
|
||||
#define BH1750_DEFAULT_I2CADDR 0x23
|
||||
#define BH1750_SECOND_I2CADDR 0x5C
|
||||
|
||||
// MTreg Werte
|
||||
// Default
|
||||
#define BH1750_MTREG_DEFAULT 69
|
||||
// Sensitivity : default = 0.45
|
||||
#define BH1750_MTREG_MIN 31
|
||||
// Sensitivity : default = 3.68
|
||||
#define BH1750_MTREG_MAX 254
|
||||
|
||||
// Hardware Modi
|
||||
// No active state
|
||||
#define BH1750_POWER_DOWN 0x00
|
||||
|
||||
// Wating for measurment command
|
||||
#define BH1750_POWER_ON 0x01
|
||||
|
||||
// Reset data register value - not accepted in POWER_DOWN mode
|
||||
#define BH1750_RESET 0x07
|
||||
|
||||
// Start measurement at 1lx resolution. Measurement time is approx 120ms.
|
||||
#define BH1750_CONTINUOUS_HIGH_RES_MODE 0x10
|
||||
|
||||
// Start measurement at 0.5lx resolution. Measurement time is approx 120ms.
|
||||
#define BH1750_CONTINUOUS_HIGH_RES_MODE_2 0x11
|
||||
|
||||
// Start measurement at 4lx resolution. Measurement time is approx 16ms.
|
||||
#define BH1750_CONTINUOUS_LOW_RES_MODE 0x13
|
||||
|
||||
// Start measurement at 1lx resolution. Measurement time is approx 120ms.
|
||||
// Device is automatically set to Power Down after measurement.
|
||||
#define BH1750_ONE_TIME_HIGH_RES_MODE 0x20
|
||||
|
||||
// Start measurement at 0.5lx resolution. Measurement time is approx 120ms.
|
||||
// Device is automatically set to Power Down after measurement.
|
||||
#define BH1750_ONE_TIME_HIGH_RES_MODE_2 0x21
|
||||
|
||||
// Start measurement at 1lx resolution. Measurement time is approx 120ms.
|
||||
// Device is automatically set to Power Down after measurement.
|
||||
#define BH1750_ONE_TIME_LOW_RES_MODE 0x23
|
||||
|
||||
#define MAX_U_LONG 4294967295;
|
||||
|
||||
/** Virtual Modi */
|
||||
typedef enum
|
||||
{
|
||||
RESOLUTION_LOW = (1), /** 4lx resolution. Measurement time is approx 16ms. */
|
||||
RESOLUTION_NORMAL = (2), /** 1lx resolution. Measurement time is approx 120ms. */
|
||||
RESOLUTION_HIGH = (3), /** 0,5lx resolution. Measurement time is approx 120ms. */
|
||||
RESOLUTION_AUTO_HIGH = (99) /** 0,11-1lx resolution. Measurement time is above 250ms. */
|
||||
}
|
||||
sensors_resolution_t;
|
||||
|
||||
typedef void (*DelayFuncPtr)(unsigned long);
|
||||
typedef unsigned long (*TimeFuncPtr)(void);
|
||||
|
||||
/**
|
||||
* BH1750 driver class.
|
||||
*/
|
||||
class AS_BH1750A {
|
||||
public:
|
||||
/**
|
||||
* Constructor.
|
||||
* Erlaubt die I2C-Adresse des Sensors zu ändern.
|
||||
* Standardadresse: 0x23, Alternativadresse: 0x5C.
|
||||
* Es sind entsprechende Konstanten definiert: BH1750_DEFAULT_I2CADDR und BH1750_SECOND_I2CADDR.
|
||||
* Bei Nichtangabe wird die Standardadresse verwendet.
|
||||
* Um die Alternativadresse zu nutzen, muss der Sensorpin 'ADR' des Chips auf VCC gelegt werden.
|
||||
*/
|
||||
AS_BH1750A(uint8_t address = BH1750_DEFAULT_I2CADDR);
|
||||
|
||||
/**
|
||||
* Führt die anfängliche Initialisierung des Sensors.
|
||||
* Mögliche Parameter:
|
||||
* - Modus für die Sensorauflösung:
|
||||
* -- RESOLUTION_LOW: Physische Sensormodus mit 4 lx Auflösung. Messzeit ca. 16ms. Bereich 0-54612.
|
||||
* -- RESOLUTION_NORMAL: Physische Sensormodus mit 1 lx Auflösung. Messzeit ca. 120ms. Bereich 0-54612.
|
||||
* -- RESOLUTION_HIGH: Physische Sensormodus mit 0,5 lx Auflösung. Messzeit ca. 120ms. Bereich 0-54612.
|
||||
* (Die Messbereiche können durch Änderung des MTreg verschoben werden.)
|
||||
* -- RESOLUTION_AUTO_HIGH: Die Werte im MTreg werden je nach Helligkeit automatisch so angepasst,
|
||||
* dass eine maximalmögliche Auflösung und Messbereich erziehlt werden.
|
||||
* Die messbaren Werte fangen von 0,11 lx und gehen bis über 100000 lx.
|
||||
* (ich weis nicht, wie genau die Werte in Grenzbereichen sind,
|
||||
* besonders bei hohen Werte habe ich meine Zweifel.)
|
||||
* Auflösung im Unteren Bereich 0,13 lx, im mittleren 0,5 lx, im oberen 1-2 lx.
|
||||
* Die Messzeiten verlängern sich durch mehrfache Messungen und
|
||||
* die Änderungen von Measurement Time (MTreg) bis max. ca. 500 ms.
|
||||
*
|
||||
* - AutoPowerDown: true = Der Sensor wird nach der Messung in den Stromsparmodus versetzt.
|
||||
* Das spätere Aufwecken wird ggf. automatisch vorgenommen, braucht jedoch geringfügig mehr Zeit.
|
||||
*
|
||||
* Defaultwerte: RESOLUTION_AUTO_HIGH, true, delay()
|
||||
*
|
||||
*/
|
||||
bool begin(sensors_resolution_t mode = RESOLUTION_AUTO_HIGH, bool autoPowerDown = true);
|
||||
|
||||
/**
|
||||
* Erlaub eine Prüfung, ob ein (ansprechbarer) BH1750-Sensor vorhanden ist.
|
||||
*/
|
||||
bool isPresent(void);
|
||||
|
||||
/**
|
||||
* Liefert aktuell gemessenen Wert für Helligkeit in lux (lx).
|
||||
* Falls sich der Sensorf in Stromsparmodus befindet, wird er automatisch geweckt.
|
||||
*
|
||||
* Wurde der Sensor (noch) nicht initialisiert (begin), wird der Wert -1 geliefert.
|
||||
*
|
||||
* Mögliche Parameter:
|
||||
*
|
||||
* - DelayFuncPtr: delay(n) Möglichkeit, eigene Delay-Funktion mitzugeben (z.B. um sleep-Modus zu verwenden).
|
||||
*
|
||||
* Defaultwerte: delay()
|
||||
*
|
||||
*/
|
||||
float readLightLevel(DelayFuncPtr fDelayPtr = &delay, TimeFuncPtr fTimePtr = &millis);
|
||||
|
||||
bool startMeasurementAsync(TimeFuncPtr fTimePtr = &millis);
|
||||
bool isMeasurementReady(void);
|
||||
float readLightLevelAsync();
|
||||
|
||||
//float checkAndReadLightLevelAsync(TimeFuncPtr fTimePtr);
|
||||
|
||||
//void reset(void);
|
||||
unsigned long nextDelay(void);
|
||||
|
||||
/**
|
||||
* Schickt den Sensor in Stromsparmodus.
|
||||
* Funktionier nur, wenn der Sensor bereits initialisiert wurde.
|
||||
*/
|
||||
void powerDown(void);
|
||||
|
||||
//bool delayExpired(); // TEST
|
||||
|
||||
private:
|
||||
int _address;
|
||||
uint8_t _hardwareMode;
|
||||
|
||||
uint8_t _MTreg;
|
||||
float _MTregFactor;
|
||||
|
||||
sensors_resolution_t _virtualMode;
|
||||
bool _autoPowerDown;
|
||||
|
||||
bool _valueReaded;
|
||||
|
||||
bool selectResolutionMode(uint8_t mode);
|
||||
void defineMTReg(uint8_t val);
|
||||
void powerOn();
|
||||
//void reset(void);
|
||||
uint16_t readRawLevel(void);
|
||||
float convertRawValue(uint16_t raw);
|
||||
bool isInitialized();
|
||||
bool write8(uint8_t data);
|
||||
|
||||
TimeFuncPtr _fTimePtr;
|
||||
int _stage = 0;
|
||||
int _nextDelay = 0;
|
||||
int _lastTimestamp = 0;
|
||||
float _lastResult = -100;
|
||||
bool delayExpired();
|
||||
void selectAutoMode();
|
||||
|
||||
// TEST
|
||||
//float readLightLevel_alt(DelayFuncPtr fDelayPtr = &delay);
|
||||
unsigned long getModeDelay();
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,502 @@
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 2.1, February 1999
|
||||
|
||||
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
[This is the first released version of the Lesser GPL. It also counts
|
||||
as the successor of the GNU Library Public License, version 2, hence
|
||||
the version number 2.1.]
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
Licenses are intended to guarantee your freedom to share and change
|
||||
free software--to make sure the software is free for all its users.
|
||||
|
||||
This license, the Lesser General Public License, applies to some
|
||||
specially designated software packages--typically libraries--of the
|
||||
Free Software Foundation and other authors who decide to use it. You
|
||||
can use it too, but we suggest you first think carefully about whether
|
||||
this license or the ordinary General Public License is the better
|
||||
strategy to use in any particular case, based on the explanations below.
|
||||
|
||||
When we speak of free software, we are referring to freedom of use,
|
||||
not price. Our General Public Licenses are designed to make sure that
|
||||
you have the freedom to distribute copies of free software (and charge
|
||||
for this service if you wish); that you receive source code or can get
|
||||
it if you want it; that you can change the software and use pieces of
|
||||
it in new free programs; and that you are informed that you can do
|
||||
these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
distributors to deny you these rights or to ask you to surrender these
|
||||
rights. These restrictions translate to certain responsibilities for
|
||||
you if you distribute copies of the library or if you modify it.
|
||||
|
||||
For example, if you distribute copies of the library, whether gratis
|
||||
or for a fee, you must give the recipients all the rights that we gave
|
||||
you. You must make sure that they, too, receive or can get the source
|
||||
code. If you link other code with the library, you must provide
|
||||
complete object files to the recipients, so that they can relink them
|
||||
with the library after making changes to the library and recompiling
|
||||
it. And you must show them these terms so they know their rights.
|
||||
|
||||
We protect your rights with a two-step method: (1) we copyright the
|
||||
library, and (2) we offer you this license, which gives you legal
|
||||
permission to copy, distribute and/or modify the library.
|
||||
|
||||
To protect each distributor, we want to make it very clear that
|
||||
there is no warranty for the free library. Also, if the library is
|
||||
modified by someone else and passed on, the recipients should know
|
||||
that what they have is not the original version, so that the original
|
||||
author's reputation will not be affected by problems that might be
|
||||
introduced by others.
|
||||
|
||||
Finally, software patents pose a constant threat to the existence of
|
||||
any free program. We wish to make sure that a company cannot
|
||||
effectively restrict the users of a free program by obtaining a
|
||||
restrictive license from a patent holder. Therefore, we insist that
|
||||
any patent license obtained for a version of the library must be
|
||||
consistent with the full freedom of use specified in this license.
|
||||
|
||||
Most GNU software, including some libraries, is covered by the
|
||||
ordinary GNU General Public License. This license, the GNU Lesser
|
||||
General Public License, applies to certain designated libraries, and
|
||||
is quite different from the ordinary General Public License. We use
|
||||
this license for certain libraries in order to permit linking those
|
||||
libraries into non-free programs.
|
||||
|
||||
When a program is linked with a library, whether statically or using
|
||||
a shared library, the combination of the two is legally speaking a
|
||||
combined work, a derivative of the original library. The ordinary
|
||||
General Public License therefore permits such linking only if the
|
||||
entire combination fits its criteria of freedom. The Lesser General
|
||||
Public License permits more lax criteria for linking other code with
|
||||
the library.
|
||||
|
||||
We call this license the "Lesser" General Public License because it
|
||||
does Less to protect the user's freedom than the ordinary General
|
||||
Public License. It also provides other free software developers Less
|
||||
of an advantage over competing non-free programs. These disadvantages
|
||||
are the reason we use the ordinary General Public License for many
|
||||
libraries. However, the Lesser license provides advantages in certain
|
||||
special circumstances.
|
||||
|
||||
For example, on rare occasions, there may be a special need to
|
||||
encourage the widest possible use of a certain library, so that it becomes
|
||||
a de-facto standard. To achieve this, non-free programs must be
|
||||
allowed to use the library. A more frequent case is that a free
|
||||
library does the same job as widely used non-free libraries. In this
|
||||
case, there is little to gain by limiting the free library to free
|
||||
software only, so we use the Lesser General Public License.
|
||||
|
||||
In other cases, permission to use a particular library in non-free
|
||||
programs enables a greater number of people to use a large body of
|
||||
free software. For example, permission to use the GNU C Library in
|
||||
non-free programs enables many more people to use the whole GNU
|
||||
operating system, as well as its variant, the GNU/Linux operating
|
||||
system.
|
||||
|
||||
Although the Lesser General Public License is Less protective of the
|
||||
users' freedom, it does ensure that the user of a program that is
|
||||
linked with the Library has the freedom and the wherewithal to run
|
||||
that program using a modified version of the Library.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow. Pay close attention to the difference between a
|
||||
"work based on the library" and a "work that uses the library". The
|
||||
former contains code derived from the library, whereas the latter must
|
||||
be combined with the library in order to run.
|
||||
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License Agreement applies to any software library or other
|
||||
program which contains a notice placed by the copyright holder or
|
||||
other authorized party saying it may be distributed under the terms of
|
||||
this Lesser General Public License (also called "this License").
|
||||
Each licensee is addressed as "you".
|
||||
|
||||
A "library" means a collection of software functions and/or data
|
||||
prepared so as to be conveniently linked with application programs
|
||||
(which use some of those functions and data) to form executables.
|
||||
|
||||
The "Library", below, refers to any such software library or work
|
||||
which has been distributed under these terms. A "work based on the
|
||||
Library" means either the Library or any derivative work under
|
||||
copyright law: that is to say, a work containing the Library or a
|
||||
portion of it, either verbatim or with modifications and/or translated
|
||||
straightforwardly into another language. (Hereinafter, translation is
|
||||
included without limitation in the term "modification".)
|
||||
|
||||
"Source code" for a work means the preferred form of the work for
|
||||
making modifications to it. For a library, complete source code means
|
||||
all the source code for all modules it contains, plus any associated
|
||||
interface definition files, plus the scripts used to control compilation
|
||||
and installation of the library.
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running a program using the Library is not restricted, and output from
|
||||
such a program is covered only if its contents constitute a work based
|
||||
on the Library (independent of the use of the Library in a tool for
|
||||
writing it). Whether that is true depends on what the Library does
|
||||
and what the program that uses the Library does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Library's
|
||||
complete source code as you receive it, in any medium, provided that
|
||||
you conspicuously and appropriately publish on each copy an
|
||||
appropriate copyright notice and disclaimer of warranty; keep intact
|
||||
all the notices that refer to this License and to the absence of any
|
||||
warranty; and distribute a copy of this License along with the
|
||||
Library.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy,
|
||||
and you may at your option offer warranty protection in exchange for a
|
||||
fee.
|
||||
|
||||
2. You may modify your copy or copies of the Library or any portion
|
||||
of it, thus forming a work based on the Library, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) The modified work must itself be a software library.
|
||||
|
||||
b) You must cause the files modified to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
c) You must cause the whole of the work to be licensed at no
|
||||
charge to all third parties under the terms of this License.
|
||||
|
||||
d) If a facility in the modified Library refers to a function or a
|
||||
table of data to be supplied by an application program that uses
|
||||
the facility, other than as an argument passed when the facility
|
||||
is invoked, then you must make a good faith effort to ensure that,
|
||||
in the event an application does not supply such function or
|
||||
table, the facility still operates, and performs whatever part of
|
||||
its purpose remains meaningful.
|
||||
|
||||
(For example, a function in a library to compute square roots has
|
||||
a purpose that is entirely well-defined independent of the
|
||||
application. Therefore, Subsection 2d requires that any
|
||||
application-supplied function or table used by this function must
|
||||
be optional: if the application does not supply it, the square
|
||||
root function must still compute square roots.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Library,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Library, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote
|
||||
it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Library.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Library
|
||||
with the Library (or with a work based on the Library) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may opt to apply the terms of the ordinary GNU General Public
|
||||
License instead of this License to a given copy of the Library. To do
|
||||
this, you must alter all the notices that refer to this License, so
|
||||
that they refer to the ordinary GNU General Public License, version 2,
|
||||
instead of to this License. (If a newer version than version 2 of the
|
||||
ordinary GNU General Public License has appeared, then you can specify
|
||||
that version instead if you wish.) Do not make any other change in
|
||||
these notices.
|
||||
|
||||
Once this change is made in a given copy, it is irreversible for
|
||||
that copy, so the ordinary GNU General Public License applies to all
|
||||
subsequent copies and derivative works made from that copy.
|
||||
|
||||
This option is useful when you wish to copy part of the code of
|
||||
the Library into a program that is not a library.
|
||||
|
||||
4. You may copy and distribute the Library (or a portion or
|
||||
derivative of it, under Section 2) in object code or executable form
|
||||
under the terms of Sections 1 and 2 above provided that you accompany
|
||||
it with the complete corresponding machine-readable source code, which
|
||||
must be distributed under the terms of Sections 1 and 2 above on a
|
||||
medium customarily used for software interchange.
|
||||
|
||||
If distribution of object code is made by offering access to copy
|
||||
from a designated place, then offering equivalent access to copy the
|
||||
source code from the same place satisfies the requirement to
|
||||
distribute the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
5. A program that contains no derivative of any portion of the
|
||||
Library, but is designed to work with the Library by being compiled or
|
||||
linked with it, is called a "work that uses the Library". Such a
|
||||
work, in isolation, is not a derivative work of the Library, and
|
||||
therefore falls outside the scope of this License.
|
||||
|
||||
However, linking a "work that uses the Library" with the Library
|
||||
creates an executable that is a derivative of the Library (because it
|
||||
contains portions of the Library), rather than a "work that uses the
|
||||
library". The executable is therefore covered by this License.
|
||||
Section 6 states terms for distribution of such executables.
|
||||
|
||||
When a "work that uses the Library" uses material from a header file
|
||||
that is part of the Library, the object code for the work may be a
|
||||
derivative work of the Library even though the source code is not.
|
||||
Whether this is true is especially significant if the work can be
|
||||
linked without the Library, or if the work is itself a library. The
|
||||
threshold for this to be true is not precisely defined by law.
|
||||
|
||||
If such an object file uses only numerical parameters, data
|
||||
structure layouts and accessors, and small macros and small inline
|
||||
functions (ten lines or less in length), then the use of the object
|
||||
file is unrestricted, regardless of whether it is legally a derivative
|
||||
work. (Executables containing this object code plus portions of the
|
||||
Library will still fall under Section 6.)
|
||||
|
||||
Otherwise, if the work is a derivative of the Library, you may
|
||||
distribute the object code for the work under the terms of Section 6.
|
||||
Any executables containing that work also fall under Section 6,
|
||||
whether or not they are linked directly with the Library itself.
|
||||
|
||||
6. As an exception to the Sections above, you may also combine or
|
||||
link a "work that uses the Library" with the Library to produce a
|
||||
work containing portions of the Library, and distribute that work
|
||||
under terms of your choice, provided that the terms permit
|
||||
modification of the work for the customer's own use and reverse
|
||||
engineering for debugging such modifications.
|
||||
|
||||
You must give prominent notice with each copy of the work that the
|
||||
Library is used in it and that the Library and its use are covered by
|
||||
this License. You must supply a copy of this License. If the work
|
||||
during execution displays copyright notices, you must include the
|
||||
copyright notice for the Library among them, as well as a reference
|
||||
directing the user to the copy of this License. Also, you must do one
|
||||
of these things:
|
||||
|
||||
a) Accompany the work with the complete corresponding
|
||||
machine-readable source code for the Library including whatever
|
||||
changes were used in the work (which must be distributed under
|
||||
Sections 1 and 2 above); and, if the work is an executable linked
|
||||
with the Library, with the complete machine-readable "work that
|
||||
uses the Library", as object code and/or source code, so that the
|
||||
user can modify the Library and then relink to produce a modified
|
||||
executable containing the modified Library. (It is understood
|
||||
that the user who changes the contents of definitions files in the
|
||||
Library will not necessarily be able to recompile the application
|
||||
to use the modified definitions.)
|
||||
|
||||
b) Use a suitable shared library mechanism for linking with the
|
||||
Library. A suitable mechanism is one that (1) uses at run time a
|
||||
copy of the library already present on the user's computer system,
|
||||
rather than copying library functions into the executable, and (2)
|
||||
will operate properly with a modified version of the library, if
|
||||
the user installs one, as long as the modified version is
|
||||
interface-compatible with the version that the work was made with.
|
||||
|
||||
c) Accompany the work with a written offer, valid for at
|
||||
least three years, to give the same user the materials
|
||||
specified in Subsection 6a, above, for a charge no more
|
||||
than the cost of performing this distribution.
|
||||
|
||||
d) If distribution of the work is made by offering access to copy
|
||||
from a designated place, offer equivalent access to copy the above
|
||||
specified materials from the same place.
|
||||
|
||||
e) Verify that the user has already received a copy of these
|
||||
materials or that you have already sent this user a copy.
|
||||
|
||||
For an executable, the required form of the "work that uses the
|
||||
Library" must include any data and utility programs needed for
|
||||
reproducing the executable from it. However, as a special exception,
|
||||
the materials to be distributed need not include anything that is
|
||||
normally distributed (in either source or binary form) with the major
|
||||
components (compiler, kernel, and so on) of the operating system on
|
||||
which the executable runs, unless that component itself accompanies
|
||||
the executable.
|
||||
|
||||
It may happen that this requirement contradicts the license
|
||||
restrictions of other proprietary libraries that do not normally
|
||||
accompany the operating system. Such a contradiction means you cannot
|
||||
use both them and the Library together in an executable that you
|
||||
distribute.
|
||||
|
||||
7. You may place library facilities that are a work based on the
|
||||
Library side-by-side in a single library together with other library
|
||||
facilities not covered by this License, and distribute such a combined
|
||||
library, provided that the separate distribution of the work based on
|
||||
the Library and of the other library facilities is otherwise
|
||||
permitted, and provided that you do these two things:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work
|
||||
based on the Library, uncombined with any other library
|
||||
facilities. This must be distributed under the terms of the
|
||||
Sections above.
|
||||
|
||||
b) Give prominent notice with the combined library of the fact
|
||||
that part of it is a work based on the Library, and explaining
|
||||
where to find the accompanying uncombined form of the same work.
|
||||
|
||||
8. You may not copy, modify, sublicense, link with, or distribute
|
||||
the Library except as expressly provided under this License. Any
|
||||
attempt otherwise to copy, modify, sublicense, link with, or
|
||||
distribute the Library is void, and will automatically terminate your
|
||||
rights under this License. However, parties who have received copies,
|
||||
or rights, from you under this License will not have their licenses
|
||||
terminated so long as such parties remain in full compliance.
|
||||
|
||||
9. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Library or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Library (or any work based on the
|
||||
Library), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Library or works based on it.
|
||||
|
||||
10. Each time you redistribute the Library (or any work based on the
|
||||
Library), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute, link with or modify the Library
|
||||
subject to these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties with
|
||||
this License.
|
||||
|
||||
11. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Library at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Library by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Library.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under any
|
||||
particular circumstance, the balance of the section is intended to apply,
|
||||
and the section as a whole is intended to apply in other circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
12. If the distribution and/or use of the Library is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Library under this License may add
|
||||
an explicit geographical distribution limitation excluding those countries,
|
||||
so that distribution is permitted only in or among countries not thus
|
||||
excluded. In such case, this License incorporates the limitation as if
|
||||
written in the body of this License.
|
||||
|
||||
13. The Free Software Foundation may publish revised and/or new
|
||||
versions of the Lesser General Public License from time to time.
|
||||
Such new versions will be similar in spirit to the present version,
|
||||
but may differ in detail to address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Library
|
||||
specifies a version number of this License which applies to it and
|
||||
"any later version", you have the option of following the terms and
|
||||
conditions either of that version or of any later version published by
|
||||
the Free Software Foundation. If the Library does not specify a
|
||||
license version number, you may choose any version ever published by
|
||||
the Free Software Foundation.
|
||||
|
||||
14. If you wish to incorporate parts of the Library into other free
|
||||
programs whose distribution conditions are incompatible with these,
|
||||
write to the author to ask for permission. For software which is
|
||||
copyrighted by the Free Software Foundation, write to the Free
|
||||
Software Foundation; we sometimes make exceptions for this. Our
|
||||
decision will be guided by the two goals of preserving the free status
|
||||
of all derivatives of our free software and of promoting the sharing
|
||||
and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
|
||||
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
|
||||
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
|
||||
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
|
||||
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
|
||||
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
|
||||
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
|
||||
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
|
||||
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
|
||||
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
|
||||
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
|
||||
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
|
||||
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
|
||||
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
|
||||
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||
DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Libraries
|
||||
|
||||
If you develop a new library, and you want it to be of the greatest
|
||||
possible use to the public, we recommend making it free software that
|
||||
everyone can redistribute and change. You can do so by permitting
|
||||
redistribution under these terms (or, alternatively, under the terms of the
|
||||
ordinary General Public License).
|
||||
|
||||
To apply these terms, attach the following notices to the library. It is
|
||||
safest to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least the
|
||||
"copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
a (Arduino) library for the BH1750FVI Digital Light Sensor
|
||||
Copyright (C) 2013 Alex Hexenmeister
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the library, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the
|
||||
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
|
||||
|
||||
{signature of Ty Coon}, 1 April 1990
|
||||
Ty Coon, President of Vice
|
||||
|
||||
That's all there is to it!
|
||||
@@ -0,0 +1,37 @@
|
||||
AS_BH1750
|
||||
=========
|
||||
|
||||
a (Arduino) library for the BH1750FVI Digital Light Sensor.
|
||||
|
||||
(http://s6z.de/joomla3/index.php/arduino/sensoren/15-umgebungslichtsensor-bh1750)
|
||||
|
||||
|
||||
Features:
|
||||
|
||||
- unterstützt beide möglichen I2C-Adressen des Sensors:
|
||||
Standardadresse: 0x23, Alternativadresse: 0x5C.
|
||||
Es sind entsprechende Konstanten definiert: BH1750_DEFAULT_I2CADDR und BH1750_SECOND_I2CADDR.
|
||||
|
||||
- alle Hardware-Auflösungsmodi:
|
||||
* RESOLUTION_LOW: Physische Sensormodus mit 4 lx Auflösung. Messzeit ca. 16ms. Bereich 0-54612.
|
||||
* RESOLUTION_NORMAL: Physische Sensormodus mit 1 lx Auflösung. Messzeit ca. 120ms. Bereich 0-54612.
|
||||
* RESOLUTION_HIGH: Physische Sensormodus mit 0,5 lx Auflösung. Messzeit ca. 120ms. Bereich 0-54612.
|
||||
|
||||
- Virtueller Modus:
|
||||
* RESOLUTION_AUTO_HIGH: Die Werte im MTreg ('Measurement Time'-Register) werden je nach Helligkeit
|
||||
automatisch so angepasst, dass eine maximalmögliche Auflösung
|
||||
und Messbereich erziehlt werden.
|
||||
Die messbaren Werte fangen von 0,11 lx und gehen bis über 100000 lx.
|
||||
(ich weis nicht, wie genau die Werte in Grenzbereichen sind,
|
||||
besonders bei hohen Werte habe ich da meine Zweifel.
|
||||
Die Werte scheinen jedoch weitgehend linear mit der steigenden Helligkeit zu wachsen.)
|
||||
Auflösung im Unteren Bereich ca. 0,13 lx, im mittleren 0,5 lx, im oberen etwa 1-2 lx.
|
||||
Die Messzeiten verlängern sich durch mehrfache Messungen und
|
||||
die Änderungen von Measurement Time (MTreg) bis max. ca. 500 ms.
|
||||
|
||||
- Methode zur Änderung von 'Measurement Time'-Registers. Damit kann die Empfindlichkeit beeinflusst werden.
|
||||
|
||||
- auto power down: Der Sensor wird nach der Messung in den Stromsparmodus versetzt.
|
||||
Das spätere Aufwecken wird ggf. automatisch vorgenommen, braucht jedoch geringfügig mehr Zeit.
|
||||
|
||||
Defaultwerte: Modus = RESOLUTION_AUTO_HIGH, AutoPowerDown = true
|
||||
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Example of AS_BH1750 library usage.
|
||||
*
|
||||
* This example initalises the BH1750 object using the default
|
||||
* adaptive auto-high-resolution mode and then makes
|
||||
* a light level reading about every second.
|
||||
* (the sensitivity and resolution are automatically adapted
|
||||
* the current light conditions)
|
||||
*
|
||||
* Wiring:
|
||||
* VCC-5v
|
||||
* GND-GND
|
||||
* SCL-SCL(analog pin 5)
|
||||
* SDA-SDA(analog pin 4)
|
||||
* ADD-NC or GND
|
||||
*
|
||||
* Copyright (c) 2013 Alexander Schulz. All right reserved.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <Wire.h>
|
||||
#include <AS_BH1750.h>
|
||||
|
||||
AS_BH1750 sensor;
|
||||
|
||||
void setup(){
|
||||
Serial.begin(9600);
|
||||
delay(50);
|
||||
|
||||
// for normal sensor resolution (1 lx resolution, 0-65535 lx, 120ms, no PowerDown) use: sensor.begin(RESOLUTION_NORMAL, false);
|
||||
// Initialize sensor. if sensor is not present, false is returned
|
||||
if(sensor.begin()) {
|
||||
Serial.println("Sensor initialized");
|
||||
}
|
||||
else {
|
||||
Serial.println("Sensor not present");
|
||||
}
|
||||
|
||||
/*
|
||||
// to check the sensor present
|
||||
if(sensor.isPresent()) {
|
||||
Serial.println("Sensor present");
|
||||
}
|
||||
else {
|
||||
Serial.println("Sensor not present");
|
||||
}*/
|
||||
}
|
||||
|
||||
void loop() {
|
||||
float lux = sensor.readLightLevel();
|
||||
Serial.print("Light level: ");
|
||||
Serial.print(lux);
|
||||
Serial.println(" lx");
|
||||
delay(1000);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
#include <Wire.h>
|
||||
#include <AS_BH1750.h>
|
||||
#include <LiquidCrystal.h>
|
||||
|
||||
/*
|
||||
* LightMeter_LCD
|
||||
*
|
||||
* Version 1.2
|
||||
* Datum: 05.08.2013
|
||||
*
|
||||
* Das Programm benutzt den BH1750 (Umgebiungslichtsensor)
|
||||
* und zeigt die Werte in Lux auf einem 16x2-Symbol-LCD.
|
||||
*
|
||||
* Verdrahtung (UNO, Nano...)
|
||||
*
|
||||
* BH1750:
|
||||
* Sensor SCL pin an A5
|
||||
* Sensor SDA pin an A4
|
||||
* Sensor VDD pin an 5V
|
||||
* Sensor GND pin an GND
|
||||
* Sensor ADDR pin frei
|
||||
*
|
||||
* LCD in 4-Bit-Modus:
|
||||
* LCD RS pin an digital pin 8
|
||||
* LCD RW pin an digital pin 13
|
||||
* LCD Enable pin an digital pin 9
|
||||
* LCD D4 pin an digital pin 4
|
||||
* LCD D5 pin an digital pin 5
|
||||
* LCD D6 pin an digital pin 6
|
||||
* LCD D7 pin an digital pin 7
|
||||
*
|
||||
*
|
||||
* Copyright (c) 2013 Alexander Schulz. All right reserved.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
AS_BH1750 lightMeter;
|
||||
|
||||
// Setup LCD-Shield
|
||||
LiquidCrystal lcd(8, 13, 9, 4, 5, 6, 7);
|
||||
|
||||
void setup() {
|
||||
// Display initialisieren
|
||||
lcd.clear();
|
||||
lcd.begin(16, 2); // 16x2 Zeichen
|
||||
lcd.setCursor(0,0);
|
||||
lcd.print("LightMeter v1.0");
|
||||
lcd.setCursor(0,1);
|
||||
lcd.print("Initializing...");
|
||||
delay(1000);
|
||||
lcd.clear();
|
||||
|
||||
if(!lightMeter.begin()){
|
||||
// Prüfen, ob Sensor vorhanden ist
|
||||
lcd.clear();
|
||||
lcd.setCursor(0,0);
|
||||
lcd.print("BH1750 not found");
|
||||
lcd.setCursor(0,1);
|
||||
lcd.print("check wiring!");
|
||||
while (1) {
|
||||
delay(1000);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void loop() {
|
||||
char clux[9];
|
||||
|
||||
// Werte auslesen und aufbereiten
|
||||
float lux = lightMeter.readLightLevel();
|
||||
dtostrf(lux, 8, 1, clux);
|
||||
|
||||
lcd.setCursor(0,0);
|
||||
lcd.print("Light level: ");
|
||||
lcd.setCursor(5,1);
|
||||
lcd.print(clux);
|
||||
lcd.print(" lx");
|
||||
|
||||
delay(500);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
#######################################
|
||||
# Syntax Coloring Map For BH1750
|
||||
#######################################
|
||||
|
||||
#######################################
|
||||
# Datatypes (KEYWORD1)
|
||||
#######################################
|
||||
|
||||
AS_BH1750 KEYWORD1
|
||||
sensors_resolution_t KEYWORD1
|
||||
|
||||
|
||||
#######################################
|
||||
# Methods and Functions (KEYWORD2)
|
||||
#######################################
|
||||
|
||||
begin KEYWORD2
|
||||
isPresent KEYWORD2
|
||||
readLightLevel KEYWORD2
|
||||
powerDown KEYWORD2
|
||||
|
||||
|
||||
#######################################
|
||||
# Instances (KEYWORD2)
|
||||
#######################################
|
||||
|
||||
|
||||
#######################################
|
||||
# Constants (LITERAL1)
|
||||
#######################################
|
||||
@@ -1,47 +0,0 @@
|
||||
{
|
||||
"description": "Library for the Adafruit Motor Shield V2 for Arduino. It supports DC motors & stepper motors with microstepping as well as stacking-support.",
|
||||
"repository": {
|
||||
"url": "https://github.com/adafruit/Adafruit_Motor_Shield_V2_Library",
|
||||
"type": "git"
|
||||
},
|
||||
"platforms": [
|
||||
"atmelavr",
|
||||
"atmelsam",
|
||||
"espressif8266",
|
||||
"intel_arc32",
|
||||
"microchippic32",
|
||||
"nordicnrf51",
|
||||
"teensy",
|
||||
"timsp430"
|
||||
],
|
||||
"export": {
|
||||
"exclude": [
|
||||
"extras",
|
||||
"docs",
|
||||
"tests",
|
||||
"test",
|
||||
"*.doxyfile",
|
||||
"*.pdf"
|
||||
],
|
||||
"include": null
|
||||
},
|
||||
"authors": [
|
||||
{
|
||||
"maintainer": true,
|
||||
"name": "Adafruit",
|
||||
"url": null,
|
||||
"email": "info@adafruit.com"
|
||||
}
|
||||
],
|
||||
"keywords": [
|
||||
"device",
|
||||
"control"
|
||||
],
|
||||
"id": 783,
|
||||
"name": "Adafruit Motor Shield V2 Library",
|
||||
"frameworks": [
|
||||
"arduino"
|
||||
],
|
||||
"version": "1.0.4",
|
||||
"homepage": null
|
||||
}
|
||||
@@ -0,0 +1,132 @@
|
||||
/***************************************************
|
||||
This is a library for the MPR121 I2C 12-chan Capacitive Sensor
|
||||
|
||||
Designed specifically to work with the MPR121 sensor from Adafruit
|
||||
----> https://www.adafruit.com/products/1982
|
||||
|
||||
These sensors use I2C to communicate, 2+ pins are required to
|
||||
interface
|
||||
Adafruit invests time and resources providing this open source code,
|
||||
please support Adafruit and open-source hardware by purchasing
|
||||
products from Adafruit!
|
||||
|
||||
Written by Limor Fried/Ladyada for Adafruit Industries.
|
||||
BSD license, all text above must be included in any redistribution
|
||||
****************************************************/
|
||||
|
||||
#include "Adafruit_MPR121.h"
|
||||
|
||||
Adafruit_MPR121::Adafruit_MPR121() {
|
||||
}
|
||||
|
||||
boolean Adafruit_MPR121::begin(uint8_t i2caddr) {
|
||||
Wire.begin();
|
||||
|
||||
_i2caddr = i2caddr;
|
||||
|
||||
// soft reset
|
||||
writeRegister(MPR121_SOFTRESET, 0x63);
|
||||
delay(1);
|
||||
for (uint8_t i=0; i<0x7F; i++) {
|
||||
// Serial.print("$"); Serial.print(i, HEX);
|
||||
// Serial.print(": 0x"); Serial.println(readRegister8(i));
|
||||
}
|
||||
|
||||
|
||||
writeRegister(MPR121_ECR, 0x0);
|
||||
|
||||
uint8_t c = readRegister8(MPR121_CONFIG2);
|
||||
|
||||
if (c != 0x24) return false;
|
||||
|
||||
|
||||
setThresholds(12, 6);
|
||||
writeRegister(MPR121_MHDR, 0x01);
|
||||
writeRegister(MPR121_NHDR, 0x01);
|
||||
writeRegister(MPR121_NCLR, 0x0E);
|
||||
writeRegister(MPR121_FDLR, 0x00);
|
||||
|
||||
writeRegister(MPR121_MHDF, 0x01);
|
||||
writeRegister(MPR121_NHDF, 0x05);
|
||||
writeRegister(MPR121_NCLF, 0x01);
|
||||
writeRegister(MPR121_FDLF, 0x00);
|
||||
|
||||
writeRegister(MPR121_NHDT, 0x00);
|
||||
writeRegister(MPR121_NCLT, 0x00);
|
||||
writeRegister(MPR121_FDLT, 0x00);
|
||||
|
||||
writeRegister(MPR121_DEBOUNCE, 0);
|
||||
writeRegister(MPR121_CONFIG1, 0x10); // default, 16uA charge current
|
||||
writeRegister(MPR121_CONFIG2, 0x20); // 0.5uS encoding, 1ms period
|
||||
|
||||
// writeRegister(MPR121_AUTOCONFIG0, 0x8F);
|
||||
|
||||
// writeRegister(MPR121_UPLIMIT, 150);
|
||||
// writeRegister(MPR121_TARGETLIMIT, 100); // should be ~400 (100 shifted)
|
||||
// writeRegister(MPR121_LOWLIMIT, 50);
|
||||
// enable all electrodes
|
||||
writeRegister(MPR121_ECR, 0x8F); // start with first 5 bits of baseline tracking
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Adafruit_MPR121::setThreshholds(uint8_t touch, uint8_t release) {
|
||||
|
||||
setThresholds(touch, release);
|
||||
}
|
||||
|
||||
void Adafruit_MPR121::setThresholds(uint8_t touch, uint8_t release) {
|
||||
for (uint8_t i=0; i<12; i++) {
|
||||
writeRegister(MPR121_TOUCHTH_0 + 2*i, touch);
|
||||
writeRegister(MPR121_RELEASETH_0 + 2*i, release);
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t Adafruit_MPR121::filteredData(uint8_t t) {
|
||||
if (t > 12) return 0;
|
||||
return readRegister16(MPR121_FILTDATA_0L + t*2);
|
||||
}
|
||||
|
||||
uint16_t Adafruit_MPR121::baselineData(uint8_t t) {
|
||||
if (t > 12) return 0;
|
||||
uint16_t bl = readRegister8(MPR121_BASELINE_0 + t);
|
||||
return (bl << 2);
|
||||
}
|
||||
|
||||
uint16_t Adafruit_MPR121::touched(void) {
|
||||
uint16_t t = readRegister16(MPR121_TOUCHSTATUS_L);
|
||||
return t & 0x0FFF;
|
||||
}
|
||||
|
||||
/*********************************************************************/
|
||||
|
||||
|
||||
uint8_t Adafruit_MPR121::readRegister8(uint8_t reg) {
|
||||
Wire.beginTransmission(_i2caddr);
|
||||
Wire.write(reg);
|
||||
Wire.endTransmission(false);
|
||||
while (Wire.requestFrom(_i2caddr, 1) != 1);
|
||||
return ( Wire.read());
|
||||
}
|
||||
|
||||
uint16_t Adafruit_MPR121::readRegister16(uint8_t reg) {
|
||||
Wire.beginTransmission(_i2caddr);
|
||||
Wire.write(reg);
|
||||
Wire.endTransmission(false);
|
||||
while (Wire.requestFrom(_i2caddr, 2) != 2);
|
||||
uint16_t v = Wire.read();
|
||||
v |= ((uint16_t) Wire.read()) << 8;
|
||||
return v;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Writes 8-bits to the specified destination register
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void Adafruit_MPR121::writeRegister(uint8_t reg, uint8_t value) {
|
||||
Wire.beginTransmission(_i2caddr);
|
||||
Wire.write((uint8_t)reg);
|
||||
Wire.write((uint8_t)(value));
|
||||
Wire.endTransmission();
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
/***************************************************
|
||||
This is a library for the MPR121 12-Channel Capacitive Sensor
|
||||
|
||||
Designed specifically to work with the MPR121 breakout from Adafruit
|
||||
----> https://www.adafruit.com/products/1982
|
||||
|
||||
These sensors use I2C to communicate, 2+ pins are required to
|
||||
interface
|
||||
Adafruit invests time and resources providing this open source code,
|
||||
please support Adafruit and open-source hardware by purchasing
|
||||
products from Adafruit!
|
||||
|
||||
Written by Limor Fried/Ladyada for Adafruit Industries.
|
||||
BSD license, all text above must be included in any redistribution
|
||||
****************************************************/
|
||||
|
||||
#ifndef ADAFRUIT_MPR121_H
|
||||
#define ADAFRUIT_MPR121_H
|
||||
|
||||
#if (ARDUINO >= 100)
|
||||
#include "Arduino.h"
|
||||
#else
|
||||
#include "WProgram.h"
|
||||
#endif
|
||||
#include <Wire.h>
|
||||
|
||||
// The default I2C address
|
||||
#define MPR121_I2CADDR_DEFAULT 0x5A
|
||||
|
||||
#define MPR121_TOUCHSTATUS_L 0x00
|
||||
#define MPR121_TOUCHSTATUS_H 0x01
|
||||
#define MPR121_FILTDATA_0L 0x04
|
||||
#define MPR121_FILTDATA_0H 0x05
|
||||
#define MPR121_BASELINE_0 0x1E
|
||||
#define MPR121_MHDR 0x2B
|
||||
#define MPR121_NHDR 0x2C
|
||||
#define MPR121_NCLR 0x2D
|
||||
#define MPR121_FDLR 0x2E
|
||||
#define MPR121_MHDF 0x2F
|
||||
#define MPR121_NHDF 0x30
|
||||
#define MPR121_NCLF 0x31
|
||||
#define MPR121_FDLF 0x32
|
||||
#define MPR121_NHDT 0x33
|
||||
#define MPR121_NCLT 0x34
|
||||
#define MPR121_FDLT 0x35
|
||||
|
||||
#define MPR121_TOUCHTH_0 0x41
|
||||
#define MPR121_RELEASETH_0 0x42
|
||||
#define MPR121_DEBOUNCE 0x5B
|
||||
#define MPR121_CONFIG1 0x5C
|
||||
#define MPR121_CONFIG2 0x5D
|
||||
#define MPR121_CHARGECURR_0 0x5F
|
||||
#define MPR121_CHARGETIME_1 0x6C
|
||||
#define MPR121_ECR 0x5E
|
||||
#define MPR121_AUTOCONFIG0 0x7B
|
||||
#define MPR121_AUTOCONFIG1 0x7C
|
||||
#define MPR121_UPLIMIT 0x7D
|
||||
#define MPR121_LOWLIMIT 0x7E
|
||||
#define MPR121_TARGETLIMIT 0x7F
|
||||
|
||||
#define MPR121_GPIODIR 0x76
|
||||
#define MPR121_GPIOEN 0x77
|
||||
#define MPR121_GPIOSET 0x78
|
||||
#define MPR121_GPIOCLR 0x79
|
||||
#define MPR121_GPIOTOGGLE 0x7A
|
||||
|
||||
|
||||
|
||||
#define MPR121_SOFTRESET 0x80
|
||||
|
||||
//.. thru to 0x1C/0x1D
|
||||
class Adafruit_MPR121 {
|
||||
public:
|
||||
// Hardware I2C
|
||||
Adafruit_MPR121(void);
|
||||
|
||||
boolean begin(uint8_t i2caddr = MPR121_I2CADDR_DEFAULT);
|
||||
|
||||
uint16_t filteredData(uint8_t t);
|
||||
uint16_t baselineData(uint8_t t);
|
||||
|
||||
uint8_t readRegister8(uint8_t reg);
|
||||
uint16_t readRegister16(uint8_t reg);
|
||||
void writeRegister(uint8_t reg, uint8_t value);
|
||||
uint16_t touched(void);
|
||||
// Add deprecated attribute so that the compiler shows a warning
|
||||
__attribute__((deprecated)) void setThreshholds(uint8_t touch, uint8_t release);
|
||||
void setThresholds(uint8_t touch, uint8_t release);
|
||||
|
||||
private:
|
||||
int8_t _i2caddr;
|
||||
};
|
||||
|
||||
#endif // ADAFRUIT_MPR121_H
|
||||
@@ -0,0 +1,32 @@
|
||||
# Adafruit_MPR121_Library
|
||||
<!-- START COMPATIBILITY TABLE -->
|
||||
|
||||
## Compatibility
|
||||
|
||||
MCU | Tested Works | Doesn't Work | Not Tested | Notes
|
||||
------------------ | :----------: | :----------: | :---------: | -----
|
||||
Atmega328 @ 16MHz | X | | |
|
||||
Atmega328 @ 12MHz | X | | |
|
||||
Atmega32u4 @ 16MHz | X | | |
|
||||
Atmega32u4 @ 8MHz | X | | |
|
||||
ESP8266 | | X | |
|
||||
Atmega2560 @ 16MHz | X | | |
|
||||
ATSAM3X8E | | X | |
|
||||
ATSAM21D | X | | |
|
||||
ATtiny85 @ 16MHz | | | X |
|
||||
ATtiny85 @ 8MHz | | | X |
|
||||
Intel Curie @ 32MHz | | | X |
|
||||
STM32F2 | | | X |
|
||||
|
||||
* ATmega328 @ 16MHz : Arduino UNO, Adafruit Pro Trinket 5V, Adafruit Metro 328, Adafruit Metro Mini
|
||||
* ATmega328 @ 12MHz : Adafruit Pro Trinket 3V
|
||||
* ATmega32u4 @ 16MHz : Arduino Leonardo, Arduino Micro, Arduino Yun, Teensy 2.0
|
||||
* ATmega32u4 @ 8MHz : Adafruit Flora, Bluefruit Micro
|
||||
* ESP8266 : Adafruit Huzzah
|
||||
* ATmega2560 @ 16MHz : Arduino Mega
|
||||
* ATSAM3X8E : Arduino Due
|
||||
* ATSAM21D : Arduino Zero, M0 Pro
|
||||
* ATtiny85 @ 16MHz : Adafruit Trinket 5V
|
||||
* ATtiny85 @ 8MHz : Adafruit Gemma, Arduino Gemma, Adafruit Trinket 3V
|
||||
|
||||
<!-- END COMPATIBILITY TABLE -->
|
||||
@@ -0,0 +1,25 @@
|
||||
This is a library for the MPR121 12-channel Capacitive touch sensor
|
||||
|
||||
Designed specifically to work with the MPR121 Breakout in the Adafruit shop
|
||||
----> https://www.adafruit.com/products/1982
|
||||
|
||||
These sensors use I2C communicate, at least 2 pins are required
|
||||
to interface
|
||||
|
||||
Adafruit invests time and resources providing this open source code,
|
||||
please support Adafruit and open-source hardware by purchasing
|
||||
products from Adafruit!
|
||||
|
||||
Written by Limor Fried/Ladyada for Adafruit Industries.
|
||||
BSD license, all text above must be included in any redistribution
|
||||
|
||||
Check out the links above for our tutorials and wiring diagrams
|
||||
|
||||
To download. click the ZIP button, and rename the uncompressed folder Adafruit_MPR121
|
||||
Check that the Adafruit_MPR121 folder contains Adafruit_MPR121.cpp and Adafruit_MPR121.h
|
||||
|
||||
Place the Adafruit_MPR121 library folder your arduinosketchfolder/libraries/ folder.
|
||||
You may need to create the libraries subfolder if its your first library. Restart the IDE.
|
||||
|
||||
We also have a great tutorial on Arduino library installation at:
|
||||
http://learn.adafruit.com/adafruit-all-about-arduino-libraries-install-use
|
||||
@@ -0,0 +1,83 @@
|
||||
/*********************************************************
|
||||
This is a library for the MPR121 12-channel Capacitive touch sensor
|
||||
|
||||
Designed specifically to work with the MPR121 Breakout in the Adafruit shop
|
||||
----> https://www.adafruit.com/products/
|
||||
|
||||
These sensors use I2C communicate, at least 2 pins are required
|
||||
to interface
|
||||
|
||||
Adafruit invests time and resources providing this open source code,
|
||||
please support Adafruit and open-source hardware by purchasing
|
||||
products from Adafruit!
|
||||
|
||||
Written by Limor Fried/Ladyada for Adafruit Industries.
|
||||
BSD license, all text above must be included in any redistribution
|
||||
**********************************************************/
|
||||
|
||||
#include <Wire.h>
|
||||
#include "Adafruit_MPR121.h"
|
||||
|
||||
// You can have up to 4 on one i2c bus but one is enough for testing!
|
||||
Adafruit_MPR121 cap = Adafruit_MPR121();
|
||||
|
||||
// Keeps track of the last pins touched
|
||||
// so we know when buttons are 'released'
|
||||
uint16_t lasttouched = 0;
|
||||
uint16_t currtouched = 0;
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
|
||||
while (!Serial) { // needed to keep leonardo/micro from starting too fast!
|
||||
delay(10);
|
||||
}
|
||||
|
||||
Serial.println("Adafruit MPR121 Capacitive Touch sensor test");
|
||||
|
||||
// Default address is 0x5A, if tied to 3.3V its 0x5B
|
||||
// If tied to SDA its 0x5C and if SCL then 0x5D
|
||||
if (!cap.begin(0x5A)) {
|
||||
Serial.println("MPR121 not found, check wiring?");
|
||||
while (1);
|
||||
}
|
||||
Serial.println("MPR121 found!");
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// Get the currently touched pads
|
||||
currtouched = cap.touched();
|
||||
|
||||
for (uint8_t i=0; i<12; i++) {
|
||||
// it if *is* touched and *wasnt* touched before, alert!
|
||||
if ((currtouched & _BV(i)) && !(lasttouched & _BV(i)) ) {
|
||||
Serial.print(i); Serial.println(" touched");
|
||||
}
|
||||
// if it *was* touched and now *isnt*, alert!
|
||||
if (!(currtouched & _BV(i)) && (lasttouched & _BV(i)) ) {
|
||||
Serial.print(i); Serial.println(" released");
|
||||
}
|
||||
}
|
||||
|
||||
// reset our state
|
||||
lasttouched = currtouched;
|
||||
|
||||
// comment out this line for detailed data from the sensor!
|
||||
return;
|
||||
|
||||
// debugging info, what
|
||||
Serial.print("\t\t\t\t\t\t\t\t\t\t\t\t\t 0x"); Serial.println(cap.touched(), HEX);
|
||||
Serial.print("Filt: ");
|
||||
for (uint8_t i=0; i<12; i++) {
|
||||
Serial.print(cap.filteredData(i)); Serial.print("\t");
|
||||
}
|
||||
Serial.println();
|
||||
Serial.print("Base: ");
|
||||
for (uint8_t i=0; i<12; i++) {
|
||||
Serial.print(cap.baselineData(i)); Serial.print("\t");
|
||||
}
|
||||
Serial.println();
|
||||
|
||||
// put a delay so it isn't overwhelming
|
||||
delay(100);
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
Adafruit_MPR121 KEYWORD1
|
||||
begin KEYWORD2
|
||||
filteredData KEYWORD2
|
||||
baselineData KEYWORD2
|
||||
touched KEYWORD2
|
||||
setThresholds KEYWORD2
|
||||
@@ -0,0 +1,9 @@
|
||||
name=Adafruit MPR121
|
||||
version=1.0.0
|
||||
author=Adafruit <info@adafruit.com>
|
||||
maintainer=Adafruit <info@adafruit.com>
|
||||
sentence=Arduino library for the MPR121-based capacitive sensors in the Adafruit shop.
|
||||
paragraph=Designed specifically to work with the MPR121 Breakout in the Adafruit shop.
|
||||
category=Sensors
|
||||
url=https://github.com/adafruit/Adafruit_MPR121
|
||||
architectures=*
|
||||
@@ -0,0 +1,46 @@
|
||||
Thank you for opening an issue on an Adafruit Arduino library repository. To
|
||||
improve the speed of resolution please review the following guidelines and
|
||||
common troubleshooting steps below before creating the issue:
|
||||
|
||||
- **Do not use GitHub issues for troubleshooting projects and issues.** Instead use
|
||||
the forums at http://forums.adafruit.com to ask questions and troubleshoot why
|
||||
something isn't working as expected. In many cases the problem is a common issue
|
||||
that you will more quickly receive help from the forum community. GitHub issues
|
||||
are meant for known defects in the code. If you don't know if there is a defect
|
||||
in the code then start with troubleshooting on the forum first.
|
||||
|
||||
- **If following a tutorial or guide be sure you didn't miss a step.** Carefully
|
||||
check all of the steps and commands to run have been followed. Consult the
|
||||
forum if you're unsure or have questions about steps in a guide/tutorial.
|
||||
|
||||
- **For Arduino projects check these very common issues to ensure they don't apply**:
|
||||
|
||||
- For uploading sketches or communicating with the board make sure you're using
|
||||
a **USB data cable** and **not** a **USB charge-only cable**. It is sometimes
|
||||
very hard to tell the difference between a data and charge cable! Try using the
|
||||
cable with other devices or swapping to another cable to confirm it is not
|
||||
the problem.
|
||||
|
||||
- **Be sure you are supplying adequate power to the board.** Check the specs of
|
||||
your board and plug in an external power supply. In many cases just
|
||||
plugging a board into your computer is not enough to power it and other
|
||||
peripherals.
|
||||
|
||||
- **Double check all soldering joints and connections.** Flakey connections
|
||||
cause many mysterious problems. See the [guide to excellent soldering](https://learn.adafruit.com/adafruit-guide-excellent-soldering/tools) for examples of good solder joints.
|
||||
|
||||
- **Ensure you are using an official Arduino or Adafruit board.** We can't
|
||||
guarantee a clone board will have the same functionality and work as expected
|
||||
with this code and don't support them.
|
||||
|
||||
If you're sure this issue is a defect in the code and checked the steps above
|
||||
please fill in the following fields to provide enough troubleshooting information.
|
||||
You may delete the guideline and text above to just leave the following details:
|
||||
|
||||
- Arduino board: **INSERT ARDUINO BOARD NAME/TYPE HERE**
|
||||
|
||||
- Arduino IDE version (found in Arduino -> About Arduino menu): **INSERT ARDUINO
|
||||
VERSION HERE**
|
||||
|
||||
- List the steps to reproduce the problem below (if possible attach a sketch or
|
||||
copy the sketch code in too): **LIST REPRO STEPS BELOW**
|
||||
@@ -0,0 +1,26 @@
|
||||
Thank you for creating a pull request to contribute to Adafruit's GitHub code!
|
||||
Before you open the request please review the following guidelines and tips to
|
||||
help it be more easily integrated:
|
||||
|
||||
- **Describe the scope of your change--i.e. what the change does and what parts
|
||||
of the code were modified.** This will help us understand any risks of integrating
|
||||
the code.
|
||||
|
||||
- **Describe any known limitations with your change.** For example if the change
|
||||
doesn't apply to a supported platform of the library please mention it.
|
||||
|
||||
- **Please run any tests or examples that can exercise your modified code.** We
|
||||
strive to not break users of the code and running tests/examples helps with this
|
||||
process.
|
||||
|
||||
Thank you again for contributing! We will try to test and integrate the change
|
||||
as soon as we can, but be aware we have many GitHub repositories to manage and
|
||||
can't immediately respond to every request. There is no need to bump or check in
|
||||
on a pull request (it will clutter the discussion of the request).
|
||||
|
||||
Also don't be worried if the request is closed or not integrated--sometimes the
|
||||
priorities of Adafruit's GitHub code (education, ease of use) might not match the
|
||||
priorities of the pull request. Don't fret, the open source community thrives on
|
||||
forks and GitHub makes it easy to keep your changes in a forked repo.
|
||||
|
||||
After reviewing the guidelines above you can delete this text from the pull request.
|
||||
+12
-12
@@ -1,14 +1,14 @@
|
||||
/******************************************************************
|
||||
This is the library for the Adafruit Motor Shield V2 for Arduino.
|
||||
This is the library for the Adafruit Motor Shield V2 for Arduino.
|
||||
It supports DC motors & Stepper motors with microstepping as well
|
||||
as stacking-support. It is *not* compatible with the V1 library!
|
||||
|
||||
It will only work with https://www.adafruit.com/products/1483
|
||||
|
||||
|
||||
Adafruit invests time and resources providing this open
|
||||
source code, please support Adafruit and open-source hardware
|
||||
by purchasing products from Adafruit!
|
||||
|
||||
|
||||
Written by Limor Fried/Ladyada for Adafruit Industries.
|
||||
BSD license, check license.txt for more information.
|
||||
All text above must be included in any redistribution.
|
||||
@@ -48,14 +48,14 @@ void Adafruit_MotorShield::begin(uint16_t freq) {
|
||||
_pwm.begin();
|
||||
_freq = freq;
|
||||
_pwm.setPWMFreq(_freq); // This is the maximum PWM frequency
|
||||
for (uint8_t i=0; i<16; i++)
|
||||
for (uint8_t i=0; i<16; i++)
|
||||
_pwm.setPWM(i, 0, 0);
|
||||
}
|
||||
|
||||
void Adafruit_MotorShield::setPWM(uint8_t pin, uint16_t value) {
|
||||
if (value > 4095) {
|
||||
_pwm.setPWM(pin, 4096, 0);
|
||||
} else
|
||||
} else
|
||||
_pwm.setPWM(pin, 0, value);
|
||||
}
|
||||
void Adafruit_MotorShield::setPin(uint8_t pin, boolean value) {
|
||||
@@ -170,7 +170,7 @@ uint16_t steps, Adafruit_MotorShield controller) {
|
||||
if (steppernum == 1) {
|
||||
latch_state &= ~_BV(MOTOR1_A) & ~_BV(MOTOR1_B) &
|
||||
~_BV(MOTOR2_A) & ~_BV(MOTOR2_B); // all motor pins to 0
|
||||
|
||||
|
||||
// enable both H bridges
|
||||
pinMode(11, OUTPUT);
|
||||
pinMode(3, OUTPUT);
|
||||
@@ -234,6 +234,7 @@ void Adafruit_StepperMotor::step(uint16_t steps, uint8_t dir, uint8_t style) {
|
||||
//Serial.println("step!"); Serial.println(uspers);
|
||||
ret = onestep(dir, style);
|
||||
delayMicroseconds(uspers);
|
||||
yield(); // required for ESP8266
|
||||
}
|
||||
}
|
||||
|
||||
@@ -281,7 +282,7 @@ uint8_t Adafruit_StepperMotor::onestep(uint8_t dir, uint8_t style) {
|
||||
} else {
|
||||
currentstep -= MICROSTEPS/2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (style == MICROSTEP) {
|
||||
if (dir == FORWARD) {
|
||||
@@ -315,12 +316,12 @@ uint8_t Adafruit_StepperMotor::onestep(uint8_t dir, uint8_t style) {
|
||||
|
||||
#ifdef MOTORDEBUG
|
||||
Serial.print("current step: "); Serial.println(currentstep, DEC);
|
||||
Serial.print(" pwmA = "); Serial.print(ocra, DEC);
|
||||
Serial.print(" pwmB = "); Serial.println(ocrb, DEC);
|
||||
Serial.print(" pwmA = "); Serial.print(ocra, DEC);
|
||||
Serial.print(" pwmB = "); Serial.println(ocrb, DEC);
|
||||
#endif
|
||||
MC->setPWM(PWMApin, ocra*16);
|
||||
MC->setPWM(PWMBpin, ocrb*16);
|
||||
|
||||
|
||||
|
||||
// release all
|
||||
uint8_t latch_state = 0; // all motor pins to 0
|
||||
@@ -351,7 +352,7 @@ uint8_t Adafruit_StepperMotor::onestep(uint8_t dir, uint8_t style) {
|
||||
break;
|
||||
case 4:
|
||||
latch_state |= 0x4; // energize coil 3 only
|
||||
break;
|
||||
break;
|
||||
case 5:
|
||||
latch_state |= 0xC; // energize coil 3+4
|
||||
break;
|
||||
@@ -394,4 +395,3 @@ uint8_t Adafruit_StepperMotor::onestep(uint8_t dir, uint8_t style) {
|
||||
|
||||
return currentstep;
|
||||
}
|
||||
|
||||
@@ -10,18 +10,20 @@ It will only work with https://www.adafruit.com/products/1438
|
||||
|
||||
## Compatibility
|
||||
|
||||
MCU | Tested Works | Doesn't Work | Not Tested | Notes
|
||||
----------------- | :----------: | :----------: | :---------: | -----
|
||||
Atmega328 @ 16MHz | X | | |
|
||||
Atmega328 @ 12MHz | X | | |
|
||||
MCU | Tested Works | Doesn't Work | Not Tested | Notes
|
||||
------------------ | :----------: | :----------: | :---------: | -----
|
||||
Atmega328 @ 16MHz | X | | |
|
||||
Atmega328 @ 12MHz | X | | |
|
||||
Atmega32u4 @ 16MHz | X | | |
|
||||
Atmega32u4 @ 8MHz | X | | |
|
||||
ESP8266 | | | X |
|
||||
Atmega32u4 @ 8MHz | X | | |
|
||||
ESP8266 | | | X |
|
||||
Atmega2560 @ 16MHz | X | | |
|
||||
ATSAM3X8E | | X | |
|
||||
ATSAM21D | | X | |
|
||||
ATtiny85 @ 16MHz | | | X |
|
||||
ATtiny85 @ 8MHz | | | X |
|
||||
ATSAM3X8E | | X | |
|
||||
ATSAM21D | | X | |
|
||||
ATtiny85 @ 16MHz | | | X |
|
||||
ATtiny85 @ 8MHz | | | X |
|
||||
Intel Curie @ 32MHz | | | X |
|
||||
STM32F2 | | | X |
|
||||
|
||||
* ATmega328 @ 16MHz : Arduino UNO, Adafruit Pro Trinket 5V, Adafruit Metro 328, Adafruit Metro Mini
|
||||
* ATmega328 @ 12MHz : Adafruit Pro Trinket 3V
|
||||
Submodule lib/Adafruit_NeoPixel deleted from f02a5a461b
+46
@@ -0,0 +1,46 @@
|
||||
Thank you for opening an issue on an Adafruit Arduino library repository. To
|
||||
improve the speed of resolution please review the following guidelines and
|
||||
common troubleshooting steps below before creating the issue:
|
||||
|
||||
- **Do not use GitHub issues for troubleshooting projects and issues.** Instead use
|
||||
the forums at http://forums.adafruit.com to ask questions and troubleshoot why
|
||||
something isn't working as expected. In many cases the problem is a common issue
|
||||
that you will more quickly receive help from the forum community. GitHub issues
|
||||
are meant for known defects in the code. If you don't know if there is a defect
|
||||
in the code then start with troubleshooting on the forum first.
|
||||
|
||||
- **If following a tutorial or guide be sure you didn't miss a step.** Carefully
|
||||
check all of the steps and commands to run have been followed. Consult the
|
||||
forum if you're unsure or have questions about steps in a guide/tutorial.
|
||||
|
||||
- **For Arduino projects check these very common issues to ensure they don't apply**:
|
||||
|
||||
- For uploading sketches or communicating with the board make sure you're using
|
||||
a **USB data cable** and **not** a **USB charge-only cable**. It is sometimes
|
||||
very hard to tell the difference between a data and charge cable! Try using the
|
||||
cable with other devices or swapping to another cable to confirm it is not
|
||||
the problem.
|
||||
|
||||
- **Be sure you are supplying adequate power to the board.** Check the specs of
|
||||
your board and plug in an external power supply. In many cases just
|
||||
plugging a board into your computer is not enough to power it and other
|
||||
peripherals.
|
||||
|
||||
- **Double check all soldering joints and connections.** Flakey connections
|
||||
cause many mysterious problems. See the [guide to excellent soldering](https://learn.adafruit.com/adafruit-guide-excellent-soldering/tools) for examples of good solder joints.
|
||||
|
||||
- **Ensure you are using an official Arduino or Adafruit board.** We can't
|
||||
guarantee a clone board will have the same functionality and work as expected
|
||||
with this code and don't support them.
|
||||
|
||||
If you're sure this issue is a defect in the code and checked the steps above
|
||||
please fill in the following fields to provide enough troubleshooting information.
|
||||
You may delete the guideline and text above to just leave the following details:
|
||||
|
||||
- Arduino board: **INSERT ARDUINO BOARD NAME/TYPE HERE**
|
||||
|
||||
- Arduino IDE version (found in Arduino -> About Arduino menu): **INSERT ARDUINO
|
||||
VERSION HERE**
|
||||
|
||||
- List the steps to reproduce the problem below (if possible attach a sketch or
|
||||
copy the sketch code in too): **LIST REPRO STEPS BELOW**
|
||||
@@ -0,0 +1,26 @@
|
||||
Thank you for creating a pull request to contribute to Adafruit's GitHub code!
|
||||
Before you open the request please review the following guidelines and tips to
|
||||
help it be more easily integrated:
|
||||
|
||||
- **Describe the scope of your change--i.e. what the change does and what parts
|
||||
of the code were modified.** This will help us understand any risks of integrating
|
||||
the code.
|
||||
|
||||
- **Describe any known limitations with your change.** For example if the change
|
||||
doesn't apply to a supported platform of the library please mention it.
|
||||
|
||||
- **Please run any tests or examples that can exercise your modified code.** We
|
||||
strive to not break users of the code and running tests/examples helps with this
|
||||
process.
|
||||
|
||||
Thank you again for contributing! We will try to test and integrate the change
|
||||
as soon as we can, but be aware we have many GitHub repositories to manage and
|
||||
can't immediately respond to every request. There is no need to bump or check in
|
||||
on a pull request (it will clutter the discussion of the request).
|
||||
|
||||
Also don't be worried if the request is closed or not integrated--sometimes the
|
||||
priorities of Adafruit's GitHub code (education, ease of use) might not match the
|
||||
priorities of the pull request. Don't fret, the open source community thrives on
|
||||
forks and GitHub makes it easy to keep your changes in a forked repo.
|
||||
|
||||
After reviewing the guidelines above you can delete this text from the pull request.
|
||||
@@ -0,0 +1,11 @@
|
||||
language: c
|
||||
sudo: false
|
||||
before_install:
|
||||
- source <(curl -SLs https://raw.githubusercontent.com/adafruit/travis-ci-arduino/master/install.sh)
|
||||
script:
|
||||
- build_main_platforms
|
||||
- build_platform trinket
|
||||
notifications:
|
||||
email:
|
||||
on_success: change
|
||||
on_failure: change
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,181 @@
|
||||
/*--------------------------------------------------------------------
|
||||
This file is part of the Adafruit NeoPixel library.
|
||||
|
||||
NeoPixel is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
NeoPixel is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with NeoPixel. If not, see
|
||||
<http://www.gnu.org/licenses/>.
|
||||
--------------------------------------------------------------------*/
|
||||
|
||||
#ifndef ADAFRUIT_NEOPIXEL_H
|
||||
#define ADAFRUIT_NEOPIXEL_H
|
||||
|
||||
#if (ARDUINO >= 100)
|
||||
#include <Arduino.h>
|
||||
#else
|
||||
#include <WProgram.h>
|
||||
#include <pins_arduino.h>
|
||||
#endif
|
||||
|
||||
// The order of primary colors in the NeoPixel data stream can vary
|
||||
// among device types, manufacturers and even different revisions of
|
||||
// the same item. The third parameter to the Adafruit_NeoPixel
|
||||
// constructor encodes the per-pixel byte offsets of the red, green
|
||||
// and blue primaries (plus white, if present) in the data stream --
|
||||
// the following #defines provide an easier-to-use named version for
|
||||
// each permutation. e.g. NEO_GRB indicates a NeoPixel-compatible
|
||||
// device expecting three bytes per pixel, with the first byte
|
||||
// containing the green value, second containing red and third
|
||||
// containing blue. The in-memory representation of a chain of
|
||||
// NeoPixels is the same as the data-stream order; no re-ordering of
|
||||
// bytes is required when issuing data to the chain.
|
||||
|
||||
// Bits 5,4 of this value are the offset (0-3) from the first byte of
|
||||
// a pixel to the location of the red color byte. Bits 3,2 are the
|
||||
// green offset and 1,0 are the blue offset. If it is an RGBW-type
|
||||
// device (supporting a white primary in addition to R,G,B), bits 7,6
|
||||
// are the offset to the white byte...otherwise, bits 7,6 are set to
|
||||
// the same value as 5,4 (red) to indicate an RGB (not RGBW) device.
|
||||
// i.e. binary representation:
|
||||
// 0bWWRRGGBB for RGBW devices
|
||||
// 0bRRRRGGBB for RGB
|
||||
|
||||
// RGB NeoPixel permutations; white and red offsets are always same
|
||||
// Offset: W R G B
|
||||
#define NEO_RGB ((0 << 6) | (0 << 4) | (1 << 2) | (2))
|
||||
#define NEO_RBG ((0 << 6) | (0 << 4) | (2 << 2) | (1))
|
||||
#define NEO_GRB ((1 << 6) | (1 << 4) | (0 << 2) | (2))
|
||||
#define NEO_GBR ((2 << 6) | (2 << 4) | (0 << 2) | (1))
|
||||
#define NEO_BRG ((1 << 6) | (1 << 4) | (2 << 2) | (0))
|
||||
#define NEO_BGR ((2 << 6) | (2 << 4) | (1 << 2) | (0))
|
||||
|
||||
// RGBW NeoPixel permutations; all 4 offsets are distinct
|
||||
// Offset: W R G B
|
||||
#define NEO_WRGB ((0 << 6) | (1 << 4) | (2 << 2) | (3))
|
||||
#define NEO_WRBG ((0 << 6) | (1 << 4) | (3 << 2) | (2))
|
||||
#define NEO_WGRB ((0 << 6) | (2 << 4) | (1 << 2) | (3))
|
||||
#define NEO_WGBR ((0 << 6) | (3 << 4) | (1 << 2) | (2))
|
||||
#define NEO_WBRG ((0 << 6) | (2 << 4) | (3 << 2) | (1))
|
||||
#define NEO_WBGR ((0 << 6) | (3 << 4) | (2 << 2) | (1))
|
||||
|
||||
#define NEO_RWGB ((1 << 6) | (0 << 4) | (2 << 2) | (3))
|
||||
#define NEO_RWBG ((1 << 6) | (0 << 4) | (3 << 2) | (2))
|
||||
#define NEO_RGWB ((2 << 6) | (0 << 4) | (1 << 2) | (3))
|
||||
#define NEO_RGBW ((3 << 6) | (0 << 4) | (1 << 2) | (2))
|
||||
#define NEO_RBWG ((2 << 6) | (0 << 4) | (3 << 2) | (1))
|
||||
#define NEO_RBGW ((3 << 6) | (0 << 4) | (2 << 2) | (1))
|
||||
|
||||
#define NEO_GWRB ((1 << 6) | (2 << 4) | (0 << 2) | (3))
|
||||
#define NEO_GWBR ((1 << 6) | (3 << 4) | (0 << 2) | (2))
|
||||
#define NEO_GRWB ((2 << 6) | (1 << 4) | (0 << 2) | (3))
|
||||
#define NEO_GRBW ((3 << 6) | (1 << 4) | (0 << 2) | (2))
|
||||
#define NEO_GBWR ((2 << 6) | (3 << 4) | (0 << 2) | (1))
|
||||
#define NEO_GBRW ((3 << 6) | (2 << 4) | (0 << 2) | (1))
|
||||
|
||||
#define NEO_BWRG ((1 << 6) | (2 << 4) | (3 << 2) | (0))
|
||||
#define NEO_BWGR ((1 << 6) | (3 << 4) | (2 << 2) | (0))
|
||||
#define NEO_BRWG ((2 << 6) | (1 << 4) | (3 << 2) | (0))
|
||||
#define NEO_BRGW ((3 << 6) | (1 << 4) | (2 << 2) | (0))
|
||||
#define NEO_BGWR ((2 << 6) | (3 << 4) | (1 << 2) | (0))
|
||||
#define NEO_BGRW ((3 << 6) | (2 << 4) | (1 << 2) | (0))
|
||||
|
||||
// Add NEO_KHZ400 to the color order value to indicate a 400 KHz
|
||||
// device. All but the earliest v1 NeoPixels expect an 800 KHz data
|
||||
// stream, this is the default if unspecified. Because flash space
|
||||
// is very limited on ATtiny devices (e.g. Trinket, Gemma), v1
|
||||
// NeoPixels aren't handled by default on those chips, though it can
|
||||
// be enabled by removing the ifndef/endif below -- but code will be
|
||||
// bigger. Conversely, can disable the NEO_KHZ400 line on other MCUs
|
||||
// to remove v1 support and save a little space.
|
||||
|
||||
#define NEO_KHZ800 0x0000 // 800 KHz datastream
|
||||
#ifndef __AVR_ATtiny85__
|
||||
#define NEO_KHZ400 0x0100 // 400 KHz datastream
|
||||
#endif
|
||||
|
||||
// If 400 KHz support is enabled, the third parameter to the constructor
|
||||
// requires a 16-bit value (in order to select 400 vs 800 KHz speed).
|
||||
// If only 800 KHz is enabled (as is default on ATtiny), an 8-bit value
|
||||
// is sufficient to encode pixel color order, saving some space.
|
||||
|
||||
#ifdef NEO_KHZ400
|
||||
typedef uint16_t neoPixelType;
|
||||
#else
|
||||
typedef uint8_t neoPixelType;
|
||||
#endif
|
||||
|
||||
class Adafruit_NeoPixel {
|
||||
|
||||
public:
|
||||
|
||||
// Constructor: number of LEDs, pin number, LED type
|
||||
Adafruit_NeoPixel(uint16_t n, uint8_t p=6, neoPixelType t=NEO_GRB + NEO_KHZ800);
|
||||
Adafruit_NeoPixel(void);
|
||||
~Adafruit_NeoPixel();
|
||||
|
||||
void
|
||||
begin(void),
|
||||
show(void),
|
||||
setPin(uint8_t p),
|
||||
setPixelColor(uint16_t n, uint8_t r, uint8_t g, uint8_t b),
|
||||
setPixelColor(uint16_t n, uint8_t r, uint8_t g, uint8_t b, uint8_t w),
|
||||
setPixelColor(uint16_t n, uint32_t c),
|
||||
setBrightness(uint8_t),
|
||||
clear(),
|
||||
updateLength(uint16_t n),
|
||||
updateType(neoPixelType t);
|
||||
uint8_t
|
||||
*getPixels(void) const,
|
||||
getBrightness(void) const;
|
||||
int8_t
|
||||
getPin(void) { return pin; };
|
||||
uint16_t
|
||||
numPixels(void) const;
|
||||
static uint32_t
|
||||
Color(uint8_t r, uint8_t g, uint8_t b),
|
||||
Color(uint8_t r, uint8_t g, uint8_t b, uint8_t w);
|
||||
uint32_t
|
||||
getPixelColor(uint16_t n) const;
|
||||
inline bool
|
||||
canShow(void) { return (micros() - endTime) >= 50L; }
|
||||
|
||||
private:
|
||||
|
||||
boolean
|
||||
#ifdef NEO_KHZ400 // If 400 KHz NeoPixel support enabled...
|
||||
is800KHz, // ...true if 800 KHz pixels
|
||||
#endif
|
||||
begun; // true if begin() previously called
|
||||
uint16_t
|
||||
numLEDs, // Number of RGB LEDs in strip
|
||||
numBytes; // Size of 'pixels' buffer below (3 or 4 bytes/pixel)
|
||||
int8_t
|
||||
pin; // Output pin number (-1 if not yet set)
|
||||
uint8_t
|
||||
brightness,
|
||||
*pixels, // Holds LED color values (3 or 4 bytes each)
|
||||
rOffset, // Index of red byte within each 3- or 4-byte pixel
|
||||
gOffset, // Index of green byte
|
||||
bOffset, // Index of blue byte
|
||||
wOffset; // Index of white byte (same as rOffset if no white)
|
||||
uint32_t
|
||||
endTime; // Latch timing reference
|
||||
#ifdef __AVR__
|
||||
volatile uint8_t
|
||||
*port; // Output PORT register
|
||||
uint8_t
|
||||
pinMask; // Output PORT bitmask
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
#endif // ADAFRUIT_NEOPIXEL_H
|
||||
@@ -0,0 +1,165 @@
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
|
||||
This version of the GNU Lesser General Public License incorporates
|
||||
the terms and conditions of version 3 of the GNU General Public
|
||||
License, supplemented by the additional permissions listed below.
|
||||
|
||||
0. Additional Definitions.
|
||||
|
||||
As used herein, "this License" refers to version 3 of the GNU Lesser
|
||||
General Public License, and the "GNU GPL" refers to version 3 of the GNU
|
||||
General Public License.
|
||||
|
||||
"The Library" refers to a covered work governed by this License,
|
||||
other than an Application or a Combined Work as defined below.
|
||||
|
||||
An "Application" is any work that makes use of an interface provided
|
||||
by the Library, but which is not otherwise based on the Library.
|
||||
Defining a subclass of a class defined by the Library is deemed a mode
|
||||
of using an interface provided by the Library.
|
||||
|
||||
A "Combined Work" is a work produced by combining or linking an
|
||||
Application with the Library. The particular version of the Library
|
||||
with which the Combined Work was made is also called the "Linked
|
||||
Version".
|
||||
|
||||
The "Minimal Corresponding Source" for a Combined Work means the
|
||||
Corresponding Source for the Combined Work, excluding any source code
|
||||
for portions of the Combined Work that, considered in isolation, are
|
||||
based on the Application, and not on the Linked Version.
|
||||
|
||||
The "Corresponding Application Code" for a Combined Work means the
|
||||
object code and/or source code for the Application, including any data
|
||||
and utility programs needed for reproducing the Combined Work from the
|
||||
Application, but excluding the System Libraries of the Combined Work.
|
||||
|
||||
1. Exception to Section 3 of the GNU GPL.
|
||||
|
||||
You may convey a covered work under sections 3 and 4 of this License
|
||||
without being bound by section 3 of the GNU GPL.
|
||||
|
||||
2. Conveying Modified Versions.
|
||||
|
||||
If you modify a copy of the Library, and, in your modifications, a
|
||||
facility refers to a function or data to be supplied by an Application
|
||||
that uses the facility (other than as an argument passed when the
|
||||
facility is invoked), then you may convey a copy of the modified
|
||||
version:
|
||||
|
||||
a) under this License, provided that you make a good faith effort to
|
||||
ensure that, in the event an Application does not supply the
|
||||
function or data, the facility still operates, and performs
|
||||
whatever part of its purpose remains meaningful, or
|
||||
|
||||
b) under the GNU GPL, with none of the additional permissions of
|
||||
this License applicable to that copy.
|
||||
|
||||
3. Object Code Incorporating Material from Library Header Files.
|
||||
|
||||
The object code form of an Application may incorporate material from
|
||||
a header file that is part of the Library. You may convey such object
|
||||
code under terms of your choice, provided that, if the incorporated
|
||||
material is not limited to numerical parameters, data structure
|
||||
layouts and accessors, or small macros, inline functions and templates
|
||||
(ten or fewer lines in length), you do both of the following:
|
||||
|
||||
a) Give prominent notice with each copy of the object code that the
|
||||
Library is used in it and that the Library and its use are
|
||||
covered by this License.
|
||||
|
||||
b) Accompany the object code with a copy of the GNU GPL and this license
|
||||
document.
|
||||
|
||||
4. Combined Works.
|
||||
|
||||
You may convey a Combined Work under terms of your choice that,
|
||||
taken together, effectively do not restrict modification of the
|
||||
portions of the Library contained in the Combined Work and reverse
|
||||
engineering for debugging such modifications, if you also do each of
|
||||
the following:
|
||||
|
||||
a) Give prominent notice with each copy of the Combined Work that
|
||||
the Library is used in it and that the Library and its use are
|
||||
covered by this License.
|
||||
|
||||
b) Accompany the Combined Work with a copy of the GNU GPL and this license
|
||||
document.
|
||||
|
||||
c) For a Combined Work that displays copyright notices during
|
||||
execution, include the copyright notice for the Library among
|
||||
these notices, as well as a reference directing the user to the
|
||||
copies of the GNU GPL and this license document.
|
||||
|
||||
d) Do one of the following:
|
||||
|
||||
0) Convey the Minimal Corresponding Source under the terms of this
|
||||
License, and the Corresponding Application Code in a form
|
||||
suitable for, and under terms that permit, the user to
|
||||
recombine or relink the Application with a modified version of
|
||||
the Linked Version to produce a modified Combined Work, in the
|
||||
manner specified by section 6 of the GNU GPL for conveying
|
||||
Corresponding Source.
|
||||
|
||||
1) Use a suitable shared library mechanism for linking with the
|
||||
Library. A suitable mechanism is one that (a) uses at run time
|
||||
a copy of the Library already present on the user's computer
|
||||
system, and (b) will operate properly with a modified version
|
||||
of the Library that is interface-compatible with the Linked
|
||||
Version.
|
||||
|
||||
e) Provide Installation Information, but only if you would otherwise
|
||||
be required to provide such information under section 6 of the
|
||||
GNU GPL, and only to the extent that such information is
|
||||
necessary to install and execute a modified version of the
|
||||
Combined Work produced by recombining or relinking the
|
||||
Application with a modified version of the Linked Version. (If
|
||||
you use option 4d0, the Installation Information must accompany
|
||||
the Minimal Corresponding Source and Corresponding Application
|
||||
Code. If you use option 4d1, you must provide the Installation
|
||||
Information in the manner specified by section 6 of the GNU GPL
|
||||
for conveying Corresponding Source.)
|
||||
|
||||
5. Combined Libraries.
|
||||
|
||||
You may place library facilities that are a work based on the
|
||||
Library side by side in a single library together with other library
|
||||
facilities that are not Applications and are not covered by this
|
||||
License, and convey such a combined library under terms of your
|
||||
choice, if you do both of the following:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work based
|
||||
on the Library, uncombined with any other library facilities,
|
||||
conveyed under the terms of this License.
|
||||
|
||||
b) Give prominent notice with the combined library that part of it
|
||||
is a work based on the Library, and explaining where to find the
|
||||
accompanying uncombined form of the same work.
|
||||
|
||||
6. Revised Versions of the GNU Lesser General Public License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions
|
||||
of the GNU Lesser General Public License from time to time. Such new
|
||||
versions will be similar in spirit to the present version, but may
|
||||
differ in detail to address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Library as you received it specifies that a certain numbered version
|
||||
of the GNU Lesser General Public License "or any later version"
|
||||
applies to it, you have the option of following the terms and
|
||||
conditions either of that published version or of any later version
|
||||
published by the Free Software Foundation. If the Library as you
|
||||
received it does not specify a version number of the GNU Lesser
|
||||
General Public License, you may choose any version of the GNU Lesser
|
||||
General Public License ever published by the Free Software Foundation.
|
||||
|
||||
If the Library as you received it specifies that a proxy can decide
|
||||
whether future versions of the GNU Lesser General Public License shall
|
||||
apply, that proxy's public statement of acceptance of any version is
|
||||
permanent authorization for you to choose that version for the
|
||||
Library.
|
||||
@@ -0,0 +1,11 @@
|
||||
# Adafruit NeoPixel Library [](https://travis-ci.org/adafruit/Adafruit_NeoPixel)
|
||||
|
||||
Arduino library for controlling single-wire-based LED pixels and strip such as the [Adafruit 60 LED/meter Digital LED strip][strip], the [Adafruit FLORA RGB Smart Pixel][flora], the [Adafruit Breadboard-friendly RGB Smart Pixel][pixel], the [Adafruit NeoPixel Stick][stick], and the [Adafruit NeoPixel Shield][shield].
|
||||
|
||||
After downloading, rename folder to 'Adafruit_NeoPixel' and install in Arduino Libraries folder. Restart Arduino IDE, then open File->Sketchbook->Library->Adafruit_NeoPixel->strandtest sketch.
|
||||
|
||||
[flora]: http://adafruit.com/products/1060
|
||||
[strip]: http://adafruit.com/products/1138
|
||||
[pixel]: http://adafruit.com/products/1312
|
||||
[stick]: http://adafruit.com/products/1426
|
||||
[shield]: http://adafruit.com/products/1430
|
||||
@@ -0,0 +1,67 @@
|
||||
// This is a mash-up of the Due show() code + insights from Michael Miller's
|
||||
// ESP8266 work for the NeoPixelBus library: github.com/Makuna/NeoPixelBus
|
||||
// Needs to be a separate .c file to enforce ICACHE_RAM_ATTR execution.
|
||||
|
||||
#ifdef ESP8266
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <eagle_soc.h>
|
||||
|
||||
static uint32_t _getCycleCount(void) __attribute__((always_inline));
|
||||
static inline uint32_t _getCycleCount(void) {
|
||||
uint32_t ccount;
|
||||
__asm__ __volatile__("rsr %0,ccount":"=a" (ccount));
|
||||
return ccount;
|
||||
}
|
||||
|
||||
void ICACHE_RAM_ATTR espShow(
|
||||
uint8_t pin, uint8_t *pixels, uint32_t numBytes, boolean is800KHz) {
|
||||
|
||||
#define CYCLES_800_T0H (F_CPU / 2500000) // 0.4us
|
||||
#define CYCLES_800_T1H (F_CPU / 1250000) // 0.8us
|
||||
#define CYCLES_800 (F_CPU / 800000) // 1.25us per bit
|
||||
#define CYCLES_400_T0H (F_CPU / 2000000) // 0.5uS
|
||||
#define CYCLES_400_T1H (F_CPU / 833333) // 1.2us
|
||||
#define CYCLES_400 (F_CPU / 400000) // 2.5us per bit
|
||||
|
||||
uint8_t *p, *end, pix, mask;
|
||||
uint32_t t, time0, time1, period, c, startTime, pinMask;
|
||||
|
||||
pinMask = _BV(pin);
|
||||
p = pixels;
|
||||
end = p + numBytes;
|
||||
pix = *p++;
|
||||
mask = 0x80;
|
||||
startTime = 0;
|
||||
|
||||
#ifdef NEO_KHZ400
|
||||
if(is800KHz) {
|
||||
#endif
|
||||
time0 = CYCLES_800_T0H;
|
||||
time1 = CYCLES_800_T1H;
|
||||
period = CYCLES_800;
|
||||
#ifdef NEO_KHZ400
|
||||
} else { // 400 KHz bitstream
|
||||
time0 = CYCLES_400_T0H;
|
||||
time1 = CYCLES_400_T1H;
|
||||
period = CYCLES_400;
|
||||
}
|
||||
#endif
|
||||
|
||||
for(t = time0;; t = time0) {
|
||||
if(pix & mask) t = time1; // Bit high duration
|
||||
while(((c = _getCycleCount()) - startTime) < period); // Wait for bit start
|
||||
GPIO_REG_WRITE(GPIO_OUT_W1TS_ADDRESS, pinMask); // Set high
|
||||
startTime = c; // Save start time
|
||||
while(((c = _getCycleCount()) - startTime) < t); // Wait high duration
|
||||
GPIO_REG_WRITE(GPIO_OUT_W1TC_ADDRESS, pinMask); // Set low
|
||||
if(!(mask >>= 1)) { // Next bit/byte
|
||||
if(p >= end) break;
|
||||
pix = *p++;
|
||||
mask = 0x80;
|
||||
}
|
||||
}
|
||||
while((_getCycleCount() - startTime) < period); // Wait for last bit
|
||||
}
|
||||
|
||||
#endif // ESP8266
|
||||
@@ -0,0 +1,263 @@
|
||||
#include <Adafruit_NeoPixel.h>
|
||||
#ifdef __AVR__
|
||||
#include <avr/power.h>
|
||||
#endif
|
||||
|
||||
#define PIN 6
|
||||
|
||||
#define NUM_LEDS 60
|
||||
|
||||
#define BRIGHTNESS 50
|
||||
|
||||
Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUM_LEDS, PIN, NEO_GRBW + NEO_KHZ800);
|
||||
|
||||
int gamma[] = {
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2,
|
||||
2, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5,
|
||||
5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10,
|
||||
10, 10, 11, 11, 11, 12, 12, 13, 13, 13, 14, 14, 15, 15, 16, 16,
|
||||
17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, 23, 24, 24, 25,
|
||||
25, 26, 27, 27, 28, 29, 29, 30, 31, 32, 32, 33, 34, 35, 35, 36,
|
||||
37, 38, 39, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 50,
|
||||
51, 52, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 66, 67, 68,
|
||||
69, 70, 72, 73, 74, 75, 77, 78, 79, 81, 82, 83, 85, 86, 87, 89,
|
||||
90, 92, 93, 95, 96, 98, 99,101,102,104,105,107,109,110,112,114,
|
||||
115,117,119,120,122,124,126,127,129,131,133,135,137,138,140,142,
|
||||
144,146,148,150,152,154,156,158,160,162,164,167,169,171,173,175,
|
||||
177,180,182,184,186,189,191,193,196,198,200,203,205,208,210,213,
|
||||
215,218,220,223,225,228,231,233,236,239,241,244,247,249,252,255 };
|
||||
|
||||
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
// This is for Trinket 5V 16MHz, you can remove these three lines if you are not using a Trinket
|
||||
#if defined (__AVR_ATtiny85__)
|
||||
if (F_CPU == 16000000) clock_prescale_set(clock_div_1);
|
||||
#endif
|
||||
// End of trinket special code
|
||||
strip.setBrightness(BRIGHTNESS);
|
||||
strip.begin();
|
||||
strip.show(); // Initialize all pixels to 'off'
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// Some example procedures showing how to display to the pixels:
|
||||
colorWipe(strip.Color(255, 0, 0), 50); // Red
|
||||
colorWipe(strip.Color(0, 255, 0), 50); // Green
|
||||
colorWipe(strip.Color(0, 0, 255), 50); // Blue
|
||||
colorWipe(strip.Color(0, 0, 0, 255), 50); // White
|
||||
|
||||
whiteOverRainbow(20,75,5);
|
||||
|
||||
pulseWhite(5);
|
||||
|
||||
// fullWhite();
|
||||
// delay(2000);
|
||||
|
||||
rainbowFade2White(3,3,1);
|
||||
|
||||
|
||||
}
|
||||
|
||||
// Fill the dots one after the other with a color
|
||||
void colorWipe(uint32_t c, uint8_t wait) {
|
||||
for(uint16_t i=0; i<strip.numPixels(); i++) {
|
||||
strip.setPixelColor(i, c);
|
||||
strip.show();
|
||||
delay(wait);
|
||||
}
|
||||
}
|
||||
|
||||
void pulseWhite(uint8_t wait) {
|
||||
for(int j = 0; j < 256 ; j++){
|
||||
for(uint16_t i=0; i<strip.numPixels(); i++) {
|
||||
strip.setPixelColor(i, strip.Color(0,0,0, gamma[j] ) );
|
||||
}
|
||||
delay(wait);
|
||||
strip.show();
|
||||
}
|
||||
|
||||
for(int j = 255; j >= 0 ; j--){
|
||||
for(uint16_t i=0; i<strip.numPixels(); i++) {
|
||||
strip.setPixelColor(i, strip.Color(0,0,0, gamma[j] ) );
|
||||
}
|
||||
delay(wait);
|
||||
strip.show();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void rainbowFade2White(uint8_t wait, int rainbowLoops, int whiteLoops) {
|
||||
float fadeMax = 100.0;
|
||||
int fadeVal = 0;
|
||||
uint32_t wheelVal;
|
||||
int redVal, greenVal, blueVal;
|
||||
|
||||
for(int k = 0 ; k < rainbowLoops ; k ++){
|
||||
|
||||
for(int j=0; j<256; j++) { // 5 cycles of all colors on wheel
|
||||
|
||||
for(int i=0; i< strip.numPixels(); i++) {
|
||||
|
||||
wheelVal = Wheel(((i * 256 / strip.numPixels()) + j) & 255);
|
||||
|
||||
redVal = red(wheelVal) * float(fadeVal/fadeMax);
|
||||
greenVal = green(wheelVal) * float(fadeVal/fadeMax);
|
||||
blueVal = blue(wheelVal) * float(fadeVal/fadeMax);
|
||||
|
||||
strip.setPixelColor( i, strip.Color( redVal, greenVal, blueVal ) );
|
||||
|
||||
}
|
||||
|
||||
//First loop, fade in!
|
||||
if(k == 0 && fadeVal < fadeMax-1) {
|
||||
fadeVal++;
|
||||
}
|
||||
|
||||
//Last loop, fade out!
|
||||
else if(k == rainbowLoops - 1 && j > 255 - fadeMax ){
|
||||
fadeVal--;
|
||||
}
|
||||
|
||||
strip.show();
|
||||
delay(wait);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
delay(500);
|
||||
|
||||
|
||||
for(int k = 0 ; k < whiteLoops ; k ++){
|
||||
|
||||
for(int j = 0; j < 256 ; j++){
|
||||
|
||||
for(uint16_t i=0; i < strip.numPixels(); i++) {
|
||||
strip.setPixelColor(i, strip.Color(0,0,0, gamma[j] ) );
|
||||
}
|
||||
strip.show();
|
||||
}
|
||||
|
||||
delay(2000);
|
||||
for(int j = 255; j >= 0 ; j--){
|
||||
|
||||
for(uint16_t i=0; i < strip.numPixels(); i++) {
|
||||
strip.setPixelColor(i, strip.Color(0,0,0, gamma[j] ) );
|
||||
}
|
||||
strip.show();
|
||||
}
|
||||
}
|
||||
|
||||
delay(500);
|
||||
|
||||
|
||||
}
|
||||
|
||||
void whiteOverRainbow(uint8_t wait, uint8_t whiteSpeed, uint8_t whiteLength ) {
|
||||
|
||||
if(whiteLength >= strip.numPixels()) whiteLength = strip.numPixels() - 1;
|
||||
|
||||
int head = whiteLength - 1;
|
||||
int tail = 0;
|
||||
|
||||
int loops = 3;
|
||||
int loopNum = 0;
|
||||
|
||||
static unsigned long lastTime = 0;
|
||||
|
||||
|
||||
while(true){
|
||||
for(int j=0; j<256; j++) {
|
||||
for(uint16_t i=0; i<strip.numPixels(); i++) {
|
||||
if((i >= tail && i <= head) || (tail > head && i >= tail) || (tail > head && i <= head) ){
|
||||
strip.setPixelColor(i, strip.Color(0,0,0, 255 ) );
|
||||
}
|
||||
else{
|
||||
strip.setPixelColor(i, Wheel(((i * 256 / strip.numPixels()) + j) & 255));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if(millis() - lastTime > whiteSpeed) {
|
||||
head++;
|
||||
tail++;
|
||||
if(head == strip.numPixels()){
|
||||
loopNum++;
|
||||
}
|
||||
lastTime = millis();
|
||||
}
|
||||
|
||||
if(loopNum == loops) return;
|
||||
|
||||
head%=strip.numPixels();
|
||||
tail%=strip.numPixels();
|
||||
strip.show();
|
||||
delay(wait);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
void fullWhite() {
|
||||
|
||||
for(uint16_t i=0; i<strip.numPixels(); i++) {
|
||||
strip.setPixelColor(i, strip.Color(0,0,0, 255 ) );
|
||||
}
|
||||
strip.show();
|
||||
}
|
||||
|
||||
|
||||
// Slightly different, this makes the rainbow equally distributed throughout
|
||||
void rainbowCycle(uint8_t wait) {
|
||||
uint16_t i, j;
|
||||
|
||||
for(j=0; j<256 * 5; j++) { // 5 cycles of all colors on wheel
|
||||
for(i=0; i< strip.numPixels(); i++) {
|
||||
strip.setPixelColor(i, Wheel(((i * 256 / strip.numPixels()) + j) & 255));
|
||||
}
|
||||
strip.show();
|
||||
delay(wait);
|
||||
}
|
||||
}
|
||||
|
||||
void rainbow(uint8_t wait) {
|
||||
uint16_t i, j;
|
||||
|
||||
for(j=0; j<256; j++) {
|
||||
for(i=0; i<strip.numPixels(); i++) {
|
||||
strip.setPixelColor(i, Wheel((i+j) & 255));
|
||||
}
|
||||
strip.show();
|
||||
delay(wait);
|
||||
}
|
||||
}
|
||||
|
||||
// Input a value 0 to 255 to get a color value.
|
||||
// The colours are a transition r - g - b - back to r.
|
||||
uint32_t Wheel(byte WheelPos) {
|
||||
WheelPos = 255 - WheelPos;
|
||||
if(WheelPos < 85) {
|
||||
return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3,0);
|
||||
}
|
||||
if(WheelPos < 170) {
|
||||
WheelPos -= 85;
|
||||
return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3,0);
|
||||
}
|
||||
WheelPos -= 170;
|
||||
return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0,0);
|
||||
}
|
||||
|
||||
uint8_t red(uint32_t c) {
|
||||
return (c >> 8);
|
||||
}
|
||||
uint8_t green(uint32_t c) {
|
||||
return (c >> 16);
|
||||
}
|
||||
uint8_t blue(uint32_t c) {
|
||||
return (c);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,165 @@
|
||||
// This is a demonstration on how to use an input device to trigger changes on your neo pixels.
|
||||
// You should wire a momentary push button to connect from ground to a digital IO pin. When you
|
||||
// press the button it will change to a new pixel animation. Note that you need to press the
|
||||
// button once to start the first animation!
|
||||
|
||||
#include <Adafruit_NeoPixel.h>
|
||||
|
||||
#define BUTTON_PIN 2 // Digital IO pin connected to the button. This will be
|
||||
// driven with a pull-up resistor so the switch should
|
||||
// pull the pin to ground momentarily. On a high -> low
|
||||
// transition the button press logic will execute.
|
||||
|
||||
#define PIXEL_PIN 6 // Digital IO pin connected to the NeoPixels.
|
||||
|
||||
#define PIXEL_COUNT 16
|
||||
|
||||
// Parameter 1 = number of pixels in strip, neopixel stick has 8
|
||||
// Parameter 2 = pin number (most are valid)
|
||||
// Parameter 3 = pixel type flags, add together as needed:
|
||||
// NEO_RGB Pixels are wired for RGB bitstream
|
||||
// NEO_GRB Pixels are wired for GRB bitstream, correct for neopixel stick
|
||||
// NEO_KHZ400 400 KHz bitstream (e.g. FLORA pixels)
|
||||
// NEO_KHZ800 800 KHz bitstream (e.g. High Density LED strip), correct for neopixel stick
|
||||
Adafruit_NeoPixel strip = Adafruit_NeoPixel(PIXEL_COUNT, PIXEL_PIN, NEO_GRB + NEO_KHZ800);
|
||||
|
||||
bool oldState = HIGH;
|
||||
int showType = 0;
|
||||
|
||||
void setup() {
|
||||
pinMode(BUTTON_PIN, INPUT_PULLUP);
|
||||
strip.begin();
|
||||
strip.show(); // Initialize all pixels to 'off'
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// Get current button state.
|
||||
bool newState = digitalRead(BUTTON_PIN);
|
||||
|
||||
// Check if state changed from high to low (button press).
|
||||
if (newState == LOW && oldState == HIGH) {
|
||||
// Short delay to debounce button.
|
||||
delay(20);
|
||||
// Check if button is still low after debounce.
|
||||
newState = digitalRead(BUTTON_PIN);
|
||||
if (newState == LOW) {
|
||||
showType++;
|
||||
if (showType > 9)
|
||||
showType=0;
|
||||
startShow(showType);
|
||||
}
|
||||
}
|
||||
|
||||
// Set the last button state to the old state.
|
||||
oldState = newState;
|
||||
}
|
||||
|
||||
void startShow(int i) {
|
||||
switch(i){
|
||||
case 0: colorWipe(strip.Color(0, 0, 0), 50); // Black/off
|
||||
break;
|
||||
case 1: colorWipe(strip.Color(255, 0, 0), 50); // Red
|
||||
break;
|
||||
case 2: colorWipe(strip.Color(0, 255, 0), 50); // Green
|
||||
break;
|
||||
case 3: colorWipe(strip.Color(0, 0, 255), 50); // Blue
|
||||
break;
|
||||
case 4: theaterChase(strip.Color(127, 127, 127), 50); // White
|
||||
break;
|
||||
case 5: theaterChase(strip.Color(127, 0, 0), 50); // Red
|
||||
break;
|
||||
case 6: theaterChase(strip.Color( 0, 0, 127), 50); // Blue
|
||||
break;
|
||||
case 7: rainbow(20);
|
||||
break;
|
||||
case 8: rainbowCycle(20);
|
||||
break;
|
||||
case 9: theaterChaseRainbow(50);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Fill the dots one after the other with a color
|
||||
void colorWipe(uint32_t c, uint8_t wait) {
|
||||
for(uint16_t i=0; i<strip.numPixels(); i++) {
|
||||
strip.setPixelColor(i, c);
|
||||
strip.show();
|
||||
delay(wait);
|
||||
}
|
||||
}
|
||||
|
||||
void rainbow(uint8_t wait) {
|
||||
uint16_t i, j;
|
||||
|
||||
for(j=0; j<256; j++) {
|
||||
for(i=0; i<strip.numPixels(); i++) {
|
||||
strip.setPixelColor(i, Wheel((i+j) & 255));
|
||||
}
|
||||
strip.show();
|
||||
delay(wait);
|
||||
}
|
||||
}
|
||||
|
||||
// Slightly different, this makes the rainbow equally distributed throughout
|
||||
void rainbowCycle(uint8_t wait) {
|
||||
uint16_t i, j;
|
||||
|
||||
for(j=0; j<256*5; j++) { // 5 cycles of all colors on wheel
|
||||
for(i=0; i< strip.numPixels(); i++) {
|
||||
strip.setPixelColor(i, Wheel(((i * 256 / strip.numPixels()) + j) & 255));
|
||||
}
|
||||
strip.show();
|
||||
delay(wait);
|
||||
}
|
||||
}
|
||||
|
||||
//Theatre-style crawling lights.
|
||||
void theaterChase(uint32_t c, uint8_t wait) {
|
||||
for (int j=0; j<10; j++) { //do 10 cycles of chasing
|
||||
for (int q=0; q < 3; q++) {
|
||||
for (int i=0; i < strip.numPixels(); i=i+3) {
|
||||
strip.setPixelColor(i+q, c); //turn every third pixel on
|
||||
}
|
||||
strip.show();
|
||||
|
||||
delay(wait);
|
||||
|
||||
for (int i=0; i < strip.numPixels(); i=i+3) {
|
||||
strip.setPixelColor(i+q, 0); //turn every third pixel off
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Theatre-style crawling lights with rainbow effect
|
||||
void theaterChaseRainbow(uint8_t wait) {
|
||||
for (int j=0; j < 256; j++) { // cycle all 256 colors in the wheel
|
||||
for (int q=0; q < 3; q++) {
|
||||
for (int i=0; i < strip.numPixels(); i=i+3) {
|
||||
strip.setPixelColor(i+q, Wheel( (i+j) % 255)); //turn every third pixel on
|
||||
}
|
||||
strip.show();
|
||||
|
||||
delay(wait);
|
||||
|
||||
for (int i=0; i < strip.numPixels(); i=i+3) {
|
||||
strip.setPixelColor(i+q, 0); //turn every third pixel off
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Input a value 0 to 255 to get a color value.
|
||||
// The colours are a transition r - g - b - back to r.
|
||||
uint32_t Wheel(byte WheelPos) {
|
||||
WheelPos = 255 - WheelPos;
|
||||
if(WheelPos < 85) {
|
||||
return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3);
|
||||
}
|
||||
if(WheelPos < 170) {
|
||||
WheelPos -= 85;
|
||||
return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3);
|
||||
}
|
||||
WheelPos -= 170;
|
||||
return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
// NeoPixel Ring simple sketch (c) 2013 Shae Erisson
|
||||
// released under the GPLv3 license to match the rest of the AdaFruit NeoPixel library
|
||||
|
||||
#include <Adafruit_NeoPixel.h>
|
||||
#ifdef __AVR__
|
||||
#include <avr/power.h>
|
||||
#endif
|
||||
|
||||
// Which pin on the Arduino is connected to the NeoPixels?
|
||||
// On a Trinket or Gemma we suggest changing this to 1
|
||||
#define PIN 6
|
||||
|
||||
// How many NeoPixels are attached to the Arduino?
|
||||
#define NUMPIXELS 16
|
||||
|
||||
// When we setup the NeoPixel library, we tell it how many pixels, and which pin to use to send signals.
|
||||
// Note that for older NeoPixel strips you might need to change the third parameter--see the strandtest
|
||||
// example for more information on possible values.
|
||||
Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);
|
||||
|
||||
int delayval = 500; // delay for half a second
|
||||
|
||||
void setup() {
|
||||
// This is for Trinket 5V 16MHz, you can remove these three lines if you are not using a Trinket
|
||||
#if defined (__AVR_ATtiny85__)
|
||||
if (F_CPU == 16000000) clock_prescale_set(clock_div_1);
|
||||
#endif
|
||||
// End of trinket special code
|
||||
|
||||
pixels.begin(); // This initializes the NeoPixel library.
|
||||
}
|
||||
|
||||
void loop() {
|
||||
|
||||
// For a set of NeoPixels the first NeoPixel is 0, second is 1, all the way up to the count of pixels minus one.
|
||||
|
||||
for(int i=0;i<NUMPIXELS;i++){
|
||||
|
||||
// pixels.Color takes RGB values, from 0,0,0 up to 255,255,255
|
||||
pixels.setPixelColor(i, pixels.Color(0,150,0)); // Moderately bright green color.
|
||||
|
||||
pixels.show(); // This sends the updated pixel color to the hardware.
|
||||
|
||||
delay(delayval); // Delay for a period of time (in milliseconds).
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,134 @@
|
||||
#include <Adafruit_NeoPixel.h>
|
||||
#ifdef __AVR__
|
||||
#include <avr/power.h>
|
||||
#endif
|
||||
|
||||
#define PIN 6
|
||||
|
||||
// Parameter 1 = number of pixels in strip
|
||||
// Parameter 2 = Arduino pin number (most are valid)
|
||||
// Parameter 3 = pixel type flags, add together as needed:
|
||||
// NEO_KHZ800 800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
|
||||
// NEO_KHZ400 400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
|
||||
// NEO_GRB Pixels are wired for GRB bitstream (most NeoPixel products)
|
||||
// NEO_RGB Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2)
|
||||
// NEO_RGBW Pixels are wired for RGBW bitstream (NeoPixel RGBW products)
|
||||
Adafruit_NeoPixel strip = Adafruit_NeoPixel(60, PIN, NEO_GRB + NEO_KHZ800);
|
||||
|
||||
// IMPORTANT: To reduce NeoPixel burnout risk, add 1000 uF capacitor across
|
||||
// pixel power leads, add 300 - 500 Ohm resistor on first pixel's data input
|
||||
// and minimize distance between Arduino and first pixel. Avoid connecting
|
||||
// on a live circuit...if you must, connect GND first.
|
||||
|
||||
void setup() {
|
||||
// This is for Trinket 5V 16MHz, you can remove these three lines if you are not using a Trinket
|
||||
#if defined (__AVR_ATtiny85__)
|
||||
if (F_CPU == 16000000) clock_prescale_set(clock_div_1);
|
||||
#endif
|
||||
// End of trinket special code
|
||||
|
||||
|
||||
strip.begin();
|
||||
strip.show(); // Initialize all pixels to 'off'
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// Some example procedures showing how to display to the pixels:
|
||||
colorWipe(strip.Color(255, 0, 0), 50); // Red
|
||||
colorWipe(strip.Color(0, 255, 0), 50); // Green
|
||||
colorWipe(strip.Color(0, 0, 255), 50); // Blue
|
||||
//colorWipe(strip.Color(0, 0, 0, 255), 50); // White RGBW
|
||||
// Send a theater pixel chase in...
|
||||
theaterChase(strip.Color(127, 127, 127), 50); // White
|
||||
theaterChase(strip.Color(127, 0, 0), 50); // Red
|
||||
theaterChase(strip.Color(0, 0, 127), 50); // Blue
|
||||
|
||||
rainbow(20);
|
||||
rainbowCycle(20);
|
||||
theaterChaseRainbow(50);
|
||||
}
|
||||
|
||||
// Fill the dots one after the other with a color
|
||||
void colorWipe(uint32_t c, uint8_t wait) {
|
||||
for(uint16_t i=0; i<strip.numPixels(); i++) {
|
||||
strip.setPixelColor(i, c);
|
||||
strip.show();
|
||||
delay(wait);
|
||||
}
|
||||
}
|
||||
|
||||
void rainbow(uint8_t wait) {
|
||||
uint16_t i, j;
|
||||
|
||||
for(j=0; j<256; j++) {
|
||||
for(i=0; i<strip.numPixels(); i++) {
|
||||
strip.setPixelColor(i, Wheel((i+j) & 255));
|
||||
}
|
||||
strip.show();
|
||||
delay(wait);
|
||||
}
|
||||
}
|
||||
|
||||
// Slightly different, this makes the rainbow equally distributed throughout
|
||||
void rainbowCycle(uint8_t wait) {
|
||||
uint16_t i, j;
|
||||
|
||||
for(j=0; j<256*5; j++) { // 5 cycles of all colors on wheel
|
||||
for(i=0; i< strip.numPixels(); i++) {
|
||||
strip.setPixelColor(i, Wheel(((i * 256 / strip.numPixels()) + j) & 255));
|
||||
}
|
||||
strip.show();
|
||||
delay(wait);
|
||||
}
|
||||
}
|
||||
|
||||
//Theatre-style crawling lights.
|
||||
void theaterChase(uint32_t c, uint8_t wait) {
|
||||
for (int j=0; j<10; j++) { //do 10 cycles of chasing
|
||||
for (int q=0; q < 3; q++) {
|
||||
for (uint16_t i=0; i < strip.numPixels(); i=i+3) {
|
||||
strip.setPixelColor(i+q, c); //turn every third pixel on
|
||||
}
|
||||
strip.show();
|
||||
|
||||
delay(wait);
|
||||
|
||||
for (uint16_t i=0; i < strip.numPixels(); i=i+3) {
|
||||
strip.setPixelColor(i+q, 0); //turn every third pixel off
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Theatre-style crawling lights with rainbow effect
|
||||
void theaterChaseRainbow(uint8_t wait) {
|
||||
for (int j=0; j < 256; j++) { // cycle all 256 colors in the wheel
|
||||
for (int q=0; q < 3; q++) {
|
||||
for (uint16_t i=0; i < strip.numPixels(); i=i+3) {
|
||||
strip.setPixelColor(i+q, Wheel( (i+j) % 255)); //turn every third pixel on
|
||||
}
|
||||
strip.show();
|
||||
|
||||
delay(wait);
|
||||
|
||||
for (uint16_t i=0; i < strip.numPixels(); i=i+3) {
|
||||
strip.setPixelColor(i+q, 0); //turn every third pixel off
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Input a value 0 to 255 to get a color value.
|
||||
// The colours are a transition r - g - b - back to r.
|
||||
uint32_t Wheel(byte WheelPos) {
|
||||
WheelPos = 255 - WheelPos;
|
||||
if(WheelPos < 85) {
|
||||
return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3);
|
||||
}
|
||||
if(WheelPos < 170) {
|
||||
WheelPos -= 85;
|
||||
return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3);
|
||||
}
|
||||
WheelPos -= 170;
|
||||
return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
#######################################
|
||||
# Syntax Coloring Map For Adafruit_NeoPixel
|
||||
#######################################
|
||||
# Class
|
||||
#######################################
|
||||
|
||||
Adafruit_NeoPixel KEYWORD1
|
||||
|
||||
#######################################
|
||||
# Methods and Functions
|
||||
#######################################
|
||||
|
||||
setPixelColor KEYWORD2
|
||||
setPin KEYWORD2
|
||||
setBrightness KEYWORD2
|
||||
numPixels KEYWORD2
|
||||
getPixelColor KEYWORD2
|
||||
Color KEYWORD2
|
||||
|
||||
#######################################
|
||||
# Constants
|
||||
#######################################
|
||||
|
||||
NEO_GRB LITERAL1
|
||||
NEO_COLMASK LITERAL1
|
||||
NEO_KHZ800 LITERAL1
|
||||
NEO_SPDMASK LITERAL1
|
||||
NEO_RGB LITERAL1
|
||||
NEO_KHZ400 LITERAL1
|
||||
@@ -0,0 +1,9 @@
|
||||
name=Adafruit NeoPixel
|
||||
version=1.0.6
|
||||
author=Adafruit
|
||||
maintainer=Adafruit <info@adafruit.com>
|
||||
sentence=Arduino library for controlling single-wire-based LED pixels and strip.
|
||||
paragraph=Arduino library for controlling single-wire-based LED pixels and strip.
|
||||
category=Display
|
||||
url=https://github.com/adafruit/Adafruit_NeoPixel
|
||||
architectures=*
|
||||
@@ -0,0 +1,154 @@
|
||||
/*
|
||||
* Copyright (C) 2008 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software< /span>
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/* Update by K. Townsend (Adafruit Industries) for lighter typedefs, and
|
||||
* extended sensor support to include color, voltage and current */
|
||||
|
||||
#ifndef _ADAFRUIT_SENSOR_H
|
||||
#define _ADAFRUIT_SENSOR_H
|
||||
|
||||
#if ARDUINO >= 100
|
||||
#include "Arduino.h"
|
||||
#include "Print.h"
|
||||
#else
|
||||
#include "WProgram.h"
|
||||
#endif
|
||||
|
||||
/* Intentionally modeled after sensors.h in the Android API:
|
||||
* https://github.com/android/platform_hardware_libhardware/blob/master/include/hardware/sensors.h */
|
||||
|
||||
/* Constants */
|
||||
#define SENSORS_GRAVITY_EARTH (9.80665F) /**< Earth's gravity in m/s^2 */
|
||||
#define SENSORS_GRAVITY_MOON (1.6F) /**< The moon's gravity in m/s^2 */
|
||||
#define SENSORS_GRAVITY_SUN (275.0F) /**< The sun's gravity in m/s^2 */
|
||||
#define SENSORS_GRAVITY_STANDARD (SENSORS_GRAVITY_EARTH)
|
||||
#define SENSORS_MAGFIELD_EARTH_MAX (60.0F) /**< Maximum magnetic field on Earth's surface */
|
||||
#define SENSORS_MAGFIELD_EARTH_MIN (30.0F) /**< Minimum magnetic field on Earth's surface */
|
||||
#define SENSORS_PRESSURE_SEALEVELHPA (1013.25F) /**< Average sea level pressure is 1013.25 hPa */
|
||||
#define SENSORS_DPS_TO_RADS (0.017453293F) /**< Degrees/s to rad/s multiplier */
|
||||
#define SENSORS_GAUSS_TO_MICROTESLA (100) /**< Gauss to micro-Tesla multiplier */
|
||||
|
||||
/** Sensor types */
|
||||
typedef enum
|
||||
{
|
||||
SENSOR_TYPE_ACCELEROMETER = (1), /**< Gravity + linear acceleration */
|
||||
SENSOR_TYPE_MAGNETIC_FIELD = (2),
|
||||
SENSOR_TYPE_ORIENTATION = (3),
|
||||
SENSOR_TYPE_GYROSCOPE = (4),
|
||||
SENSOR_TYPE_LIGHT = (5),
|
||||
SENSOR_TYPE_PRESSURE = (6),
|
||||
SENSOR_TYPE_PROXIMITY = (8),
|
||||
SENSOR_TYPE_GRAVITY = (9),
|
||||
SENSOR_TYPE_LINEAR_ACCELERATION = (10), /**< Acceleration not including gravity */
|
||||
SENSOR_TYPE_ROTATION_VECTOR = (11),
|
||||
SENSOR_TYPE_RELATIVE_HUMIDITY = (12),
|
||||
SENSOR_TYPE_AMBIENT_TEMPERATURE = (13),
|
||||
SENSOR_TYPE_VOLTAGE = (15),
|
||||
SENSOR_TYPE_CURRENT = (16),
|
||||
SENSOR_TYPE_COLOR = (17)
|
||||
} sensors_type_t;
|
||||
|
||||
/** struct sensors_vec_s is used to return a vector in a common format. */
|
||||
typedef struct {
|
||||
union {
|
||||
float v[3];
|
||||
struct {
|
||||
float x;
|
||||
float y;
|
||||
float z;
|
||||
};
|
||||
/* Orientation sensors */
|
||||
struct {
|
||||
float roll; /**< Rotation around the longitudinal axis (the plane body, 'X axis'). Roll is positive and increasing when moving downward. -90°<=roll<=90° */
|
||||
float pitch; /**< Rotation around the lateral axis (the wing span, 'Y axis'). Pitch is positive and increasing when moving upwards. -180°<=pitch<=180°) */
|
||||
float heading; /**< Angle between the longitudinal axis (the plane body) and magnetic north, measured clockwise when viewing from the top of the device. 0-359° */
|
||||
};
|
||||
};
|
||||
int8_t status;
|
||||
uint8_t reserved[3];
|
||||
} sensors_vec_t;
|
||||
|
||||
/** struct sensors_color_s is used to return color data in a common format. */
|
||||
typedef struct {
|
||||
union {
|
||||
float c[3];
|
||||
/* RGB color space */
|
||||
struct {
|
||||
float r; /**< Red component */
|
||||
float g; /**< Green component */
|
||||
float b; /**< Blue component */
|
||||
};
|
||||
};
|
||||
uint32_t rgba; /**< 24-bit RGBA value */
|
||||
} sensors_color_t;
|
||||
|
||||
/* Sensor event (36 bytes) */
|
||||
/** struct sensor_event_s is used to provide a single sensor event in a common format. */
|
||||
typedef struct
|
||||
{
|
||||
int32_t version; /**< must be sizeof(struct sensors_event_t) */
|
||||
int32_t sensor_id; /**< unique sensor identifier */
|
||||
int32_t type; /**< sensor type */
|
||||
int32_t reserved0; /**< reserved */
|
||||
int32_t timestamp; /**< time is in milliseconds */
|
||||
union
|
||||
{
|
||||
float data[4];
|
||||
sensors_vec_t acceleration; /**< acceleration values are in meter per second per second (m/s^2) */
|
||||
sensors_vec_t magnetic; /**< magnetic vector values are in micro-Tesla (uT) */
|
||||
sensors_vec_t orientation; /**< orientation values are in degrees */
|
||||
sensors_vec_t gyro; /**< gyroscope values are in rad/s */
|
||||
float temperature; /**< temperature is in degrees centigrade (Celsius) */
|
||||
float distance; /**< distance in centimeters */
|
||||
float light; /**< light in SI lux units */
|
||||
float pressure; /**< pressure in hectopascal (hPa) */
|
||||
float relative_humidity; /**< relative humidity in percent */
|
||||
float current; /**< current in milliamps (mA) */
|
||||
float voltage; /**< voltage in volts (V) */
|
||||
sensors_color_t color; /**< color in RGB component values */
|
||||
};
|
||||
} sensors_event_t;
|
||||
|
||||
/* Sensor details (40 bytes) */
|
||||
/** struct sensor_s is used to describe basic information about a specific sensor. */
|
||||
typedef struct
|
||||
{
|
||||
char name[12]; /**< sensor name */
|
||||
int32_t version; /**< version of the hardware + driver */
|
||||
int32_t sensor_id; /**< unique sensor identifier */
|
||||
int32_t type; /**< this sensor's type (ex. SENSOR_TYPE_LIGHT) */
|
||||
float max_value; /**< maximum value of this sensor's value in SI units */
|
||||
float min_value; /**< minimum value of this sensor's value in SI units */
|
||||
float resolution; /**< smallest difference between two values reported by this sensor */
|
||||
int32_t min_delay; /**< min delay in microseconds between events. zero = not a constant rate */
|
||||
} sensor_t;
|
||||
|
||||
class Adafruit_Sensor {
|
||||
public:
|
||||
// Constructor(s)
|
||||
Adafruit_Sensor() {}
|
||||
virtual ~Adafruit_Sensor() {}
|
||||
|
||||
// These must be defined by the subclass
|
||||
virtual void enableAutoRange(bool enabled) {};
|
||||
virtual bool getEvent(sensors_event_t*) = 0;
|
||||
virtual void getSensor(sensor_t*) = 0;
|
||||
|
||||
private:
|
||||
bool _autoRange;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,221 @@
|
||||
# Adafruit Unified Sensor Driver #
|
||||
|
||||
Many small embedded systems exist to collect data from sensors, analyse the data, and either take an appropriate action or send that sensor data to another system for processing.
|
||||
|
||||
One of the many challenges of embedded systems design is the fact that parts you used today may be out of production tomorrow, or system requirements may change and you may need to choose a different sensor down the road.
|
||||
|
||||
Creating new drivers is a relatively easy task, but integrating them into existing systems is both error prone and time consuming since sensors rarely use the exact same units of measurement.
|
||||
|
||||
By reducing all data to a single **sensors\_event\_t** 'type' and settling on specific, **standardised SI units** for each sensor family the same sensor types return values that are comparable with any other similar sensor. This enables you to switch sensor models with very little impact on the rest of the system, which can help mitigate some of the risks and problems of sensor availability and code reuse.
|
||||
|
||||
The unified sensor abstraction layer is also useful for data-logging and data-transmission since you only have one well-known type to log or transmit over the air or wire.
|
||||
|
||||
## Unified Sensor Drivers ##
|
||||
|
||||
The following drivers are based on the Adafruit Unified Sensor Driver:
|
||||
|
||||
**Accelerometers**
|
||||
- [Adafruit\_ADXL345](https://github.com/adafruit/Adafruit_ADXL345)
|
||||
- [Adafruit\_LSM303DLHC](https://github.com/adafruit/Adafruit_LSM303DLHC)
|
||||
- [Adafruit\_MMA8451\_Library](https://github.com/adafruit/Adafruit_MMA8451_Library)
|
||||
|
||||
**Gyroscope**
|
||||
- [Adafruit\_L3GD20\_U](https://github.com/adafruit/Adafruit_L3GD20_U)
|
||||
|
||||
**Light**
|
||||
- [Adafruit\_TSL2561](https://github.com/adafruit/Adafruit_TSL2561)
|
||||
- [Adafruit\_TSL2591\_Library](https://github.com/adafruit/Adafruit_TSL2591_Library)
|
||||
|
||||
**Magnetometers**
|
||||
- [Adafruit\_LSM303DLHC](https://github.com/adafruit/Adafruit_LSM303DLHC)
|
||||
- [Adafruit\_HMC5883\_Unified](https://github.com/adafruit/Adafruit_HMC5883_Unified)
|
||||
|
||||
**Barometric Pressure**
|
||||
- [Adafruit\_BMP085\_Unified](https://github.com/adafruit/Adafruit_BMP085_Unified)
|
||||
- [Adafruit\_BMP183\_Unified\_Library](https://github.com/adafruit/Adafruit_BMP183_Unified_Library)
|
||||
|
||||
**Humidity & Temperature**
|
||||
- [DHT-sensor-library](https://github.com/adafruit/DHT-sensor-library)
|
||||
|
||||
**Orientation**
|
||||
- [Adafruit_BNO055](https://github.com/adafruit/Adafruit_BNO055)
|
||||
|
||||
## How Does it Work? ##
|
||||
|
||||
Any driver that supports the Adafruit unified sensor abstraction layer will implement the Adafruit\_Sensor base class. There are two main typedefs and one enum defined in Adafruit_Sensor.h that are used to 'abstract' away the sensor details and values:
|
||||
|
||||
**Sensor Types (sensors\_type\_t)**
|
||||
|
||||
These pre-defined sensor types are used to properly handle the two related typedefs below, and allows us determine what types of units the sensor uses, etc.
|
||||
|
||||
```
|
||||
/** Sensor types */
|
||||
typedef enum
|
||||
{
|
||||
SENSOR_TYPE_ACCELEROMETER = (1),
|
||||
SENSOR_TYPE_MAGNETIC_FIELD = (2),
|
||||
SENSOR_TYPE_ORIENTATION = (3),
|
||||
SENSOR_TYPE_GYROSCOPE = (4),
|
||||
SENSOR_TYPE_LIGHT = (5),
|
||||
SENSOR_TYPE_PRESSURE = (6),
|
||||
SENSOR_TYPE_PROXIMITY = (8),
|
||||
SENSOR_TYPE_GRAVITY = (9),
|
||||
SENSOR_TYPE_LINEAR_ACCELERATION = (10),
|
||||
SENSOR_TYPE_ROTATION_VECTOR = (11),
|
||||
SENSOR_TYPE_RELATIVE_HUMIDITY = (12),
|
||||
SENSOR_TYPE_AMBIENT_TEMPERATURE = (13),
|
||||
SENSOR_TYPE_VOLTAGE = (15),
|
||||
SENSOR_TYPE_CURRENT = (16),
|
||||
SENSOR_TYPE_COLOR = (17)
|
||||
} sensors_type_t;
|
||||
```
|
||||
|
||||
**Sensor Details (sensor\_t)**
|
||||
|
||||
This typedef describes the specific capabilities of this sensor, and allows us to know what sensor we are using beneath the abstraction layer.
|
||||
|
||||
```
|
||||
/* Sensor details (40 bytes) */
|
||||
/** struct sensor_s is used to describe basic information about a specific sensor. */
|
||||
typedef struct
|
||||
{
|
||||
char name[12];
|
||||
int32_t version;
|
||||
int32_t sensor_id;
|
||||
int32_t type;
|
||||
float max_value;
|
||||
float min_value;
|
||||
float resolution;
|
||||
int32_t min_delay;
|
||||
} sensor_t;
|
||||
```
|
||||
|
||||
The individual fields are intended to be used as follows:
|
||||
|
||||
- **name**: The sensor name or ID, up to a maximum of twelve characters (ex. "MPL115A2")
|
||||
- **version**: The version of the sensor HW and the driver to allow us to differentiate versions of the board or driver
|
||||
- **sensor\_id**: A unique sensor identifier that is used to differentiate this specific sensor instance from any others that are present on the system or in the sensor network
|
||||
- **type**: The sensor type, based on **sensors\_type\_t** in sensors.h
|
||||
- **max\_value**: The maximum value that this sensor can return (in the appropriate SI unit)
|
||||
- **min\_value**: The minimum value that this sensor can return (in the appropriate SI unit)
|
||||
- **resolution**: The smallest difference between two values that this sensor can report (in the appropriate SI unit)
|
||||
- **min\_delay**: The minimum delay in microseconds between two sensor events, or '0' if there is no constant sensor rate
|
||||
|
||||
**Sensor Data/Events (sensors\_event\_t)**
|
||||
|
||||
This typedef is used to return sensor data from any sensor supported by the abstraction layer, using standard SI units and scales.
|
||||
|
||||
```
|
||||
/* Sensor event (36 bytes) */
|
||||
/** struct sensor_event_s is used to provide a single sensor event in a common format. */
|
||||
typedef struct
|
||||
{
|
||||
int32_t version;
|
||||
int32_t sensor_id;
|
||||
int32_t type;
|
||||
int32_t reserved0;
|
||||
int32_t timestamp;
|
||||
union
|
||||
{
|
||||
float data[4];
|
||||
sensors_vec_t acceleration;
|
||||
sensors_vec_t magnetic;
|
||||
sensors_vec_t orientation;
|
||||
sensors_vec_t gyro;
|
||||
float temperature;
|
||||
float distance;
|
||||
float light;
|
||||
float pressure;
|
||||
float relative_humidity;
|
||||
float current;
|
||||
float voltage;
|
||||
sensors_color_t color;
|
||||
};
|
||||
} sensors_event_t;
|
||||
```
|
||||
It includes the following fields:
|
||||
|
||||
- **version**: Contain 'sizeof(sensors\_event\_t)' to identify which version of the API we're using in case this changes in the future
|
||||
- **sensor\_id**: A unique sensor identifier that is used to differentiate this specific sensor instance from any others that are present on the system or in the sensor network (must match the sensor\_id value in the corresponding sensor\_t enum above!)
|
||||
- **type**: the sensor type, based on **sensors\_type\_t** in sensors.h
|
||||
- **timestamp**: time in milliseconds when the sensor value was read
|
||||
- **data[4]**: An array of four 32-bit values that allows us to encapsulate any type of sensor data via a simple union (further described below)
|
||||
|
||||
**Required Functions**
|
||||
|
||||
In addition to the two standard types and the sensor type enum, all drivers based on Adafruit_Sensor must also implement the following two functions:
|
||||
|
||||
```
|
||||
bool getEvent(sensors_event_t*);
|
||||
```
|
||||
Calling this function will populate the supplied sensors\_event\_t reference with the latest available sensor data. You should call this function as often as you want to update your data.
|
||||
|
||||
```
|
||||
void getSensor(sensor_t*);
|
||||
```
|
||||
Calling this function will provide some basic information about the sensor (the sensor name, driver version, min and max values, etc.
|
||||
|
||||
**Standardised SI values for sensors\_event\_t**
|
||||
|
||||
A key part of the abstraction layer is the standardisation of values on SI units of a particular scale, which is accomplished via the data[4] union in sensors\_event\_t above. This 16 byte union includes fields for each main sensor type, and uses the following SI units and scales:
|
||||
|
||||
- **acceleration**: values are in **meter per second per second** (m/s^2)
|
||||
- **magnetic**: values are in **micro-Tesla** (uT)
|
||||
- **orientation**: values are in **degrees**
|
||||
- **gyro**: values are in **rad/s**
|
||||
- **temperature**: values in **degrees centigrade** (Celsius)
|
||||
- **distance**: values are in **centimeters**
|
||||
- **light**: values are in **SI lux** units
|
||||
- **pressure**: values are in **hectopascal** (hPa)
|
||||
- **relative\_humidity**: values are in **percent**
|
||||
- **current**: values are in **milliamps** (mA)
|
||||
- **voltage**: values are in **volts** (V)
|
||||
- **color**: values are in 0..1.0 RGB channel luminosity and 32-bit RGBA format
|
||||
|
||||
## The Unified Driver Abstraction Layer in Practice ##
|
||||
|
||||
Using the unified sensor abstraction layer is relatively easy once a compliant driver has been created.
|
||||
|
||||
Every compliant sensor can now be read using a single, well-known 'type' (sensors\_event\_t), and there is a standardised way of interrogating a sensor about its specific capabilities (via sensor\_t).
|
||||
|
||||
An example of reading the [TSL2561](https://github.com/adafruit/Adafruit_TSL2561) light sensor can be seen below:
|
||||
|
||||
```
|
||||
Adafruit_TSL2561 tsl = Adafruit_TSL2561(TSL2561_ADDR_FLOAT, 12345);
|
||||
...
|
||||
/* Get a new sensor event */
|
||||
sensors_event_t event;
|
||||
tsl.getEvent(&event);
|
||||
|
||||
/* Display the results (light is measured in lux) */
|
||||
if (event.light)
|
||||
{
|
||||
Serial.print(event.light); Serial.println(" lux");
|
||||
}
|
||||
else
|
||||
{
|
||||
/* If event.light = 0 lux the sensor is probably saturated
|
||||
and no reliable data could be generated! */
|
||||
Serial.println("Sensor overload");
|
||||
}
|
||||
```
|
||||
|
||||
Similarly, we can get the basic technical capabilities of this sensor with the following code:
|
||||
|
||||
```
|
||||
sensor_t sensor;
|
||||
|
||||
sensor_t sensor;
|
||||
tsl.getSensor(&sensor);
|
||||
|
||||
/* Display the sensor details */
|
||||
Serial.println("------------------------------------");
|
||||
Serial.print ("Sensor: "); Serial.println(sensor.name);
|
||||
Serial.print ("Driver Ver: "); Serial.println(sensor.version);
|
||||
Serial.print ("Unique ID: "); Serial.println(sensor.sensor_id);
|
||||
Serial.print ("Max Value: "); Serial.print(sensor.max_value); Serial.println(" lux");
|
||||
Serial.print ("Min Value: "); Serial.print(sensor.min_value); Serial.println(" lux");
|
||||
Serial.print ("Resolution: "); Serial.print(sensor.resolution); Serial.println(" lux");
|
||||
Serial.println("------------------------------------");
|
||||
Serial.println("");
|
||||
```
|
||||
@@ -0,0 +1,9 @@
|
||||
name=Adafruit Unified Sensor
|
||||
version=1.0.2
|
||||
author=Adafruit <info@adafruit.com>
|
||||
maintainer=Adafruit <info@adafruit.com>
|
||||
sentence=Required for all Adafruit Unified Sensor based libraries.
|
||||
paragraph=A unified sensor abstraction layer used by many Adafruit sensor libraries.
|
||||
category=Sensors
|
||||
url=https://github.com/adafruit/Adafruit_Sensor
|
||||
architectures=*
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
Thank you for opening an issue on an Adafruit Arduino library repository. To
|
||||
improve the speed of resolution please review the following guidelines and
|
||||
common troubleshooting steps below before creating the issue:
|
||||
|
||||
- **Do not use GitHub issues for troubleshooting projects and issues.** Instead use
|
||||
the forums at http://forums.adafruit.com to ask questions and troubleshoot why
|
||||
something isn't working as expected. In many cases the problem is a common issue
|
||||
that you will more quickly receive help from the forum community. GitHub issues
|
||||
are meant for known defects in the code. If you don't know if there is a defect
|
||||
in the code then start with troubleshooting on the forum first.
|
||||
|
||||
- **If following a tutorial or guide be sure you didn't miss a step.** Carefully
|
||||
check all of the steps and commands to run have been followed. Consult the
|
||||
forum if you're unsure or have questions about steps in a guide/tutorial.
|
||||
|
||||
- **For Arduino projects check these very common issues to ensure they don't apply**:
|
||||
|
||||
- For uploading sketches or communicating with the board make sure you're using
|
||||
a **USB data cable** and **not** a **USB charge-only cable**. It is sometimes
|
||||
very hard to tell the difference between a data and charge cable! Try using the
|
||||
cable with other devices or swapping to another cable to confirm it is not
|
||||
the problem.
|
||||
|
||||
- **Be sure you are supplying adequate power to the board.** Check the specs of
|
||||
your board and plug in an external power supply. In many cases just
|
||||
plugging a board into your computer is not enough to power it and other
|
||||
peripherals.
|
||||
|
||||
- **Double check all soldering joints and connections.** Flakey connections
|
||||
cause many mysterious problems. See the [guide to excellent soldering](https://learn.adafruit.com/adafruit-guide-excellent-soldering/tools) for examples of good solder joints.
|
||||
|
||||
- **Ensure you are using an official Arduino or Adafruit board.** We can't
|
||||
guarantee a clone board will have the same functionality and work as expected
|
||||
with this code and don't support them.
|
||||
|
||||
If you're sure this issue is a defect in the code and checked the steps above
|
||||
please fill in the following fields to provide enough troubleshooting information.
|
||||
You may delete the guideline and text above to just leave the following details:
|
||||
|
||||
- Arduino board: **INSERT ARDUINO BOARD NAME/TYPE HERE**
|
||||
|
||||
- Arduino IDE version (found in Arduino -> About Arduino menu): **INSERT ARDUINO
|
||||
VERSION HERE**
|
||||
|
||||
- List the steps to reproduce the problem below (if possible attach a sketch or
|
||||
copy the sketch code in too): **LIST REPRO STEPS BELOW**
|
||||
@@ -0,0 +1,26 @@
|
||||
Thank you for creating a pull request to contribute to Adafruit's GitHub code!
|
||||
Before you open the request please review the following guidelines and tips to
|
||||
help it be more easily integrated:
|
||||
|
||||
- **Describe the scope of your change--i.e. what the change does and what parts
|
||||
of the code were modified.** This will help us understand any risks of integrating
|
||||
the code.
|
||||
|
||||
- **Describe any known limitations with your change.** For example if the change
|
||||
doesn't apply to a supported platform of the library please mention it.
|
||||
|
||||
- **Please run any tests or examples that can exercise your modified code.** We
|
||||
strive to not break users of the code and running tests/examples helps with this
|
||||
process.
|
||||
|
||||
Thank you again for contributing! We will try to test and integrate the change
|
||||
as soon as we can, but be aware we have many GitHub repositories to manage and
|
||||
can't immediately respond to every request. There is no need to bump or check in
|
||||
on a pull request (it will clutter the discussion of the request).
|
||||
|
||||
Also don't be worried if the request is closed or not integrated--sometimes the
|
||||
priorities of Adafruit's GitHub code (education, ease of use) might not match the
|
||||
priorities of the pull request. Don't fret, the open source community thrives on
|
||||
forks and GitHub makes it easy to keep your changes in a forked repo.
|
||||
|
||||
After reviewing the guidelines above you can delete this text from the pull request.
|
||||
@@ -0,0 +1,334 @@
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@file Adafruit_TCS34725.cpp
|
||||
@author KTOWN (Adafruit Industries)
|
||||
@license BSD (see license.txt)
|
||||
|
||||
Driver for the TCS34725 digital color sensors.
|
||||
|
||||
Adafruit invests time and resources providing this open source code,
|
||||
please support Adafruit and open-source hardware by purchasing
|
||||
products from Adafruit!
|
||||
|
||||
@section HISTORY
|
||||
|
||||
v1.0 - First release
|
||||
*/
|
||||
/**************************************************************************/
|
||||
#ifdef __AVR
|
||||
#include <avr/pgmspace.h>
|
||||
#elif defined(ESP8266)
|
||||
#include <pgmspace.h>
|
||||
#endif
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "Adafruit_TCS34725.h"
|
||||
|
||||
/*========================================================================*/
|
||||
/* PRIVATE FUNCTIONS */
|
||||
/*========================================================================*/
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Implements missing powf function
|
||||
*/
|
||||
/**************************************************************************/
|
||||
float powf(const float x, const float y)
|
||||
{
|
||||
return (float)(pow((double)x, (double)y));
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Writes a register and an 8 bit value over I2C
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void Adafruit_TCS34725::write8 (uint8_t reg, uint32_t value)
|
||||
{
|
||||
Wire.beginTransmission(TCS34725_ADDRESS);
|
||||
#if ARDUINO >= 100
|
||||
Wire.write(TCS34725_COMMAND_BIT | reg);
|
||||
Wire.write(value & 0xFF);
|
||||
#else
|
||||
Wire.send(TCS34725_COMMAND_BIT | reg);
|
||||
Wire.send(value & 0xFF);
|
||||
#endif
|
||||
Wire.endTransmission();
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Reads an 8 bit value over I2C
|
||||
*/
|
||||
/**************************************************************************/
|
||||
uint8_t Adafruit_TCS34725::read8(uint8_t reg)
|
||||
{
|
||||
Wire.beginTransmission(TCS34725_ADDRESS);
|
||||
#if ARDUINO >= 100
|
||||
Wire.write(TCS34725_COMMAND_BIT | reg);
|
||||
#else
|
||||
Wire.send(TCS34725_COMMAND_BIT | reg);
|
||||
#endif
|
||||
Wire.endTransmission();
|
||||
|
||||
Wire.requestFrom(TCS34725_ADDRESS, 1);
|
||||
#if ARDUINO >= 100
|
||||
return Wire.read();
|
||||
#else
|
||||
return Wire.receive();
|
||||
#endif
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Reads a 16 bit values over I2C
|
||||
*/
|
||||
/**************************************************************************/
|
||||
uint16_t Adafruit_TCS34725::read16(uint8_t reg)
|
||||
{
|
||||
uint16_t x; uint16_t t;
|
||||
|
||||
Wire.beginTransmission(TCS34725_ADDRESS);
|
||||
#if ARDUINO >= 100
|
||||
Wire.write(TCS34725_COMMAND_BIT | reg);
|
||||
#else
|
||||
Wire.send(TCS34725_COMMAND_BIT | reg);
|
||||
#endif
|
||||
Wire.endTransmission();
|
||||
|
||||
Wire.requestFrom(TCS34725_ADDRESS, 2);
|
||||
#if ARDUINO >= 100
|
||||
t = Wire.read();
|
||||
x = Wire.read();
|
||||
#else
|
||||
t = Wire.receive();
|
||||
x = Wire.receive();
|
||||
#endif
|
||||
x <<= 8;
|
||||
x |= t;
|
||||
return x;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
Enables the device
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void Adafruit_TCS34725::enable(void)
|
||||
{
|
||||
write8(TCS34725_ENABLE, TCS34725_ENABLE_PON);
|
||||
delay(3);
|
||||
write8(TCS34725_ENABLE, TCS34725_ENABLE_PON | TCS34725_ENABLE_AEN);
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
Disables the device (putting it in lower power sleep mode)
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void Adafruit_TCS34725::disable(void)
|
||||
{
|
||||
/* Turn the device off to save power */
|
||||
uint8_t reg = 0;
|
||||
reg = read8(TCS34725_ENABLE);
|
||||
write8(TCS34725_ENABLE, reg & ~(TCS34725_ENABLE_PON | TCS34725_ENABLE_AEN));
|
||||
}
|
||||
|
||||
/*========================================================================*/
|
||||
/* CONSTRUCTORS */
|
||||
/*========================================================================*/
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
Constructor
|
||||
*/
|
||||
/**************************************************************************/
|
||||
Adafruit_TCS34725::Adafruit_TCS34725(tcs34725IntegrationTime_t it, tcs34725Gain_t gain)
|
||||
{
|
||||
_tcs34725Initialised = false;
|
||||
_tcs34725IntegrationTime = it;
|
||||
_tcs34725Gain = gain;
|
||||
}
|
||||
|
||||
/*========================================================================*/
|
||||
/* PUBLIC FUNCTIONS */
|
||||
/*========================================================================*/
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
Initializes I2C and configures the sensor (call this function before
|
||||
doing anything else)
|
||||
*/
|
||||
/**************************************************************************/
|
||||
boolean Adafruit_TCS34725::begin(void)
|
||||
{
|
||||
Wire.begin();
|
||||
|
||||
/* Make sure we're actually connected */
|
||||
uint8_t x = read8(TCS34725_ID);
|
||||
if ((x != 0x44) && (x != 0x10))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
_tcs34725Initialised = true;
|
||||
|
||||
/* Set default integration time and gain */
|
||||
setIntegrationTime(_tcs34725IntegrationTime);
|
||||
setGain(_tcs34725Gain);
|
||||
|
||||
/* Note: by default, the device is in power down mode on bootup */
|
||||
enable();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
Sets the integration time for the TC34725
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void Adafruit_TCS34725::setIntegrationTime(tcs34725IntegrationTime_t it)
|
||||
{
|
||||
if (!_tcs34725Initialised) begin();
|
||||
|
||||
/* Update the timing register */
|
||||
write8(TCS34725_ATIME, it);
|
||||
|
||||
/* Update value placeholders */
|
||||
_tcs34725IntegrationTime = it;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
Adjusts the gain on the TCS34725 (adjusts the sensitivity to light)
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void Adafruit_TCS34725::setGain(tcs34725Gain_t gain)
|
||||
{
|
||||
if (!_tcs34725Initialised) begin();
|
||||
|
||||
/* Update the timing register */
|
||||
write8(TCS34725_CONTROL, gain);
|
||||
|
||||
/* Update value placeholders */
|
||||
_tcs34725Gain = gain;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Reads the raw red, green, blue and clear channel values
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void Adafruit_TCS34725::getRawData (uint16_t *r, uint16_t *g, uint16_t *b, uint16_t *c)
|
||||
{
|
||||
if (!_tcs34725Initialised) begin();
|
||||
|
||||
*c = read16(TCS34725_CDATAL);
|
||||
*r = read16(TCS34725_RDATAL);
|
||||
*g = read16(TCS34725_GDATAL);
|
||||
*b = read16(TCS34725_BDATAL);
|
||||
|
||||
/* Set a delay for the integration time */
|
||||
switch (_tcs34725IntegrationTime)
|
||||
{
|
||||
case TCS34725_INTEGRATIONTIME_2_4MS:
|
||||
delay(3);
|
||||
break;
|
||||
case TCS34725_INTEGRATIONTIME_24MS:
|
||||
delay(24);
|
||||
break;
|
||||
case TCS34725_INTEGRATIONTIME_50MS:
|
||||
delay(50);
|
||||
break;
|
||||
case TCS34725_INTEGRATIONTIME_101MS:
|
||||
delay(101);
|
||||
break;
|
||||
case TCS34725_INTEGRATIONTIME_154MS:
|
||||
delay(154);
|
||||
break;
|
||||
case TCS34725_INTEGRATIONTIME_700MS:
|
||||
delay(700);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Converts the raw R/G/B values to color temperature in degrees
|
||||
Kelvin
|
||||
*/
|
||||
/**************************************************************************/
|
||||
uint16_t Adafruit_TCS34725::calculateColorTemperature(uint16_t r, uint16_t g, uint16_t b)
|
||||
{
|
||||
float X, Y, Z; /* RGB to XYZ correlation */
|
||||
float xc, yc; /* Chromaticity co-ordinates */
|
||||
float n; /* McCamy's formula */
|
||||
float cct;
|
||||
|
||||
/* 1. Map RGB values to their XYZ counterparts. */
|
||||
/* Based on 6500K fluorescent, 3000K fluorescent */
|
||||
/* and 60W incandescent values for a wide range. */
|
||||
/* Note: Y = Illuminance or lux */
|
||||
X = (-0.14282F * r) + (1.54924F * g) + (-0.95641F * b);
|
||||
Y = (-0.32466F * r) + (1.57837F * g) + (-0.73191F * b);
|
||||
Z = (-0.68202F * r) + (0.77073F * g) + ( 0.56332F * b);
|
||||
|
||||
/* 2. Calculate the chromaticity co-ordinates */
|
||||
xc = (X) / (X + Y + Z);
|
||||
yc = (Y) / (X + Y + Z);
|
||||
|
||||
/* 3. Use McCamy's formula to determine the CCT */
|
||||
n = (xc - 0.3320F) / (0.1858F - yc);
|
||||
|
||||
/* Calculate the final CCT */
|
||||
cct = (449.0F * powf(n, 3)) + (3525.0F * powf(n, 2)) + (6823.3F * n) + 5520.33F;
|
||||
|
||||
/* Return the results in degrees Kelvin */
|
||||
return (uint16_t)cct;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Converts the raw R/G/B values to lux
|
||||
*/
|
||||
/**************************************************************************/
|
||||
uint16_t Adafruit_TCS34725::calculateLux(uint16_t r, uint16_t g, uint16_t b)
|
||||
{
|
||||
float illuminance;
|
||||
|
||||
/* This only uses RGB ... how can we integrate clear or calculate lux */
|
||||
/* based exclusively on clear since this might be more reliable? */
|
||||
illuminance = (-0.32466F * r) + (1.57837F * g) + (-0.73191F * b);
|
||||
|
||||
return (uint16_t)illuminance;
|
||||
}
|
||||
|
||||
|
||||
void Adafruit_TCS34725::setInterrupt(boolean i) {
|
||||
uint8_t r = read8(TCS34725_ENABLE);
|
||||
if (i) {
|
||||
r |= TCS34725_ENABLE_AIEN;
|
||||
} else {
|
||||
r &= ~TCS34725_ENABLE_AIEN;
|
||||
}
|
||||
write8(TCS34725_ENABLE, r);
|
||||
}
|
||||
|
||||
void Adafruit_TCS34725::clearInterrupt(void) {
|
||||
Wire.beginTransmission(TCS34725_ADDRESS);
|
||||
#if ARDUINO >= 100
|
||||
Wire.write(TCS34725_COMMAND_BIT | 0x66);
|
||||
#else
|
||||
Wire.send(TCS34725_COMMAND_BIT | 0x66);
|
||||
#endif
|
||||
Wire.endTransmission();
|
||||
}
|
||||
|
||||
|
||||
void Adafruit_TCS34725::setIntLimits(uint16_t low, uint16_t high) {
|
||||
write8(0x04, low & 0xFF);
|
||||
write8(0x05, low >> 8);
|
||||
write8(0x06, high & 0xFF);
|
||||
write8(0x07, high >> 8);
|
||||
}
|
||||
@@ -0,0 +1,144 @@
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@file Adafruit_TCS34725.h
|
||||
@author KTOWN (Adafruit Industries)
|
||||
|
||||
@section LICENSE
|
||||
|
||||
Software License Agreement (BSD License)
|
||||
|
||||
Copyright (c) 2013, Adafruit Industries
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
3. Neither the name of the copyright holders nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/**************************************************************************/
|
||||
#ifndef _TCS34725_H_
|
||||
#define _TCS34725_H_
|
||||
|
||||
#if ARDUINO >= 100
|
||||
#include <Arduino.h>
|
||||
#else
|
||||
#include <WProgram.h>
|
||||
#endif
|
||||
|
||||
#include <Wire.h>
|
||||
|
||||
#define TCS34725_ADDRESS (0x29)
|
||||
|
||||
#define TCS34725_COMMAND_BIT (0x80)
|
||||
|
||||
#define TCS34725_ENABLE (0x00)
|
||||
#define TCS34725_ENABLE_AIEN (0x10) /* RGBC Interrupt Enable */
|
||||
#define TCS34725_ENABLE_WEN (0x08) /* Wait enable - Writing 1 activates the wait timer */
|
||||
#define TCS34725_ENABLE_AEN (0x02) /* RGBC Enable - Writing 1 actives the ADC, 0 disables it */
|
||||
#define TCS34725_ENABLE_PON (0x01) /* Power on - Writing 1 activates the internal oscillator, 0 disables it */
|
||||
#define TCS34725_ATIME (0x01) /* Integration time */
|
||||
#define TCS34725_WTIME (0x03) /* Wait time (if TCS34725_ENABLE_WEN is asserted) */
|
||||
#define TCS34725_WTIME_2_4MS (0xFF) /* WLONG0 = 2.4ms WLONG1 = 0.029s */
|
||||
#define TCS34725_WTIME_204MS (0xAB) /* WLONG0 = 204ms WLONG1 = 2.45s */
|
||||
#define TCS34725_WTIME_614MS (0x00) /* WLONG0 = 614ms WLONG1 = 7.4s */
|
||||
#define TCS34725_AILTL (0x04) /* Clear channel lower interrupt threshold */
|
||||
#define TCS34725_AILTH (0x05)
|
||||
#define TCS34725_AIHTL (0x06) /* Clear channel upper interrupt threshold */
|
||||
#define TCS34725_AIHTH (0x07)
|
||||
#define TCS34725_PERS (0x0C) /* Persistence register - basic SW filtering mechanism for interrupts */
|
||||
#define TCS34725_PERS_NONE (0b0000) /* Every RGBC cycle generates an interrupt */
|
||||
#define TCS34725_PERS_1_CYCLE (0b0001) /* 1 clean channel value outside threshold range generates an interrupt */
|
||||
#define TCS34725_PERS_2_CYCLE (0b0010) /* 2 clean channel values outside threshold range generates an interrupt */
|
||||
#define TCS34725_PERS_3_CYCLE (0b0011) /* 3 clean channel values outside threshold range generates an interrupt */
|
||||
#define TCS34725_PERS_5_CYCLE (0b0100) /* 5 clean channel values outside threshold range generates an interrupt */
|
||||
#define TCS34725_PERS_10_CYCLE (0b0101) /* 10 clean channel values outside threshold range generates an interrupt */
|
||||
#define TCS34725_PERS_15_CYCLE (0b0110) /* 15 clean channel values outside threshold range generates an interrupt */
|
||||
#define TCS34725_PERS_20_CYCLE (0b0111) /* 20 clean channel values outside threshold range generates an interrupt */
|
||||
#define TCS34725_PERS_25_CYCLE (0b1000) /* 25 clean channel values outside threshold range generates an interrupt */
|
||||
#define TCS34725_PERS_30_CYCLE (0b1001) /* 30 clean channel values outside threshold range generates an interrupt */
|
||||
#define TCS34725_PERS_35_CYCLE (0b1010) /* 35 clean channel values outside threshold range generates an interrupt */
|
||||
#define TCS34725_PERS_40_CYCLE (0b1011) /* 40 clean channel values outside threshold range generates an interrupt */
|
||||
#define TCS34725_PERS_45_CYCLE (0b1100) /* 45 clean channel values outside threshold range generates an interrupt */
|
||||
#define TCS34725_PERS_50_CYCLE (0b1101) /* 50 clean channel values outside threshold range generates an interrupt */
|
||||
#define TCS34725_PERS_55_CYCLE (0b1110) /* 55 clean channel values outside threshold range generates an interrupt */
|
||||
#define TCS34725_PERS_60_CYCLE (0b1111) /* 60 clean channel values outside threshold range generates an interrupt */
|
||||
#define TCS34725_CONFIG (0x0D)
|
||||
#define TCS34725_CONFIG_WLONG (0x02) /* Choose between short and long (12x) wait times via TCS34725_WTIME */
|
||||
#define TCS34725_CONTROL (0x0F) /* Set the gain level for the sensor */
|
||||
#define TCS34725_ID (0x12) /* 0x44 = TCS34721/TCS34725, 0x4D = TCS34723/TCS34727 */
|
||||
#define TCS34725_STATUS (0x13)
|
||||
#define TCS34725_STATUS_AINT (0x10) /* RGBC Clean channel interrupt */
|
||||
#define TCS34725_STATUS_AVALID (0x01) /* Indicates that the RGBC channels have completed an integration cycle */
|
||||
#define TCS34725_CDATAL (0x14) /* Clear channel data */
|
||||
#define TCS34725_CDATAH (0x15)
|
||||
#define TCS34725_RDATAL (0x16) /* Red channel data */
|
||||
#define TCS34725_RDATAH (0x17)
|
||||
#define TCS34725_GDATAL (0x18) /* Green channel data */
|
||||
#define TCS34725_GDATAH (0x19)
|
||||
#define TCS34725_BDATAL (0x1A) /* Blue channel data */
|
||||
#define TCS34725_BDATAH (0x1B)
|
||||
|
||||
typedef enum
|
||||
{
|
||||
TCS34725_INTEGRATIONTIME_2_4MS = 0xFF, /**< 2.4ms - 1 cycle - Max Count: 1024 */
|
||||
TCS34725_INTEGRATIONTIME_24MS = 0xF6, /**< 24ms - 10 cycles - Max Count: 10240 */
|
||||
TCS34725_INTEGRATIONTIME_50MS = 0xEB, /**< 50ms - 20 cycles - Max Count: 20480 */
|
||||
TCS34725_INTEGRATIONTIME_101MS = 0xD5, /**< 101ms - 42 cycles - Max Count: 43008 */
|
||||
TCS34725_INTEGRATIONTIME_154MS = 0xC0, /**< 154ms - 64 cycles - Max Count: 65535 */
|
||||
TCS34725_INTEGRATIONTIME_700MS = 0x00 /**< 700ms - 256 cycles - Max Count: 65535 */
|
||||
}
|
||||
tcs34725IntegrationTime_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
TCS34725_GAIN_1X = 0x00, /**< No gain */
|
||||
TCS34725_GAIN_4X = 0x01, /**< 4x gain */
|
||||
TCS34725_GAIN_16X = 0x02, /**< 16x gain */
|
||||
TCS34725_GAIN_60X = 0x03 /**< 60x gain */
|
||||
}
|
||||
tcs34725Gain_t;
|
||||
|
||||
class Adafruit_TCS34725 {
|
||||
public:
|
||||
Adafruit_TCS34725(tcs34725IntegrationTime_t = TCS34725_INTEGRATIONTIME_2_4MS, tcs34725Gain_t = TCS34725_GAIN_1X);
|
||||
|
||||
boolean begin(void);
|
||||
void setIntegrationTime(tcs34725IntegrationTime_t it);
|
||||
void setGain(tcs34725Gain_t gain);
|
||||
void getRawData(uint16_t *r, uint16_t *g, uint16_t *b, uint16_t *c);
|
||||
uint16_t calculateColorTemperature(uint16_t r, uint16_t g, uint16_t b);
|
||||
uint16_t calculateLux(uint16_t r, uint16_t g, uint16_t b);
|
||||
void write8 (uint8_t reg, uint32_t value);
|
||||
uint8_t read8 (uint8_t reg);
|
||||
uint16_t read16 (uint8_t reg);
|
||||
void setInterrupt(boolean flag);
|
||||
void clearInterrupt(void);
|
||||
void setIntLimits(uint16_t l, uint16_t h);
|
||||
void enable(void);
|
||||
|
||||
private:
|
||||
boolean _tcs34725Initialised;
|
||||
tcs34725Gain_t _tcs34725Gain;
|
||||
tcs34725IntegrationTime_t _tcs34725IntegrationTime;
|
||||
|
||||
void disable(void);
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,21 @@
|
||||
#Adafruit TCS34725 Color Sensor Driver #
|
||||
|
||||
This driver is for the Adafruit TCS34725 Breakout.
|
||||
------> http://www.adafruit.com/products/1334
|
||||
|
||||
## About this Driver ##
|
||||
|
||||
These modules use I2C to communicate, 2 pins are required to
|
||||
interface
|
||||
|
||||
Adafruit invests time and resources providing this open source code,
|
||||
please support Adafruit and open-source hardware by purchasing
|
||||
products from Adafruit!
|
||||
|
||||
Written by Kevin (KTOWN) Townsend for Adafruit Industries.
|
||||
BSD license, check license.txt for more information
|
||||
All text above must be included in any redistribution
|
||||
|
||||
To download. click the ZIP button in the top bar, and check this tutorial
|
||||
for instructions on how to install:
|
||||
http://learn.adafruit.com/adafruit-all-about-arduino-libraries-install-use
|
||||
@@ -0,0 +1,88 @@
|
||||
#include <Wire.h>
|
||||
#include "Adafruit_TCS34725.h"
|
||||
|
||||
// Pick analog outputs, for the UNO these three work well
|
||||
// use ~560 ohm resistor between Red & Blue, ~1K for green (its brighter)
|
||||
#define redpin 3
|
||||
#define greenpin 5
|
||||
#define bluepin 6
|
||||
// for a common anode LED, connect the common pin to +5V
|
||||
// for common cathode, connect the common to ground
|
||||
|
||||
// set to false if using a common cathode LED
|
||||
#define commonAnode true
|
||||
|
||||
// our RGB -> eye-recognized gamma color
|
||||
byte gammatable[256];
|
||||
|
||||
|
||||
Adafruit_TCS34725 tcs = Adafruit_TCS34725(TCS34725_INTEGRATIONTIME_50MS, TCS34725_GAIN_4X);
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
Serial.println("Color View Test!");
|
||||
|
||||
if (tcs.begin()) {
|
||||
Serial.println("Found sensor");
|
||||
} else {
|
||||
Serial.println("No TCS34725 found ... check your connections");
|
||||
while (1); // halt!
|
||||
}
|
||||
|
||||
// use these three pins to drive an LED
|
||||
pinMode(redpin, OUTPUT);
|
||||
pinMode(greenpin, OUTPUT);
|
||||
pinMode(bluepin, OUTPUT);
|
||||
|
||||
// thanks PhilB for this gamma table!
|
||||
// it helps convert RGB colors to what humans see
|
||||
for (int i=0; i<256; i++) {
|
||||
float x = i;
|
||||
x /= 255;
|
||||
x = pow(x, 2.5);
|
||||
x *= 255;
|
||||
|
||||
if (commonAnode) {
|
||||
gammatable[i] = 255 - x;
|
||||
} else {
|
||||
gammatable[i] = x;
|
||||
}
|
||||
//Serial.println(gammatable[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void loop() {
|
||||
uint16_t clear, red, green, blue;
|
||||
|
||||
tcs.setInterrupt(false); // turn on LED
|
||||
|
||||
delay(60); // takes 50ms to read
|
||||
|
||||
tcs.getRawData(&red, &green, &blue, &clear);
|
||||
|
||||
tcs.setInterrupt(true); // turn off LED
|
||||
|
||||
Serial.print("C:\t"); Serial.print(clear);
|
||||
Serial.print("\tR:\t"); Serial.print(red);
|
||||
Serial.print("\tG:\t"); Serial.print(green);
|
||||
Serial.print("\tB:\t"); Serial.print(blue);
|
||||
|
||||
// Figure out some basic hex code for visualization
|
||||
uint32_t sum = clear;
|
||||
float r, g, b;
|
||||
r = red; r /= sum;
|
||||
g = green; g /= sum;
|
||||
b = blue; b /= sum;
|
||||
r *= 256; g *= 256; b *= 256;
|
||||
Serial.print("\t");
|
||||
Serial.print((int)r, HEX); Serial.print((int)g, HEX); Serial.print((int)b, HEX);
|
||||
Serial.println();
|
||||
|
||||
//Serial.print((int)r ); Serial.print(" "); Serial.print((int)g);Serial.print(" "); Serial.println((int)b );
|
||||
|
||||
analogWrite(redpin, gammatable[(int)r]);
|
||||
analogWrite(greenpin, gammatable[(int)g]);
|
||||
analogWrite(bluepin, gammatable[(int)b]);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,80 @@
|
||||
/* For use with the colorview Arduino example sketch
|
||||
Update the Serial() new call to match your serial port
|
||||
e.g. COM4, /dev/usbserial, etc!
|
||||
*/
|
||||
|
||||
|
||||
import processing.serial.*;
|
||||
import java.awt.datatransfer.*;
|
||||
import java.awt.Toolkit;
|
||||
|
||||
Serial port;
|
||||
|
||||
void setup(){
|
||||
size(200,200);
|
||||
port = new Serial(this, "COM4", 9600); //remember to replace COM20 with the appropriate serial port on your computer
|
||||
}
|
||||
|
||||
|
||||
String buff = "";
|
||||
|
||||
int wRed, wGreen, wBlue, wClear;
|
||||
String hexColor = "ffffff";
|
||||
|
||||
|
||||
void draw(){
|
||||
background(wRed,wGreen,wBlue);
|
||||
// check for serial, and process
|
||||
while (port.available() > 0) {
|
||||
serialEvent(port.read());
|
||||
}
|
||||
}
|
||||
|
||||
void serialEvent(int serial) {
|
||||
if(serial != '\n') {
|
||||
buff += char(serial);
|
||||
} else {
|
||||
//println(buff);
|
||||
|
||||
int cRed = buff.indexOf("R");
|
||||
int cGreen = buff.indexOf("G");
|
||||
int cBlue = buff.indexOf("B");
|
||||
int clear = buff.indexOf("C");
|
||||
if(clear >=0){
|
||||
String val = buff.substring(clear+3);
|
||||
val = val.split("\t")[0];
|
||||
wClear = Integer.parseInt(val.trim());
|
||||
} else { return; }
|
||||
|
||||
if(cRed >=0){
|
||||
String val = buff.substring(cRed+3);
|
||||
val = val.split("\t")[0];
|
||||
wRed = Integer.parseInt(val.trim());
|
||||
} else { return; }
|
||||
|
||||
if(cGreen >=0) {
|
||||
String val = buff.substring(cGreen+3);
|
||||
val = val.split("\t")[0];
|
||||
wGreen = Integer.parseInt(val.trim());
|
||||
} else { return; }
|
||||
|
||||
if(cBlue >=0) {
|
||||
String val = buff.substring(cBlue+3);
|
||||
val = val.split("\t")[0];
|
||||
wBlue = Integer.parseInt(val.trim());
|
||||
} else { return; }
|
||||
|
||||
print("Red: "); print(wRed);
|
||||
print("\tGrn: "); print(wGreen);
|
||||
print("\tBlue: "); print(wBlue);
|
||||
print("\tClr: "); println(wClear);
|
||||
|
||||
wRed *= 255; wRed /= wClear;
|
||||
wGreen *= 255; wGreen /= wClear;
|
||||
wBlue *= 255; wBlue /= wClear;
|
||||
|
||||
hexColor = hex(color(wRed, wGreen, wBlue), 6);
|
||||
println(hexColor);
|
||||
buff = "";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
#include <Wire.h>
|
||||
#include <Adafruit_TCS34725.h>
|
||||
|
||||
|
||||
/* Initialise with specific int time and gain values */
|
||||
Adafruit_TCS34725 tcs = Adafruit_TCS34725(TCS34725_INTEGRATIONTIME_700MS, TCS34725_GAIN_1X);
|
||||
const int interruptPin = 2;
|
||||
volatile boolean state = false;
|
||||
|
||||
|
||||
//Interrupt Service Routine
|
||||
void isr()
|
||||
{
|
||||
state = true;
|
||||
}
|
||||
|
||||
|
||||
/* tcs.getRawData() does a delay(Integration_Time) after the sensor readout.
|
||||
We don't need to wait for the next integration cycle because we receive an interrupt when the integration cycle is complete*/
|
||||
void getRawData_noDelay(uint16_t *r, uint16_t *g, uint16_t *b, uint16_t *c)
|
||||
{
|
||||
*c = tcs.read16(TCS34725_CDATAL);
|
||||
*r = tcs.read16(TCS34725_RDATAL);
|
||||
*g = tcs.read16(TCS34725_GDATAL);
|
||||
*b = tcs.read16(TCS34725_BDATAL);
|
||||
}
|
||||
|
||||
|
||||
void setup() {
|
||||
pinMode(interruptPin, INPUT_PULLUP); //TCS interrupt output is Active-LOW and Open-Drain
|
||||
attachInterrupt(digitalPinToInterrupt(interruptPin), isr, FALLING);
|
||||
|
||||
Serial.begin(9600);
|
||||
|
||||
if (tcs.begin()) {
|
||||
Serial.println("Found sensor");
|
||||
} else {
|
||||
Serial.println("No TCS34725 found ... check your connections");
|
||||
while (1);
|
||||
}
|
||||
|
||||
// Set persistence filter to generate an interrupt for every RGB Cycle, regardless of the integration limits
|
||||
tcs.write8(TCS34725_PERS, TCS34725_PERS_NONE);
|
||||
tcs.setInterrupt(true);
|
||||
|
||||
Serial.flush();
|
||||
}
|
||||
|
||||
|
||||
void loop() {
|
||||
if (state) {
|
||||
uint16_t r, g, b, c, colorTemp, lux;
|
||||
getRawData_noDelay(&r, &g, &b, &c);
|
||||
colorTemp = tcs.calculateColorTemperature(r, g, b);
|
||||
lux = tcs.calculateLux(r, g, b);
|
||||
|
||||
Serial.print("Color Temp: "); Serial.print(colorTemp, DEC); Serial.print(" K - ");
|
||||
Serial.print("Lux: "); Serial.print(lux, DEC); Serial.print(" - ");
|
||||
Serial.print("R: "); Serial.print(r, DEC); Serial.print(" ");
|
||||
Serial.print("G: "); Serial.print(g, DEC); Serial.print(" ");
|
||||
Serial.print("B: "); Serial.print(b, DEC); Serial.print(" ");
|
||||
Serial.print("C: "); Serial.print(c, DEC); Serial.print(" ");
|
||||
Serial.println(" ");
|
||||
Serial.flush();
|
||||
|
||||
tcs.clearInterrupt();
|
||||
state = false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
#include <Wire.h>
|
||||
#include "Adafruit_TCS34725.h"
|
||||
|
||||
/* Example code for the Adafruit TCS34725 breakout library */
|
||||
|
||||
/* Connect SCL to analog 5
|
||||
Connect SDA to analog 4
|
||||
Connect VDD to 3.3V DC
|
||||
Connect GROUND to common ground */
|
||||
|
||||
/* Initialise with default values (int time = 2.4ms, gain = 1x) */
|
||||
// Adafruit_TCS34725 tcs = Adafruit_TCS34725();
|
||||
|
||||
/* Initialise with specific int time and gain values */
|
||||
Adafruit_TCS34725 tcs = Adafruit_TCS34725(TCS34725_INTEGRATIONTIME_700MS, TCS34725_GAIN_1X);
|
||||
|
||||
void setup(void) {
|
||||
Serial.begin(9600);
|
||||
|
||||
if (tcs.begin()) {
|
||||
Serial.println("Found sensor");
|
||||
} else {
|
||||
Serial.println("No TCS34725 found ... check your connections");
|
||||
while (1);
|
||||
}
|
||||
|
||||
// Now we're ready to get readings!
|
||||
}
|
||||
|
||||
void loop(void) {
|
||||
uint16_t r, g, b, c, colorTemp, lux;
|
||||
|
||||
tcs.getRawData(&r, &g, &b, &c);
|
||||
colorTemp = tcs.calculateColorTemperature(r, g, b);
|
||||
lux = tcs.calculateLux(r, g, b);
|
||||
|
||||
Serial.print("Color Temp: "); Serial.print(colorTemp, DEC); Serial.print(" K - ");
|
||||
Serial.print("Lux: "); Serial.print(lux, DEC); Serial.print(" - ");
|
||||
Serial.print("R: "); Serial.print(r, DEC); Serial.print(" ");
|
||||
Serial.print("G: "); Serial.print(g, DEC); Serial.print(" ");
|
||||
Serial.print("B: "); Serial.print(b, DEC); Serial.print(" ");
|
||||
Serial.print("C: "); Serial.print(c, DEC); Serial.print(" ");
|
||||
Serial.println(" ");
|
||||
}
|
||||
@@ -0,0 +1,211 @@
|
||||
#include <Wire.h>
|
||||
#include "Adafruit_TCS34725.h"
|
||||
|
||||
//
|
||||
// An experimental wrapper class that implements the improved lux and color temperature from
|
||||
// TAOS and a basic autorange mechanism.
|
||||
//
|
||||
// Written by ductsoup, public domain
|
||||
//
|
||||
|
||||
// RGB Color Sensor with IR filter and White LED - TCS34725
|
||||
// I2C 7-bit address 0x29, 8-bit address 0x52
|
||||
//
|
||||
// http://www.adafruit.com/product/1334
|
||||
// http://learn.adafruit.com/adafruit-color-sensors/overview
|
||||
// http://www.adafruit.com/datasheets/TCS34725.pdf
|
||||
// http://www.ams.com/eng/Products/Light-Sensors/Color-Sensor/TCS34725
|
||||
// http://www.ams.com/eng/content/view/download/265215 <- DN40, calculations
|
||||
// http://www.ams.com/eng/content/view/download/181895 <- DN39, some thoughts on autogain
|
||||
// http://www.ams.com/eng/content/view/download/145158 <- DN25 (original Adafruit calculations)
|
||||
//
|
||||
// connect LED to digital 4 or GROUND for ambient light sensing
|
||||
// connect SCL to analog 5
|
||||
// connect SDA to analog 4
|
||||
// connect Vin to 3.3-5V DC
|
||||
// connect GROUND to common ground
|
||||
|
||||
// some magic numbers for this device from the DN40 application note
|
||||
#define TCS34725_R_Coef 0.136
|
||||
#define TCS34725_G_Coef 1.000
|
||||
#define TCS34725_B_Coef -0.444
|
||||
#define TCS34725_GA 1.0
|
||||
#define TCS34725_DF 310.0
|
||||
#define TCS34725_CT_Coef 3810.0
|
||||
#define TCS34725_CT_Offset 1391.0
|
||||
|
||||
// Autorange class for TCS34725
|
||||
class tcs34725 {
|
||||
public:
|
||||
tcs34725(void);
|
||||
|
||||
boolean begin(void);
|
||||
void getData(void);
|
||||
|
||||
boolean isAvailable, isSaturated;
|
||||
uint16_t againx, atime, atime_ms;
|
||||
uint16_t r, g, b, c;
|
||||
uint16_t ir;
|
||||
uint16_t r_comp, g_comp, b_comp, c_comp;
|
||||
uint16_t saturation, saturation75;
|
||||
float cratio, cpl, ct, lux, maxlux;
|
||||
|
||||
private:
|
||||
struct tcs_agc {
|
||||
tcs34725Gain_t ag;
|
||||
tcs34725IntegrationTime_t at;
|
||||
uint16_t mincnt;
|
||||
uint16_t maxcnt;
|
||||
};
|
||||
static const tcs_agc agc_lst[];
|
||||
uint16_t agc_cur;
|
||||
|
||||
void setGainTime(void);
|
||||
Adafruit_TCS34725 tcs;
|
||||
};
|
||||
//
|
||||
// Gain/time combinations to use and the min/max limits for hysteresis
|
||||
// that avoid saturation. They should be in order from dim to bright.
|
||||
//
|
||||
// Also set the first min count and the last max count to 0 to indicate
|
||||
// the start and end of the list.
|
||||
//
|
||||
const tcs34725::tcs_agc tcs34725::agc_lst[] = {
|
||||
{ TCS34725_GAIN_60X, TCS34725_INTEGRATIONTIME_700MS, 0, 20000 },
|
||||
{ TCS34725_GAIN_60X, TCS34725_INTEGRATIONTIME_154MS, 4990, 63000 },
|
||||
{ TCS34725_GAIN_16X, TCS34725_INTEGRATIONTIME_154MS, 16790, 63000 },
|
||||
{ TCS34725_GAIN_4X, TCS34725_INTEGRATIONTIME_154MS, 15740, 63000 },
|
||||
{ TCS34725_GAIN_1X, TCS34725_INTEGRATIONTIME_154MS, 15740, 0 }
|
||||
};
|
||||
tcs34725::tcs34725() : agc_cur(0), isAvailable(0), isSaturated(0) {
|
||||
}
|
||||
|
||||
// initialize the sensor
|
||||
boolean tcs34725::begin(void) {
|
||||
tcs = Adafruit_TCS34725(agc_lst[agc_cur].at, agc_lst[agc_cur].ag);
|
||||
if ((isAvailable = tcs.begin()))
|
||||
setGainTime();
|
||||
return(isAvailable);
|
||||
}
|
||||
|
||||
// Set the gain and integration time
|
||||
void tcs34725::setGainTime(void) {
|
||||
tcs.setGain(agc_lst[agc_cur].ag);
|
||||
tcs.setIntegrationTime(agc_lst[agc_cur].at);
|
||||
atime = int(agc_lst[agc_cur].at);
|
||||
atime_ms = ((256 - atime) * 2.4);
|
||||
switch(agc_lst[agc_cur].ag) {
|
||||
case TCS34725_GAIN_1X:
|
||||
againx = 1;
|
||||
break;
|
||||
case TCS34725_GAIN_4X:
|
||||
againx = 4;
|
||||
break;
|
||||
case TCS34725_GAIN_16X:
|
||||
againx = 16;
|
||||
break;
|
||||
case TCS34725_GAIN_60X:
|
||||
againx = 60;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Retrieve data from the sensor and do the calculations
|
||||
void tcs34725::getData(void) {
|
||||
// read the sensor and autorange if necessary
|
||||
tcs.getRawData(&r, &g, &b, &c);
|
||||
while(1) {
|
||||
if (agc_lst[agc_cur].maxcnt && c > agc_lst[agc_cur].maxcnt)
|
||||
agc_cur++;
|
||||
else if (agc_lst[agc_cur].mincnt && c < agc_lst[agc_cur].mincnt)
|
||||
agc_cur--;
|
||||
else break;
|
||||
|
||||
setGainTime();
|
||||
delay((256 - atime) * 2.4 * 2); // shock absorber
|
||||
tcs.getRawData(&r, &g, &b, &c);
|
||||
break;
|
||||
}
|
||||
|
||||
// DN40 calculations
|
||||
ir = (r + g + b > c) ? (r + g + b - c) / 2 : 0;
|
||||
r_comp = r - ir;
|
||||
g_comp = g - ir;
|
||||
b_comp = b - ir;
|
||||
c_comp = c - ir;
|
||||
cratio = float(ir) / float(c);
|
||||
|
||||
saturation = ((256 - atime) > 63) ? 65535 : 1024 * (256 - atime);
|
||||
saturation75 = (atime_ms < 150) ? (saturation - saturation / 4) : saturation;
|
||||
isSaturated = (atime_ms < 150 && c > saturation75) ? 1 : 0;
|
||||
cpl = (atime_ms * againx) / (TCS34725_GA * TCS34725_DF);
|
||||
maxlux = 65535 / (cpl * 3);
|
||||
|
||||
lux = (TCS34725_R_Coef * float(r_comp) + TCS34725_G_Coef * float(g_comp) + TCS34725_B_Coef * float(b_comp)) / cpl;
|
||||
ct = TCS34725_CT_Coef * float(b_comp) / float(r_comp) + TCS34725_CT_Offset;
|
||||
}
|
||||
|
||||
tcs34725 rgb_sensor;
|
||||
|
||||
void setup(void) {
|
||||
Serial.begin(115200);
|
||||
rgb_sensor.begin();
|
||||
pinMode(4, OUTPUT);
|
||||
digitalWrite(4, LOW); // @gremlins Bright light, bright light!
|
||||
}
|
||||
|
||||
void loop(void) {
|
||||
rgb_sensor.getData();
|
||||
Serial.print(F("Gain:"));
|
||||
Serial.print(rgb_sensor.againx);
|
||||
Serial.print(F("x "));
|
||||
Serial.print(F("Time:"));
|
||||
Serial.print(rgb_sensor.atime_ms);
|
||||
Serial.print(F("ms (0x"));
|
||||
Serial.print(rgb_sensor.atime, HEX);
|
||||
Serial.println(F(")"));
|
||||
|
||||
Serial.print(F("Raw R:"));
|
||||
Serial.print(rgb_sensor.r);
|
||||
Serial.print(F(" G:"));
|
||||
Serial.print(rgb_sensor.g);
|
||||
Serial.print(F(" B:"));
|
||||
Serial.print(rgb_sensor.b);
|
||||
Serial.print(F(" C:"));
|
||||
Serial.println(rgb_sensor.c);
|
||||
|
||||
Serial.print(F("IR:"));
|
||||
Serial.print(rgb_sensor.ir);
|
||||
Serial.print(F(" CRATIO:"));
|
||||
Serial.print(rgb_sensor.cratio);
|
||||
Serial.print(F(" Sat:"));
|
||||
Serial.print(rgb_sensor.saturation);
|
||||
Serial.print(F(" Sat75:"));
|
||||
Serial.print(rgb_sensor.saturation75);
|
||||
Serial.print(F(" "));
|
||||
Serial.println(rgb_sensor.isSaturated ? "*SATURATED*" : "");
|
||||
|
||||
Serial.print(F("CPL:"));
|
||||
Serial.print(rgb_sensor.cpl);
|
||||
Serial.print(F(" Max lux:"));
|
||||
Serial.println(rgb_sensor.maxlux);
|
||||
|
||||
Serial.print(F("Compensated R:"));
|
||||
Serial.print(rgb_sensor.r_comp);
|
||||
Serial.print(F(" G:"));
|
||||
Serial.print(rgb_sensor.g_comp);
|
||||
Serial.print(F(" B:"));
|
||||
Serial.print(rgb_sensor.b_comp);
|
||||
Serial.print(F(" C:"));
|
||||
Serial.println(rgb_sensor.c_comp);
|
||||
|
||||
Serial.print(F("Lux:"));
|
||||
Serial.print(rgb_sensor.lux);
|
||||
Serial.print(F(" CT:"));
|
||||
Serial.print(rgb_sensor.ct);
|
||||
Serial.println(F("K"));
|
||||
|
||||
Serial.println();
|
||||
|
||||
delay(2000);
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
name=Adafruit TCS34725
|
||||
version=1.0.1
|
||||
author=Adafruit
|
||||
maintainer=Adafruit <info@adafruit.com>
|
||||
sentence=Driver for Adafruit's TCS34725 RGB Color Sensor Breakout
|
||||
paragraph=Driver for Adafruit's TCS34725 RGB Color Sensor Breakout
|
||||
category=Sensors
|
||||
url=https://github.com/adafruit/Adafruit_TCS34725
|
||||
architectures=*
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
Thank you for opening an issue on an Adafruit Arduino library repository. To
|
||||
improve the speed of resolution please review the following guidelines and
|
||||
common troubleshooting steps below before creating the issue:
|
||||
|
||||
- **Do not use GitHub issues for troubleshooting projects and issues.** Instead use
|
||||
the forums at http://forums.adafruit.com to ask questions and troubleshoot why
|
||||
something isn't working as expected. In many cases the problem is a common issue
|
||||
that you will more quickly receive help from the forum community. GitHub issues
|
||||
are meant for known defects in the code. If you don't know if there is a defect
|
||||
in the code then start with troubleshooting on the forum first.
|
||||
|
||||
- **If following a tutorial or guide be sure you didn't miss a step.** Carefully
|
||||
check all of the steps and commands to run have been followed. Consult the
|
||||
forum if you're unsure or have questions about steps in a guide/tutorial.
|
||||
|
||||
- **For Arduino projects check these very common issues to ensure they don't apply**:
|
||||
|
||||
- For uploading sketches or communicating with the board make sure you're using
|
||||
a **USB data cable** and **not** a **USB charge-only cable**. It is sometimes
|
||||
very hard to tell the difference between a data and charge cable! Try using the
|
||||
cable with other devices or swapping to another cable to confirm it is not
|
||||
the problem.
|
||||
|
||||
- **Be sure you are supplying adequate power to the board.** Check the specs of
|
||||
your board and plug in an external power supply. In many cases just
|
||||
plugging a board into your computer is not enough to power it and other
|
||||
peripherals.
|
||||
|
||||
- **Double check all soldering joints and connections.** Flakey connections
|
||||
cause many mysterious problems. See the [guide to excellent soldering](https://learn.adafruit.com/adafruit-guide-excellent-soldering/tools) for examples of good solder joints.
|
||||
|
||||
- **Ensure you are using an official Arduino or Adafruit board.** We can't
|
||||
guarantee a clone board will have the same functionality and work as expected
|
||||
with this code and don't support them.
|
||||
|
||||
If you're sure this issue is a defect in the code and checked the steps above
|
||||
please fill in the following fields to provide enough troubleshooting information.
|
||||
You may delete the guideline and text above to just leave the following details:
|
||||
|
||||
- Arduino board: **INSERT ARDUINO BOARD NAME/TYPE HERE**
|
||||
|
||||
- Arduino IDE version (found in Arduino -> About Arduino menu): **INSERT ARDUINO
|
||||
VERSION HERE**
|
||||
|
||||
- List the steps to reproduce the problem below (if possible attach a sketch or
|
||||
copy the sketch code in too): **LIST REPRO STEPS BELOW**
|
||||
@@ -0,0 +1,26 @@
|
||||
Thank you for creating a pull request to contribute to Adafruit's GitHub code!
|
||||
Before you open the request please review the following guidelines and tips to
|
||||
help it be more easily integrated:
|
||||
|
||||
- **Describe the scope of your change--i.e. what the change does and what parts
|
||||
of the code were modified.** This will help us understand any risks of integrating
|
||||
the code.
|
||||
|
||||
- **Describe any known limitations with your change.** For example if the change
|
||||
doesn't apply to a supported platform of the library please mention it.
|
||||
|
||||
- **Please run any tests or examples that can exercise your modified code.** We
|
||||
strive to not break users of the code and running tests/examples helps with this
|
||||
process.
|
||||
|
||||
Thank you again for contributing! We will try to test and integrate the change
|
||||
as soon as we can, but be aware we have many GitHub repositories to manage and
|
||||
can't immediately respond to every request. There is no need to bump or check in
|
||||
on a pull request (it will clutter the discussion of the request).
|
||||
|
||||
Also don't be worried if the request is closed or not integrated--sometimes the
|
||||
priorities of Adafruit's GitHub code (education, ease of use) might not match the
|
||||
priorities of the pull request. Don't fret, the open source community thrives on
|
||||
forks and GitHub makes it easy to keep your changes in a forked repo.
|
||||
|
||||
After reviewing the guidelines above you can delete this text from the pull request.
|
||||
@@ -0,0 +1,504 @@
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@file Adafruit_TSL2591.cpp
|
||||
@author KT0WN (adafruit.com)
|
||||
|
||||
This is a library for the Adafruit TSL2591 breakout board
|
||||
This library works with the Adafruit TSL2591 breakout
|
||||
----> https://www.adafruit.com/products/1980
|
||||
|
||||
Check out the links above for our tutorials and wiring diagrams
|
||||
These chips use I2C to communicate
|
||||
|
||||
Adafruit invests time and resources providing this open source code,
|
||||
please support Adafruit and open-source hardware by purchasing
|
||||
products from Adafruit!
|
||||
|
||||
@section LICENSE
|
||||
|
||||
Software License Agreement (BSD License)
|
||||
|
||||
Copyright (c) 2014 Adafruit Industries
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
3. Neither the name of the copyright holders nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/**************************************************************************/
|
||||
#if defined(ESP8266) || defined(ESP32)
|
||||
#include <pgmspace.h>
|
||||
#else
|
||||
#include <avr/pgmspace.h>
|
||||
#endif
|
||||
#if defined(__AVR__)
|
||||
#include <util/delay.h>
|
||||
#endif
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "Adafruit_TSL2591.h"
|
||||
|
||||
Adafruit_TSL2591::Adafruit_TSL2591(int32_t sensorID)
|
||||
{
|
||||
_initialized = false;
|
||||
_integration = TSL2591_INTEGRATIONTIME_100MS;
|
||||
_gain = TSL2591_GAIN_MED;
|
||||
_sensorID = sensorID;
|
||||
|
||||
// we cant do wire initialization till later, because we havent loaded Wire yet
|
||||
}
|
||||
|
||||
boolean Adafruit_TSL2591::begin(void)
|
||||
{
|
||||
Wire.begin();
|
||||
|
||||
/*
|
||||
for (uint8_t i=0; i<0x20; i++)
|
||||
{
|
||||
uint8_t id = read8(0x12);
|
||||
Serial.print("$"); Serial.print(i, HEX);
|
||||
Serial.print(" = 0x"); Serial.println(read8(i), HEX);
|
||||
}
|
||||
*/
|
||||
|
||||
uint8_t id = read8(TSL2591_COMMAND_BIT | TSL2591_REGISTER_DEVICE_ID);
|
||||
if (id == 0x50 )
|
||||
{
|
||||
// Serial.println("Found Adafruit_TSL2591");
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
_initialized = true;
|
||||
|
||||
// Set default integration time and gain
|
||||
setTiming(_integration);
|
||||
setGain(_gain);
|
||||
|
||||
// Note: by default, the device is in power down mode on bootup
|
||||
disable();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Adafruit_TSL2591::enable(void)
|
||||
{
|
||||
if (!_initialized)
|
||||
{
|
||||
if (!begin())
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Enable the device by setting the control bit to 0x01
|
||||
write8(TSL2591_COMMAND_BIT | TSL2591_REGISTER_ENABLE, TSL2591_ENABLE_POWERON | TSL2591_ENABLE_AEN | TSL2591_ENABLE_AIEN | TSL2591_ENABLE_NPIEN);
|
||||
}
|
||||
|
||||
void Adafruit_TSL2591::disable(void)
|
||||
{
|
||||
if (!_initialized)
|
||||
{
|
||||
if (!begin())
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Disable the device by setting the control bit to 0x00
|
||||
write8(TSL2591_COMMAND_BIT | TSL2591_REGISTER_ENABLE, TSL2591_ENABLE_POWEROFF);
|
||||
}
|
||||
|
||||
void Adafruit_TSL2591::setGain(tsl2591Gain_t gain)
|
||||
{
|
||||
if (!_initialized)
|
||||
{
|
||||
if (!begin())
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
enable();
|
||||
_gain = gain;
|
||||
write8(TSL2591_COMMAND_BIT | TSL2591_REGISTER_CONTROL, _integration | _gain);
|
||||
disable();
|
||||
}
|
||||
|
||||
tsl2591Gain_t Adafruit_TSL2591::getGain()
|
||||
{
|
||||
return _gain;
|
||||
}
|
||||
|
||||
void Adafruit_TSL2591::setTiming(tsl2591IntegrationTime_t integration)
|
||||
{
|
||||
if (!_initialized)
|
||||
{
|
||||
if (!begin())
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
enable();
|
||||
_integration = integration;
|
||||
write8(TSL2591_COMMAND_BIT | TSL2591_REGISTER_CONTROL, _integration | _gain);
|
||||
disable();
|
||||
}
|
||||
|
||||
tsl2591IntegrationTime_t Adafruit_TSL2591::getTiming()
|
||||
{
|
||||
return _integration;
|
||||
}
|
||||
|
||||
float Adafruit_TSL2591::calculateLuxf(uint16_t ch0, uint16_t ch1)
|
||||
{
|
||||
float atime, again;
|
||||
float cpl, lux1, lux2, lux;
|
||||
uint32_t chan0, chan1;
|
||||
|
||||
// Check for overflow conditions first
|
||||
if ((ch0 == 0xFFFF) | (ch1 == 0xFFFF))
|
||||
{
|
||||
// Signal an overflow
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Note: This algorithm is based on preliminary coefficients
|
||||
// provided by AMS and may need to be updated in the future
|
||||
|
||||
switch (_integration)
|
||||
{
|
||||
case TSL2591_INTEGRATIONTIME_100MS :
|
||||
atime = 100.0F;
|
||||
break;
|
||||
case TSL2591_INTEGRATIONTIME_200MS :
|
||||
atime = 200.0F;
|
||||
break;
|
||||
case TSL2591_INTEGRATIONTIME_300MS :
|
||||
atime = 300.0F;
|
||||
break;
|
||||
case TSL2591_INTEGRATIONTIME_400MS :
|
||||
atime = 400.0F;
|
||||
break;
|
||||
case TSL2591_INTEGRATIONTIME_500MS :
|
||||
atime = 500.0F;
|
||||
break;
|
||||
case TSL2591_INTEGRATIONTIME_600MS :
|
||||
atime = 600.0F;
|
||||
break;
|
||||
default: // 100ms
|
||||
atime = 100.0F;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (_gain)
|
||||
{
|
||||
case TSL2591_GAIN_LOW :
|
||||
again = 1.0F;
|
||||
break;
|
||||
case TSL2591_GAIN_MED :
|
||||
again = 25.0F;
|
||||
break;
|
||||
case TSL2591_GAIN_HIGH :
|
||||
again = 428.0F;
|
||||
break;
|
||||
case TSL2591_GAIN_MAX :
|
||||
again = 9876.0F;
|
||||
break;
|
||||
default:
|
||||
again = 1.0F;
|
||||
break;
|
||||
}
|
||||
|
||||
// cpl = (ATIME * AGAIN) / DF
|
||||
cpl = (atime * again) / TSL2591_LUX_DF;
|
||||
|
||||
lux1 = (((float) ch0 - (float) ch1)) * (1.0F - ((float) ch1 / (float) ch0)) / cpl;//( (float)ch0 - (TSL2591_LUX_COEFB * (float)ch1) ) / cpl;
|
||||
lux2 = ((TSL2591_LUX_COEFC * (float) ch0) - (TSL2591_LUX_COEFD * (float) ch1)) / cpl;
|
||||
lux = lux1 > lux2 ? lux1 : lux2;
|
||||
|
||||
// Alternate lux calculation
|
||||
//lux = ( (float)ch0 - ( 1.7F * (float)ch1 ) ) / cpl;
|
||||
|
||||
// Signal I2C had no errors
|
||||
return lux;
|
||||
}
|
||||
|
||||
uint32_t Adafruit_TSL2591::calculateLux(uint16_t ch0, uint16_t ch1)
|
||||
{
|
||||
return (uint32_t) calculateLuxf(ch0, ch1);
|
||||
}
|
||||
|
||||
uint32_t Adafruit_TSL2591::getFullLuminosity (void)
|
||||
{
|
||||
if (!_initialized)
|
||||
{
|
||||
if (!begin())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Enable the device
|
||||
enable();
|
||||
|
||||
// Wait x ms for ADC to complete
|
||||
for (uint8_t d=0; d<=_integration; d++)
|
||||
{
|
||||
delay(120);
|
||||
}
|
||||
|
||||
uint32_t x;
|
||||
uint16_t y;
|
||||
y |= read16(TSL2591_COMMAND_BIT | TSL2591_REGISTER_CHAN0_LOW);
|
||||
x = read16(TSL2591_COMMAND_BIT | TSL2591_REGISTER_CHAN1_LOW);
|
||||
x <<= 16;
|
||||
x |= y;
|
||||
|
||||
disable();
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
uint16_t Adafruit_TSL2591::getLuminosity (uint8_t channel)
|
||||
{
|
||||
uint32_t x = getFullLuminosity();
|
||||
|
||||
if (channel == TSL2591_FULLSPECTRUM)
|
||||
{
|
||||
// Reads two byte value from channel 0 (visible + infrared)
|
||||
return (x & 0xFFFF);
|
||||
}
|
||||
else if (channel == TSL2591_INFRARED)
|
||||
{
|
||||
// Reads two byte value from channel 1 (infrared)
|
||||
return (x >> 16);
|
||||
}
|
||||
else if (channel == TSL2591_VISIBLE)
|
||||
{
|
||||
// Reads all and subtracts out just the visible!
|
||||
return ( (x & 0xFFFF) - (x >> 16));
|
||||
}
|
||||
|
||||
// unknown channel!
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Adafruit_TSL2591::registerInterrupt(uint16_t lowerThreshold, uint16_t upperThreshold)
|
||||
{
|
||||
if (!_initialized)
|
||||
{
|
||||
if (!begin())
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
enable();
|
||||
write8(TSL2591_COMMAND_BIT | TSL2591_REGISTER_THRESHOLD_NPAILTL, lowerThreshold);
|
||||
write8(TSL2591_COMMAND_BIT | TSL2591_REGISTER_THRESHOLD_NPAILTH, lowerThreshold >> 8);
|
||||
write8(TSL2591_COMMAND_BIT | TSL2591_REGISTER_THRESHOLD_NPAIHTL, upperThreshold);
|
||||
write8(TSL2591_COMMAND_BIT | TSL2591_REGISTER_THRESHOLD_NPAIHTH, upperThreshold >> 8);
|
||||
disable();
|
||||
}
|
||||
|
||||
void Adafruit_TSL2591::registerInterrupt(uint16_t lowerThreshold, uint16_t upperThreshold, tsl2591Persist_t persist)
|
||||
{
|
||||
if (!_initialized)
|
||||
{
|
||||
if (!begin())
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
enable();
|
||||
write8(TSL2591_COMMAND_BIT | TSL2591_REGISTER_PERSIST_FILTER, persist);
|
||||
write8(TSL2591_COMMAND_BIT | TSL2591_REGISTER_THRESHOLD_AILTL, lowerThreshold);
|
||||
write8(TSL2591_COMMAND_BIT | TSL2591_REGISTER_THRESHOLD_AILTH, lowerThreshold >> 8);
|
||||
write8(TSL2591_COMMAND_BIT | TSL2591_REGISTER_THRESHOLD_AIHTL, upperThreshold);
|
||||
write8(TSL2591_COMMAND_BIT | TSL2591_REGISTER_THRESHOLD_AIHTH, upperThreshold >> 8);
|
||||
disable();
|
||||
}
|
||||
|
||||
void Adafruit_TSL2591::clearInterrupt()
|
||||
{
|
||||
if (!_initialized)
|
||||
{
|
||||
if (!begin())
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
enable();
|
||||
write8(TSL2591_CLEAR_INT);
|
||||
disable();
|
||||
}
|
||||
|
||||
|
||||
uint8_t Adafruit_TSL2591::getStatus()
|
||||
{
|
||||
if (!_initialized)
|
||||
{
|
||||
if (!begin())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Enable the device
|
||||
enable();
|
||||
uint8_t x;
|
||||
x = read8(TSL2591_COMMAND_BIT | TSL2591_REGISTER_DEVICE_STATUS);
|
||||
disable();
|
||||
return x;
|
||||
}
|
||||
|
||||
|
||||
uint8_t Adafruit_TSL2591::read8(uint8_t reg)
|
||||
{
|
||||
uint8_t x;
|
||||
|
||||
Wire.beginTransmission(TSL2591_ADDR);
|
||||
#if ARDUINO >= 100
|
||||
Wire.write(reg);
|
||||
#else
|
||||
Wire.send(reg);
|
||||
#endif
|
||||
Wire.endTransmission();
|
||||
|
||||
Wire.requestFrom(TSL2591_ADDR, 1);
|
||||
#if ARDUINO >= 100
|
||||
x = Wire.read();
|
||||
#else
|
||||
x = Wire.receive();
|
||||
#endif
|
||||
// while (! Wire.available());
|
||||
// return Wire.read();
|
||||
return x;
|
||||
}
|
||||
|
||||
uint16_t Adafruit_TSL2591::read16(uint8_t reg)
|
||||
{
|
||||
uint16_t x;
|
||||
uint16_t t;
|
||||
|
||||
Wire.beginTransmission(TSL2591_ADDR);
|
||||
#if ARDUINO >= 100
|
||||
Wire.write(reg);
|
||||
#else
|
||||
Wire.send(reg);
|
||||
#endif
|
||||
Wire.endTransmission();
|
||||
|
||||
Wire.requestFrom(TSL2591_ADDR, 2);
|
||||
#if ARDUINO >= 100
|
||||
t = Wire.read();
|
||||
x = Wire.read();
|
||||
#else
|
||||
t = Wire.receive();
|
||||
x = Wire.receive();
|
||||
#endif
|
||||
x <<= 8;
|
||||
x |= t;
|
||||
return x;
|
||||
}
|
||||
|
||||
void Adafruit_TSL2591::write8 (uint8_t reg, uint8_t value)
|
||||
{
|
||||
Wire.beginTransmission(TSL2591_ADDR);
|
||||
#if ARDUINO >= 100
|
||||
Wire.write(reg);
|
||||
Wire.write(value);
|
||||
#else
|
||||
Wire.send(reg);
|
||||
Wire.send(value);
|
||||
#endif
|
||||
Wire.endTransmission();
|
||||
}
|
||||
|
||||
|
||||
void Adafruit_TSL2591::write8 (uint8_t reg)
|
||||
{
|
||||
Wire.beginTransmission(TSL2591_ADDR);
|
||||
#if ARDUINO >= 100
|
||||
Wire.write(reg);
|
||||
#else
|
||||
Wire.send(reg);
|
||||
#endif
|
||||
Wire.endTransmission();
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Gets the most recent sensor event
|
||||
*/
|
||||
/**************************************************************************/
|
||||
bool Adafruit_TSL2591::getEvent(sensors_event_t *event)
|
||||
{
|
||||
uint16_t ir, full;
|
||||
uint32_t lum = getFullLuminosity();
|
||||
/* Early silicon seems to have issues when there is a sudden jump in */
|
||||
/* light levels. :( To work around this for now sample the sensor 2x */
|
||||
lum = getFullLuminosity();
|
||||
ir = lum >> 16;
|
||||
full = lum & 0xFFFF;
|
||||
|
||||
/* Clear the event */
|
||||
memset(event, 0, sizeof(sensors_event_t));
|
||||
|
||||
event->version = sizeof(sensors_event_t);
|
||||
event->sensor_id = _sensorID;
|
||||
event->type = SENSOR_TYPE_LIGHT;
|
||||
event->timestamp = millis();
|
||||
|
||||
/* Calculate the actual lux value */
|
||||
/* 0 = sensor overflow (too much light) */
|
||||
event->light = calculateLux(full, ir);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Gets the sensor_t data
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void Adafruit_TSL2591::getSensor(sensor_t *sensor)
|
||||
{
|
||||
/* Clear the sensor_t object */
|
||||
memset(sensor, 0, sizeof(sensor_t));
|
||||
|
||||
/* Insert the sensor name in the fixed length char array */
|
||||
strncpy (sensor->name, "TSL2591", sizeof(sensor->name) - 1);
|
||||
sensor->name[sizeof(sensor->name)- 1] = 0;
|
||||
sensor->version = 1;
|
||||
sensor->sensor_id = _sensorID;
|
||||
sensor->type = SENSOR_TYPE_LIGHT;
|
||||
sensor->min_delay = 0;
|
||||
sensor->max_value = 88000.0;
|
||||
sensor->min_value = 0.0;
|
||||
sensor->resolution = 1.0;
|
||||
}
|
||||
@@ -0,0 +1,187 @@
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@file Adafruit_TSL2591.h
|
||||
@author KT0WN (adafruit.com)
|
||||
|
||||
This is a library for the Adafruit TSL2591 breakout board
|
||||
This library works with the Adafruit TSL2591 breakout
|
||||
----> https://www.adafruit.com/products/1980
|
||||
|
||||
Check out the links above for our tutorials and wiring diagrams
|
||||
These chips use I2C to communicate
|
||||
|
||||
Adafruit invests time and resources providing this open source code,
|
||||
please support Adafruit and open-source hardware by purchasing
|
||||
products from Adafruit!
|
||||
|
||||
@section LICENSE
|
||||
|
||||
Software License Agreement (BSD License)
|
||||
|
||||
Copyright (c) 2014 Adafruit Industries
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
3. Neither the name of the copyright holders nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef _TSL2591_H_
|
||||
#define _TSL2591_H_
|
||||
|
||||
#if ARDUINO >= 100
|
||||
#include <Arduino.h>
|
||||
#else
|
||||
#include <WProgram.h>
|
||||
#endif
|
||||
#include <Adafruit_Sensor.h>
|
||||
#include <Wire.h>
|
||||
|
||||
#define TSL2591_VISIBLE (2) // channel 0 - channel 1
|
||||
#define TSL2591_INFRARED (1) // channel 1
|
||||
#define TSL2591_FULLSPECTRUM (0) // channel 0
|
||||
|
||||
#define TSL2591_ADDR (0x29)
|
||||
#define TSL2591_READBIT (0x01)
|
||||
|
||||
#define TSL2591_COMMAND_BIT (0xA0) // 1010 0000: bits 7 and 5 for 'command normal'
|
||||
#define TSL2591_CLEAR_INT (0xE7)
|
||||
#define TSL2591_TEST_INT (0xE4)
|
||||
#define TSL2591_WORD_BIT (0x20) // 1 = read/write word (rather than byte)
|
||||
#define TSL2591_BLOCK_BIT (0x10) // 1 = using block read/write
|
||||
|
||||
#define TSL2591_ENABLE_POWEROFF (0x00)
|
||||
#define TSL2591_ENABLE_POWERON (0x01)
|
||||
#define TSL2591_ENABLE_AEN (0x02) // ALS Enable. This field activates ALS function. Writing a one activates the ALS. Writing a zero disables the ALS.
|
||||
#define TSL2591_ENABLE_AIEN (0x10) // ALS Interrupt Enable. When asserted permits ALS interrupts to be generated, subject to the persist filter.
|
||||
#define TSL2591_ENABLE_NPIEN (0x80) // No Persist Interrupt Enable. When asserted NP Threshold conditions will generate an interrupt, bypassing the persist filter
|
||||
|
||||
#define TSL2591_LUX_DF (408.0F)
|
||||
#define TSL2591_LUX_COEFB (1.64F) // CH0 coefficient
|
||||
#define TSL2591_LUX_COEFC (0.59F) // CH1 coefficient A
|
||||
#define TSL2591_LUX_COEFD (0.86F) // CH2 coefficient B
|
||||
|
||||
enum
|
||||
{
|
||||
TSL2591_REGISTER_ENABLE = 0x00,
|
||||
TSL2591_REGISTER_CONTROL = 0x01,
|
||||
TSL2591_REGISTER_THRESHOLD_AILTL = 0x04, // ALS low threshold lower byte
|
||||
TSL2591_REGISTER_THRESHOLD_AILTH = 0x05, // ALS low threshold upper byte
|
||||
TSL2591_REGISTER_THRESHOLD_AIHTL = 0x06, // ALS high threshold lower byte
|
||||
TSL2591_REGISTER_THRESHOLD_AIHTH = 0x07, // ALS high threshold upper byte
|
||||
TSL2591_REGISTER_THRESHOLD_NPAILTL = 0x08, // No Persist ALS low threshold lower byte
|
||||
TSL2591_REGISTER_THRESHOLD_NPAILTH = 0x09, // etc
|
||||
TSL2591_REGISTER_THRESHOLD_NPAIHTL = 0x0A,
|
||||
TSL2591_REGISTER_THRESHOLD_NPAIHTH = 0x0B,
|
||||
TSL2591_REGISTER_PERSIST_FILTER = 0x0C,
|
||||
TSL2591_REGISTER_PACKAGE_PID = 0x11,
|
||||
TSL2591_REGISTER_DEVICE_ID = 0x12,
|
||||
TSL2591_REGISTER_DEVICE_STATUS = 0x13,
|
||||
TSL2591_REGISTER_CHAN0_LOW = 0x14,
|
||||
TSL2591_REGISTER_CHAN0_HIGH = 0x15,
|
||||
TSL2591_REGISTER_CHAN1_LOW = 0x16,
|
||||
TSL2591_REGISTER_CHAN1_HIGH = 0x17
|
||||
};
|
||||
|
||||
typedef enum
|
||||
{
|
||||
TSL2591_INTEGRATIONTIME_100MS = 0x00,
|
||||
TSL2591_INTEGRATIONTIME_200MS = 0x01,
|
||||
TSL2591_INTEGRATIONTIME_300MS = 0x02,
|
||||
TSL2591_INTEGRATIONTIME_400MS = 0x03,
|
||||
TSL2591_INTEGRATIONTIME_500MS = 0x04,
|
||||
TSL2591_INTEGRATIONTIME_600MS = 0x05,
|
||||
}
|
||||
tsl2591IntegrationTime_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
// bit 7:4: 0
|
||||
TSL2591_PERSIST_EVERY = 0x00, // Every ALS cycle generates an interrupt
|
||||
TSL2591_PERSIST_ANY = 0x01, // Any value outside of threshold range
|
||||
TSL2591_PERSIST_2 = 0x02, // 2 consecutive values out of range
|
||||
TSL2591_PERSIST_3 = 0x03, // 3 consecutive values out of range
|
||||
TSL2591_PERSIST_5 = 0x04, // 5 consecutive values out of range
|
||||
TSL2591_PERSIST_10 = 0x05, // 10 consecutive values out of range
|
||||
TSL2591_PERSIST_15 = 0x06, // 15 consecutive values out of range
|
||||
TSL2591_PERSIST_20 = 0x07, // 20 consecutive values out of range
|
||||
TSL2591_PERSIST_25 = 0x08, // 25 consecutive values out of range
|
||||
TSL2591_PERSIST_30 = 0x09, // 30 consecutive values out of range
|
||||
TSL2591_PERSIST_35 = 0x0A, // 35 consecutive values out of range
|
||||
TSL2591_PERSIST_40 = 0x0B, // 40 consecutive values out of range
|
||||
TSL2591_PERSIST_45 = 0x0C, // 45 consecutive values out of range
|
||||
TSL2591_PERSIST_50 = 0x0D, // 50 consecutive values out of range
|
||||
TSL2591_PERSIST_55 = 0x0E, // 55 consecutive values out of range
|
||||
TSL2591_PERSIST_60 = 0x0F, // 60 consecutive values out of range
|
||||
}
|
||||
tsl2591Persist_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
TSL2591_GAIN_LOW = 0x00, // low gain (1x)
|
||||
TSL2591_GAIN_MED = 0x10, // medium gain (25x)
|
||||
TSL2591_GAIN_HIGH = 0x20, // medium gain (428x)
|
||||
TSL2591_GAIN_MAX = 0x30, // max gain (9876x)
|
||||
}
|
||||
tsl2591Gain_t;
|
||||
|
||||
class Adafruit_TSL2591 : public Adafruit_Sensor
|
||||
{
|
||||
public:
|
||||
Adafruit_TSL2591(int32_t sensorID = -1);
|
||||
|
||||
boolean begin ( void );
|
||||
void enable ( void );
|
||||
void disable ( void );
|
||||
void write8 ( uint8_t r);
|
||||
void write8 ( uint8_t r, uint8_t v );
|
||||
uint16_t read16 ( uint8_t reg );
|
||||
uint8_t read8 ( uint8_t reg );
|
||||
|
||||
uint32_t calculateLux ( uint16_t ch0, uint16_t ch1 );
|
||||
float calculateLuxf ( uint16_t ch0, uint16_t ch1 );
|
||||
void setGain ( tsl2591Gain_t gain );
|
||||
void setTiming ( tsl2591IntegrationTime_t integration );
|
||||
uint16_t getLuminosity (uint8_t channel );
|
||||
uint32_t getFullLuminosity ( );
|
||||
|
||||
tsl2591IntegrationTime_t getTiming();
|
||||
tsl2591Gain_t getGain();
|
||||
|
||||
// Interrupt
|
||||
void clearInterrupt(void);
|
||||
void registerInterrupt(uint16_t lowerThreshold, uint16_t upperThreshold);
|
||||
void registerInterrupt(uint16_t lowerThreshold, uint16_t upperThreshold, tsl2591Persist_t persist);
|
||||
uint8_t getStatus();
|
||||
|
||||
/* Unified Sensor API Functions */
|
||||
bool getEvent ( sensors_event_t* );
|
||||
void getSensor ( sensor_t* );
|
||||
|
||||
private:
|
||||
tsl2591IntegrationTime_t _integration;
|
||||
tsl2591Gain_t _gain;
|
||||
int32_t _sensorID;
|
||||
|
||||
boolean _initialized;
|
||||
};
|
||||
#endif
|
||||
@@ -0,0 +1,9 @@
|
||||
This is an Arduino library for the TSL2591 digital luminosity (light) sensors.
|
||||
|
||||
Pick one up at http://www.adafruit.com/products/1980
|
||||
|
||||
To download. click the DOWNLOADS button in the top right corner, rename the uncompressed folder Adafruit_TSL2591. Check that the Adafruit_TSL2591 folder contains Adafruit_TSL2591.cpp and Adafruit_TSL2591.h
|
||||
|
||||
Place the Adafruit_TSL2591 library folder your <arduinosketchfolder>/libraries/ folder. You may need to create the libraries subfolder if its your first library. Restart the IDE.
|
||||
|
||||
You'll also need the Adafruit_Sensor library from https://github.com/adafruit/Adafruit_Sensor
|
||||
@@ -0,0 +1,200 @@
|
||||
/* TSL2591 Digital Light Sensor */
|
||||
/* Dynamic Range: 600M:1 */
|
||||
/* Maximum Lux: 88K */
|
||||
|
||||
#include <Wire.h>
|
||||
#include <Adafruit_Sensor.h>
|
||||
#include "Adafruit_TSL2591.h"
|
||||
|
||||
// Example for demonstrating the TSL2591 library - public domain!
|
||||
|
||||
// connect SCL to analog 5
|
||||
// connect SDA to analog 4
|
||||
// connect Vin to 3.3-5V DC
|
||||
// connect GROUND to common ground
|
||||
|
||||
Adafruit_TSL2591 tsl = Adafruit_TSL2591(2591); // pass in a number for the sensor identifier (for your use later)
|
||||
|
||||
/**************************************************************************/
|
||||
/*
|
||||
Displays some basic information on this sensor from the unified
|
||||
sensor API sensor_t type (see Adafruit_Sensor for more information)
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void displaySensorDetails(void)
|
||||
{
|
||||
sensor_t sensor;
|
||||
tsl.getSensor(&sensor);
|
||||
Serial.println(F("------------------------------------"));
|
||||
Serial.print (F("Sensor: ")); Serial.println(sensor.name);
|
||||
Serial.print (F("Driver Ver: ")); Serial.println(sensor.version);
|
||||
Serial.print (F("Unique ID: ")); Serial.println(sensor.sensor_id);
|
||||
Serial.print (F("Max Value: ")); Serial.print(sensor.max_value); Serial.println(F(" lux"));
|
||||
Serial.print (F("Min Value: ")); Serial.print(sensor.min_value); Serial.println(F(" lux"));
|
||||
Serial.print (F("Resolution: ")); Serial.print(sensor.resolution); Serial.println(F(" lux"));
|
||||
Serial.println(F("------------------------------------"));
|
||||
Serial.println(F(""));
|
||||
delay(500);
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*
|
||||
Configures the gain and integration time for the TSL2591
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void configureSensor(void)
|
||||
{
|
||||
// You can change the gain on the fly, to adapt to brighter/dimmer light situations
|
||||
//tsl.setGain(TSL2591_GAIN_LOW); // 1x gain (bright light)
|
||||
tsl.setGain(TSL2591_GAIN_MED); // 25x gain
|
||||
// tsl.setGain(TSL2591_GAIN_HIGH); // 428x gain
|
||||
|
||||
// Changing the integration time gives you a longer time over which to sense light
|
||||
// longer timelines are slower, but are good in very low light situtations!
|
||||
tsl.setTiming(TSL2591_INTEGRATIONTIME_100MS); // shortest integration time (bright light)
|
||||
// tsl.setTiming(TSL2591_INTEGRATIONTIME_200MS);
|
||||
// tsl.setTiming(TSL2591_INTEGRATIONTIME_300MS);
|
||||
// tsl.setTiming(TSL2591_INTEGRATIONTIME_400MS);
|
||||
// tsl.setTiming(TSL2591_INTEGRATIONTIME_500MS);
|
||||
// tsl.setTiming(TSL2591_INTEGRATIONTIME_600MS); // longest integration time (dim light)
|
||||
|
||||
/* Display the gain and integration time for reference sake */
|
||||
Serial.println(F("------------------------------------"));
|
||||
Serial.print (F("Gain: "));
|
||||
tsl2591Gain_t gain = tsl.getGain();
|
||||
switch(gain)
|
||||
{
|
||||
case TSL2591_GAIN_LOW:
|
||||
Serial.println(F("1x (Low)"));
|
||||
break;
|
||||
case TSL2591_GAIN_MED:
|
||||
Serial.println(F("25x (Medium)"));
|
||||
break;
|
||||
case TSL2591_GAIN_HIGH:
|
||||
Serial.println(F("428x (High)"));
|
||||
break;
|
||||
case TSL2591_GAIN_MAX:
|
||||
Serial.println(F("9876x (Max)"));
|
||||
break;
|
||||
}
|
||||
Serial.print (F("Timing: "));
|
||||
Serial.print((tsl.getTiming() + 1) * 100, DEC);
|
||||
Serial.println(F(" ms"));
|
||||
Serial.println(F("------------------------------------"));
|
||||
Serial.println(F(""));
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/*
|
||||
Program entry point for the Arduino sketch
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void setup(void)
|
||||
{
|
||||
Serial.begin(9600);
|
||||
|
||||
Serial.println(F("Starting Adafruit TSL2591 Test!"));
|
||||
|
||||
if (tsl.begin())
|
||||
{
|
||||
Serial.println(F("Found a TSL2591 sensor"));
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.println(F("No sensor found ... check your wiring?"));
|
||||
while (1);
|
||||
}
|
||||
|
||||
/* Display some basic information on this sensor */
|
||||
displaySensorDetails();
|
||||
|
||||
/* Configure the sensor */
|
||||
configureSensor();
|
||||
|
||||
// Now we're ready to get readings ... move on to loop()!
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*
|
||||
Shows how to perform a basic read on visible, full spectrum or
|
||||
infrared light (returns raw 16-bit ADC values)
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void simpleRead(void)
|
||||
{
|
||||
// Simple data read example. Just read the infrared, fullspecrtrum diode
|
||||
// or 'visible' (difference between the two) channels.
|
||||
// This can take 100-600 milliseconds! Uncomment whichever of the following you want to read
|
||||
uint16_t x = tsl.getLuminosity(TSL2591_VISIBLE);
|
||||
//uint16_t x = tsl.getLuminosity(TSL2591_FULLSPECTRUM);
|
||||
//uint16_t x = tsl.getLuminosity(TSL2591_INFRARED);
|
||||
|
||||
Serial.print(F("[ ")); Serial.print(millis()); Serial.print(F(" ms ] "));
|
||||
Serial.print(F("Luminosity: "));
|
||||
Serial.println(x, DEC);
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*
|
||||
Show how to read IR and Full Spectrum at once and convert to lux
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void advancedRead(void)
|
||||
{
|
||||
// More advanced data read example. Read 32 bits with top 16 bits IR, bottom 16 bits full spectrum
|
||||
// That way you can do whatever math and comparisons you want!
|
||||
uint32_t lum = tsl.getFullLuminosity();
|
||||
uint16_t ir, full;
|
||||
ir = lum >> 16;
|
||||
full = lum & 0xFFFF;
|
||||
Serial.print(F("[ ")); Serial.print(millis()); Serial.print(F(" ms ] "));
|
||||
Serial.print(F("IR: ")); Serial.print(ir); Serial.print(F(" "));
|
||||
Serial.print(F("Full: ")); Serial.print(full); Serial.print(F(" "));
|
||||
Serial.print(F("Visible: ")); Serial.print(full - ir); Serial.print(F(" "));
|
||||
Serial.print(F("Lux: ")); Serial.println(tsl.calculateLux(full, ir));
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*
|
||||
Performs a read using the Adafruit Unified Sensor API.
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void unifiedSensorAPIRead(void)
|
||||
{
|
||||
/* Get a new sensor event */
|
||||
sensors_event_t event;
|
||||
tsl.getEvent(&event);
|
||||
|
||||
/* Display the results (light is measured in lux) */
|
||||
Serial.print(F("[ ")); Serial.print(event.timestamp); Serial.print(F(" ms ] "));
|
||||
if ((event.light == 0) |
|
||||
(event.light > 4294966000.0) |
|
||||
(event.light <-4294966000.0))
|
||||
{
|
||||
/* If event.light = 0 lux the sensor is probably saturated */
|
||||
/* and no reliable data could be generated! */
|
||||
/* if event.light is +/- 4294967040 there was a float over/underflow */
|
||||
Serial.println(F("Invalid data (adjust gain or timing)"));
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.print(event.light); Serial.println(F(" lux"));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/*
|
||||
Arduino loop function, called once 'setup' is complete (your own code
|
||||
should go here)
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void loop(void)
|
||||
{
|
||||
//simpleRead();
|
||||
advancedRead();
|
||||
// unifiedSensorAPIRead();
|
||||
|
||||
delay(500);
|
||||
}
|
||||
@@ -0,0 +1,229 @@
|
||||
/* TSL2591 Digital Light Sensor, example with (simple) interrupt support */
|
||||
/* Dynamic Range: 600M:1 */
|
||||
/* Maximum Lux: 88K */
|
||||
|
||||
/* This example shows how the interrupt system on the TLS2591
|
||||
* can be used to detect a meaningful change in light levels.
|
||||
*
|
||||
* Two thresholds can be set:
|
||||
*
|
||||
* Lower Threshold - Any light sample on CHAN0 below this value
|
||||
* will trigger an interrupt
|
||||
* Upper Threshold - Any light sample on CHAN0 above this value
|
||||
* will trigger an interrupt
|
||||
*
|
||||
* If CHAN0 (full light) crosses below the low threshold specified,
|
||||
* or above the higher threshold, an interrupt is asserted on the interrupt
|
||||
* pin. The use of the HW pin is optional, though, since the change can
|
||||
* also be detected in software by looking at the status byte via
|
||||
* tsl.getStatus().
|
||||
*
|
||||
* An optional third parameter can be used in the .registerInterrupt
|
||||
* function to indicate the number of samples that must stay outside
|
||||
* the threshold window before the interrupt fires, providing some basic
|
||||
* debouncing of light level data.
|
||||
*
|
||||
* For example, the following code will fire an interrupt on any and every
|
||||
* sample outside the window threshold (meaning a sample below 100 or above
|
||||
* 1500 on CHAN0 or FULL light):
|
||||
*
|
||||
* tsl.registerInterrupt(100, 1500, TSL2591_PERSIST_ANY);
|
||||
*
|
||||
* This code would require five consecutive changes before the interrupt
|
||||
* fires though (see tls2591Persist_t in Adafruit_TLS2591.h for possible
|
||||
* values):
|
||||
*
|
||||
* tsl.registerInterrupt(100, 1500, TSL2591_PERSIST_5);
|
||||
*/
|
||||
|
||||
#include <Wire.h>
|
||||
#include <Adafruit_Sensor.h>
|
||||
#include "Adafruit_TSL2591.h"
|
||||
|
||||
// Example for demonstrating the TSL2591 library - public domain!
|
||||
|
||||
// connect SCL to analog 5
|
||||
// connect SDA to analog 4
|
||||
// connect Vin to 3.3-5V DC
|
||||
// connect GROUND to common ground
|
||||
|
||||
// Interrupt thresholds and persistance
|
||||
#define TLS2591_INT_THRESHOLD_LOWER (100)
|
||||
#define TLS2591_INT_THRESHOLD_UPPER (1500)
|
||||
//#define TLS2591_INT_PERSIST (TSL2591_PERSIST_ANY) // Fire on any valid change
|
||||
#define TLS2591_INT_PERSIST (TSL2591_PERSIST_60) // Require at least 60 samples to fire
|
||||
|
||||
Adafruit_TSL2591 tsl = Adafruit_TSL2591(2591); // pass in a number for the sensor identifier (for your use later)
|
||||
|
||||
/**************************************************************************/
|
||||
/*
|
||||
Displays some basic information on this sensor from the unified
|
||||
sensor API sensor_t type (see Adafruit_Sensor for more information)
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void displaySensorDetails(void)
|
||||
{
|
||||
sensor_t sensor;
|
||||
tsl.getSensor(&sensor);
|
||||
Serial.println("------------------------------------");
|
||||
Serial.print ("Sensor: "); Serial.println(sensor.name);
|
||||
Serial.print ("Driver Ver: "); Serial.println(sensor.version);
|
||||
Serial.print ("Unique ID: "); Serial.println(sensor.sensor_id);
|
||||
Serial.print ("Max Value: "); Serial.print(sensor.max_value); Serial.println(" lux");
|
||||
Serial.print ("Min Value: "); Serial.print(sensor.min_value); Serial.println(" lux");
|
||||
Serial.print ("Resolution: "); Serial.print(sensor.resolution); Serial.println(" lux");
|
||||
Serial.println("------------------------------------");
|
||||
Serial.println("");
|
||||
delay(500);
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*
|
||||
Configures the gain and integration time for the TSL2591
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void configureSensor(void)
|
||||
{
|
||||
// You can change the gain on the fly, to adapt to brighter/dimmer light situations
|
||||
//tsl.setGain(TSL2591_GAIN_LOW); // 1x gain (bright light)
|
||||
tsl.setGain(TSL2591_GAIN_MED); // 25x gain
|
||||
// tsl.setGain(TSL2591_GAIN_HIGH); // 428x gain
|
||||
|
||||
// Changing the integration time gives you a longer time over which to sense light
|
||||
// longer timelines are slower, but are good in very low light situtations!
|
||||
tsl.setTiming(TSL2591_INTEGRATIONTIME_100MS); // shortest integration time (bright light)
|
||||
// tsl.setTiming(TSL2591_INTEGRATIONTIME_200MS);
|
||||
// tsl.setTiming(TSL2591_INTEGRATIONTIME_300MS);
|
||||
// tsl.setTiming(TSL2591_INTEGRATIONTIME_400MS);
|
||||
// tsl.setTiming(TSL2591_INTEGRATIONTIME_500MS);
|
||||
// tsl.setTiming(TSL2591_INTEGRATIONTIME_600MS); // longest integration time (dim light)
|
||||
|
||||
/* Display the gain and integration time for reference sake */
|
||||
Serial.println("------------------------------------");
|
||||
Serial.print ("Gain: ");
|
||||
tsl2591Gain_t gain = tsl.getGain();
|
||||
switch (gain)
|
||||
{
|
||||
case TSL2591_GAIN_LOW:
|
||||
Serial.println("1x (Low)");
|
||||
break;
|
||||
case TSL2591_GAIN_MED:
|
||||
Serial.println("25x (Medium)");
|
||||
break;
|
||||
case TSL2591_GAIN_HIGH:
|
||||
Serial.println("428x (High)");
|
||||
break;
|
||||
case TSL2591_GAIN_MAX:
|
||||
Serial.println("9876x (Max)");
|
||||
break;
|
||||
}
|
||||
Serial.print ("Timing: ");
|
||||
Serial.print((tsl.getTiming() + 1) * 100, DEC);
|
||||
Serial.println(" ms");
|
||||
Serial.println("------------------------------------");
|
||||
Serial.println("");
|
||||
|
||||
/* Setup the SW interrupt to trigger between 100 and 1500 lux */
|
||||
/* Threshold values are defined at the top of this sketch */
|
||||
tsl.clearInterrupt();
|
||||
tsl.registerInterrupt(TLS2591_INT_THRESHOLD_LOWER,
|
||||
TLS2591_INT_THRESHOLD_UPPER,
|
||||
TLS2591_INT_PERSIST);
|
||||
|
||||
/* Display the interrupt threshold window */
|
||||
Serial.print("Interrupt Threshold Window: -");
|
||||
Serial.print(TLS2591_INT_THRESHOLD_LOWER, DEC);
|
||||
Serial.print(" to +");
|
||||
Serial.println(TLS2591_INT_THRESHOLD_LOWER, DEC);
|
||||
Serial.println("");
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/*
|
||||
Program entry point for the Arduino sketch
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void setup(void)
|
||||
{
|
||||
Serial.begin(9600);
|
||||
|
||||
// Enable this line for Flora, Zero and Feather boards with no FTDI chip
|
||||
// Waits for the serial port to connect before sending data out
|
||||
// while (!Serial) { delay(1); }
|
||||
|
||||
Serial.println("Starting Adafruit TSL2591 interrupt Test!");
|
||||
|
||||
if (tsl.begin())
|
||||
{
|
||||
Serial.println("Found a TSL2591 sensor");
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.println("No sensor found ... check your wiring?");
|
||||
while (1);
|
||||
}
|
||||
|
||||
/* Display some basic information on this sensor */
|
||||
displaySensorDetails();
|
||||
|
||||
/* Configure the sensor (including the interrupt threshold) */
|
||||
configureSensor();
|
||||
|
||||
// Now we're ready to get readings ... move on to loop()!
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*
|
||||
Show how to read IR and Full Spectrum at once and convert to lux
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void advancedRead(void)
|
||||
{
|
||||
// More advanced data read example. Read 32 bits with top 16 bits IR, bottom 16 bits full spectrum
|
||||
// That way you can do whatever math and comparisons you want!
|
||||
uint32_t lum = tsl.getFullLuminosity();
|
||||
uint16_t ir, full;
|
||||
ir = lum >> 16;
|
||||
full = lum & 0xFFFF;
|
||||
Serial.print("[ "); Serial.print(millis()); Serial.print(" ms ] ");
|
||||
Serial.print("IR: "); Serial.print(ir); Serial.print(" ");
|
||||
Serial.print("Full: "); Serial.print(full); Serial.print(" ");
|
||||
Serial.print("Visible: "); Serial.print(full - ir); Serial.print(" ");
|
||||
Serial.print("Lux: "); Serial.println(tsl.calculateLux(full, ir));
|
||||
}
|
||||
|
||||
|
||||
void getStatus(void)
|
||||
{
|
||||
uint8_t x = tsl.getStatus();
|
||||
// bit 4: ALS Interrupt occured
|
||||
// bit 5: No-persist Interrupt occurence
|
||||
if (x & 0x10) {
|
||||
Serial.print("[ "); Serial.print(millis()); Serial.print(" ms ] ");
|
||||
Serial.println("ALS Interrupt occured");
|
||||
}
|
||||
if (x & 0x20) {
|
||||
Serial.print("[ "); Serial.print(millis()); Serial.print(" ms ] ");
|
||||
Serial.println("No-persist Interrupt occured");
|
||||
}
|
||||
|
||||
// Serial.print("[ "); Serial.print(millis()); Serial.print(" ms ] ");
|
||||
Serial.print("Status: ");
|
||||
Serial.println(x, BIN);
|
||||
tsl.clearInterrupt();
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/*
|
||||
Arduino loop function, called once 'setup' is complete (your own code
|
||||
should go here)
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void loop(void)
|
||||
{
|
||||
advancedRead();
|
||||
getStatus();
|
||||
delay(500);
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
name=Adafruit TSL2591 Library
|
||||
version=1.0.2
|
||||
author=Adafruit
|
||||
maintainer=Adafruit <info@adafruit.com>
|
||||
sentence=Library for the TSL2591 digital luminosity (light) sensors.
|
||||
paragraph=Library for the TSL2591 digital luminosity (light) sensors.
|
||||
category=Sensors
|
||||
url=https://github.com/adafruit/Adafruit_TSL2591_Library
|
||||
architectures=*
|
||||
Submodule lib/ArduinoJson deleted from a498abc14a
@@ -0,0 +1,5 @@
|
||||
# http://clang.llvm.org/docs/ClangFormatStyleOptions.html
|
||||
|
||||
BasedOnStyle: Google
|
||||
Standard: Cpp03
|
||||
AllowShortFunctionsOnASingleLine: Empty
|
||||
@@ -0,0 +1 @@
|
||||
*.sh text eol=lf
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
<!--
|
||||
Thanks for using ArduinoJson :-)
|
||||
|
||||
Before opening an issue, please make sure you've read these:
|
||||
https://github.com/bblanchon/ArduinoJson/wiki/FAQ
|
||||
https://github.com/bblanchon/ArduinoJson/wiki/Avoiding-pitfalls
|
||||
|
||||
Next, make sure you provide all the relevant information: platform, code snippet, and error messages.
|
||||
|
||||
Please be concise!
|
||||
-->
|
||||
@@ -0,0 +1,8 @@
|
||||
.DS_Store
|
||||
/.idea
|
||||
/build
|
||||
/bin
|
||||
/lib
|
||||
/sftp-config.json
|
||||
.tags
|
||||
.tags_sorted_by_file
|
||||
@@ -0,0 +1,118 @@
|
||||
sudo: false
|
||||
language: cpp
|
||||
matrix:
|
||||
include:
|
||||
- compiler: gcc
|
||||
addons:
|
||||
apt:
|
||||
sources: ['ubuntu-toolchain-r-test']
|
||||
packages: ['g++-4.4']
|
||||
env: SCRIPT=cmake CMAKE_CXX_COMPILER=g++-4.4
|
||||
- compiler: gcc
|
||||
addons:
|
||||
apt:
|
||||
sources: ['ubuntu-toolchain-r-test']
|
||||
packages: ['g++-4.5']
|
||||
env: SCRIPT=cmake CMAKE_CXX_COMPILER=g++-4.5
|
||||
- compiler: gcc
|
||||
addons:
|
||||
apt:
|
||||
sources: ['ubuntu-toolchain-r-test']
|
||||
packages: ['g++-4.6']
|
||||
env: SCRIPT=cmake CMAKE_CXX_COMPILER=g++-4.6
|
||||
- compiler: gcc
|
||||
addons:
|
||||
apt:
|
||||
sources: ['ubuntu-toolchain-r-test']
|
||||
packages: ['g++-4.7']
|
||||
env: SCRIPT=cmake CMAKE_CXX_COMPILER=g++-4.7
|
||||
- compiler: gcc
|
||||
addons:
|
||||
apt:
|
||||
sources: ['ubuntu-toolchain-r-test']
|
||||
packages: ['g++-4.8']
|
||||
env: SCRIPT=cmake CMAKE_CXX_COMPILER=g++-4.8
|
||||
- compiler: gcc
|
||||
addons:
|
||||
apt:
|
||||
sources: ['ubuntu-toolchain-r-test']
|
||||
packages: ['g++-4.9']
|
||||
env: SCRIPT=cmake CMAKE_CXX_COMPILER=g++-4.9
|
||||
- compiler: gcc
|
||||
addons:
|
||||
apt:
|
||||
sources: ['ubuntu-toolchain-r-test']
|
||||
packages: ['g++-5']
|
||||
env: SCRIPT=cmake CMAKE_CXX_COMPILER=g++-5
|
||||
- compiler: clang
|
||||
env: SCRIPT=cmake CMAKE_CXX_COMPILER=clang++
|
||||
- compiler: clang
|
||||
addons:
|
||||
apt:
|
||||
sources: ['ubuntu-toolchain-r-test','llvm-toolchain-precise-3.5']
|
||||
packages: ['clang-3.5']
|
||||
env: SCRIPT=cmake CMAKE_CXX_COMPILER=clang++-3.5
|
||||
- compiler: clang
|
||||
addons:
|
||||
apt:
|
||||
sources: ['ubuntu-toolchain-r-test','llvm-toolchain-precise-3.6']
|
||||
packages: ['clang-3.6']
|
||||
env: SCRIPT=cmake CMAKE_CXX_COMPILER=clang++-3.6
|
||||
- compiler: clang
|
||||
addons:
|
||||
apt:
|
||||
sources: ['ubuntu-toolchain-r-test','llvm-toolchain-precise-3.7']
|
||||
packages: ['clang-3.7']
|
||||
env: SCRIPT=cmake CMAKE_CXX_COMPILER=clang++-3.7
|
||||
- compiler: clang
|
||||
addons:
|
||||
apt:
|
||||
sources: ['ubuntu-toolchain-r-test','llvm-toolchain-precise-3.8']
|
||||
packages: ['clang-3.8']
|
||||
env: SCRIPT=cmake CMAKE_CXX_COMPILER=clang++-3.8
|
||||
- compiler: gcc
|
||||
env: SCRIPT=coverage
|
||||
- os: osx
|
||||
osx_image: beta-xcode6.1
|
||||
compiler: clang
|
||||
env: SCRIPT=cmake-osx
|
||||
- os: osx
|
||||
osx_image: beta-xcode6.2
|
||||
compiler: clang
|
||||
env: SCRIPT=cmake-osx
|
||||
- os: osx
|
||||
osx_image: beta-xcode6.3
|
||||
compiler: clang
|
||||
env: SCRIPT=cmake-osx
|
||||
- os: osx
|
||||
osx_image: xcode6.4
|
||||
compiler: clang
|
||||
env: SCRIPT=cmake-osx
|
||||
- os: osx
|
||||
osx_image: xcode7
|
||||
compiler: clang
|
||||
env: SCRIPT=cmake-osx
|
||||
- os: osx
|
||||
osx_image: xcode7.1
|
||||
compiler: clang
|
||||
env: SCRIPT=cmake-osx
|
||||
- os: osx
|
||||
osx_image: xcode7.2
|
||||
compiler: clang
|
||||
env: SCRIPT=cmake-osx
|
||||
- os: osx
|
||||
osx_image: xcode7.3
|
||||
compiler: clang
|
||||
env: SCRIPT=cmake-osx
|
||||
- env: SCRIPT=arduino VERSION=1.5.8 BOARD=arduino:avr:uno
|
||||
- env: SCRIPT=arduino VERSION=1.6.7 BOARD=arduino:avr:uno
|
||||
- env: SCRIPT=arduino VERSION=1.6.8 BOARD=arduino:avr:uno
|
||||
- env: SCRIPT=arduino VERSION=1.6.9 BOARD=arduino:avr:uno
|
||||
- env: SCRIPT=platformio BOARD=uno
|
||||
- env: SCRIPT=platformio BOARD=due
|
||||
- env: SCRIPT=platformio BOARD=esp01
|
||||
- env: SCRIPT=platformio BOARD=teensy31
|
||||
cache:
|
||||
directories:
|
||||
- "~/.platformio"
|
||||
script: scripts/travis/$SCRIPT.sh
|
||||
@@ -0,0 +1,8 @@
|
||||
// Copyright Benoit Blanchon 2014-2016
|
||||
// MIT License
|
||||
//
|
||||
// Arduino JSON library
|
||||
// https://github.com/bblanchon/ArduinoJson
|
||||
// If you like this project, please add a star!
|
||||
|
||||
#include "include/ArduinoJson.h"
|
||||
@@ -0,0 +1,303 @@
|
||||
ArduinoJson: change log
|
||||
=======================
|
||||
|
||||
v5.6.4
|
||||
------
|
||||
|
||||
* Fixed error in float serialization (issue #324)
|
||||
|
||||
v5.6.3
|
||||
------
|
||||
|
||||
* Improved speed of float serialization (about twice faster)
|
||||
* Added `as<JsonArray>()` as a synonym for `as<JsonArray&>()`... (issue #291)
|
||||
* Fixed `call of overloaded isinf(double&) is ambiguous` (issue #284)
|
||||
|
||||
v5.6.2
|
||||
------
|
||||
|
||||
* Fixed build when another lib does `#undef isnan` (issue #284)
|
||||
|
||||
v5.6.1
|
||||
------
|
||||
|
||||
* Added missing `#pragma once` (issue #310)
|
||||
|
||||
v5.6.0
|
||||
------
|
||||
|
||||
* ArduinoJson is now a header-only library (issue #199)
|
||||
|
||||
v5.5.1
|
||||
------
|
||||
|
||||
* Fixed compilation error with Intel Galileo (issue #299)
|
||||
|
||||
v5.5.0
|
||||
------
|
||||
|
||||
* Added `JsonVariant::success()` (issue #279)
|
||||
* Renamed `JsonVariant::invalid<T>()` to `JsonVariant::defaultValue<T>()`
|
||||
|
||||
v5.4.0
|
||||
------
|
||||
|
||||
* Changed `::String` to `ArduinoJson::String` (issue #275)
|
||||
* Changed `::Print` to `ArduinoJson::Print` too
|
||||
|
||||
v5.3.0
|
||||
------
|
||||
|
||||
* Added custom implementation of `ftoa` (issues #266, #267, #269 and #270)
|
||||
* Added `JsonVariant JsonBuffer::parse()` (issue #265)
|
||||
* Fixed `unsigned long` printed as `signed long` (issue #170)
|
||||
|
||||
v5.2.0
|
||||
------
|
||||
|
||||
* Added `JsonVariant::as<char*>()` as a synonym for `JsonVariant::as<const char*>()` (issue #257)
|
||||
* Added example `JsonHttpClient` (issue #256)
|
||||
* Added `JsonArray::copyTo()` and `JsonArray::copyFrom()` (issue #254)
|
||||
* Added `RawJson()` to insert pregenerated JSON portions (issue #259)
|
||||
|
||||
v5.1.1
|
||||
------
|
||||
|
||||
* Removed `String` duplication when one replaces a value in a `JsonObject` (PR #232 by @ulion)
|
||||
|
||||
v5.1.0
|
||||
------
|
||||
|
||||
* Added support of `long long` (issue #171)
|
||||
* Moved all build settings to `ArduinoJson/Configuration.hpp`
|
||||
|
||||
**BREAKING CHANGE**:
|
||||
If you defined `ARDUINOJSON_ENABLE_STD_STREAM`, you now need to define it to `1`.
|
||||
|
||||
v5.0.8
|
||||
------
|
||||
|
||||
* Made the library compatible with [PlatformIO](http://platformio.org/) (issue #181)
|
||||
* Fixed `JsonVariant::is<bool>()` that was incorrectly returning false (issue #214)
|
||||
|
||||
v5.0.7
|
||||
------
|
||||
|
||||
* Made library easier to use from a CMake project: simply `add_subdirectory(ArduinoJson/src)`
|
||||
* Changed `String` to be a `typedef` of `std::string` (issues #142 and #161)
|
||||
|
||||
**BREAKING CHANGES**:
|
||||
- `JsonVariant(true).as<String>()` now returns `"true"` instead of `"1"`
|
||||
- `JsonVariant(false).as<String>()` now returns `"false"` instead of `"0"`
|
||||
|
||||
v5.0.6
|
||||
------
|
||||
|
||||
* Added parameter to `DynamicJsonBuffer` constructor to set initial size (issue #152)
|
||||
* Fixed warning about library category in Arduino 1.6.6 (issue #147)
|
||||
* Examples: Added a loop to wait for serial port to be ready (issue #156)
|
||||
|
||||
v5.0.5
|
||||
------
|
||||
|
||||
* Added overload `JsonObjectSuscript::set(value, decimals)` (issue #143)
|
||||
* Use `float` instead of `double` to reduce the size of `JsonVariant` (issue #134)
|
||||
|
||||
v5.0.4
|
||||
------
|
||||
|
||||
* Fixed ambiguous overload with `JsonArraySubscript` and `JsonObjectSubscript` (issue #122)
|
||||
|
||||
v5.0.3
|
||||
------
|
||||
|
||||
* Fixed `printTo(String)` which wrote numbers instead of strings (issue #120)
|
||||
* Fixed return type of `JsonArray::is<T>()` and some others (issue #121)
|
||||
|
||||
v5.0.2
|
||||
------
|
||||
|
||||
* Fixed segmentation fault in `parseObject(String)` and `parseArray(String)`, when the
|
||||
`StaticJsonBuffer` is too small to hold a copy of the string
|
||||
* Fixed Clang warning "register specifier is deprecated" (issue #102)
|
||||
* Fixed GCC warning "declaration shadows a member" (issue #103)
|
||||
* Fixed memory alignment, which made ESP8266 crash (issue #104)
|
||||
* Fixed compilation on Visual Studio 2010 and 2012 (issue #107)
|
||||
|
||||
v5.0.1
|
||||
------
|
||||
|
||||
* Fixed compilation with Arduino 1.0.6 (issue #99)
|
||||
|
||||
v5.0.0
|
||||
------
|
||||
|
||||
* Added support of `String` class (issues #55, #56, #70, #77)
|
||||
* Added `JsonBuffer::strdup()` to make a copy of a string (issues #10, #57)
|
||||
* Implicitly call `strdup()` for `String` but not for `char*` (issues #84, #87)
|
||||
* Added support of non standard JSON input (issue #44)
|
||||
* Added support of comments in JSON input (issue #88)
|
||||
* Added implicit cast between numerical types (issues #64, #69, #93)
|
||||
* Added ability to read number values as string (issue #90)
|
||||
* Redesigned `JsonVariant` to leverage converting constructors instead of assignment operators (issue #66)
|
||||
* Switched to new the library layout (requires Arduino 1.0.6 or above)
|
||||
|
||||
**BREAKING CHANGES**:
|
||||
- `JsonObject::add()` was renamed to `set()`
|
||||
- `JsonArray::at()` and `JsonObject::at()` were renamed to `get()`
|
||||
- Number of digits of floating point value are now set with `double_with_n_digits()`
|
||||
|
||||
**Personal note about the `String` class**:
|
||||
Support of the `String` class has been added to the library because many people use it in their programs.
|
||||
However, you should not see this as an invitation to use the `String` class.
|
||||
The `String` class is **bad** because it uses dynamic memory allocation.
|
||||
Compared to static allocation, it compiles to a bigger, slower program, and is less predictable.
|
||||
You certainly don't want that in an embedded environment!
|
||||
|
||||
v4.6
|
||||
----
|
||||
|
||||
* Fixed segmentation fault in `DynamicJsonBuffer` when memory allocation fails (issue #92)
|
||||
|
||||
v4.5
|
||||
----
|
||||
|
||||
* Fixed buffer overflow when input contains a backslash followed by a terminator (issue #81)
|
||||
|
||||
**Upgrading is recommended** since previous versions contain a potential security risk.
|
||||
|
||||
Special thanks to [Giancarlo Canales Barreto](https://github.com/gcanalesb) for finding this nasty bug.
|
||||
|
||||
v4.4
|
||||
----
|
||||
|
||||
* Added `JsonArray::measureLength()` and `JsonObject::measureLength()` (issue #75)
|
||||
|
||||
v4.3
|
||||
----
|
||||
|
||||
* Added `JsonArray::removeAt()` to remove an element of an array (issue #58)
|
||||
* Fixed stack-overflow in `DynamicJsonBuffer` when parsing huge JSON files (issue #65)
|
||||
* Fixed wrong return value of `parseArray()` and `parseObject()` when allocation fails (issue #68)
|
||||
|
||||
v4.2
|
||||
----
|
||||
|
||||
* Switched back to old library layout (issues #39, #43 and #45)
|
||||
* Removed global new operator overload (issue #40, #45 and #46)
|
||||
* Added an example with EthernetServer
|
||||
|
||||
v4.1
|
||||
----
|
||||
|
||||
* Added DynamicJsonBuffer (issue #19)
|
||||
|
||||
v4.0
|
||||
----
|
||||
|
||||
* Unified parser and generator API (issue #23)
|
||||
* Updated library layout, now requires Arduino 1.0.6 or newer
|
||||
|
||||
**BREAKING CHANGE**: API changed significantly, see [Migrating code to the new API](https://github.com/bblanchon/ArduinoJson/wiki/Migrating-code-to-the-new-API).
|
||||
|
||||
|
||||
v3.4
|
||||
----
|
||||
|
||||
* Fixed escaped char parsing (issue #16)
|
||||
|
||||
|
||||
v3.3
|
||||
----
|
||||
|
||||
* Added indented output for the JSON generator (issue #11), see example bellow.
|
||||
* Added `IndentedPrint`, a decorator for `Print` to allow indented output
|
||||
|
||||
Example:
|
||||
|
||||
JsonOject<2> json;
|
||||
json["key"] = "value";
|
||||
json.prettyPrintTo(Serial);
|
||||
|
||||
v3.2
|
||||
----
|
||||
|
||||
* Fixed a bug when adding nested object in `JsonArray` (bug introduced in v3.1).
|
||||
|
||||
v3.1
|
||||
----
|
||||
|
||||
* Calling `Generator::JsonObject::add()` twice with the same `key` now replaces the `value`
|
||||
* Added `Generator::JsonObject::operator[]`, see bellow the new API
|
||||
* Added `Generator::JsonObject::remove()` (issue #9)
|
||||
|
||||
Old generator API:
|
||||
|
||||
JsonObject<3> root;
|
||||
root.add("sensor", "gps");
|
||||
root.add("time", 1351824120);
|
||||
root.add("data", array);
|
||||
|
||||
New generator API:
|
||||
|
||||
JsonObject<3> root;
|
||||
root["sensor"] = "gps";
|
||||
root["time"] = 1351824120;
|
||||
root["data"] = array;
|
||||
|
||||
v3.0
|
||||
----
|
||||
|
||||
* New parser API, see bellow
|
||||
* Renamed `JsonHashTable` into `JsonObject`
|
||||
* Added iterators for `JsonArray` and `JsonObject` (issue #4)
|
||||
|
||||
Old parser API:
|
||||
|
||||
JsonHashTable root = parser.parseHashTable(json);
|
||||
|
||||
char* sensor = root.getString("sensor");
|
||||
long time = root.getLong("time");
|
||||
double latitude = root.getArray("data").getDouble(0);
|
||||
double longitude = root.getArray("data").getDouble(1);
|
||||
|
||||
New parser API:
|
||||
|
||||
JsonObject root = parser.parse(json);
|
||||
|
||||
char* sensor = root["sensor"];
|
||||
long time = root["time"];
|
||||
double latitude = root["data"][0];
|
||||
double longitude = root["data"][1];
|
||||
|
||||
v2.1
|
||||
----
|
||||
|
||||
* Fixed case `#include "jsmn.cpp"` which caused an error in Linux (issue #6)
|
||||
* Fixed a buffer overrun in JSON Parser (issue #5)
|
||||
|
||||
v2.0
|
||||
----
|
||||
|
||||
* Added JSON encoding (issue #2)
|
||||
* Renamed the library `ArduinoJsonParser` becomes `ArduinoJson`
|
||||
|
||||
**Breaking change**: you need to add the following line at the top of your program.
|
||||
|
||||
using namespace ArduinoJson::Parser;
|
||||
|
||||
v1.2
|
||||
----
|
||||
|
||||
* Fixed error in JSON parser example (issue #1)
|
||||
|
||||
v1.1
|
||||
----
|
||||
|
||||
* Example: changed `char* json` into `char[] json` so that the bytes are not write protected
|
||||
* Fixed parsing bug when the JSON contains multi-dimensional arrays
|
||||
|
||||
v1.0
|
||||
----
|
||||
|
||||
Initial release
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user