Compare commits

...
118 Commits
Author SHA1 Message Date
Edwin Eefting 32dc1e69e5 automaticly updated release notes for v2.0.0-dev8 2017-04-24 13:21:32 +02:00
Edwin Eefting 9e53288ca4 fixed #239 due to improper PSTR. cleaned up string handling 2017-04-24 01:13:47 +02:00
Edwin Eefting 6ca0e5416c properly escape html in C011 generic http advanced. 2017-04-24 00:54:48 +02:00
Edwin Eefting 686d862024 escape html in the rules page, so that strings like &param do not cause problems. fixes issue #231 2017-04-24 00:36:19 +02:00
Edwin Eefting 60f1c79e2a dont use arduino OTA in the dev env 2017-04-24 00:33:04 +02:00
Edwin Eefting 25240591a3 Revert "Plugin_008-RFID extended with wiegand 34-bits and key-pad (4-bits per key) support". Now uses too much IRAM.
This reverts commit 7a197f516c.
2017-04-24 00:12:26 +02:00
Edwin Eefting 75b28225a6 select env 2017-04-23 23:56:32 +02:00
JKandDatuX 4e3fa4243a added union to TaskDevicePin1..3
use classic usage with single varables:
        if (Settings.TaskDevicePin1[event->TaskIndex] >= 0)
          pinMode(Settings.TaskDevicePin1[event->TaskIndex], OUTPUT);
        if (Settings.TaskDevicePin2[event->TaskIndex] >= 0)
          pinMode(Settings.TaskDevicePin2[event->TaskIndex], OUTPUT);
        if (Settings.TaskDevicePin3[event->TaskIndex] >= 0)
          pinMode(Settings.TaskDevicePin3[event->TaskIndex], OUTPUT);

or use in a more compact way as array:
        for (byte i=0; i<3; i++)
          if (Settings.TaskDevicePin[i][event->TaskIndex] >= 0)
            pinMode(Settings.TaskDevicePin[i][event->TaskIndex], OUTPUT);

or use in combination simultaneously (memory for single vars and array overlaps)
2017-04-23 21:21:17 +02:00
JKandDatuX 56a313f941 Using 3 I/O-pins consequently 2017-04-23 21:20:25 +02:00
imthemichiandDatuX 7a197f516c Plugin_008-RFID extended with wiegand 34-bits and key-pad (4-bits per key) support 2017-04-23 21:18:06 +02:00
tedendaandDatuX 48497a0786 Update _P049_MHZ19.ino 2017-04-23 21:16:20 +02:00
DatuXandGitHub 9badfe8fed Update README.md 2017-04-23 21:11:08 +02:00
Edwin Eefting 8f67ebe16f oops moved lib/Adafruit_TCS34725 to wrong place 2017-04-23 21:01:14 +02:00
Edwin Eefting b52c5a884f now no longer a submodule. lib/IRremoteESP8266 upstream version v1.0.2 2017-04-23 20:50:37 +02:00
Edwin Eefting 24e4f8c1fd now no longer a submodule. lib/ArduinoJson upstream version v5.6.4 2017-04-23 20:49:39 +02:00
Edwin Eefting 84c50f4863 now no longer a submodule, lib/Adafruit_TCS34725 upstream version 1.0.1-13-g12be4c6 2017-04-23 20:48:21 +02:00
Edwin Eefting 4d7e602155 now no longer a submodule. lib/Adafruit_NeoPixel, upstream version v1.0.6 2017-04-23 20:46:02 +02:00
Edwin Eefting 8d47f10519 now no longer a submodule lib/AS_BH1750, upstream version 092f0b1c5fa74eb2abe3d1b2925190d066e9506d 2017-04-23 20:44:26 +02:00
Edwin Eefting 3c616348f7 converted submodule to normal directory. lib/Adafruit_Motor_Shield_V2 upstream commit ee4c4d334f498d54cdf80c9cc6f5bdec2533f8bf 2017-04-23 20:39:26 +02:00
Edwin Eefting abe5ccec5d improved statusled handling in background tasks 2017-04-23 19:23:21 +02:00
Edwin Eefting 916de7909f fixed stability issues in c009. probably caused by illegal PSTR usage, but i completly cleaned up all string handling 2017-04-23 19:03:52 +02:00
Edwin Eefting ff720188f7 starting working on stability reporting function 2017-04-23 18:13:40 +02:00
Edwin Eefting d1180e4e47 replaced all readstringuntil() with safeReadStringUntil() 2017-04-16 18:57:28 +02:00
Dirk MoellerandDatuX 4e52fdeaab fix typo 2017-04-15 18:53:11 +02:00
Dirk MoellerandDatuX 67e2cff541 new function, Plugin_004_DS_setResolution und Plugin_004_DS_getResolution 2017-04-15 18:53:11 +02:00
beicandDatuX 1d9286419a Added detection for the SI1145 to I2C scenner
Added detection for the UV Index Sensor SI1145 to I2C scenner
2017-04-15 18:51:59 +02:00
beicandDatuX b6c1510365 Naming correction by Datasheet
According to manufacturer datasheet, it's nothing to do with "Ambient", they call it "Digital Infrared Thermometer"
https://www.melexis.com/-/media/files/documents/datasheets/mlx90614-datasheet-melexis.pdf
2017-04-13 00:39:31 +02:00
Edwin Eefting 323255143e added issue template to get cleaner bug reports 2017-04-13 00:03:29 +02:00
Edwin Eefting d0eedce248 fixed lots of common issues that might cause crashes in c011. also see https://github.com/letscontrolit/ESPEasy/issues/117#issuecomment-293713370 2017-04-12 23:35:01 +02:00
beicandDatuX 76fca12d1a Little naming correction
Little naming correction added "&" instead of "+" and changed letter "a" to be Uppercase.
2017-04-12 21:46:16 +02:00
beicandDatuX 70f7888905 Environment naming will better fit in...
"Environment" naming will better fit in instead of the long "Temperature & Pressure", and we will get a few char space more to use and it will fit nicely into the drop-down combo box too, otherwise is way to long!
2017-04-12 21:45:53 +02:00
beicandDatuX 1f65f16d09 Environment naming will better fit in...
"Environment" naming will better fit in instead of the long "Temperature & Humidity", and we will get a few char space more to use and it will fit nicely into the drop-down combo box too, otherwise is way to long!
2017-04-12 21:45:42 +02:00
beicandDatuX 541bc4e868 Environment naming will better fit in...
"Environment" naming will better fit in instead of the long "Temperature & Humidity", and we will get a few char space more to use and it will fit nicely into the drop-down combo box too, otherwise is way to long!
2017-04-12 21:45:30 +02:00
beicandDatuX bd3310ab0c Environment naming will better fit in...
"Environment" naming will better fit in instead of the long "Temperature & Pressure", and we will get a few char space more to use and it will fit nicely into the drop-down combo box too, otherwise is way to long!
2017-04-12 21:45:19 +02:00
beicandDatuX 8054930597 Environment naming will better fit in...
"Environment" naming will better fit in instead of the long "Temperature & Pressure", and we will get a few char space more to use and it will fit nicely into the drop-down combo box too, otherwise is way to long!
2017-04-12 21:45:08 +02:00
beicandDatuX b51d65c8cd Environment naming will better fit in... + naming
"Environment" naming will better fit in instead of the long "Temperature & Humidity", and we will get a few char space more to use and it will fit nicely into the drop-down combo box too, otherwise is way to long, plus added sensor naming like DHT11/12/22!
2017-04-12 21:44:55 +02:00
beicandDatuX e49c32ea01 Environment naming will better fit in + HTU21D
"Environment" naming will better fit in instead of the long "Temperature & Humidity", and we will get a few char space more to use and it will fit nicely into the drop-down combo box too, otherwise is way to long!
2017-04-12 21:44:41 +02:00
beicandDatuX 73a0136556 Environment naming will better fit in...
"Environment" naming will better fit in instead of the long "Temperature & Humidity & Pressure", and we will get a few char space more to use and it will fit nicely into the drop-down combo box too, otherwise is way to long!
2017-04-12 21:44:23 +02:00
krikkandDatuX 27ee456413 removed all unnecessary Strings due to new addLog with FlashStringHelper (#223) 2017-04-12 21:39:48 +02:00
Edwin Eefting 6f1a0c8dc7 fixed crashes caused by large MQTT packets 2017-04-12 00:43:04 +02:00
beicandDatuX 93710e2268 Added detection for the HTU21D to I2C scenner
Added HTU21D to I2C scenner as is on the 0x40 addresse
2017-04-10 22:44:36 +02:00
Edwin Eefting 14fb8e9738 avoid unneccesary string conversions and static buffers in c001 2017-04-10 22:42:17 +02:00
Edwin Eefting 24a2b62840 removed unneccesay delays from c001 2017-04-10 22:20:05 +02:00
Edwin Eefting d35889f9ae avoid static buffers in c001. addLog now also supports F(), so we dont need all those temporary variable definitions 2017-04-10 21:58:25 +02:00
Edwin Eefting 29fd1312cd fixed crash in C001 (when opening /controllers) 2017-04-10 20:13:36 +02:00
JKandDatuX 9a13b3cbdd More informative and intuitive status LED 2017-04-10 16:26:35 +02:00
DatuXandGitHub 5b90077df0 Update CONTRIBUTING.md 2017-04-09 16:05:39 +02:00
DatuXandGitHub fdb755a9c4 Update CONTRIBUTING.md 2017-04-09 15:51:01 +02:00
Edwin Eefting 39edb76ee0 contributing guidelines 2017-04-09 15:36:58 +02:00
Edwin Eefting 1e70ce91e7 Merge branch 'mega' of github.com:letscontrolit/ESPEasy into mega 2017-04-09 14:35:27 +02:00
Edwin Eefting bafee423b2 recuded number of pulsecounters from 8 to 4 to save IRAM 2017-04-09 14:34:38 +02:00
DatuXandGitHub d2a38c5f34 Update README.md 2017-04-09 13:52:52 +02:00
DatuXandGitHub 73d3be972d Update README.md 2017-04-09 13:52:21 +02:00
krikkandDatuX 01be80ca8c Bh1750: enhance to check for valid value (#208) 2017-04-09 13:43:03 +02:00
Emmanuel TattoandDatuX 6d9c7de7c0 getBearing should be outside the FEATURE_ARDUINO_OTA condition (#207) 2017-04-09 13:41:03 +02:00
krikkandDatuX 64c6970696 Httpadvanced crashfix + patch method (#204) 2017-04-09 13:36:35 +02:00
krikkandDatuX 7fa3150921 _P047_i2c-soil-moisture-sensor: allow change of sensor address (#201) 2017-04-09 13:35:52 +02:00
krikkandDatuX 268f99c5e3 Support for Tcs34725 RGB Color Sensor (#195) 2017-04-09 13:35:19 +02:00
beicandDatuX 988d0bbcb2 Menu correction, added BMP180 (#199)
Temperature & Pressure - BMP085/BMP180
2017-04-09 13:33:56 +02:00
DatuXandGitHub 2268a2115b Update README.md 2017-04-04 22:41:00 +02:00
krikkandDatuX f624c5737a Motorshield plugin string fixes (#200) (reduced memory usage) 2017-04-04 22:08:52 +02:00
Edwin Eefting 9c66f83fab cleaned up servo stuff 2017-04-04 00:30:41 +02:00
Edwin Eefting 65b78ee753 reduce memory usage N001 N002 2017-04-04 00:07:46 +02:00
Edwin Eefting 6097708952 reduced ram usage C003 ... C011 2017-04-03 23:52:10 +02:00
Edwin Eefting 7941bc6158 reduced mem C001 C002 2017-04-03 23:32:26 +02:00
Edwin Eefting d15139501c reduced memory usage _C001 2017-04-03 23:11:22 +02:00
Edwin Eefting d9674925d0 initial memory analyser and results 2017-04-03 20:34:34 +02:00
Edwin Eefting 027313872c make the IRTX plugin work without the IR plugin 2017-04-02 19:01:58 +02:00
Edwin Eefting 57c351a4d3 moved arduinojson and liquidcrytal includes to correct plugins. reanbled IR-modules to solve memory issues 2017-04-02 18:07:37 +02:00
Edwin Eefting 07b6642823 initial version of memory analyser 2017-04-02 17:51:13 +02:00
Edwin Eefting e44464f532 temporary disabled IR plugins, because of iram1_0_seg issues 2017-04-02 01:38:27 +02:00
David ConranandDatuX 43c8317c99 update sendSony() call to use repeats.
The SONY IR protocol calls for the remote code to be sent >= 3 times for it to work. Thus you should probably call this with a repeat=2.
Note however, don't merge this until you've updated easyesp to use the correct IRremoteESP8266 library (#188 #189) which implements the repeat feature.
2017-04-01 22:07:36 +02:00
David ConranandDatuX 16aceaac73 Update IRremoteESP8266 library url in .gitmodules
Replace the url to the old un-maintained fork of the IRremoteESP8266 library to its upstream canonical (and maintained) library.

This might explain why we've had some odd non-reproducible reports of our (IRremoteESP8266) library not working as expected.
2017-04-01 22:07:19 +02:00
krikkandDatuX cbf7ba59d4 added i2c address selection to ino219 plugin (#192) 2017-04-01 22:05:43 +02:00
jbaumannandDatuX 1464c00fb0 Addition of ESP8285 targets (#187)
* Addition of ESP8285 targets

In addition to the normal ESP8266 targets there are now targets for
normal_8285, test_8285 and dev_8285. Each of these targets provides an
additional build flag with -DESP8285

* Added ESP8285 build targets with correct flash size

Correction of the build modification done before, now with correct flash
siez of 1M

* Provide different GPIO dropdown lists for 8266 and 8285

The ESP8266 and ESP8285 expose different sets of GPIOs. This new version
of the web server provides different dropdown lists depending on the
build flag -DESP8285 (which is set in the new targets for building
ESP8285 fw).
2017-04-01 22:04:40 +02:00
krikkandDatuX 3f489fd32b cppcheck style fixes... (#186) 2017-04-01 22:02:04 +02:00
krikkandDatuX 6534d89cd7 rewrote bh1750 sensor based on better library... (#182) 2017-03-31 18:40:31 +02:00
krikkandDatuX 5d56d00fa2 Pulsecounter minor fix (#184) 2017-03-27 19:41:43 +02:00
krikkandDatuX 2cabe08eb8 I2csoilmoisture fixed bug with sleep mode (#178)
* added missing sensor types: LONG & WIND

* did a bit of code cleanup, like you suggested... removed a lot of code, and works as before! :)

* fixed typo

* added date to the time displays... changed password fields to type=password

* motorshield library should be a submodule, enhanced the motorshield plugin, with better command parsing, but still work to do..

* fully implemented steppers and DCMotors

* add replacement variable for systime, vcc, ip, sysload, uptime

* fixed bug with sleep mode

* 20 ms delay to wakeup should be enough
2017-03-23 17:24:37 +01:00
Jochen KrapfandDatuX 1e5a43ae6d Added function isDeepSleepEnabled() (#177)
Added function isDeepSleepEnabled()


Deep sleep time is limited to 32 bit (~1.2h)
2017-03-23 17:22:44 +01:00
krikkandDatuX fbd7fa83b6 Tsl2561 rewrite (#174)
complete rewrite, now has better support for lower lux values, also better handling of higher values, add ability to change gain and sleep mode, based on sparkfun library
2017-03-23 17:19:06 +01:00
krikkandDatuX 6de51645b3 re-did old pull requests (#172)
re-did the following pull requests to mega repository:
#89 Fix url link to setup after the first WiFi setup
#93 Allow use it with rain gauge

setting hostname on arduinoOTA
warning to not change filename on setting save/load (had the issue myself)
2017-03-23 17:12:41 +01:00
adb76andDatuX cfc3af3510 BME280: Ensure sensor is in sleep mode to set the config, fix small typo
Based on the specification it is necessary that the sensor is in sleep
mode when the configuration registers are changed. So the call with the
config registers should also be the last call since we are leaving the
sleep mode and are changing to the forced mode.
2017-03-19 14:24:19 +01:00
krikkandDatuX a4f8e0178f corrected name for TSL2561, add option to use different sensor adress (#170) 2017-03-18 17:15:30 +01:00
krikkandDatuX b3edbdf225 http advanced: add replacement variable for systime, vcc, ip, sysload, uptime (#167)
* added missing sensor types: LONG & WIND

* did a bit of code cleanup, like you suggested... removed a lot of code, and works as before! :)

* fixed typo

* added date to the time displays... changed password fields to type=password

* motorshield library should be a submodule, enhanced the motorshield plugin, with better command parsing, but still work to do..

* fully implemented steppers and DCMotors

* add replacement variable for systime, vcc, ip, sysload, uptime
2017-03-18 17:07:07 +01:00
adb76andDatuX 1d1d69a13f Set BME280 to recommended values for climate / weather sensor
According to Bosch Sensortec the suggested settings for climate /
weather monitoring are:

Sensor mode:  forced mode, 1 sample / minute
Oversampling settings: pressure ×1, temperature ×1, humidity ×1
IIR filter settings: filter off

To measure new values in the forced mode a write to the
"BME280_REGISTER_CONTROL" is necessary, which I added to the temperature
reading.
2017-03-18 16:15:15 +01:00
DatuXandGitHub dca6871a4e Merge pull request #168 from infernix/mega-mhz19update
Extend MH-Z19 sensor support
2017-03-18 04:39:51 +01:00
Gerben Meijer 9d3b119448 Extend MH-Z19 sensor support
* Added commands to set the measurement range to 1000/2000/3000/5000ppm.
* Added command to do sensor zero calibration (actually 400ppm
  calibration)
* Added command to en/disable Automatic Background Calibration
* Added command to reset sensor
* Ignore (but log) any sensor boot time values
* Ignore (but log) any sensor values where stability isn't optimal
* Report undocumented U value (minimum CO2 per time period for ABC?) to log and MQTT
* Much more verbose logginga
* Shifts serial read buffer upon CRC errors (usually happens when sensor
  restarts during operation, or timing is off at device boot)
2017-03-18 01:17:08 +01:00
krikkandDatuX 45ad68cd61 motorshield library should be a submodule, enhanced the motorshield plugin... (#162)
* added missing sensor types: LONG & WIND

* did a bit of code cleanup, like you suggested... removed a lot of code, and works as before! :)

* fixed typo

* added date to the time displays... changed password fields to type=password

* motorshield library should be a submodule, enhanced the motorshield plugin, with better command parsing, but still work to do..

* fully implemented steppers and DCMotors
2017-03-16 21:58:03 +01:00
dev0andDatuX 9402fb73a9 _C009.ino: RFC conformity and removed obsolet code (#163)
I have changed http request from GET to POST as already suggested by @mvdbro to fulfill RFC compliance. Furthermore the obsolte commands from url were removed and I added build information to JSON data.
2017-03-15 11:38:59 +01:00
Edwin Eefting 853ddb0d38 automaticly updated release notes for v2.0.0-dev7 2017-03-15 01:42:15 +01:00
Edwin Eefting fbdc78e46d fix in release-script (forgot to commit it last time) 2017-03-15 01:40:47 +01:00
Edwin Eefting c0da3a1831 automaticly updated release notes for v2.0.0-dev7 2017-03-15 01:32:29 +01:00
Edwin Eefting d7f32b1cb1 fixed Arduino IDE compilebug and added help to enable plugin sets in Arduino IDE 2017-03-15 01:26:18 +01:00
Edwin Eefting e9aec70ba9 added i2scanner via serial. removed spaces from Adafruit Motor Shield library so it works with arduino IDE 2017-03-15 01:20:40 +01:00
krikkandDatuX 750658be10 show date in webinterface, and changed password fields to type=password (#161) 2017-03-14 17:52:58 +01:00
Edwin Eefting 510bd22533 timers can be disabled by setting them to 0 now. cleaned up event output logging. added timer out-of-bounds checks 2017-03-14 01:12:53 +01:00
krikkandDatuX 85de1ba4ac code cleanup for HTTP advanced controller 2017-03-13 22:55:56 +01:00
Edwin Eefting 3bdabc8974 automaticly updated release notes for v2.0.0-dev6 2017-03-13 11:54:41 +01:00
Edwin Eefting bb45183df3 automaticly updated release notes for v2.0.0-dev6 2017-03-13 11:52:02 +01:00
Jochen KrapfandDatuX 0a1f9d5e47 cancel deep sleep loop by pulling the pin GPIO16(D0) to GND (#158)
recommended wiring: 3-pin-header with 1=RST, 2=D0, 3=GND
short 1-2 for normal deep sleep / wakeup loop
short 2-3 to cancel sleep loop for modifying settings
2017-03-13 11:51:28 +01:00
Edwin Eefting 1a92890e4e added plugin to testing. remove useless value variable 2017-03-13 01:03:03 +01:00
GeraldandDatuX bfc0dbc131 added missing sensor type, to fix problem with i2c soilmoisture sensor... (#157) 2017-03-13 00:46:26 +01:00
GeraldandDatuX 05bde80ffd HTTP Advanced, enhanced, so that only one http request is sent for one sensor (#156) 2017-03-13 00:44:16 +01:00
Edwin Eefting b3aa5f4bc6 major change: changed the timing of the first sensor read after initial boot. cleaned up and improved deep sleeping code. 2017-03-12 20:04:52 +01:00
Edwin Eefting 80ae38e196 cold boot startup delay 2017-03-12 19:07:15 +01:00
Edwin Eefting 9535482dbf enabled Arduino OTA for dev-firmware only, to ease developing. minor output-tweaks 2017-03-12 17:17:55 +01:00
Edwin Eefting e2862cef05 Implemented speaker and tone functions from https://www.letscontrolit.com/forum/viewtopic.php?f=4&t=343&hilit=speaker&start=10 2017-03-12 15:45:52 +01:00
Edwin Eefting 8b97538382 use sizeof instead of magic numbers 2017-03-12 14:19:20 +01:00
Edwin Eefting cc4addec9f enable status light as soon as wifi is connected 2017-03-12 14:18:50 +01:00
dzikusandDatuX 0461f5bd96 Added BMP280_CONFIG_SETTING to reduce the temperature of sensor and use oversampling filter (#155)
Added BMP280_CONFIG_SETTING to reduce the temperature of sensor and use oversampling filter
2017-03-12 13:23:37 +01:00
Edwin Eefting 09e95cd1ff do hardwareinit() earlier so that outputs are set immeadiatly instead of waiting for connect. fixes https://github.com/letscontrolit/ESPEasy/issues/114 2017-03-12 02:28:09 +01:00
Edwin Eefting 8a02f2cbd2 remove artificial sensor startup delays. (now all sensors are send immediatly after booting and wifi-connecting) 2017-03-12 02:21:40 +01:00
Edwin Eefting 63f1bb9a9e added NDIR CO2 Sensor MH-Z19 plugin to TESTING plugin set 2017-03-12 02:12:52 +01:00
Edwin Eefting ea1c033402 bug fix: plugin_id should not start with a 0. (compiler interprets this as octal!) 2017-03-12 02:07:28 +01:00
Edwin Eefting ce1f35e5ff Revert "bug fix: plugin_id should not start with a 0. (compiler interprets this as octal!)"
This reverts commit b5131b3fac.
2017-03-12 02:00:00 +01:00
Edwin Eefting b5131b3fac bug fix: plugin_id should not start with a 0. (compiler interprets this as octal!) 2017-03-11 23:58:16 +01:00
Edwin Eefting 66852bdc8d created script to assist in creating releases 2017-03-11 18:35:50 +01:00
474 changed files with 168886 additions and 1502 deletions
+29
View File
@@ -0,0 +1,29 @@
# 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.
* Try to create different pull requests for different features/fixes.
* Dont combine a lot of different stuff in one huge pull request.
* Incomplete or unstable plugins should have a PLUGIN_BUILD_DEV ifdef around them.
* New plugins that seem to be working correctly should have a PLUGIN_BUILD_TESTING around until they are tested enough.
* Also see our general guidelines at: https://www.letscontrolit.com/wiki/index.php/ESPEasyDevelopmentGuidelines
+14
View File
@@ -0,0 +1,14 @@
### Steps to reproduce
How can we trigger this problem?
### Expected behavior
Tell us what should happen?
### Actual behavior
Tell us what happens instead?
### System configuration
Hardware:
Software or git version:
-9
View File
@@ -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
+3
View File
@@ -9,3 +9,6 @@ Check here to learn how to use this branch and help us improving ESPEasy: http:/
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
+63
View File
@@ -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
+178
View File
@@ -1,3 +1,181 @@
-----------------------------
Changes in release v2.0.0-dev8
-----------------------------
Release date: Mon Apr 24 13:21:32 CEST 2017
DatuX (6):
Update README.md
Update README.md
Update README.md
Update CONTRIBUTING.md
Update CONTRIBUTING.md
Update README.md
David Conran (2):
Update IRremoteESP8266 library url in .gitmodules
update sendSony() call to use repeats.
Dirk Moeller (2):
new function, Plugin_004_DS_setResolution und Plugin_004_DS_getResolution
fix typo
Edwin Eefting (36):
temporary disabled IR plugins, because of iram1_0_seg issues
initial version of memory analyser
moved arduinojson and liquidcrytal includes to correct plugins. reanbled IR-modules to solve memory issues
make the IRTX plugin work without the IR plugin
initial memory analyser and results
reduced memory usage _C001
reduced mem C001 C002
reduced ram usage C003 ... C011
reduce memory usage N001 N002
cleaned up servo stuff
recuded number of pulsecounters from 8 to 4 to save IRAM
contributing guidelines
fixed crash in C001 (when opening /controllers)
avoid static buffers in c001. addLog now also supports F(), so we dont need all those temporary variable definitions
removed unneccesay delays from c001
avoid unneccesary string conversions and static buffers in c001
fixed crashes caused by large MQTT packets
fixed lots of common issues that might cause crashes in c011. also see https://github.com/letscontrolit/ESPEasy/issues/117#issuecomment-293713370
added issue template to get cleaner bug reports
replaced all readstringuntil() with safeReadStringUntil()
starting working on stability reporting function
fixed stability issues in c009. probably caused by illegal PSTR usage, but i completly cleaned up all string handling
improved statusled handling in background tasks
converted submodule to normal directory. lib/Adafruit_Motor_Shield_V2 upstream commit ee4c4d334f498d54cdf80c9cc6f5bdec2533f8bf
now no longer a submodule lib/AS_BH1750, upstream version 092f0b1c5fa74eb2abe3d1b2925190d066e9506d
now no longer a submodule. lib/Adafruit_NeoPixel, upstream version v1.0.6
now no longer a submodule, lib/Adafruit_TCS34725 upstream version 1.0.1-13-g12be4c6
now no longer a submodule. lib/ArduinoJson upstream version v5.6.4
now no longer a submodule. lib/IRremoteESP8266 upstream version v1.0.2
oops moved lib/Adafruit_TCS34725 to wrong place
select env
Revert "Plugin_008-RFID extended with wiegand 34-bits and key-pad (4-bits per key) support". Now uses too much IRAM.
dont use arduino OTA in the dev env
escape html in the rules page, so that strings like &param do not cause problems. fixes issue #231
properly escape html in C011 generic http advanced.
fixed #239 due to improper PSTR. cleaned up string handling
Emmanuel Tatto (1):
getBearing should be outside the FEATURE_ARDUINO_OTA condition (#207)
Gerben Meijer (1):
Extend MH-Z19 sensor support
JK (3):
More informative and intuitive status LED
Using 3 I/O-pins consequently
added union to TaskDevicePin1..3
Jochen Krapf (1):
Added function isDeepSleepEnabled() (#177)
adb76 (2):
Set BME280 to recommended values for climate / weather sensor
BME280: Ensure sensor is in sleep mode to set the config, fix small typo
beic (13):
Menu correction, added BMP180 (#199)
Added detection for the HTU21D to I2C scenner
Environment naming will better fit in...
Environment naming will better fit in + HTU21D
Environment naming will better fit in... + naming
Environment naming will better fit in...
Environment naming will better fit in...
Environment naming will better fit in...
Environment naming will better fit in...
Environment naming will better fit in...
Little naming correction
Naming correction by Datasheet
Added detection for the SI1145 to I2C scenner
dev0 (1):
_C009.ino: RFC conformity and removed obsolet code (#163)
imthemichi (1):
Plugin_008-RFID extended with wiegand 34-bits and key-pad (4-bits per key) support
jbaumann (1):
Addition of ESP8285 targets (#187)
krikk (16):
motorshield library should be a submodule, enhanced the motorshield plugin... (#162)
http advanced: add replacement variable for systime, vcc, ip, sysload, uptime (#167)
corrected name for TSL2561, add option to use different sensor adress (#170)
re-did old pull requests (#172)
Tsl2561 rewrite (#174)
I2csoilmoisture fixed bug with sleep mode (#178)
Pulsecounter minor fix (#184)
rewrote bh1750 sensor based on better library... (#182)
cppcheck style fixes... (#186)
added i2c address selection to ino219 plugin (#192)
Motorshield plugin string fixes (#200) (reduced memory usage)
Support for Tcs34725 RGB Color Sensor (#195)
_P047_i2c-soil-moisture-sensor: allow change of sensor address (#201)
Httpadvanced crashfix + patch method (#204)
Bh1750: enhance to check for valid value (#208)
removed all unnecessary Strings due to new addLog with FlashStringHelper (#223)
tedenda (1):
Update _P049_MHZ19.ino
-----------------------------
Changes in release v2.0.0-dev7
-----------------------------
Release date: Wed Mar 15 01:42:15 CET 2017
Edwin Eefting (5):
timers can be disabled by setting them to 0 now. cleaned up event output logging. added timer out-of-bounds checks
added i2scanner via serial. removed spaces from Adafruit Motor Shield library so it works with arduino IDE
fixed Arduino IDE compilebug and added help to enable plugin sets in Arduino IDE
automaticly updated release notes for v2.0.0-dev7
fix in release-script (forgot to commit it last time)
krikk (2):
code cleanup for HTTP advanced controller
show date in webinterface, and changed password fields to type=password (#161)
-----------------------------
Changes in release v2.0.0-dev6
-----------------------------
Release date: Mon Mar 13 11:54:41 CET 2017
Edwin Eefting (15):
created script to assist in creating releases
bug fix: plugin_id should not start with a 0. (compiler interprets this as octal!)
Revert "bug fix: plugin_id should not start with a 0. (compiler interprets this as octal!)"
bug fix: plugin_id should not start with a 0. (compiler interprets this as octal!)
added NDIR CO2 Sensor MH-Z19 plugin to TESTING plugin set
remove artificial sensor startup delays. (now all sensors are send immediatly after booting and wifi-connecting)
do hardwareinit() earlier so that outputs are set immeadiatly instead of waiting for connect. fixes https://github.com/letscontrolit/ESPEasy/issues/114
enable status light as soon as wifi is connected
use sizeof instead of magic numbers
Implemented speaker and tone functions from https://www.letscontrolit.com/forum/viewtopic.php?f=4&t=343&hilit=speaker&start=10
enabled Arduino OTA for dev-firmware only, to ease developing. minor output-tweaks
cold boot startup delay
major change: changed the timing of the first sensor read after initial boot. cleaned up and improved deep sleeping code.
added plugin to testing. remove useless value variable
automaticly updated release notes for v2.0.0-dev6
Gerald (2):
HTTP Advanced, enhanced, so that only one http request is sent for one sensor (#156)
added missing sensor type, to fix problem with i2c soilmoisture sensor... (#157)
Jochen Krapf (1):
cancel deep sleep loop by pulling the pin GPIO16(D0) to GND (#158)
dzikus (1):
Added BMP280_CONFIG_SETTING to reduce the temperature of sensor and use oversampling filter (#155)
-----------------------------
Changes in release v2.0.0-dev5
-----------------------------
+13
View File
@@ -0,0 +1,13 @@
# Compiled Object files
*.slo
*.lo
*.o
# Compiled Dynamic libraries
*.so
*.dylib
# Compiled Static libraries
*.lai
*.la
*.a
+476
View File
@@ -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);
}
+183
View File
@@ -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
+705
View File
@@ -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;
}
}
+207
View File
@@ -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
+502
View File
@@ -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!
+37
View File
@@ -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);
}
+30
View File
@@ -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
}
+46
View File
@@ -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.
@@ -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
}
}
@@ -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
+46
View File
@@ -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**
+26
View File
@@ -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.
+11
View File
@@ -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
+181
View File
@@ -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
+165
View File
@@ -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.
+11
View File
@@ -0,0 +1,11 @@
# Adafruit NeoPixel Library [![Build Status](https://travis-ci.org/adafruit/Adafruit_NeoPixel.svg?branch=master)](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
+67
View File
@@ -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);
}
+29
View File
@@ -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
+9
View File
@@ -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=*
+46
View File
@@ -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**
+26
View File
@@ -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.
+334
View File
@@ -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);
}
+144
View File
@@ -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
+21
View File
@@ -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);
}
+9
View File
@@ -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=*
Submodule lib/ArduinoJson deleted from a498abc14a
+5
View File
@@ -0,0 +1,5 @@
# http://clang.llvm.org/docs/ClangFormatStyleOptions.html
BasedOnStyle: Google
Standard: Cpp03
AllowShortFunctionsOnASingleLine: Empty
+1
View File
@@ -0,0 +1 @@
*.sh text eol=lf
+11
View File
@@ -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!
-->
+8
View File
@@ -0,0 +1,8 @@
.DS_Store
/.idea
/build
/bin
/lib
/sftp-config.json
.tags
.tags_sorted_by_file
+118
View 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
+8
View File
@@ -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"
+303
View File
@@ -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
+21
View File
@@ -0,0 +1,21 @@
# Copyright Benoit Blanchon 2014-2016
# MIT License
#
# Arduino JSON library
# https://github.com/bblanchon/ArduinoJson
# If you like this project, please add a star!
cmake_minimum_required(VERSION 3.0)
project(ArduinoJson)
enable_testing()
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/lib)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/lib)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/bin)
if(${COVERAGE})
set(CMAKE_CXX_FLAGS "-g -O0 -fprofile-arcs -ftest-coverage")
endif()
add_subdirectory(test)
+10
View File
@@ -0,0 +1,10 @@
The MIT License (MIT)
---------------------
Copyright © 2014-2016 Benoit BLANCHON
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+130
View File
@@ -0,0 +1,130 @@
Arduino JSON library
====================
[![Build status](https://ci.appveyor.com/api/projects/status/m7s53wav1l0abssg/branch/master?svg=true)](https://ci.appveyor.com/project/bblanchon/arduinojson/branch/master) [![Build Status](https://travis-ci.org/bblanchon/ArduinoJson.svg?branch=master)](https://travis-ci.org/bblanchon/ArduinoJson) [![Coverage Status](https://img.shields.io/coveralls/bblanchon/ArduinoJson.svg)](https://coveralls.io/r/bblanchon/ArduinoJson?branch=master) [![Star this project](http://githubbadges.com/star.svg?user=bblanchon&repo=ArduinoJson&style=flat&color=fff&background=007ec6)](https://github.com/bblanchon/ArduinoJson)
*An elegant and efficient JSON library for embedded systems.*
It's designed to have the most intuitive API, the smallest footprint and works without any allocation on the heap (no malloc).
It has been written with Arduino in mind, but it isn't linked to Arduino libraries so you can use this library in any other C++ project.
Features
--------
* JSON decoding (comments are supported)
* JSON encoding (with optional indentation)
* Elegant API, very easy to use
* Fixed memory allocation (zero malloc)
* No data duplication (zero copy)
* Portable (written in C++98)
* Self-contained (no external dependency)
* Small footprint
* Header-only library
* MIT License
Works on
--------
* All Arduino boards (Uno, Due, Mini, Micro, Yun...)
* ESP8266
* Teensy
* Intel Edison and Galileo
* PlatformIO
* Energia
* RedBearLab boards (BLE Nano...)
* Computers (Windows, Linux, OSX...)
See [FAQ: Compatibility issues](https://github.com/bblanchon/ArduinoJson/wiki/Compatibility-issues)
Quick start
-----------
#### Decoding / Parsing
```c++
char json[] = "{\"sensor\":\"gps\",\"time\":1351824120,\"data\":[48.756080,2.302038]}";
StaticJsonBuffer<200> jsonBuffer;
JsonObject& root = jsonBuffer.parseObject(json);
const char* sensor = root["sensor"];
long time = root["time"];
double latitude = root["data"][0];
double longitude = root["data"][1];
```
#### Encoding / Generating
```c++
StaticJsonBuffer<200> jsonBuffer;
JsonObject& root = jsonBuffer.createObject();
root["sensor"] = "gps";
root["time"] = 1351824120;
JsonArray& data = root.createNestedArray("data");
data.add(48.756080, 6); // 6 is the number of decimals to print
data.add(2.302038, 6); // if not specified, 2 digits are printed
root.printTo(Serial);
// This prints:
// {"sensor":"gps","time":1351824120,"data":[48.756080,2.302038]}
```
Documentation
-------------
The documentation is available online in the [Arduino JSON wiki](https://github.com/bblanchon/ArduinoJson/wiki)
Testimonials
------------
From Arduino's Forum user `jflaplante`:
> I tried aJson json-arduino before trying your library. I always ran into memory problem after a while.
> I have no such problem so far with your library. It is working perfectly with my web services.
From Arduino's Forum user `gbathree`:
> Thanks so much - this is an awesome library! If you want to see what we're doing with it - the project is located at www.photosynq.org.
From StackOverflow user `thegreendroid`:
> It has a really elegant, simple API and it works like a charm on embedded and Windows/Linux platforms. We recently started using this on an embedded project and I can vouch for its quality.
From GitHub user `zacsketches`:
> Thanks for a great library!!!
> I've been watching you consistently develop this library over the past six months, and I used it today for a publish and subscribe architecture designed to help hobbyists move into more advanced robotics. Your library allowed me to implement remote subscription in order to facilitate multi-processor robots.
> ArduinoJson saved me a week's worth of time!!
[From Reddit user `erm_what_`](https://www.reddit.com/r/arduino/comments/3jj6ep/announcing_arduinojson_50/cusjk8c):
> This is a great library and I wouldn't be able to do the project I'm doing without it. I completely recommend it.
[From Reddit user `makerhacks`](https://www.reddit.com/r/arduino/comments/3jj6ep/announcing_arduinojson_50/cusqg7b):
> I am just starting an ESP8266 clock project and now I can output JSON from my server script and interpret it painlessly.
[From Twitter user `@hemalchevli`](https://twitter.com/hemalchevli/status/715788439397011456):
> ArduinoJson library should be used as a benchmark/reference for making libraries. Truly elegant.
Donators
--------
Special thanks to the following persons and companies who made generous donations to the library author:
* Robert Murphy <img alt='USA' src='https://cdnjs.cloudflare.com/ajax/libs/emojione/2.1.4/assets/svg/1f1fa-1f1f8.svg' width='18' height='18'>
* Surge Communications <img alt='USA' src='https://cdnjs.cloudflare.com/ajax/libs/emojione/2.1.4/assets/svg/1f1fa-1f1f8.svg' width='18' height='18'>
* Alex Scott <img alt='United Kingdom' src='https://cdnjs.cloudflare.com/ajax/libs/emojione/2.1.4/assets/svg/1f1ec-1f1e7.svg' width='18' height='18'>
* Firepick Services LLC <img alt='USA' src='https://cdnjs.cloudflare.com/ajax/libs/emojione/2.1.4/assets/svg/1f1fa-1f1f8.svg' width='18' height='18'>
* A B Doodkorte <img alt='Netherlands' src='https://cdnjs.cloudflare.com/ajax/libs/emojione/2.1.4/assets/svg/1f1f3-1f1f1.svg' width='18' height='18'>
* Scott Smith <img alt='USA' src='https://cdnjs.cloudflare.com/ajax/libs/emojione/2.1.4/assets/svg/1f1fa-1f1f8.svg' width='18' height='18'>
* Johann Stieger <img alt='Austria' src='https://cdnjs.cloudflare.com/ajax/libs/emojione/2.1.4/assets/svg/1f1e6-1f1f9.svg' width='18' height='18'>
* Gustavo Donizeti Gini <img alt='Brazil' src='https://cdnjs.cloudflare.com/ajax/libs/emojione/2.1.4/assets/svg/1f1e7-1f1f7.svg' width='18' height='18'>
* Charles-Henri Hallard <img alt='France' src='https://cdnjs.cloudflare.com/ajax/libs/emojione/2.1.4/assets/svg/1f1eb-1f1f7.svg' width='18' height='18'>
* Martijn van den Burg <img alt='Netherlands' src='https://cdnjs.cloudflare.com/ajax/libs/emojione/2.1.4/assets/svg/1f1f3-1f1f1.svg' width='18' height='18'>
* Nick Koumaris <img alt='Greece' src='https://cdnjs.cloudflare.com/ajax/libs/emojione/2.1.4/assets/svg/1f1ec-1f1f7.svg' width='18' height='18'>
* Jon Williams <img alt='USA' src='https://cdnjs.cloudflare.com/ajax/libs/emojione/2.1.4/assets/svg/1f1fa-1f1f8.svg' width='18' height='18'>
* Kestutis Liaugminas <img alt='Lithuania' src='https://cdnjs.cloudflare.com/ajax/libs/emojione/2.1.4/assets/svg/1f1f1-1f1f9.svg' width='18' height='18'>
---
Found this library useful? Please star this project or [help me back with a donation!](https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=donate%40benoitblanchon%2efr&lc=GB&item_name=Benoit%20Blanchon&item_number=Arduino%20JSON&currency_code=EUR&bn=PP%2dDonationsBF%3abtn_donate_LG%2egif%3aNonHosted) :smile:
+18
View File
@@ -0,0 +1,18 @@
version: 5.6.4.{build}
environment:
matrix:
- CMAKE_GENERATOR: Visual Studio 14 2015
- CMAKE_GENERATOR: Visual Studio 12 2013
- CMAKE_GENERATOR: Visual Studio 11 2012
- CMAKE_GENERATOR: Visual Studio 10 2010
# - CMAKE_GENERATOR: MinGW Makefiles
# Note: Disabled because of unexplicated error -1073741511
# This used to work fine with GCC 4.8.2 then failed after they upgraded to GCC 4.9.3
configuration: Debug
before_build:
- set PATH=C:\MinGW\bin;%PATH:C:\Program Files\Git\usr\bin;=% # Workaround for CMake not wanting sh.exe on PATH for MinGW
- cmake -DCMAKE_BUILD_TYPE=%CONFIGURATION% -G "%CMAKE_GENERATOR%" .
build_script:
- cmake --build . --config %CONFIGURATION%
test_script:
- ctest -V .
@@ -0,0 +1,35 @@
// 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 <ArduinoJson.h>
using namespace ArduinoJson::Internals;
void setup() {
Serial.begin(9600);
while (!Serial) {
// wait serial port initialization
}
IndentedPrint serial(Serial);
serial.setTabSize(4);
serial.println("This is at indentation 0");
serial.indent();
serial.println("This is at indentation 1");
serial.println("This is also at indentation 1");
serial.indent();
serial.println("This is at indentation 2");
serial.unindent();
serial.unindent();
serial.println("This is back at indentation 0");
}
void loop() {
// not used in this example
}
@@ -0,0 +1,70 @@
// 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 <ArduinoJson.h>
void setup() {
Serial.begin(9600);
while (!Serial) {
// wait serial port initialization
}
// Memory pool for JSON object tree.
//
// Inside the brackets, 200 is the size of the pool in bytes.
// If the JSON object is more complex, you need to increase that value.
StaticJsonBuffer<200> jsonBuffer;
// StaticJsonBuffer allocates memory on the stack, it can be
// replaced by DynamicJsonBuffer which allocates in the heap.
// It's simpler but less efficient.
//
// DynamicJsonBuffer jsonBuffer;
// Create the root of the object tree.
//
// It's a reference to the JsonObject, the actual bytes are inside the
// JsonBuffer with all the other nodes of the object tree.
// Memory is freed when jsonBuffer goes out of scope.
JsonObject& root = jsonBuffer.createObject();
// Add values in the object
//
// Most of the time, you can rely on the implicit casts.
// In other case, you can do root.set<long>("time", 1351824120);
root["sensor"] = "gps";
root["time"] = 1351824120;
// Add a nested array.
//
// It's also possible to create the array separately and add it to the
// JsonObject but it's less efficient.
JsonArray& data = root.createNestedArray("data");
data.add(double_with_n_digits(48.756080, 6));
data.add(double_with_n_digits(2.302038, 6));
root.printTo(Serial);
// This prints:
// {"sensor":"gps","time":1351824120,"data":[48.756080,2.302038]}
Serial.println();
root.prettyPrintTo(Serial);
// This prints:
// {
// "sensor": "gps",
// "time": 1351824120,
// "data": [
// 48.756080,
// 2.302038
// ]
// }
}
void loop() {
// not used in this example
}
@@ -0,0 +1,195 @@
// Sample Arduino Json Web Client
// Downloads and parse http://jsonplaceholder.typicode.com/users/1
//
// 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 <ArduinoJson.h>
#include <SPI.h>
#include <Ethernet.h>
EthernetClient client;
const char* server = "jsonplaceholder.typicode.com"; // server's address
const char* resource = "/users/1"; // http resource
const unsigned long BAUD_RATE = 9600; // serial connection speed
const unsigned long HTTP_TIMEOUT = 10000; // max respone time from server
const size_t MAX_CONTENT_SIZE = 512; // max size of the HTTP response
// The type of data that we want to extract from the page
struct UserData {
char name[32];
char company[32];
};
// ARDUINO entry point #1: runs once when you press reset or power the board
void setup() {
initSerial();
initEthernet();
}
// ARDUINO entry point #2: runs over and over again forever
void loop() {
if (connect(server)) {
if (sendRequest(server, resource) && skipResponseHeaders()) {
char response[MAX_CONTENT_SIZE];
readReponseContent(response, sizeof(response));
UserData userData;
if (parseUserData(response, &userData)) {
printUserData(&userData);
}
}
disconnect();
}
wait();
}
// Initialize Serial port
void initSerial() {
Serial.begin(BAUD_RATE);
while (!Serial) {
; // wait for serial port to initialize
}
Serial.println("Serial ready");
}
// Initialize Ethernet library
void initEthernet() {
byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};
if (!Ethernet.begin(mac)) {
Serial.println("Failed to configure Ethernet");
return;
}
Serial.println("Ethernet ready");
delay(1000);
}
// Open connection to the HTTP server
bool connect(const char* hostName) {
Serial.print("Connect to ");
Serial.println(hostName);
bool ok = client.connect(hostName, 80);
Serial.println(ok ? "Connected" : "Connection Failed!");
return ok;
}
// Send the HTTP GET request to the server
bool sendRequest(const char* host, const char* resource) {
Serial.print("GET ");
Serial.println(resource);
client.print("GET ");
client.print(resource);
client.println(" HTTP/1.1");
client.print("Host: ");
client.println(server);
client.println("Connection: close");
client.println();
return true;
}
// Skip HTTP headers so that we are at the beginning of the response's body
bool skipResponseHeaders() {
// HTTP headers end with an empty line
char endOfHeaders[] = "\r\n\r\n";
client.setTimeout(HTTP_TIMEOUT);
bool ok = client.find(endOfHeaders);
if (!ok) {
Serial.println("No response or invalid response!");
}
return ok;
}
// Read the body of the response from the HTTP server
void readReponseContent(char* content, size_t maxSize) {
size_t length = client.readBytes(content, maxSize);
content[length] = 0;
Serial.println(content);
}
// Parse the JSON from the input string and extract the interesting values
// Here is the JSON we need to parse
// {
// "id": 1,
// "name": "Leanne Graham",
// "username": "Bret",
// "email": "Sincere@april.biz",
// "address": {
// "street": "Kulas Light",
// "suite": "Apt. 556",
// "city": "Gwenborough",
// "zipcode": "92998-3874",
// "geo": {
// "lat": "-37.3159",
// "lng": "81.1496"
// }
// },
// "phone": "1-770-736-8031 x56442",
// "website": "hildegard.org",
// "company": {
// "name": "Romaguera-Crona",
// "catchPhrase": "Multi-layered client-server neural-net",
// "bs": "harness real-time e-markets"
// }
// }
bool parseUserData(char* content, struct UserData* userData) {
// Compute optimal size of the JSON buffer according to what we need to parse.
// This is only required if you use StaticJsonBuffer.
const size_t BUFFER_SIZE =
JSON_OBJECT_SIZE(8) // the root object has 8 elements
+ JSON_OBJECT_SIZE(5) // the "address" object has 5 elements
+ JSON_OBJECT_SIZE(2) // the "geo" object has 2 elements
+ JSON_OBJECT_SIZE(3); // the "company" object has 3 elements
// Allocate a temporary memory pool on the stack
StaticJsonBuffer<BUFFER_SIZE> jsonBuffer;
// If the memory pool is too big for the stack, use this instead:
// DynamicJsonBuffer jsonBuffer;
JsonObject& root = jsonBuffer.parseObject(content);
if (!root.success()) {
Serial.println("JSON parsing failed!");
return false;
}
// Here were copy the strings we're interested in
strcpy(userData->name, root["name"]);
strcpy(userData->company, root["company"]["name"]);
// It's not mandatory to make a copy, you could just use the pointers
// Since, they are pointing inside the "content" buffer, so you need to make
// sure it's still in memory when you read the string
return true;
}
// Print the data extracted from the JSON
void printUserData(const struct UserData* userData) {
Serial.print("Name = ");
Serial.println(userData->name);
Serial.print("Company = ");
Serial.println(userData->company);
}
// Close the connection with the HTTP server
void disconnect() {
Serial.println("Disconnect");
client.stop();
}
// Pause for a 1 minute
void wait() {
Serial.println("Wait 60 seconds");
delay(60000);
}
@@ -0,0 +1,67 @@
// 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 <ArduinoJson.h>
void setup() {
Serial.begin(9600);
while (!Serial) {
// wait serial port initialization
}
// Memory pool for JSON object tree.
//
// Inside the brackets, 200 is the size of the pool in bytes,
// If the JSON object is more complex, you need to increase that value.
StaticJsonBuffer<200> jsonBuffer;
// StaticJsonBuffer allocates memory on the stack, it can be
// replaced by DynamicJsonBuffer which allocates in the heap.
// It's simpler but less efficient.
//
// DynamicJsonBuffer jsonBuffer;
// JSON input string.
//
// It's better to use a char[] as shown here.
// If you use a const char* or a String, ArduinoJson will
// have to make a copy of the input in the JsonBuffer.
char json[] =
"{\"sensor\":\"gps\",\"time\":1351824120,\"data\":[48.756080,2.302038]}";
// Root of the object tree.
//
// It's a reference to the JsonObject, the actual bytes are inside the
// JsonBuffer with all the other nodes of the object tree.
// Memory is freed when jsonBuffer goes out of scope.
JsonObject& root = jsonBuffer.parseObject(json);
// Test if parsing succeeds.
if (!root.success()) {
Serial.println("parseObject() failed");
return;
}
// Fetch values.
//
// Most of the time, you can rely on the implicit casts.
// In other case, you can do root["time"].as<long>();
const char* sensor = root["sensor"];
long time = root["time"];
double latitude = root["data"][0];
double longitude = root["data"][1];
// Print values.
Serial.println(sensor);
Serial.println(time);
Serial.println(latitude, 6);
Serial.println(longitude, 6);
}
void loop() {
// not used in this example
}
@@ -0,0 +1,74 @@
// Sample Arduino Json Web Server
// Created by Benoit Blanchon.
// Heavily inspired by "Web Server" from David A. Mellis and Tom Igoe
#include <SPI.h>
#include <Ethernet.h>
#include <ArduinoJson.h>
byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};
IPAddress ip(192, 168, 0, 177);
EthernetServer server(80);
bool readRequest(EthernetClient& client) {
bool currentLineIsBlank = true;
while (client.connected()) {
if (client.available()) {
char c = client.read();
if (c == '\n' && currentLineIsBlank) {
return true;
} else if (c == '\n') {
currentLineIsBlank = true;
} else if (c != '\r') {
currentLineIsBlank = false;
}
}
}
return false;
}
JsonObject& prepareResponse(JsonBuffer& jsonBuffer) {
JsonObject& root = jsonBuffer.createObject();
JsonArray& analogValues = root.createNestedArray("analog");
for (int pin = 0; pin < 6; pin++) {
int value = analogRead(pin);
analogValues.add(value);
}
JsonArray& digitalValues = root.createNestedArray("digital");
for (int pin = 0; pin < 14; pin++) {
int value = digitalRead(pin);
digitalValues.add(value);
}
return root;
}
void writeResponse(EthernetClient& client, JsonObject& json) {
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: application/json");
client.println("Connection: close");
client.println();
json.prettyPrintTo(client);
}
void setup() {
Ethernet.begin(mac, ip);
server.begin();
}
void loop() {
EthernetClient client = server.available();
if (client) {
bool success = readRequest(client);
if (success) {
StaticJsonBuffer<500> jsonBuffer;
JsonObject& json = prepareResponse(jsonBuffer);
writeResponse(client, json);
}
delay(1);
client.stop();
}
}
@@ -0,0 +1,55 @@
// Send a JSON object on UDP at regular interval
//
// You can easily test this program with netcat:
// $ nc -ulp 8888
//
// by Benoit Blanchon, MIT License 2015-2016
#include <SPI.h>
#include <Ethernet.h>
#include <ArduinoJson.h>
byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};
IPAddress localIp(192, 168, 0, 177);
IPAddress remoteIp(192, 168, 0, 109);
unsigned int remotePort = 8888;
unsigned localPort = 8888;
EthernetUDP udp;
JsonObject& buildJson(JsonBuffer& jsonBuffer) {
JsonObject& root = jsonBuffer.createObject();
JsonArray& analogValues = root.createNestedArray("analog");
for (int pin = 0; pin < 6; pin++) {
int value = analogRead(pin);
analogValues.add(value);
}
JsonArray& digitalValues = root.createNestedArray("digital");
for (int pin = 0; pin < 14; pin++) {
int value = digitalRead(pin);
digitalValues.add(value);
}
return root;
}
void sendJson(JsonObject& json) {
udp.beginPacket(remoteIp, remotePort);
json.printTo(udp);
udp.println();
udp.endPacket();
}
void setup() {
Ethernet.begin(mac, localIp);
udp.begin(localPort);
}
void loop() {
delay(1000);
StaticJsonBuffer<300> jsonBuffer;
JsonObject& json = buildJson(jsonBuffer);
sendJson(json);
}
+9
View File
@@ -0,0 +1,9 @@
// 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 "ArduinoJson.hpp"
using namespace ArduinoJson;
+21
View File
@@ -0,0 +1,21 @@
// Copyright Benoit Blanchon 2014-2016
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// If you like this project, please add a star!
#pragma once
#include "ArduinoJson/DynamicJsonBuffer.hpp"
#include "ArduinoJson/JsonArray.hpp"
#include "ArduinoJson/JsonObject.hpp"
#include "ArduinoJson/StaticJsonBuffer.hpp"
#include "ArduinoJson/Internals/JsonParser.ipp"
#include "ArduinoJson/JsonArray.ipp"
#include "ArduinoJson/JsonBuffer.ipp"
#include "ArduinoJson/JsonObject.ipp"
#include "ArduinoJson/JsonVariant.ipp"
using namespace ArduinoJson;
@@ -0,0 +1,89 @@
// Copyright Benoit Blanchon 2014-2016
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// If you like this project, please add a star!
#pragma once
#ifdef ARDUINO // assume this is an embedded platform
// store using float instead of double to reduce the memory usage (issue #134)
#ifndef ARDUINOJSON_USE_DOUBLE
#define ARDUINOJSON_USE_DOUBLE 0
#endif
// store using a long because it usually match the size of a float.
#ifndef ARDUINOJSON_USE_LONG_LONG
#define ARDUINOJSON_USE_LONG_LONG 0
#endif
#ifndef ARDUINOJSON_USE_INT64
#define ARDUINOJSON_USE_INT64 0
#endif
// arduino has its own implementation of String to replace std::string
#ifndef ARDUINOJSON_USE_ARDUINO_STRING
#define ARDUINOJSON_USE_ARDUINO_STRING 1
#endif
// arduino doesn't support STL stream
#ifndef ARDUINOJSON_ENABLE_STD_STREAM
#define ARDUINOJSON_ENABLE_STD_STREAM 0
#endif
#ifndef ARDUINOJSON_ENABLE_ALIGNMENT
#ifdef ARDUINO_ARCH_AVR
// alignment isn't needed for 8-bit AVR
#define ARDUINOJSON_ENABLE_ALIGNMENT 0
#else
// but must processor needs pointer to be align on word size
#define ARDUINOJSON_ENABLE_ALIGNMENT 1
#endif
#endif
#else // assume this is a computer
// on a computer we have plenty of memory so we can use doubles
#ifndef ARDUINOJSON_USE_DOUBLE
#define ARDUINOJSON_USE_DOUBLE 1
#endif
// use long long when available
#ifndef ARDUINOJSON_USE_LONG_LONG
#if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1800)
#define ARDUINOJSON_USE_LONG_LONG 1
#else
#define ARDUINOJSON_USE_LONG_LONG 0
#endif
#endif
// use _int64 on old versions of Visual Studio
#ifndef ARDUINOJSON_USE_INT64
#if defined(_MSC_VER) && _MSC_VER <= 1700
#define ARDUINOJSON_USE_INT64 1
#else
#define ARDUINOJSON_USE_INT64 0
#endif
#endif
// on a computer, we can use std::string
#ifndef ARDUINOJSON_USE_ARDUINO_STRING
#define ARDUINOJSON_USE_ARDUINO_STRING 0
#endif
// on a computer, we can assume that the STL is there
#ifndef ARDUINOJSON_ENABLE_STD_STREAM
#define ARDUINOJSON_ENABLE_STD_STREAM 1
#endif
#ifndef ARDUINOJSON_ENABLE_ALIGNMENT
// even if not required, most cpu's are faster with aligned pointers
#define ARDUINOJSON_ENABLE_ALIGNMENT 1
#endif
#endif
#if ARDUINOJSON_USE_LONG_LONG && ARDUINOJSON_USE_INT64
#error ARDUINOJSON_USE_LONG_LONG and ARDUINOJSON_USE_INT64 cannot be set together
#endif
@@ -0,0 +1,18 @@
// Copyright Benoit Blanchon 2014-2016
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// If you like this project, please add a star!
#pragma once
#include "Internals/BlockJsonBuffer.hpp"
namespace ArduinoJson {
// Implements a JsonBuffer with dynamic memory allocation.
// You are strongly encouraged to consider using StaticJsonBuffer which is much
// more suitable for embedded systems.
typedef Internals::BlockJsonBuffer<Internals::DefaultAllocator>
DynamicJsonBuffer;
}
@@ -0,0 +1,115 @@
// Copyright Benoit Blanchon 2014-2016
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// If you like this project, please add a star!
#pragma once
#include "../JsonBuffer.hpp"
#include <stdlib.h>
#if defined(__clang__)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wnon-virtual-dtor"
#elif defined(__GNUC__)
#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
#pragma GCC diagnostic push
#endif
#pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
#endif
namespace ArduinoJson {
namespace Internals {
class DefaultAllocator {
public:
void* allocate(size_t size) {
return malloc(size);
}
void deallocate(void* pointer) {
free(pointer);
}
};
template <typename TAllocator>
class BlockJsonBuffer : public JsonBuffer {
struct Block;
struct EmptyBlock {
Block* next;
size_t capacity;
size_t size;
};
struct Block : EmptyBlock {
uint8_t data[1];
};
public:
BlockJsonBuffer(size_t initialSize = 256)
: _head(NULL), _nextBlockSize(initialSize) {}
~BlockJsonBuffer() {
Block* currentBlock = _head;
while (currentBlock != NULL) {
Block* nextBlock = currentBlock->next;
_allocator.deallocate(currentBlock);
currentBlock = nextBlock;
}
}
size_t size() const {
size_t total = 0;
for (const Block* b = _head; b; b = b->next) total += b->size;
return total;
}
virtual void* alloc(size_t bytes) {
return canAllocInHead(bytes) ? allocInHead(bytes) : allocInNewBlock(bytes);
}
private:
bool canAllocInHead(size_t bytes) const {
return _head != NULL && _head->size + bytes <= _head->capacity;
}
void* allocInHead(size_t bytes) {
void* p = _head->data + _head->size;
_head->size += round_size_up(bytes);
return p;
}
void* allocInNewBlock(size_t bytes) {
size_t capacity = _nextBlockSize;
if (bytes > capacity) capacity = bytes;
if (!addNewBlock(capacity)) return NULL;
_nextBlockSize *= 2;
return allocInHead(bytes);
}
bool addNewBlock(size_t capacity) {
size_t bytes = sizeof(EmptyBlock) + capacity;
Block* block = static_cast<Block*>(_allocator.allocate(bytes));
if (block == NULL) return false;
block->capacity = capacity;
block->size = 0;
block->next = _head;
_head = block;
return true;
}
TAllocator _allocator;
Block* _head;
size_t _nextBlockSize;
};
}
}
#if defined(__clang__)
#pragma clang diagnostic pop
#elif defined(__GNUC__)
#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
#pragma GCC diagnostic pop
#endif
#endif
@@ -0,0 +1,56 @@
// Copyright Benoit Blanchon 2014-2016
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// If you like this project, please add a star!
#pragma once
namespace ArduinoJson {
namespace Internals {
inline const char *skipCStyleComment(const char *ptr) {
ptr += 2;
for (;;) {
if (ptr[0] == '\0') return ptr;
if (ptr[0] == '*' && ptr[1] == '/') return ptr + 2;
ptr++;
}
}
inline const char *skipCppStyleComment(const char *ptr) {
ptr += 2;
for (;;) {
if (ptr[0] == '\0' || ptr[0] == '\n') return ptr;
ptr++;
}
}
inline const char *skipSpacesAndComments(const char *ptr) {
for (;;) {
switch (ptr[0]) {
case ' ':
case '\t':
case '\r':
case '\n':
ptr++;
continue;
case '/':
switch (ptr[1]) {
case '*':
ptr = skipCStyleComment(ptr);
break;
case '/':
ptr = skipCppStyleComment(ptr);
break;
default:
return ptr;
}
break;
default:
return ptr;
}
}
}
}
}
@@ -0,0 +1,21 @@
// Copyright Benoit Blanchon 2014-2016
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// If you like this project, please add a star!
#pragma once
#include "../Print.hpp"
namespace ArduinoJson {
namespace Internals {
// A dummy Print implementation used in JsonPrintable::measureLength()
class DummyPrint : public Print {
public:
virtual size_t write(uint8_t) { return 1; }
};
}
}
@@ -0,0 +1,33 @@
// Copyright Benoit Blanchon 2014-2016
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// If you like this project, please add a star!
#pragma once
#include "../Print.hpp"
#include "../String.hpp"
namespace ArduinoJson {
namespace Internals {
// A Print implementation that allows to write in a String
class DynamicStringBuilder : public Print {
public:
DynamicStringBuilder(String &str) : _str(str) {}
virtual size_t write(uint8_t c) {
// Need to cast to char, otherwise String will print a number (issue #120)
_str += static_cast<char>(c);
return 1;
}
private:
DynamicStringBuilder &operator=(const DynamicStringBuilder &);
String &_str;
};
}
}
@@ -0,0 +1,42 @@
// Copyright Benoit Blanchon 2014-2016
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// If you like this project, please add a star!
#pragma once
#include "../Print.hpp"
namespace ArduinoJson {
namespace Internals {
class Encoding {
public:
// Optimized for code size on a 8-bit AVR
static char escapeChar(char c) {
const char *p = escapeTable(false);
while (p[0] && p[1] != c) {
p += 2;
}
return p[0];
}
// Optimized for code size on a 8-bit AVR
static char unescapeChar(char c) {
const char *p = escapeTable(true);
for (;;) {
if (p[0] == '\0') return c;
if (p[0] == c) return p[1];
p += 2;
}
}
private:
static const char *escapeTable(bool excludeIdenticals) {
return &"\"\"\\\\b\bf\fn\nr\rt\t"[excludeIdenticals ? 4 : 0];
}
};
}
}
@@ -0,0 +1,65 @@
// Copyright Benoit Blanchon 2014-2016
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// If you like this project, please add a star!
#pragma once
#include "../Print.hpp"
namespace ArduinoJson {
namespace Internals {
// Decorator on top of Print to allow indented output.
// This class is used by JsonPrintable::prettyPrintTo() but can also be used
// for your own purpose, like logging.
class IndentedPrint : public Print {
public:
explicit IndentedPrint(Print &p) : sink(&p) {
level = 0;
tabSize = 2;
isNewLine = true;
}
virtual size_t write(uint8_t c) {
size_t n = 0;
if (isNewLine) n += writeTabs();
n += sink->write(c);
isNewLine = c == '\n';
return n;
}
// Adds one level of indentation
void indent() {
if (level < MAX_LEVEL) level++;
}
// Removes one level of indentation
void unindent() {
if (level > 0) level--;
}
// Set the number of space printed for each level of indentation
void setTabSize(uint8_t n) {
if (n < MAX_TAB_SIZE) tabSize = n & MAX_TAB_SIZE;
}
private:
Print *sink;
uint8_t level : 4;
uint8_t tabSize : 3;
bool isNewLine : 1;
size_t writeTabs() {
size_t n = 0;
for (int i = 0; i < level * tabSize; i++) n += sink->write(' ');
return n;
}
static const int MAX_LEVEL = 15; // because it's only 4 bits
static const int MAX_TAB_SIZE = 7; // because it's only 3 bits
};
}
}
@@ -0,0 +1,25 @@
// Copyright Benoit Blanchon 2014-2016
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// If you like this project, please add a star!
#pragma once
#include "../JsonBuffer.hpp"
namespace ArduinoJson {
namespace Internals {
class JsonBufferAllocated {
public:
void *operator new(size_t n, JsonBuffer *jsonBuffer) throw() {
if (!jsonBuffer) return NULL;
return jsonBuffer->alloc(n);
}
void operator delete(void *, JsonBuffer *) throw() {}
};
}
}
@@ -0,0 +1,21 @@
// Copyright Benoit Blanchon 2014-2016
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// If you like this project, please add a star!
#pragma once
#include "../Configuration.hpp"
namespace ArduinoJson {
namespace Internals {
#if ARDUINOJSON_USE_DOUBLE
typedef double JsonFloat;
#else
typedef float JsonFloat;
#endif
}
}
@@ -0,0 +1,26 @@
// Copyright Benoit Blanchon 2014-2016
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// If you like this project, please add a star!
#pragma once
#include "../Configuration.hpp"
namespace ArduinoJson {
namespace Internals {
#if ARDUINOJSON_USE_LONG_LONG
typedef long long JsonInteger;
typedef unsigned long long JsonUInt;
#elif ARDUINOJSON_USE_INT64
typedef __int64 JsonInteger;
typedef unsigned _int64 JsonUInt;
#else
typedef long JsonInteger;
typedef unsigned long JsonUInt;
#endif
}
}
@@ -0,0 +1,66 @@
// Copyright Benoit Blanchon 2014-2016
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// If you like this project, please add a star!
#pragma once
#include "../JsonBuffer.hpp"
#include "../JsonVariant.hpp"
namespace ArduinoJson {
namespace Internals {
// Parse JSON string to create JsonArrays and JsonObjects
// This internal class is not indended to be used directly.
// Instead, use JsonBuffer.parseArray() or .parseObject()
class JsonParser {
public:
JsonParser(JsonBuffer *buffer, char *json, uint8_t nestingLimit)
: _buffer(buffer),
_readPtr(json ? json : ""),
_writePtr(json),
_nestingLimit(nestingLimit) {}
JsonArray &parseArray();
JsonObject &parseObject();
JsonVariant parseVariant() {
JsonVariant result;
parseAnythingTo(&result);
return result;
}
private:
bool skip(char charToSkip);
const char *parseString();
bool parseAnythingTo(JsonVariant *destination);
FORCE_INLINE bool parseAnythingToUnsafe(JsonVariant *destination);
inline bool parseArrayTo(JsonVariant *destination);
inline bool parseObjectTo(JsonVariant *destination);
inline bool parseStringTo(JsonVariant *destination);
static inline bool isInRange(char c, char min, char max) {
return min <= c && c <= max;
}
static inline bool isLetterOrNumber(char c) {
return isInRange(c, '0', '9') || isInRange(c, 'a', 'z') ||
isInRange(c, 'A', 'Z') || c == '-' || c == '.';
}
static inline bool isQuote(char c) {
return c == '\'' || c == '\"';
}
JsonBuffer *_buffer;
const char *_readPtr;
char *_writePtr;
uint8_t _nestingLimit;
};
}
}
@@ -0,0 +1,191 @@
// Copyright Benoit Blanchon 2014-2016
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// If you like this project, please add a star!
#pragma once
#include "Comments.hpp"
#include "JsonParser.hpp"
inline bool ArduinoJson::Internals::JsonParser::skip(char charToSkip) {
const char *ptr = skipSpacesAndComments(_readPtr);
if (*ptr != charToSkip) return false;
ptr++;
_readPtr = skipSpacesAndComments(ptr);
return true;
}
inline bool ArduinoJson::Internals::JsonParser::parseAnythingTo(
JsonVariant *destination) {
if (_nestingLimit == 0) return false;
_nestingLimit--;
bool success = parseAnythingToUnsafe(destination);
_nestingLimit++;
return success;
}
inline bool ArduinoJson::Internals::JsonParser::parseAnythingToUnsafe(
JsonVariant *destination) {
_readPtr = skipSpacesAndComments(_readPtr);
switch (*_readPtr) {
case '[':
return parseArrayTo(destination);
case '{':
return parseObjectTo(destination);
default:
return parseStringTo(destination);
}
}
inline ArduinoJson::JsonArray &
ArduinoJson::Internals::JsonParser::parseArray() {
// Create an empty array
JsonArray &array = _buffer->createArray();
// Check opening braket
if (!skip('[')) goto ERROR_MISSING_BRACKET;
if (skip(']')) goto SUCCESS_EMPTY_ARRAY;
// Read each value
for (;;) {
// 1 - Parse value
JsonVariant value;
if (!parseAnythingTo(&value)) goto ERROR_INVALID_VALUE;
if (!array.add(value)) goto ERROR_NO_MEMORY;
// 2 - More values?
if (skip(']')) goto SUCCES_NON_EMPTY_ARRAY;
if (!skip(',')) goto ERROR_MISSING_COMMA;
}
SUCCESS_EMPTY_ARRAY:
SUCCES_NON_EMPTY_ARRAY:
return array;
ERROR_INVALID_VALUE:
ERROR_MISSING_BRACKET:
ERROR_MISSING_COMMA:
ERROR_NO_MEMORY:
return JsonArray::invalid();
}
inline bool ArduinoJson::Internals::JsonParser::parseArrayTo(
JsonVariant *destination) {
JsonArray &array = parseArray();
if (!array.success()) return false;
*destination = array;
return true;
}
inline ArduinoJson::JsonObject &
ArduinoJson::Internals::JsonParser::parseObject() {
// Create an empty object
JsonObject &object = _buffer->createObject();
// Check opening brace
if (!skip('{')) goto ERROR_MISSING_BRACE;
if (skip('}')) goto SUCCESS_EMPTY_OBJECT;
// Read each key value pair
for (;;) {
// 1 - Parse key
const char *key = parseString();
if (!key) goto ERROR_INVALID_KEY;
if (!skip(':')) goto ERROR_MISSING_COLON;
// 2 - Parse value
JsonVariant value;
if (!parseAnythingTo(&value)) goto ERROR_INVALID_VALUE;
if (!object.set(key, value)) goto ERROR_NO_MEMORY;
// 3 - More keys/values?
if (skip('}')) goto SUCCESS_NON_EMPTY_OBJECT;
if (!skip(',')) goto ERROR_MISSING_COMMA;
}
SUCCESS_EMPTY_OBJECT:
SUCCESS_NON_EMPTY_OBJECT:
return object;
ERROR_INVALID_KEY:
ERROR_INVALID_VALUE:
ERROR_MISSING_BRACE:
ERROR_MISSING_COLON:
ERROR_MISSING_COMMA:
ERROR_NO_MEMORY:
return JsonObject::invalid();
}
inline bool ArduinoJson::Internals::JsonParser::parseObjectTo(
JsonVariant *destination) {
JsonObject &object = parseObject();
if (!object.success()) return false;
*destination = object;
return true;
}
inline const char *ArduinoJson::Internals::JsonParser::parseString() {
const char *readPtr = _readPtr;
char *writePtr = _writePtr;
char c = *readPtr;
if (isQuote(c)) { // quotes
char stopChar = c;
for (;;) {
c = *++readPtr;
if (c == '\0') break;
if (c == stopChar) {
readPtr++;
break;
}
if (c == '\\') {
// replace char
c = Encoding::unescapeChar(*++readPtr);
if (c == '\0') break;
}
*writePtr++ = c;
}
} else { // no quotes
for (;;) {
if (!isLetterOrNumber(c)) break;
*writePtr++ = c;
c = *++readPtr;
}
}
// end the string here
*writePtr++ = '\0';
const char *startPtr = _writePtr;
// update end ptr
_readPtr = readPtr;
_writePtr = writePtr;
// return pointer to unquoted string
return startPtr;
}
inline bool ArduinoJson::Internals::JsonParser::parseStringTo(
JsonVariant *destination) {
bool hasQuotes = isQuote(_readPtr[0]);
const char *value = parseString();
if (value == NULL) return false;
if (hasQuotes) {
*destination = value;
} else {
*destination = RawJson(value);
}
return true;
}
@@ -0,0 +1,97 @@
// Copyright Benoit Blanchon 2014-2016
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// If you like this project, please add a star!
#pragma once
#include "../Configuration.hpp"
#include "DummyPrint.hpp"
#include "IndentedPrint.hpp"
#include "JsonWriter.hpp"
#include "Prettyfier.hpp"
#include "StaticStringBuilder.hpp"
#include "DynamicStringBuilder.hpp"
#if ARDUINOJSON_ENABLE_STD_STREAM
#include "StreamPrintAdapter.hpp"
#endif
namespace ArduinoJson {
namespace Internals {
// Implements all the overloads of printTo() and prettyPrintTo()
// Caution: this class use a template parameter to avoid virtual methods.
// This is a bit curious but allows to reduce the size of JsonVariant, JsonArray
// and JsonObject.
template <typename T>
class JsonPrintable {
public:
size_t printTo(Print &print) const {
JsonWriter writer(print);
downcast().writeTo(writer);
return writer.bytesWritten();
}
#if ARDUINOJSON_ENABLE_STD_STREAM
std::ostream &printTo(std::ostream &os) const {
StreamPrintAdapter adapter(os);
printTo(adapter);
return os;
}
#endif
size_t printTo(char *buffer, size_t bufferSize) const {
StaticStringBuilder sb(buffer, bufferSize);
return printTo(sb);
}
size_t printTo(String &str) const {
DynamicStringBuilder sb(str);
return printTo(sb);
}
size_t prettyPrintTo(IndentedPrint &print) const {
Prettyfier p(print);
return printTo(p);
}
size_t prettyPrintTo(char *buffer, size_t bufferSize) const {
StaticStringBuilder sb(buffer, bufferSize);
return prettyPrintTo(sb);
}
size_t prettyPrintTo(Print &print) const {
IndentedPrint indentedPrint = IndentedPrint(print);
return prettyPrintTo(indentedPrint);
}
size_t prettyPrintTo(String &str) const {
DynamicStringBuilder sb(str);
return prettyPrintTo(sb);
}
size_t measureLength() const {
DummyPrint dp;
return printTo(dp);
}
size_t measurePrettyLength() const {
DummyPrint dp;
return prettyPrintTo(dp);
}
private:
const T &downcast() const { return *static_cast<const T *>(this); }
};
#if ARDUINOJSON_ENABLE_STD_STREAM
template <typename T>
inline std::ostream &operator<<(std::ostream &os, const JsonPrintable<T> &v) {
return v.printTo(os);
}
#endif
}
}
@@ -0,0 +1,45 @@
// Copyright Benoit Blanchon 2014-2016
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// If you like this project, please add a star!
#pragma once
namespace ArduinoJson {
namespace Internals {
// A metafunction that returns the type of the value returned by
// JsonVariant::as<T>()
template <typename T>
struct JsonVariantAs {
typedef T type;
};
template <>
struct JsonVariantAs<char*> {
typedef const char* type;
};
template <>
struct JsonVariantAs<JsonArray> {
typedef JsonArray& type;
};
template <>
struct JsonVariantAs<const JsonArray> {
typedef const JsonArray& type;
};
template <>
struct JsonVariantAs<JsonObject> {
typedef JsonObject& type;
};
template <>
struct JsonVariantAs<const JsonObject> {
typedef const JsonObject& type;
};
}
}
@@ -0,0 +1,30 @@
// Copyright Benoit Blanchon 2014-2016
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// If you like this project, please add a star!
#pragma once
#include "JsonFloat.hpp"
#include "JsonInteger.hpp"
namespace ArduinoJson {
// Forward declarations
class JsonArray;
class JsonObject;
namespace Internals {
// A union that defines the actual content of a JsonVariant.
// The enum JsonVariantType determines which member is in use.
union JsonVariantContent {
JsonFloat asFloat; // used for double and float
JsonUInt asInteger; // used for bool, char, short, int and longs
const char* asString; // asString can be null
JsonArray* asArray; // asArray cannot be null
JsonObject* asObject; // asObject cannot be null
};
}
}

Some files were not shown because too many files have changed in this diff Show More