Browse Source

initial commit

Tobias Müller 4 months ago
parent
commit
ced9fb271d
49 changed files with 3930 additions and 0 deletions
  1. 5 0
      .gitignore
  2. 10 0
      .vscode/extensions.json
  3. 3 0
      .vscode/settings.json
  4. 39 0
      include/README
  5. 41 0
      include/Toaster.h
  6. 20 0
      lib/DS18B20/LICENSE.txt
  7. 51 0
      lib/DS18B20/README.md
  8. 32 0
      lib/DS18B20/examples/Alarms/Alarms.ino
  9. 58 0
      lib/DS18B20/examples/Multiple/Multiple.ino
  10. 33 0
      lib/DS18B20/examples/Single/Single.ino
  11. BIN
      lib/DS18B20/extras/mixed_mode.png
  12. BIN
      lib/DS18B20/extras/multiple_external.png
  13. BIN
      lib/DS18B20/extras/multiple_parasite.png
  14. BIN
      lib/DS18B20/extras/single_external.png
  15. BIN
      lib/DS18B20/extras/single_parasite.png
  16. 31 0
      lib/DS18B20/keywords.txt
  17. 10 0
      lib/DS18B20/library.properties
  18. 361 0
      lib/DS18B20/src/DS18B20.cpp
  19. 86 0
      lib/DS18B20/src/DS18B20.h
  20. 25 0
      lib/LiquidCrystal/README.adoc
  21. 78 0
      lib/LiquidCrystal/examples/Autoscroll/Autoscroll.ino
  22. 65 0
      lib/LiquidCrystal/examples/Blink/Blink.ino
  23. 65 0
      lib/LiquidCrystal/examples/Cursor/Cursor.ino
  24. 147 0
      lib/LiquidCrystal/examples/CustomCharacter/CustomCharacter.ino
  25. 65 0
      lib/LiquidCrystal/examples/Display/Display.ino
  26. 65 0
      lib/LiquidCrystal/examples/HelloWorld/HelloWorld.ino
  27. 90 0
      lib/LiquidCrystal/examples/Scroll/Scroll.ino
  28. 69 0
      lib/LiquidCrystal/examples/SerialDisplay/SerialDisplay.ino
  29. 90 0
      lib/LiquidCrystal/examples/TextDirection/TextDirection.ino
  30. 76 0
      lib/LiquidCrystal/examples/setCursor/setCursor.ino
  31. 38 0
      lib/LiquidCrystal/keywords.txt
  32. 9 0
      lib/LiquidCrystal/library.properties
  33. 326 0
      lib/LiquidCrystal/src/LiquidCrystal.cpp
  34. 108 0
      lib/LiquidCrystal/src/LiquidCrystal.h
  35. 580 0
      lib/OneWire/OneWire.cpp
  36. 182 0
      lib/OneWire/OneWire.h
  37. 64 0
      lib/OneWire/docs/issue_template.md
  38. 112 0
      lib/OneWire/examples/DS18x20_Temperature/DS18x20_Temperature.ino
  39. 74 0
      lib/OneWire/examples/DS2408_Switch/DS2408_Switch.ino
  40. 75 0
      lib/OneWire/examples/DS250x_PROM/DS250x_PROM.ino
  41. 38 0
      lib/OneWire/keywords.txt
  42. 61 0
      lib/OneWire/library.json
  43. 10 0
      lib/OneWire/library.properties
  44. 445 0
      lib/OneWire/util/OneWire_direct_gpio.h
  45. 55 0
      lib/OneWire/util/OneWire_direct_regtype.h
  46. 46 0
      lib/README
  47. 15 0
      platformio.ini
  48. 66 0
      src/Toaster.cpp
  49. 11 0
      test/README

+ 5 - 0
.gitignore

@@ -0,0 +1,5 @@
+.pio
+.vscode/.browse.c_cpp.db*
+.vscode/c_cpp_properties.json
+.vscode/launch.json
+.vscode/ipch

+ 10 - 0
.vscode/extensions.json

@@ -0,0 +1,10 @@
+{
+    // See http://go.microsoft.com/fwlink/?LinkId=827846
+    // for the documentation about the extensions.json format
+    "recommendations": [
+        "platformio.platformio-ide"
+    ],
+    "unwantedRecommendations": [
+        "ms-vscode.cpptools-extension-pack"
+    ]
+}

+ 3 - 0
.vscode/settings.json

@@ -0,0 +1,3 @@
+{
+    "cmake.configureOnOpen": true
+}

+ 39 - 0
include/README

@@ -0,0 +1,39 @@
+
+This directory is intended for project header files.
+
+A header file is a file containing C declarations and macro definitions
+to be shared between several project source files. You request the use of a
+header file in your project source file (C, C++, etc) located in `src` folder
+by including it, with the C preprocessing directive `#include'.
+
+```src/main.c
+
+#include "header.h"
+
+int main (void)
+{
+ ...
+}
+```
+
+Including a header file produces the same results as copying the header file
+into each source file that needs it. Such copying would be time-consuming
+and error-prone. With a header file, the related declarations appear
+in only one place. If they need to be changed, they can be changed in one
+place, and programs that include the header file will automatically use the
+new version when next recompiled. The header file eliminates the labor of
+finding and changing all the copies as well as the risk that a failure to
+find one copy will result in inconsistencies within a program.
+
+In C, the usual convention is to give header files names that end with `.h'.
+It is most portable to use only letters, digits, dashes, and underscores in
+header file names, and at most one dot.
+
+Read more about using header files in official GCC documentation:
+
+* Include Syntax
+* Include Operation
+* Once-Only Headers
+* Computed Includes
+
+https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html

+ 41 - 0
include/Toaster.h

@@ -0,0 +1,41 @@
+//////////                 Definiere Header                 //////////
+#ifndef TOASTER_H
+#define TOASTER_H
+
+//////////           Inkludierte Header-Dateien             //////////
+#include <Arduino.h>
+#include "DS18B20.h"
+#include "LiquidCrystal.h"
+
+//////////                Definierte Symbole                //////////
+#define MAGNET_PIN 11
+#define TEMPSENSOR_PIN 6
+#define HEATER_DUTYCYCLE_PIN A1
+#define HEATER_PIN 3
+#define LED_PIN 5
+#define STOP_PIN 2
+#define TIMER_PIN A0
+
+#define MAX_TIME 360000
+#define BAUDRATE 9600
+
+//////////               Definierte Funktionen              //////////
+
+/**
+ * @brief Function to print temperature, actual time and max time on LC-Display.
+ * 
+ * @param temp_in_c (float) temperature in degree celsius
+ * @param t_in_s (int) actual time since start.
+ * @param tmax_in_s (int) max time after program ends
+ */
+void lcd(float temp_in_c, int t_in_s, int tmax_in_s);
+
+/**
+ * @brief Get actual temperature.
+ * 
+ * @return (float) temperature in degree celsius
+ */
+float get_temp(void);
+
+//////////                  Header Ende                     //////////
+#endif

+ 20 - 0
lib/DS18B20/LICENSE.txt

@@ -0,0 +1,20 @@
+The MIT License (MIT)
+
+Copyright (c) 2013 Mathias Munk Hansen
+
+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.

+ 51 - 0
lib/DS18B20/README.md

@@ -0,0 +1,51 @@
+# DS18B20 #
+
+Arduino library for the Maxim Integrated DS18B20 1-Wire temperature sensor. This library is very simple and intuitive to use, and supports auto-discovering sensors with an optional high/low condition or manually addressing individual sensors.
+
+For example, we can get the temperature from every sensor on the wire with just a few lines of code:
+
+```
+#include <DS18B20.h>
+
+DS18B20 ds(2);
+
+void setup() {
+  Serial.begin(9600);
+}
+
+void loop() {
+  while (ds.selectNext()) {
+    Serial.println(ds.getTempC());
+  }
+}
+```
+
+See the included [examples](/examples/) for more.
+
+## Installation ##
+
+This library uses the OneWire library, so you will need to have this installed. Install it using the Library Manager in the Arduino IDE or download the latest release from [GitHub](https://github.com/PaulStoffregen/OneWire).
+
+In the **OneWire.h** file set `ONEWIRE_SEARCH` to 0 since the search functionality is also implemented in this library (don't do this if you need the search functionality for other 1-Wire devices). CRC must be enabled (choose whichever algorithm you prefer). This may save some space on your Arduino.
+
+## Wiring the DS18B20 ##
+The resistor shown in all the circuit diagrams is 4.7k Ohm pullup resistor.
+
+### External Power Mode ###
+
+#### Single ####
+![A single externally powered DS18B20](/extras/single_external.png)
+
+#### Multiple ####
+![Multiple externally powered DS18B20s](/extras/multiple_external.png)
+
+### Parasitic Power Mode ###
+
+#### Single ####
+![A single parasite powered DS18B20](/extras/single_parasite.png)
+
+#### Multiple ####
+![Multiple parasite powered DS18B20s](/extras/multiple_parasite.png)
+
+### Mixed Power Mode ###
+![Mixed mode DS18B20s](/extras/mixed_mode.png)

+ 32 - 0
lib/DS18B20/examples/Alarms/Alarms.ino

@@ -0,0 +1,32 @@
+#include <DS18B20.h>
+
+#define LOW_ALARM 20
+#define HIGH_ALARM 25
+
+DS18B20 ds(2);
+
+void setup() {
+  Serial.begin(9600);
+
+  while (ds.selectNext()) {
+    ds.setAlarms(LOW_ALARM, HIGH_ALARM);
+  }
+}
+
+void loop() {
+  ds.doConversion();
+
+  while (ds.selectNextAlarm()) {
+    Serial.print("Alarm Low: ");
+    Serial.print(ds.getAlarmLow());
+    Serial.println(" C");
+    Serial.print("Alarm High: ");
+    Serial.print(ds.getAlarmHigh());
+    Serial.println(" C");
+    Serial.print("Temperature: ");
+    Serial.print(ds.getTempC());
+    Serial.println(" C\n");
+  }
+
+  delay(10000);
+}

+ 58 - 0
lib/DS18B20/examples/Multiple/Multiple.ino

@@ -0,0 +1,58 @@
+#include <DS18B20.h>
+
+DS18B20 ds(2);
+
+void setup() {
+  Serial.begin(9600);
+  Serial.print("Devices: ");
+  Serial.println(ds.getNumberOfDevices());
+  Serial.println();
+}
+
+void loop() {
+  while (ds.selectNext()) {
+    switch (ds.getFamilyCode()) {
+      case MODEL_DS18S20:
+        Serial.println("Model: DS18S20/DS1820");
+        break;
+      case MODEL_DS1822:
+        Serial.println("Model: DS1822");
+        break;
+      case MODEL_DS18B20:
+        Serial.println("Model: DS18B20");
+        break;
+      default:
+        Serial.println("Unrecognized Device");
+        break;
+    }
+
+    uint8_t address[8];
+    ds.getAddress(address);
+
+    Serial.print("Address:");
+    for (uint8_t i = 0; i < 8; i++) {
+      Serial.print(" ");
+      Serial.print(address[i]);
+    }
+    Serial.println();
+
+    Serial.print("Resolution: ");
+    Serial.println(ds.getResolution());
+
+    Serial.print("Power Mode: ");
+    if (ds.getPowerMode()) {
+      Serial.println("External");
+    } else {
+      Serial.println("Parasite");
+    }
+
+    Serial.print("Temperature: ");
+    Serial.print(ds.getTempC());
+    Serial.print(" C / ");
+    Serial.print(ds.getTempF());
+    Serial.println(" F");
+    Serial.println();
+  }
+
+  delay(10000);
+}

+ 33 - 0
lib/DS18B20/examples/Single/Single.ino

@@ -0,0 +1,33 @@
+#include <DS18B20.h>
+
+#define LOW_ALARM 20
+#define HIGH_ALARM 25
+
+DS18B20 ds(2);
+uint8_t address[] = {40, 250, 31, 218, 4, 0, 0, 52};
+uint8_t selected;
+
+void setup() {
+  Serial.begin(9600);
+  selected = ds.select(address);
+
+  if (selected) {
+    ds.setAlarms(LOW_ALARM, HIGH_ALARM);
+  } else {
+    Serial.println("Device not found!");
+  }
+}
+
+void loop() {
+  if (selected) {
+    if (ds.hasAlarm()) {
+      Serial.print("Warning! Temperature is ");
+      Serial.print(ds.getTempC());
+      Serial.println(" C");
+    }
+  } else {
+    Serial.println("Device not found!");
+  }
+
+  delay(10000);
+}

BIN
lib/DS18B20/extras/mixed_mode.png


BIN
lib/DS18B20/extras/multiple_external.png


BIN
lib/DS18B20/extras/multiple_parasite.png


BIN
lib/DS18B20/extras/single_external.png


BIN
lib/DS18B20/extras/single_parasite.png


+ 31 - 0
lib/DS18B20/keywords.txt

@@ -0,0 +1,31 @@
+DS18B20	KEYWORD1
+
+select	KEYWORD2
+selectNext	KEYWORD2
+selectNextAlarm	KEYWORD2
+resetSearch	KEYWORD2
+getTempC	KEYWORD2
+getTempF	KEYWORD2
+getResolution	KEYWORD2
+setResolution	KEYWORD2
+getPowerMode	KEYWORD2
+getFamilyCode	KEYWORD2
+getAddress	KEYWORD2
+doConversion	KEYWORD2
+getNumberOfDevices	KEYWORD2
+hasAlarm	KEYWORD2
+setAlarms	KEYWORD2
+getAlarmLow	KEYWORD2
+setAlarmLow	KEYWORD2
+getAlarmHigh	KEYWORD2
+setAlarmHigh	KEYWORD2
+setRegisters	KEYWORD2
+getLowRegister	KEYWORD2
+setLowRegister	KEYWORD2
+getHighRegister	KEYWORD2
+setHighRegister	KEYWORD2
+
+MODEL_DS1820	LITERAL1
+MODEL_DS18S20	LITERAL1
+MODEL_DS1822	LITERAL1
+MODEL_DS18B20	LITERAL1

+ 10 - 0
lib/DS18B20/library.properties

@@ -0,0 +1,10 @@
+name=DS18B20
+version=1.0.0
+author=Mathias Munk Hansen
+maintainer=Mathias Munk Hansen <matmunk@gmail.com>
+sentence=Arduino library for the Maxim Integrated DS18B20 1-Wire temperature sensor.
+paragraph=This library is very simple and intuitive to use, and supports auto-discovering sensors with an optional high/low condition or manually addressing individual sensors.
+category=Sensors
+url=https://github.com/matmunk/DS18B20
+architectures=*
+includes=DS18B20.h

+ 361 - 0
lib/DS18B20/src/DS18B20.cpp

@@ -0,0 +1,361 @@
+#include <DS18B20.h>
+
+DS18B20::DS18B20(uint8_t pin) : oneWire(OneWire(pin)) {
+    resetSearch();
+    sendCommand(SKIP_ROM, READ_POWER_SUPPLY);
+    globalPowerMode = oneWire.read_bit();
+
+    while (selectNext()) {
+        uint8_t resolution = getResolution();
+
+        if (resolution > globalResolution) {
+            globalResolution = resolution;
+        }
+
+        numberOfDevices++;
+    }
+}
+
+uint8_t DS18B20::select(uint8_t address[]) {
+    if (isConnected(address)) {
+        memcpy(selectedAddress, address, 8);
+
+        if (readScratchpad()) {
+            selectedResolution = getResolution();
+
+            sendCommand(MATCH_ROM, READ_POWER_SUPPLY);
+            selectedPowerMode = oneWire.read_bit();
+
+            return 1;
+        }
+    }
+
+    return 0;
+}
+
+uint8_t DS18B20::selectNext() {
+    if (oneWireSearch(SEARCH_ROM)) {
+        return select(searchAddress);
+    }
+
+    return 0;
+}
+
+uint8_t DS18B20::selectNextAlarm() {
+    if (oneWireSearch(ALARM_SEARCH)) {
+        return select(searchAddress);
+    }
+
+    return 0;
+}
+
+void DS18B20::resetSearch() {
+    lastDiscrepancy = 0;
+    lastDevice = 0;
+}
+
+float DS18B20::getTempC() {
+    sendCommand(MATCH_ROM, CONVERT_T, !selectedPowerMode);
+    delayForConversion(selectedResolution, selectedPowerMode);
+    readScratchpad();
+    uint8_t lsb = selectedScratchpad[TEMP_LSB];
+    uint8_t msb = selectedScratchpad[TEMP_MSB];
+
+    switch (selectedResolution) {
+        case 9:
+            lsb &= 0xF8;
+            break;
+        case 10:
+            lsb &= 0xFC;
+            break;
+        case 11:
+            lsb &= 0xFE;
+            break;
+    }
+
+    uint8_t sign = msb & 0x80;
+    int16_t temp = (msb << 8) + lsb;
+
+    if (sign) {
+        temp = ((temp ^ 0xffff) + 1) * -1;
+    }
+
+    return temp / 16.0;
+}
+
+float DS18B20::getTempF() {
+    return getTempC() * 1.8 + 32;
+}
+
+uint8_t DS18B20::getResolution() {
+    switch (selectedScratchpad[CONFIGURATION]) {
+        case RES_9_BIT:
+            return 9;
+        case RES_10_BIT:
+            return 10;
+        case RES_11_BIT:
+            return 11;
+        case RES_12_BIT:
+            return 12;
+    }
+}
+
+void DS18B20::setResolution(uint8_t resolution) {
+    resolution = constrain(resolution, 9, 12);
+
+    switch (resolution) {
+        case 9:
+            selectedScratchpad[CONFIGURATION] = RES_9_BIT;
+            break;
+        case 10:
+            selectedScratchpad[CONFIGURATION] = RES_10_BIT;
+            break;
+        case 11:
+            selectedScratchpad[CONFIGURATION] = RES_11_BIT;
+            break;
+        case 12:
+            selectedScratchpad[CONFIGURATION] = RES_12_BIT;
+            break;
+    }
+
+    if (resolution > globalResolution) {
+        globalResolution = resolution;
+    }
+
+    writeScratchpad();
+}
+
+uint8_t DS18B20::getPowerMode() {
+    return selectedPowerMode;
+}
+
+uint8_t DS18B20::getFamilyCode() {
+    return selectedAddress[0];
+}
+
+void DS18B20::getAddress(uint8_t address[]) {
+    memcpy(address, selectedAddress, 8);
+}
+
+void DS18B20::doConversion() {
+    sendCommand(SKIP_ROM, CONVERT_T, !globalPowerMode);
+    delayForConversion(globalResolution, globalPowerMode);
+}
+
+uint8_t DS18B20::getNumberOfDevices() {
+    return numberOfDevices;
+}
+
+uint8_t DS18B20::hasAlarm() {
+    uint8_t oldResolution = selectedResolution;
+    setResolution(9);
+    float temp = getTempC();
+    setResolution(oldResolution);
+    return ((temp <= selectedScratchpad[ALARM_LOW]) || (temp >= selectedScratchpad[ALARM_HIGH]));
+}
+
+void DS18B20::setAlarms(int8_t alarmLow, int8_t alarmHigh) {
+    setAlarmLow(alarmLow);
+    setAlarmHigh(alarmHigh);
+    writeScratchpad();
+}
+
+int8_t DS18B20::getAlarmLow() {
+    return selectedScratchpad[ALARM_LOW];
+}
+
+void DS18B20::setAlarmLow(int8_t alarmLow) {
+    alarmLow = constrain(alarmLow, -55, 125);
+    selectedScratchpad[ALARM_LOW] = alarmLow;
+    writeScratchpad();
+}
+
+int8_t DS18B20::getAlarmHigh() {
+    return selectedScratchpad[ALARM_HIGH];
+}
+
+void DS18B20::setAlarmHigh(int8_t alarmHigh) {
+    alarmHigh = constrain(alarmHigh, -55, 125);
+    selectedScratchpad[ALARM_HIGH] = alarmHigh;
+    writeScratchpad();
+}
+
+void DS18B20::setRegisters(int8_t lowRegister, int8_t highRegister) {
+    setAlarms(lowRegister, highRegister);
+}
+
+int8_t DS18B20::getLowRegister() {
+    return getAlarmLow();
+}
+
+void DS18B20::setLowRegister(int8_t lowRegister) {
+    setAlarmLow(lowRegister);
+}
+
+int8_t DS18B20::getHighRegister() {
+    return getAlarmHigh();
+}
+
+void DS18B20::setHighRegister(int8_t highRegister) {
+    setAlarmHigh(highRegister);
+}
+
+uint8_t DS18B20::readScratchpad() {
+    sendCommand(MATCH_ROM, READ_SCRATCHPAD);
+
+    for (uint8_t i = 0; i < SIZE_SCRATCHPAD; i++) {
+        selectedScratchpad[i] = oneWire.read();
+    }
+
+    return OneWire::crc8(selectedScratchpad, 8) == selectedScratchpad[CRC8];
+}
+
+void DS18B20::writeScratchpad() {
+    sendCommand(MATCH_ROM, WRITE_SCRATCHPAD);
+    oneWire.write(selectedScratchpad[ALARM_HIGH]);
+    oneWire.write(selectedScratchpad[ALARM_LOW]);
+    oneWire.write(selectedScratchpad[CONFIGURATION]);
+    sendCommand(MATCH_ROM, COPY_SCRATCHPAD, !selectedPowerMode);
+
+    if (!selectedPowerMode) {
+        delay(10);
+    }
+}
+
+uint8_t DS18B20::sendCommand(uint8_t romCommand) {
+    if (!oneWire.reset()) {
+        return 0;
+    }
+
+    switch (romCommand) {
+        case SEARCH_ROM:
+        case SKIP_ROM:
+        case ALARM_SEARCH:
+            oneWire.write(romCommand);
+            break;
+        case MATCH_ROM:
+            oneWire.select(selectedAddress);
+            break;
+        default:
+            return 0;
+    }
+
+    return 1;
+}
+
+uint8_t DS18B20::sendCommand(uint8_t romCommand, uint8_t functionCommand, uint8_t power) {
+    if (!sendCommand(romCommand)) {
+        return 0;
+    }
+
+    switch (functionCommand) {
+        case CONVERT_T:
+        case COPY_SCRATCHPAD:
+            oneWire.write(functionCommand, power);
+            break;
+        case WRITE_SCRATCHPAD:
+        case READ_SCRATCHPAD:
+        case READ_POWER_SUPPLY:
+            oneWire.write(functionCommand);
+            break;
+        default:
+            return 0;
+    }
+
+    return 1;
+}
+
+uint8_t DS18B20::oneWireSearch(uint8_t romCommand) {
+    if (lastDevice || !sendCommand(romCommand)) {
+        resetSearch();
+        return 0;
+    }
+
+    uint8_t lastZero = 0;
+    uint8_t direction, byteNumber, bitNumber, currentBit, currentBitComp;
+
+    for (uint8_t bitPosition = 0; bitPosition < 64; bitPosition++) {
+        currentBit = oneWire.read_bit();
+        currentBitComp = oneWire.read_bit();
+
+        if (currentBit && currentBitComp) {
+            lastDiscrepancy = 0;
+            return 0;
+        }
+
+        byteNumber = bitPosition / 8;
+        bitNumber = bitPosition % 8;
+
+        if (!currentBit && !currentBitComp) {
+            if (bitPosition == lastDiscrepancy) {
+                direction = 1;
+            } else if (bitPosition > lastDiscrepancy) {
+                direction = 0;
+                lastZero = bitPosition;
+            } else {
+                direction = bitRead(searchAddress[byteNumber], bitNumber);
+
+                if (!direction) {
+                    lastZero = bitPosition;
+                }
+            }
+        } else {
+            direction = currentBit;
+        }
+
+        bitWrite(searchAddress[byteNumber], bitNumber, direction);
+        oneWire.write_bit(direction);
+    }
+
+    lastDiscrepancy = lastZero;
+
+    if (!lastDiscrepancy) {
+        lastDevice = 1;
+    }
+
+    return 1;
+}
+
+uint8_t DS18B20::isConnected(uint8_t address[]) {
+    if (!sendCommand(SEARCH_ROM)) {
+        return 0;
+    }
+
+    uint8_t currentBit, currentBitComp, byteNumber, bitNumber;
+
+    for (uint8_t bitPosition = 0; bitPosition < 64; bitPosition++) {
+        currentBit = oneWire.read_bit();
+        currentBitComp = oneWire.read_bit();
+
+        if (currentBit && currentBitComp) {
+            return 0;
+        }
+
+        byteNumber = bitPosition / 8;
+        bitNumber = bitPosition % 8;
+        oneWire.write_bit(bitRead(address[byteNumber], bitNumber));
+    }
+
+    return 1;
+}
+
+void DS18B20::delayForConversion(uint8_t resolution, uint8_t powerMode) {
+    if (powerMode) {
+        while (!oneWire.read_bit());
+    } else {
+        switch (resolution) {
+            case 9:
+                delay(CONV_TIME_9_BIT);
+                break;
+            case 10:
+                delay(CONV_TIME_10_BIT);
+                break;
+            case 11:
+                delay(CONV_TIME_11_BIT);
+                break;
+            case 12:
+                delay(CONV_TIME_12_BIT);
+                break;
+        }
+    }
+}

+ 86 - 0
lib/DS18B20/src/DS18B20.h

@@ -0,0 +1,86 @@
+#ifndef DS18B20_H
+#define DS18B20_H
+
+#include "Arduino.h"
+#include <OneWire.h>
+
+#define SEARCH_ROM 0xF0
+#define READ_ROM 0x33
+#define MATCH_ROM 0x55
+#define SKIP_ROM 0xCC
+#define ALARM_SEARCH 0xEC
+#define CONVERT_T 0x44
+#define WRITE_SCRATCHPAD 0x4E
+#define READ_SCRATCHPAD 0xBE
+#define COPY_SCRATCHPAD 0x48
+#define RECALL 0xB8
+#define READ_POWER_SUPPLY 0xB4
+#define MODEL_DS1820 0x10
+#define MODEL_DS18S20 0x10
+#define MODEL_DS1822 0x22
+#define MODEL_DS18B20 0x28
+#define SIZE_SCRATCHPAD 9
+#define TEMP_LSB 0
+#define TEMP_MSB 1
+#define ALARM_HIGH 2
+#define ALARM_LOW 3
+#define CONFIGURATION 4
+#define CRC8 8
+#define RES_9_BIT 0x1F
+#define RES_10_BIT 0x3F
+#define RES_11_BIT 0x5F
+#define RES_12_BIT 0x7F
+#define CONV_TIME_9_BIT 94
+#define CONV_TIME_10_BIT 188
+#define CONV_TIME_11_BIT 375
+#define CONV_TIME_12_BIT 750
+
+class DS18B20 {
+    public:
+        DS18B20(uint8_t pin);
+        uint8_t select(uint8_t address[]);
+        uint8_t selectNext();
+        uint8_t selectNextAlarm();
+        void resetSearch();
+        float getTempC();
+        float getTempF();
+        uint8_t getResolution();
+        void setResolution(uint8_t resolution);
+        uint8_t getPowerMode();
+        uint8_t getFamilyCode();
+        void getAddress(uint8_t address[]);
+        void doConversion();
+        uint8_t getNumberOfDevices();
+        uint8_t hasAlarm();
+        void setAlarms(int8_t alarmLow, int8_t alarmHigh);
+        int8_t getAlarmLow();
+        void setAlarmLow(int8_t alarmLow);
+        int8_t getAlarmHigh();
+        void setAlarmHigh(int8_t alarmHigh);
+        void setRegisters(int8_t lowRegister, int8_t highRegister);
+        int8_t getLowRegister();
+        void setLowRegister(int8_t lowRegister);
+        int8_t getHighRegister();
+        void setHighRegister(int8_t highRegister);
+    private:
+        OneWire oneWire;
+        uint8_t globalResolution;
+        uint8_t globalPowerMode;
+        uint8_t numberOfDevices;
+        uint8_t selectedAddress[8];
+        uint8_t selectedScratchpad[SIZE_SCRATCHPAD];
+        uint8_t selectedResolution;
+        uint8_t selectedPowerMode;
+        uint8_t searchAddress[8];
+        uint8_t lastDiscrepancy;
+        uint8_t lastDevice;
+        uint8_t readScratchpad();
+        void writeScratchpad();
+        uint8_t sendCommand(uint8_t romCommand);
+        uint8_t sendCommand(uint8_t romCommand, uint8_t functionCommand, uint8_t power = 0);
+        uint8_t oneWireSearch(uint8_t romCommand);
+        uint8_t isConnected(uint8_t address[]);
+        void delayForConversion(uint8_t resolution, uint8_t powerMode);
+};
+
+#endif

+ 25 - 0
lib/LiquidCrystal/README.adoc

@@ -0,0 +1,25 @@
+= Liquid Crystal Library for Arduino =
+
+This library allows an Arduino board to control LiquidCrystal displays (LCDs) based on the Hitachi HD44780 (or a compatible) chipset, which is found on most text-based LCDs.
+
+For more information about this library please visit us at
+http://www.arduino.cc/en/Reference/LiquidCrystal
+
+== License ==
+
+Copyright (C) 2006-2008 Hans-Christoph Steiner. All rights reserved.
+Copyright (c) 2010 Arduino LLC. 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

+ 78 - 0
lib/LiquidCrystal/examples/Autoscroll/Autoscroll.ino

@@ -0,0 +1,78 @@
+/*
+  LiquidCrystal Library - Autoscroll
+
+ Demonstrates the use a 16x2 LCD display.  The LiquidCrystal
+ library works with all LCD displays that are compatible with the
+ Hitachi HD44780 driver. There are many of them out there, and you
+ can usually tell them by the 16-pin interface.
+
+ This sketch demonstrates the use of the autoscroll()
+ and noAutoscroll() functions to make new text scroll or not.
+
+ The circuit:
+ * LCD RS pin to digital pin 12
+ * LCD Enable pin to digital pin 11
+ * LCD D4 pin to digital pin 5
+ * LCD D5 pin to digital pin 4
+ * LCD D6 pin to digital pin 3
+ * LCD D7 pin to digital pin 2
+ * LCD R/W pin to ground
+ * 10K resistor:
+ * ends to +5V and ground
+ * wiper to LCD VO pin (pin 3)
+
+ Library originally added 18 Apr 2008
+ by David A. Mellis
+ library modified 5 Jul 2009
+ by Limor Fried (http://www.ladyada.net)
+ example added 9 Jul 2009
+ by Tom Igoe
+ modified 22 Nov 2010
+ by Tom Igoe
+ modified 7 Nov 2016
+ by Arturo Guadalupi
+
+ This example code is in the public domain.
+
+ http://www.arduino.cc/en/Tutorial/LiquidCrystalAutoscroll
+
+*/
+
+// include the library code:
+#include <LiquidCrystal.h>
+
+// initialize the library by associating any needed LCD interface pin
+// with the arduino pin number it is connected to
+const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 3, d7 = 2;
+LiquidCrystal lcd(rs, en, d4, d5, d6, d7);
+
+void setup() {
+  // set up the LCD's number of columns and rows:
+  lcd.begin(16, 2);
+}
+
+void loop() {
+  // set the cursor to (0,0):
+  lcd.setCursor(0, 0);
+  // print from 0 to 9:
+  for (int thisChar = 0; thisChar < 10; thisChar++) {
+    lcd.print(thisChar);
+    delay(500);
+  }
+
+  // set the cursor to (16,1):
+  lcd.setCursor(16, 1);
+  // set the display to automatically scroll:
+  lcd.autoscroll();
+  // print from 0 to 9:
+  for (int thisChar = 0; thisChar < 10; thisChar++) {
+    lcd.print(thisChar);
+    delay(500);
+  }
+  // turn off automatic scrolling
+  lcd.noAutoscroll();
+
+  // clear screen for the next loop:
+  lcd.clear();
+}
+

+ 65 - 0
lib/LiquidCrystal/examples/Blink/Blink.ino

@@ -0,0 +1,65 @@
+/*
+  LiquidCrystal Library - Blink
+
+ Demonstrates the use a 16x2 LCD display.  The LiquidCrystal
+ library works with all LCD displays that are compatible with the
+ Hitachi HD44780 driver. There are many of them out there, and you
+ can usually tell them by the 16-pin interface.
+
+ This sketch prints "Hello World!" to the LCD and makes the
+ cursor block blink.
+
+ The circuit:
+ * LCD RS pin to digital pin 12
+ * LCD Enable pin to digital pin 11
+ * LCD D4 pin to digital pin 5
+ * LCD D5 pin to digital pin 4
+ * LCD D6 pin to digital pin 3
+ * LCD D7 pin to digital pin 2
+ * LCD R/W pin to ground
+ * 10K resistor:
+   * ends to +5V and ground
+   * wiper to LCD VO pin (pin 3)
+
+ Library originally added 18 Apr 2008
+ by David A. Mellis
+ library modified 5 Jul 2009
+ by Limor Fried (http://www.ladyada.net)
+ example added 9 Jul 2009
+ by Tom Igoe
+ modified 22 Nov 2010
+ by Tom Igoe
+ modified 7 Nov 2016
+ by Arturo Guadalupi
+
+ This example code is in the public domain.
+
+ http://www.arduino.cc/en/Tutorial/LiquidCrystalBlink
+
+*/
+
+// include the library code:
+#include <LiquidCrystal.h>
+
+// initialize the library by associating any needed LCD interface pin
+// with the arduino pin number it is connected to
+const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 3, d7 = 2;
+LiquidCrystal lcd(rs, en, d4, d5, d6, d7);
+
+void setup() {
+  // set up the LCD's number of columns and rows:
+  lcd.begin(16, 2);
+  // Print a message to the LCD.
+  lcd.print("hello, world!");
+}
+
+void loop() {
+  // Turn off the blinking cursor:
+  lcd.noBlink();
+  delay(3000);
+  // Turn on the blinking cursor:
+  lcd.blink();
+  delay(3000);
+}
+
+

+ 65 - 0
lib/LiquidCrystal/examples/Cursor/Cursor.ino

@@ -0,0 +1,65 @@
+/*
+  LiquidCrystal Library - Cursor
+
+ Demonstrates the use a 16x2 LCD display.  The LiquidCrystal
+ library works with all LCD displays that are compatible with the
+ Hitachi HD44780 driver. There are many of them out there, and you
+ can usually tell them by the 16-pin interface.
+
+ This sketch prints "Hello World!" to the LCD and
+ uses the cursor()  and noCursor() methods to turn
+ on and off the cursor.
+
+ The circuit:
+ * LCD RS pin to digital pin 12
+ * LCD Enable pin to digital pin 11
+ * LCD D4 pin to digital pin 5
+ * LCD D5 pin to digital pin 4
+ * LCD D6 pin to digital pin 3
+ * LCD D7 pin to digital pin 2
+ * LCD R/W pin to ground
+ * 10K resistor:
+ * ends to +5V and ground
+ * wiper to LCD VO pin (pin 3)
+
+ Library originally added 18 Apr 2008
+ by David A. Mellis
+ library modified 5 Jul 2009
+ by Limor Fried (http://www.ladyada.net)
+ example added 9 Jul 2009
+ by Tom Igoe
+ modified 22 Nov 2010
+ by Tom Igoe
+ modified 7 Nov 2016
+ by Arturo Guadalupi
+
+ This example code is in the public domain.
+
+ http://www.arduino.cc/en/Tutorial/LiquidCrystalCursor
+
+*/
+
+// include the library code:
+#include <LiquidCrystal.h>
+
+// initialize the library by associating any needed LCD interface pin
+// with the arduino pin number it is connected to
+const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 3, d7 = 2;
+LiquidCrystal lcd(rs, en, d4, d5, d6, d7);
+
+void setup() {
+  // set up the LCD's number of columns and rows:
+  lcd.begin(16, 2);
+  // Print a message to the LCD.
+  lcd.print("hello, world!");
+}
+
+void loop() {
+  // Turn off the cursor:
+  lcd.noCursor();
+  delay(500);
+  // Turn on the cursor:
+  lcd.cursor();
+  delay(500);
+}
+

+ 147 - 0
lib/LiquidCrystal/examples/CustomCharacter/CustomCharacter.ino

@@ -0,0 +1,147 @@
+/*
+  LiquidCrystal Library - Custom Characters
+
+ Demonstrates how to add custom characters on an LCD  display.
+ The LiquidCrystal library works with all LCD displays that are
+ compatible with the  Hitachi HD44780 driver. There are many of
+ them out there, and you can usually tell them by the 16-pin interface.
+
+ This sketch prints "I <heart> Arduino!" and a little dancing man
+ to the LCD.
+
+  The circuit:
+ * LCD RS pin to digital pin 12
+ * LCD Enable pin to digital pin 11
+ * LCD D4 pin to digital pin 5
+ * LCD D5 pin to digital pin 4
+ * LCD D6 pin to digital pin 3
+ * LCD D7 pin to digital pin 2
+ * LCD R/W pin to ground
+ * 10K potentiometer:
+ * ends to +5V and ground
+ * wiper to LCD VO pin (pin 3)
+ * 10K poterntiometer on pin A0
+
+ created 21 Mar 2011
+ by Tom Igoe
+ modified 11 Nov 2013
+ by Scott Fitzgerald
+ modified 7 Nov 2016
+ by Arturo Guadalupi
+
+ Based on Adafruit's example at
+ https://github.com/adafruit/SPI_VFD/blob/master/examples/createChar/createChar.pde
+
+ This example code is in the public domain.
+ http://www.arduino.cc/en/Tutorial/LiquidCrystalCustomCharacter
+
+ Also useful:
+ http://icontexto.com/charactercreator/
+
+*/
+
+// include the library code:
+#include <LiquidCrystal.h>
+
+// initialize the library by associating any needed LCD interface pin
+// with the arduino pin number it is connected to
+const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 3, d7 = 2;
+LiquidCrystal lcd(rs, en, d4, d5, d6, d7);
+
+// make some custom characters:
+byte heart[8] = {
+  0b00000,
+  0b01010,
+  0b11111,
+  0b11111,
+  0b11111,
+  0b01110,
+  0b00100,
+  0b00000
+};
+
+byte smiley[8] = {
+  0b00000,
+  0b00000,
+  0b01010,
+  0b00000,
+  0b00000,
+  0b10001,
+  0b01110,
+  0b00000
+};
+
+byte frownie[8] = {
+  0b00000,
+  0b00000,
+  0b01010,
+  0b00000,
+  0b00000,
+  0b00000,
+  0b01110,
+  0b10001
+};
+
+byte armsDown[8] = {
+  0b00100,
+  0b01010,
+  0b00100,
+  0b00100,
+  0b01110,
+  0b10101,
+  0b00100,
+  0b01010
+};
+
+byte armsUp[8] = {
+  0b00100,
+  0b01010,
+  0b00100,
+  0b10101,
+  0b01110,
+  0b00100,
+  0b00100,
+  0b01010
+};
+
+void setup() {
+  // initialize LCD and set up the number of columns and rows:
+  lcd.begin(16, 2);
+
+  // create a new character
+  lcd.createChar(0, heart);
+  // create a new character
+  lcd.createChar(1, smiley);
+  // create a new character
+  lcd.createChar(2, frownie);
+  // create a new character
+  lcd.createChar(3, armsDown);
+  // create a new character
+  lcd.createChar(4, armsUp);
+
+  // set the cursor to the top left
+  lcd.setCursor(0, 0);
+
+  // Print a message to the lcd.
+  lcd.print("I ");
+  lcd.write(byte(0)); // when calling lcd.write() '0' must be cast as a byte
+  lcd.print(" Arduino! ");
+  lcd.write((byte)1);
+
+}
+
+void loop() {
+  // read the potentiometer on A0:
+  int sensorReading = analogRead(A0);
+  // map the result to 200 - 1000:
+  int delayTime = map(sensorReading, 0, 1023, 200, 1000);
+  // set the cursor to the bottom row, 5th position:
+  lcd.setCursor(4, 1);
+  // draw the little man, arms down:
+  lcd.write(3);
+  delay(delayTime);
+  lcd.setCursor(4, 1);
+  // draw him arms up:
+  lcd.write(4);
+  delay(delayTime);
+}

+ 65 - 0
lib/LiquidCrystal/examples/Display/Display.ino

@@ -0,0 +1,65 @@
+/*
+  LiquidCrystal Library - display() and noDisplay()
+
+ Demonstrates the use a 16x2 LCD display.  The LiquidCrystal
+ library works with all LCD displays that are compatible with the
+ Hitachi HD44780 driver. There are many of them out there, and you
+ can usually tell them by the 16-pin interface.
+
+ This sketch prints "Hello World!" to the LCD and uses the
+ display() and noDisplay() functions to turn on and off
+ the display.
+
+ The circuit:
+ * LCD RS pin to digital pin 12
+ * LCD Enable pin to digital pin 11
+ * LCD D4 pin to digital pin 5
+ * LCD D5 pin to digital pin 4
+ * LCD D6 pin to digital pin 3
+ * LCD D7 pin to digital pin 2
+ * LCD R/W pin to ground
+ * 10K resistor:
+ * ends to +5V and ground
+ * wiper to LCD VO pin (pin 3)
+
+ Library originally added 18 Apr 2008
+ by David A. Mellis
+ library modified 5 Jul 2009
+ by Limor Fried (http://www.ladyada.net)
+ example added 9 Jul 2009
+ by Tom Igoe
+ modified 22 Nov 2010
+ by Tom Igoe
+ modified 7 Nov 2016
+ by Arturo Guadalupi
+
+ This example code is in the public domain.
+
+ http://www.arduino.cc/en/Tutorial/LiquidCrystalDisplay
+
+*/
+
+// include the library code:
+#include <LiquidCrystal.h>
+
+// initialize the library by associating any needed LCD interface pin
+// with the arduino pin number it is connected to
+const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 3, d7 = 2;
+LiquidCrystal lcd(rs, en, d4, d5, d6, d7);
+
+void setup() {
+  // set up the LCD's number of columns and rows:
+  lcd.begin(16, 2);
+  // Print a message to the LCD.
+  lcd.print("hello, world!");
+}
+
+void loop() {
+  // Turn off the display:
+  lcd.noDisplay();
+  delay(500);
+  // Turn on the display:
+  lcd.display();
+  delay(500);
+}
+

+ 65 - 0
lib/LiquidCrystal/examples/HelloWorld/HelloWorld.ino

@@ -0,0 +1,65 @@
+/*
+  LiquidCrystal Library - Hello World
+
+ Demonstrates the use a 16x2 LCD display.  The LiquidCrystal
+ library works with all LCD displays that are compatible with the
+ Hitachi HD44780 driver. There are many of them out there, and you
+ can usually tell them by the 16-pin interface.
+
+ This sketch prints "Hello World!" to the LCD
+ and shows the time.
+
+  The circuit:
+ * LCD RS pin to digital pin 12
+ * LCD Enable pin to digital pin 11
+ * LCD D4 pin to digital pin 5
+ * LCD D5 pin to digital pin 4
+ * LCD D6 pin to digital pin 3
+ * LCD D7 pin to digital pin 2
+ * LCD R/W pin to ground
+ * LCD VSS pin to ground
+ * LCD VCC pin to 5V
+ * 10K resistor:
+ * ends to +5V and ground
+ * wiper to LCD VO pin (pin 3)
+
+ Library originally added 18 Apr 2008
+ by David A. Mellis
+ library modified 5 Jul 2009
+ by Limor Fried (http://www.ladyada.net)
+ example added 9 Jul 2009
+ by Tom Igoe
+ modified 22 Nov 2010
+ by Tom Igoe
+ modified 7 Nov 2016
+ by Arturo Guadalupi
+
+ This example code is in the public domain.
+
+ http://www.arduino.cc/en/Tutorial/LiquidCrystalHelloWorld
+
+*/
+
+// include the library code:
+#include <LiquidCrystal.h>
+
+// initialize the library by associating any needed LCD interface pin
+// with the arduino pin number it is connected to
+const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 3, d7 = 2;
+LiquidCrystal lcd(rs, en, d4, d5, d6, d7);
+
+void setup() {
+  // set up the LCD's number of columns and rows:
+  lcd.begin(16, 2);
+  // Print a message to the LCD.
+  lcd.print("hello, world!");
+}
+
+void loop() {
+  // set the cursor to column 0, line 1
+  // (note: line 1 is the second row, since counting begins with 0):
+  lcd.setCursor(0, 1);
+  // print the number of seconds since reset:
+  lcd.print(millis() / 1000);
+}
+

+ 90 - 0
lib/LiquidCrystal/examples/Scroll/Scroll.ino

@@ -0,0 +1,90 @@
+/*
+  LiquidCrystal Library - scrollDisplayLeft() and scrollDisplayRight()
+
+ Demonstrates the use a 16x2 LCD display.  The LiquidCrystal
+ library works with all LCD displays that are compatible with the
+ Hitachi HD44780 driver. There are many of them out there, and you
+ can usually tell them by the 16-pin interface.
+
+ This sketch prints "Hello World!" to the LCD and uses the
+ scrollDisplayLeft() and scrollDisplayRight() methods to scroll
+ the text.
+
+  The circuit:
+ * LCD RS pin to digital pin 12
+ * LCD Enable pin to digital pin 11
+ * LCD D4 pin to digital pin 5
+ * LCD D5 pin to digital pin 4
+ * LCD D6 pin to digital pin 3
+ * LCD D7 pin to digital pin 2
+ * LCD R/W pin to ground
+ * 10K resistor:
+ * ends to +5V and ground
+ * wiper to LCD VO pin (pin 3)
+
+ Library originally added 18 Apr 2008
+ by David A. Mellis
+ library modified 5 Jul 2009
+ by Limor Fried (http://www.ladyada.net)
+ example added 9 Jul 2009
+ by Tom Igoe
+ modified 22 Nov 2010
+ by Tom Igoe
+ modified 7 Nov 2016
+ by Arturo Guadalupi
+
+ This example code is in the public domain.
+
+ http://www.arduino.cc/en/Tutorial/LiquidCrystalScroll
+
+*/
+
+// include the library code:
+#include <LiquidCrystal.h>
+
+// initialize the library by associating any needed LCD interface pin
+// with the arduino pin number it is connected to
+const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 3, d7 = 2;
+LiquidCrystal lcd(rs, en, d4, d5, d6, d7);
+
+void setup() {
+  // set up the LCD's number of columns and rows:
+  lcd.begin(16, 2);
+  // Print a message to the LCD.
+  lcd.print("hello, world!");
+  delay(1000);
+}
+
+void loop() {
+  // scroll 13 positions (string length) to the left
+  // to move it offscreen left:
+  for (int positionCounter = 0; positionCounter < 13; positionCounter++) {
+    // scroll one position left:
+    lcd.scrollDisplayLeft();
+    // wait a bit:
+    delay(150);
+  }
+
+  // scroll 29 positions (string length + display length) to the right
+  // to move it offscreen right:
+  for (int positionCounter = 0; positionCounter < 29; positionCounter++) {
+    // scroll one position right:
+    lcd.scrollDisplayRight();
+    // wait a bit:
+    delay(150);
+  }
+
+  // scroll 16 positions (display length + string length) to the left
+  // to move it back to center:
+  for (int positionCounter = 0; positionCounter < 16; positionCounter++) {
+    // scroll one position left:
+    lcd.scrollDisplayLeft();
+    // wait a bit:
+    delay(150);
+  }
+
+  // delay at the end of the full loop:
+  delay(1000);
+
+}
+

+ 69 - 0
lib/LiquidCrystal/examples/SerialDisplay/SerialDisplay.ino

@@ -0,0 +1,69 @@
+/*
+  LiquidCrystal Library - Serial Input
+
+ Demonstrates the use a 16x2 LCD display.  The LiquidCrystal
+ library works with all LCD displays that are compatible with the
+ Hitachi HD44780 driver. There are many of them out there, and you
+ can usually tell them by the 16-pin interface.
+
+ This sketch displays text sent over the serial port
+ (e.g. from the Serial Monitor) on an attached LCD.
+
+ The circuit:
+ * LCD RS pin to digital pin 12
+ * LCD Enable pin to digital pin 11
+ * LCD D4 pin to digital pin 5
+ * LCD D5 pin to digital pin 4
+ * LCD D6 pin to digital pin 3
+ * LCD D7 pin to digital pin 2
+ * LCD R/W pin to ground
+ * 10K resistor:
+ * ends to +5V and ground
+ * wiper to LCD VO pin (pin 3)
+
+ Library originally added 18 Apr 2008
+ by David A. Mellis
+ library modified 5 Jul 2009
+ by Limor Fried (http://www.ladyada.net)
+ example added 9 Jul 2009
+ by Tom Igoe
+ modified 22 Nov 2010
+ by Tom Igoe
+ modified 7 Nov 2016
+ by Arturo Guadalupi
+
+ This example code is in the public domain.
+
+ http://www.arduino.cc/en/Tutorial/LiquidCrystalSerialDisplay
+
+*/
+
+// include the library code:
+#include <LiquidCrystal.h>
+
+// initialize the library by associating any needed LCD interface pin
+// with the arduino pin number it is connected to
+const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 3, d7 = 2;
+LiquidCrystal lcd(rs, en, d4, d5, d6, d7);
+
+void setup() {
+  // set up the LCD's number of columns and rows:
+  lcd.begin(16, 2);
+  // initialize the serial communications:
+  Serial.begin(9600);
+}
+
+void loop() {
+  // when characters arrive over the serial port...
+  if (Serial.available()) {
+    // wait a bit for the entire message to arrive
+    delay(100);
+    // clear the screen
+    lcd.clear();
+    // read all the available characters
+    while (Serial.available() > 0) {
+      // display each character to the LCD
+      lcd.write(Serial.read());
+    }
+  }
+}

+ 90 - 0
lib/LiquidCrystal/examples/TextDirection/TextDirection.ino

@@ -0,0 +1,90 @@
+/*
+ LiquidCrystal Library - TextDirection
+
+ Demonstrates the use a 16x2 LCD display.  The LiquidCrystal
+ library works with all LCD displays that are compatible with the
+ Hitachi HD44780 driver. There are many of them out there, and you
+ can usually tell them by the 16-pin interface.
+
+ This sketch demonstrates how to use leftToRight() and rightToLeft()
+ to move the cursor.
+
+ The circuit:
+  * LCD RS pin to digital pin 12
+  * LCD Enable pin to digital pin 11
+  * LCD D4 pin to digital pin 5
+  * LCD D5 pin to digital pin 4
+  * LCD D6 pin to digital pin 3
+  * LCD D7 pin to digital pin 2
+  * LCD R/W pin to ground
+  * 10K resistor:
+  * ends to +5V and ground
+  * wiper to LCD VO pin (pin 3)
+
+ Library originally added 18 Apr 2008
+ by David A. Mellis
+ library modified 5 Jul 2009
+ by Limor Fried (http://www.ladyada.net)
+ example added 9 Jul 2009
+ by Tom Igoe
+ modified 22 Nov 2010
+ by Tom Igoe
+ modified 7 Nov 2016
+ by Arturo Guadalupi
+
+ This example code is in the public domain.
+
+ http://www.arduino.cc/en/Tutorial/LiquidCrystalTextDirection
+
+*/
+
+// include the library code:
+#include <LiquidCrystal.h>
+
+// initialize the library by associating any needed LCD interface pin
+// with the arduino pin number it is connected to
+const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 3, d7 = 2;
+LiquidCrystal lcd(rs, en, d4, d5, d6, d7);
+
+int thisChar = 'a';
+
+void setup() {
+  // set up the LCD's number of columns and rows:
+  lcd.begin(16, 2);
+  // turn on the cursor:
+  lcd.cursor();
+}
+
+void loop() {
+  // reverse directions at 'm':
+  if (thisChar == 'm') {
+    // go right for the next letter
+    lcd.rightToLeft();
+  }
+  // reverse again at 's':
+  if (thisChar == 's') {
+    // go left for the next letter
+    lcd.leftToRight();
+  }
+  // reset at 'z':
+  if (thisChar > 'z') {
+    // go to (0,0):
+    lcd.home();
+    // start again at 0
+    thisChar = 'a';
+  }
+  // print the character
+  lcd.write(thisChar);
+  // wait a second:
+  delay(1000);
+  // increment the letter:
+  thisChar++;
+}
+
+
+
+
+
+
+
+

+ 76 - 0
lib/LiquidCrystal/examples/setCursor/setCursor.ino

@@ -0,0 +1,76 @@
+/*
+  LiquidCrystal Library - setCursor
+
+ Demonstrates the use a 16x2 LCD display.  The LiquidCrystal
+ library works with all LCD displays that are compatible with the
+ Hitachi HD44780 driver. There are many of them out there, and you
+ can usually tell them by the 16-pin interface.
+
+ This sketch prints to all the positions of the LCD using the
+ setCursor() method:
+
+  The circuit:
+ * LCD RS pin to digital pin 12
+ * LCD Enable pin to digital pin 11
+ * LCD D4 pin to digital pin 5
+ * LCD D5 pin to digital pin 4
+ * LCD D6 pin to digital pin 3
+ * LCD D7 pin to digital pin 2
+ * LCD R/W pin to ground
+ * 10K resistor:
+ * ends to +5V and ground
+ * wiper to LCD VO pin (pin 3)
+
+ Library originally added 18 Apr 2008
+ by David A. Mellis
+ library modified 5 Jul 2009
+ by Limor Fried (http://www.ladyada.net)
+ example added 9 Jul 2009
+ by Tom Igoe
+ modified 22 Nov 2010
+ by Tom Igoe
+ modified 7 Nov 2016
+ by Arturo Guadalupi
+
+ This example code is in the public domain.
+
+ http://www.arduino.cc/en/Tutorial/LiquidCrystalSetCursor
+
+*/
+
+// include the library code:
+#include <LiquidCrystal.h>
+
+// initialize the library by associating any needed LCD interface pin
+// with the arduino pin number it is connected to
+const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 3, d7 = 2;
+LiquidCrystal lcd(rs, en, d4, d5, d6, d7);
+
+// these constants won't change.  But you can change the size of
+// your LCD using them:
+const int numRows = 2;
+const int numCols = 16;
+
+void setup() {
+  // set up the LCD's number of columns and rows:
+  lcd.begin(numCols, numRows);
+}
+
+void loop() {
+  // loop from ASCII 'a' to ASCII 'z':
+  for (int thisLetter = 'a'; thisLetter <= 'z'; thisLetter++) {
+    // loop over the columns:
+    for (int  thisRow = 0; thisRow < numRows; thisRow++) {
+      // loop over the rows:
+      for (int thisCol = 0; thisCol < numCols; thisCol++) {
+        // set the cursor position:
+        lcd.setCursor(thisCol, thisRow);
+        // print the letter:
+        lcd.write(thisLetter);
+        delay(200);
+      }
+    }
+  }
+}
+
+

+ 38 - 0
lib/LiquidCrystal/keywords.txt

@@ -0,0 +1,38 @@
+#######################################
+# Syntax Coloring Map For LiquidCrystal
+#######################################
+
+#######################################
+# Datatypes (KEYWORD1)
+#######################################
+
+LiquidCrystal	KEYWORD1	LiquidCrystal
+
+#######################################
+# Methods and Functions (KEYWORD2)
+#######################################
+
+begin	KEYWORD2
+clear	KEYWORD2
+home	KEYWORD2
+print	KEYWORD2
+setCursor	KEYWORD2
+cursor	KEYWORD2
+noCursor	KEYWORD2
+blink	KEYWORD2
+noBlink	KEYWORD2
+display	KEYWORD2
+noDisplay	KEYWORD2
+autoscroll	KEYWORD2
+noAutoscroll	KEYWORD2
+leftToRight	KEYWORD2
+rightToLeft	KEYWORD2
+scrollDisplayLeft	KEYWORD2
+scrollDisplayRight	KEYWORD2
+createChar	KEYWORD2
+setRowOffsets	KEYWORD2
+
+#######################################
+# Constants (LITERAL1)
+#######################################
+

+ 9 - 0
lib/LiquidCrystal/library.properties

@@ -0,0 +1,9 @@
+name=LiquidCrystal
+version=1.0.7
+author=Arduino, Adafruit
+maintainer=Arduino <info@arduino.cc>
+sentence=Allows communication with alphanumerical liquid crystal displays (LCDs). 
+paragraph=This library allows an Arduino/Genuino board to control LiquidCrystal displays (LCDs) based on the Hitachi HD44780 (or a compatible) chipset, which is found on most text-based LCDs. The library works with in either 4 or 8 bit mode (i.e. using 4 or 8 data lines in addition to the rs, enable, and, optionally, the rw control lines).
+category=Display
+url=http://www.arduino.cc/en/Reference/LiquidCrystal
+architectures=*

+ 326 - 0
lib/LiquidCrystal/src/LiquidCrystal.cpp

@@ -0,0 +1,326 @@
+#include "LiquidCrystal.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <inttypes.h>
+#include "Arduino.h"
+
+// When the display powers up, it is configured as follows:
+//
+// 1. Display clear
+// 2. Function set: 
+//    DL = 1; 8-bit interface data 
+//    N = 0; 1-line display 
+//    F = 0; 5x8 dot character font 
+// 3. Display on/off control: 
+//    D = 0; Display off 
+//    C = 0; Cursor off 
+//    B = 0; Blinking off 
+// 4. Entry mode set: 
+//    I/D = 1; Increment by 1 
+//    S = 0; No shift 
+//
+// Note, however, that resetting the Arduino doesn't reset the LCD, so we
+// can't assume that its in that state when a sketch starts (and the
+// LiquidCrystal constructor is called).
+
+LiquidCrystal::LiquidCrystal(uint8_t rs, uint8_t rw, uint8_t enable,
+			     uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3,
+			     uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7)
+{
+  init(0, rs, rw, enable, d0, d1, d2, d3, d4, d5, d6, d7);
+}
+
+LiquidCrystal::LiquidCrystal(uint8_t rs, uint8_t enable,
+			     uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3,
+			     uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7)
+{
+  init(0, rs, 255, enable, d0, d1, d2, d3, d4, d5, d6, d7);
+}
+
+LiquidCrystal::LiquidCrystal(uint8_t rs, uint8_t rw, uint8_t enable,
+			     uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3)
+{
+  init(1, rs, rw, enable, d0, d1, d2, d3, 0, 0, 0, 0);
+}
+
+LiquidCrystal::LiquidCrystal(uint8_t rs,  uint8_t enable,
+			     uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3)
+{
+  init(1, rs, 255, enable, d0, d1, d2, d3, 0, 0, 0, 0);
+}
+
+void LiquidCrystal::init(uint8_t fourbitmode, uint8_t rs, uint8_t rw, uint8_t enable,
+			 uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3,
+			 uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7)
+{
+  _rs_pin = rs;
+  _rw_pin = rw;
+  _enable_pin = enable;
+  
+  _data_pins[0] = d0;
+  _data_pins[1] = d1;
+  _data_pins[2] = d2;
+  _data_pins[3] = d3; 
+  _data_pins[4] = d4;
+  _data_pins[5] = d5;
+  _data_pins[6] = d6;
+  _data_pins[7] = d7; 
+
+  if (fourbitmode)
+    _displayfunction = LCD_4BITMODE | LCD_1LINE | LCD_5x8DOTS;
+  else 
+    _displayfunction = LCD_8BITMODE | LCD_1LINE | LCD_5x8DOTS;
+  
+  begin(16, 1);  
+}
+
+void LiquidCrystal::begin(uint8_t cols, uint8_t lines, uint8_t dotsize) {
+  if (lines > 1) {
+    _displayfunction |= LCD_2LINE;
+  }
+  _numlines = lines;
+
+  setRowOffsets(0x00, 0x40, 0x00 + cols, 0x40 + cols);  
+
+  // for some 1 line displays you can select a 10 pixel high font
+  if ((dotsize != LCD_5x8DOTS) && (lines == 1)) {
+    _displayfunction |= LCD_5x10DOTS;
+  }
+
+  pinMode(_rs_pin, OUTPUT);
+  // we can save 1 pin by not using RW. Indicate by passing 255 instead of pin#
+  if (_rw_pin != 255) { 
+    pinMode(_rw_pin, OUTPUT);
+  }
+  pinMode(_enable_pin, OUTPUT);
+  
+  // Do these once, instead of every time a character is drawn for speed reasons.
+  for (int i=0; i<((_displayfunction & LCD_8BITMODE) ? 8 : 4); ++i)
+  {
+    pinMode(_data_pins[i], OUTPUT);
+   } 
+
+  // SEE PAGE 45/46 FOR INITIALIZATION SPECIFICATION!
+  // according to datasheet, we need at least 40ms after power rises above 2.7V
+  // before sending commands. Arduino can turn on way before 4.5V so we'll wait 50
+  delayMicroseconds(50000); 
+  // Now we pull both RS and R/W low to begin commands
+  digitalWrite(_rs_pin, LOW);
+  digitalWrite(_enable_pin, LOW);
+  if (_rw_pin != 255) { 
+    digitalWrite(_rw_pin, LOW);
+  }
+  
+  //put the LCD into 4 bit or 8 bit mode
+  if (! (_displayfunction & LCD_8BITMODE)) {
+    // this is according to the hitachi HD44780 datasheet
+    // figure 24, pg 46
+
+    // we start in 8bit mode, try to set 4 bit mode
+    write4bits(0x03);
+    delayMicroseconds(4500); // wait min 4.1ms
+
+    // second try
+    write4bits(0x03);
+    delayMicroseconds(4500); // wait min 4.1ms
+    
+    // third go!
+    write4bits(0x03); 
+    delayMicroseconds(150);
+
+    // finally, set to 4-bit interface
+    write4bits(0x02); 
+  } else {
+    // this is according to the hitachi HD44780 datasheet
+    // page 45 figure 23
+
+    // Send function set command sequence
+    command(LCD_FUNCTIONSET | _displayfunction);
+    delayMicroseconds(4500);  // wait more than 4.1ms
+
+    // second try
+    command(LCD_FUNCTIONSET | _displayfunction);
+    delayMicroseconds(150);
+
+    // third go
+    command(LCD_FUNCTIONSET | _displayfunction);
+  }
+
+  // finally, set # lines, font size, etc.
+  command(LCD_FUNCTIONSET | _displayfunction);  
+
+  // turn the display on with no cursor or blinking default
+  _displaycontrol = LCD_DISPLAYON | LCD_CURSOROFF | LCD_BLINKOFF;  
+  display();
+
+  // clear it off
+  clear();
+
+  // Initialize to default text direction (for romance languages)
+  _displaymode = LCD_ENTRYLEFT | LCD_ENTRYSHIFTDECREMENT;
+  // set the entry mode
+  command(LCD_ENTRYMODESET | _displaymode);
+
+}
+
+void LiquidCrystal::setRowOffsets(int row0, int row1, int row2, int row3)
+{
+  _row_offsets[0] = row0;
+  _row_offsets[1] = row1;
+  _row_offsets[2] = row2;
+  _row_offsets[3] = row3;
+}
+
+/********** high level commands, for the user! */
+void LiquidCrystal::clear()
+{
+  command(LCD_CLEARDISPLAY);  // clear display, set cursor position to zero
+  delayMicroseconds(2000);  // this command takes a long time!
+}
+
+void LiquidCrystal::home()
+{
+  command(LCD_RETURNHOME);  // set cursor position to zero
+  delayMicroseconds(2000);  // this command takes a long time!
+}
+
+void LiquidCrystal::setCursor(uint8_t col, uint8_t row)
+{
+  const size_t max_lines = sizeof(_row_offsets) / sizeof(*_row_offsets);
+  if ( row >= max_lines ) {
+    row = max_lines - 1;    // we count rows starting w/0
+  }
+  if ( row >= _numlines ) {
+    row = _numlines - 1;    // we count rows starting w/0
+  }
+  
+  command(LCD_SETDDRAMADDR | (col + _row_offsets[row]));
+}
+
+// Turn the display on/off (quickly)
+void LiquidCrystal::noDisplay() {
+  _displaycontrol &= ~LCD_DISPLAYON;
+  command(LCD_DISPLAYCONTROL | _displaycontrol);
+}
+void LiquidCrystal::display() {
+  _displaycontrol |= LCD_DISPLAYON;
+  command(LCD_DISPLAYCONTROL | _displaycontrol);
+}
+
+// Turns the underline cursor on/off
+void LiquidCrystal::noCursor() {
+  _displaycontrol &= ~LCD_CURSORON;
+  command(LCD_DISPLAYCONTROL | _displaycontrol);
+}
+void LiquidCrystal::cursor() {
+  _displaycontrol |= LCD_CURSORON;
+  command(LCD_DISPLAYCONTROL | _displaycontrol);
+}
+
+// Turn on and off the blinking cursor
+void LiquidCrystal::noBlink() {
+  _displaycontrol &= ~LCD_BLINKON;
+  command(LCD_DISPLAYCONTROL | _displaycontrol);
+}
+void LiquidCrystal::blink() {
+  _displaycontrol |= LCD_BLINKON;
+  command(LCD_DISPLAYCONTROL | _displaycontrol);
+}
+
+// These commands scroll the display without changing the RAM
+void LiquidCrystal::scrollDisplayLeft(void) {
+  command(LCD_CURSORSHIFT | LCD_DISPLAYMOVE | LCD_MOVELEFT);
+}
+void LiquidCrystal::scrollDisplayRight(void) {
+  command(LCD_CURSORSHIFT | LCD_DISPLAYMOVE | LCD_MOVERIGHT);
+}
+
+// This is for text that flows Left to Right
+void LiquidCrystal::leftToRight(void) {
+  _displaymode |= LCD_ENTRYLEFT;
+  command(LCD_ENTRYMODESET | _displaymode);
+}
+
+// This is for text that flows Right to Left
+void LiquidCrystal::rightToLeft(void) {
+  _displaymode &= ~LCD_ENTRYLEFT;
+  command(LCD_ENTRYMODESET | _displaymode);
+}
+
+// This will 'right justify' text from the cursor
+void LiquidCrystal::autoscroll(void) {
+  _displaymode |= LCD_ENTRYSHIFTINCREMENT;
+  command(LCD_ENTRYMODESET | _displaymode);
+}
+
+// This will 'left justify' text from the cursor
+void LiquidCrystal::noAutoscroll(void) {
+  _displaymode &= ~LCD_ENTRYSHIFTINCREMENT;
+  command(LCD_ENTRYMODESET | _displaymode);
+}
+
+// Allows us to fill the first 8 CGRAM locations
+// with custom characters
+void LiquidCrystal::createChar(uint8_t location, uint8_t charmap[]) {
+  location &= 0x7; // we only have 8 locations 0-7
+  command(LCD_SETCGRAMADDR | (location << 3));
+  for (int i=0; i<8; i++) {
+    write(charmap[i]);
+  }
+}
+
+/*********** mid level commands, for sending data/cmds */
+
+inline void LiquidCrystal::command(uint8_t value) {
+  send(value, LOW);
+}
+
+inline size_t LiquidCrystal::write(uint8_t value) {
+  send(value, HIGH);
+  return 1; // assume sucess
+}
+
+/************ low level data pushing commands **********/
+
+// write either command or data, with automatic 4/8-bit selection
+void LiquidCrystal::send(uint8_t value, uint8_t mode) {
+  digitalWrite(_rs_pin, mode);
+
+  // if there is a RW pin indicated, set it low to Write
+  if (_rw_pin != 255) { 
+    digitalWrite(_rw_pin, LOW);
+  }
+  
+  if (_displayfunction & LCD_8BITMODE) {
+    write8bits(value); 
+  } else {
+    write4bits(value>>4);
+    write4bits(value);
+  }
+}
+
+void LiquidCrystal::pulseEnable(void) {
+  digitalWrite(_enable_pin, LOW);
+  delayMicroseconds(1);    
+  digitalWrite(_enable_pin, HIGH);
+  delayMicroseconds(1);    // enable pulse must be >450ns
+  digitalWrite(_enable_pin, LOW);
+  delayMicroseconds(100);   // commands need > 37us to settle
+}
+
+void LiquidCrystal::write4bits(uint8_t value) {
+  for (int i = 0; i < 4; i++) {
+    digitalWrite(_data_pins[i], (value >> i) & 0x01);
+  }
+
+  pulseEnable();
+}
+
+void LiquidCrystal::write8bits(uint8_t value) {
+  for (int i = 0; i < 8; i++) {
+    digitalWrite(_data_pins[i], (value >> i) & 0x01);
+  }
+  
+  pulseEnable();
+}

+ 108 - 0
lib/LiquidCrystal/src/LiquidCrystal.h

@@ -0,0 +1,108 @@
+#ifndef LiquidCrystal_h
+#define LiquidCrystal_h
+
+#include <inttypes.h>
+#include "Print.h"
+
+// commands
+#define LCD_CLEARDISPLAY 0x01
+#define LCD_RETURNHOME 0x02
+#define LCD_ENTRYMODESET 0x04
+#define LCD_DISPLAYCONTROL 0x08
+#define LCD_CURSORSHIFT 0x10
+#define LCD_FUNCTIONSET 0x20
+#define LCD_SETCGRAMADDR 0x40
+#define LCD_SETDDRAMADDR 0x80
+
+// flags for display entry mode
+#define LCD_ENTRYRIGHT 0x00
+#define LCD_ENTRYLEFT 0x02
+#define LCD_ENTRYSHIFTINCREMENT 0x01
+#define LCD_ENTRYSHIFTDECREMENT 0x00
+
+// flags for display on/off control
+#define LCD_DISPLAYON 0x04
+#define LCD_DISPLAYOFF 0x00
+#define LCD_CURSORON 0x02
+#define LCD_CURSOROFF 0x00
+#define LCD_BLINKON 0x01
+#define LCD_BLINKOFF 0x00
+
+// flags for display/cursor shift
+#define LCD_DISPLAYMOVE 0x08
+#define LCD_CURSORMOVE 0x00
+#define LCD_MOVERIGHT 0x04
+#define LCD_MOVELEFT 0x00
+
+// flags for function set
+#define LCD_8BITMODE 0x10
+#define LCD_4BITMODE 0x00
+#define LCD_2LINE 0x08
+#define LCD_1LINE 0x00
+#define LCD_5x10DOTS 0x04
+#define LCD_5x8DOTS 0x00
+
+class LiquidCrystal : public Print {
+public:
+  LiquidCrystal(uint8_t rs, uint8_t enable,
+		uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3,
+		uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7);
+  LiquidCrystal(uint8_t rs, uint8_t rw, uint8_t enable,
+		uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3,
+		uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7);
+  LiquidCrystal(uint8_t rs, uint8_t rw, uint8_t enable,
+		uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3);
+  LiquidCrystal(uint8_t rs, uint8_t enable,
+		uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3);
+
+  void init(uint8_t fourbitmode, uint8_t rs, uint8_t rw, uint8_t enable,
+	    uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3,
+	    uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7);
+    
+  void begin(uint8_t cols, uint8_t rows, uint8_t charsize = LCD_5x8DOTS);
+
+  void clear();
+  void home();
+
+  void noDisplay();
+  void display();
+  void noBlink();
+  void blink();
+  void noCursor();
+  void cursor();
+  void scrollDisplayLeft();
+  void scrollDisplayRight();
+  void leftToRight();
+  void rightToLeft();
+  void autoscroll();
+  void noAutoscroll();
+
+  void setRowOffsets(int row1, int row2, int row3, int row4);
+  void createChar(uint8_t, uint8_t[]);
+  void setCursor(uint8_t, uint8_t); 
+  virtual size_t write(uint8_t);
+  void command(uint8_t);
+  
+  using Print::write;
+private:
+  void send(uint8_t, uint8_t);
+  void write4bits(uint8_t);
+  void write8bits(uint8_t);
+  void pulseEnable();
+
+  uint8_t _rs_pin; // LOW: command.  HIGH: character.
+  uint8_t _rw_pin; // LOW: write to LCD.  HIGH: read from LCD.
+  uint8_t _enable_pin; // activated by a HIGH pulse.
+  uint8_t _data_pins[8];
+
+  uint8_t _displayfunction;
+  uint8_t _displaycontrol;
+  uint8_t _displaymode;
+
+  uint8_t _initialized;
+
+  uint8_t _numlines;
+  uint8_t _row_offsets[4];
+};
+
+#endif

+ 580 - 0
lib/OneWire/OneWire.cpp

@@ -0,0 +1,580 @@
+/*
+Copyright (c) 2007, Jim Studt  (original old version - many contributors since)
+
+The latest version of this library may be found at:
+  http://www.pjrc.com/teensy/td_libs_OneWire.html
+
+OneWire has been maintained by Paul Stoffregen (paul@pjrc.com) since
+January 2010.
+
+DO NOT EMAIL for technical support, especially not for ESP chips!
+All project support questions must be posted on public forums
+relevant to the board or chips used.  If using Arduino, post on
+Arduino's forum.  If using ESP, post on the ESP community forums.
+There is ABSOLUTELY NO TECH SUPPORT BY PRIVATE EMAIL!
+
+Github's issue tracker for OneWire should be used only to report
+specific bugs.  DO NOT request project support via Github.  All
+project and tech support questions must be posted on forums, not
+github issues.  If you experience a problem and you are not
+absolutely sure it's an issue with the library, ask on a forum
+first.  Only use github to report issues after experts have
+confirmed the issue is with OneWire rather than your project.
+
+Back in 2010, OneWire was in need of many bug fixes, but had
+been abandoned the original author (Jim Studt).  None of the known
+contributors were interested in maintaining OneWire.  Paul typically
+works on OneWire every 6 to 12 months.  Patches usually wait that
+long.  If anyone is interested in more actively maintaining OneWire,
+please contact Paul (this is pretty much the only reason to use
+private email about OneWire).
+
+OneWire is now very mature code.  No changes other than adding
+definitions for newer hardware support are anticipated.
+
+Version 2.3:
+  Unknown chip fallback mode, Roger Clark
+  Teensy-LC compatibility, Paul Stoffregen
+  Search bug fix, Love Nystrom
+
+Version 2.2:
+  Teensy 3.0 compatibility, Paul Stoffregen, paul@pjrc.com
+  Arduino Due compatibility, http://arduino.cc/forum/index.php?topic=141030
+  Fix DS18B20 example negative temperature
+  Fix DS18B20 example's low res modes, Ken Butcher
+  Improve reset timing, Mark Tillotson
+  Add const qualifiers, Bertrik Sikken
+  Add initial value input to crc16, Bertrik Sikken
+  Add target_search() function, Scott Roberts
+
+Version 2.1:
+  Arduino 1.0 compatibility, Paul Stoffregen
+  Improve temperature example, Paul Stoffregen
+  DS250x_PROM example, Guillermo Lovato
+  PIC32 (chipKit) compatibility, Jason Dangel, dangel.jason AT gmail.com
+  Improvements from Glenn Trewitt:
+  - crc16() now works
+  - check_crc16() does all of calculation/checking work.
+  - Added read_bytes() and write_bytes(), to reduce tedious loops.
+  - Added ds2408 example.
+  Delete very old, out-of-date readme file (info is here)
+
+Version 2.0: Modifications by Paul Stoffregen, January 2010:
+http://www.pjrc.com/teensy/td_libs_OneWire.html
+  Search fix from Robin James
+    http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1238032295/27#27
+  Use direct optimized I/O in all cases
+  Disable interrupts during timing critical sections
+    (this solves many random communication errors)
+  Disable interrupts during read-modify-write I/O
+  Reduce RAM consumption by eliminating unnecessary
+    variables and trimming many to 8 bits
+  Optimize both crc8 - table version moved to flash
+
+Modified to work with larger numbers of devices - avoids loop.
+Tested in Arduino 11 alpha with 12 sensors.
+26 Sept 2008 -- Robin James
+http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1238032295/27#27
+
+Updated to work with arduino-0008 and to include skip() as of
+2007/07/06. --RJL20
+
+Modified to calculate the 8-bit CRC directly, avoiding the need for
+the 256-byte lookup table to be loaded in RAM.  Tested in arduino-0010
+-- Tom Pollard, Jan 23, 2008
+
+Jim Studt's original library was modified by Josh Larios.
+
+Tom Pollard, pollard@alum.mit.edu, contributed around May 20, 2008
+
+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.
+
+Much of the code was inspired by Derek Yerger's code, though I don't
+think much of that remains.  In any event that was..
+    (copyleft) 2006 by Derek Yerger - Free to distribute freely.
+
+The CRC code was excerpted and inspired by the Dallas Semiconductor
+sample code bearing this copyright.
+//---------------------------------------------------------------------------
+// Copyright (C) 2000 Dallas Semiconductor Corporation, All Rights Reserved.
+//
+// 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 DALLAS SEMICONDUCTOR 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.
+//
+// Except as contained in this notice, the name of Dallas Semiconductor
+// shall not be used except as stated in the Dallas Semiconductor
+// Branding Policy.
+//--------------------------------------------------------------------------
+*/
+
+#include <Arduino.h>
+#include "OneWire.h"
+#include "util/OneWire_direct_gpio.h"
+
+
+void OneWire::begin(uint8_t pin)
+{
+	pinMode(pin, INPUT);
+	bitmask = PIN_TO_BITMASK(pin);
+	baseReg = PIN_TO_BASEREG(pin);
+#if ONEWIRE_SEARCH
+	reset_search();
+#endif
+}
+
+
+// Perform the onewire reset function.  We will wait up to 250uS for
+// the bus to come high, if it doesn't then it is broken or shorted
+// and we return a 0;
+//
+// Returns 1 if a device asserted a presence pulse, 0 otherwise.
+//
+uint8_t OneWire::reset(void)
+{
+	IO_REG_TYPE mask IO_REG_MASK_ATTR = bitmask;
+	volatile IO_REG_TYPE *reg IO_REG_BASE_ATTR = baseReg;
+	uint8_t r;
+	uint8_t retries = 125;
+
+	noInterrupts();
+	DIRECT_MODE_INPUT(reg, mask);
+	interrupts();
+	// wait until the wire is high... just in case
+	do {
+		if (--retries == 0) return 0;
+		delayMicroseconds(2);
+	} while ( !DIRECT_READ(reg, mask));
+
+	noInterrupts();
+	DIRECT_WRITE_LOW(reg, mask);
+	DIRECT_MODE_OUTPUT(reg, mask);	// drive output low
+	interrupts();
+	delayMicroseconds(480);
+	noInterrupts();
+	DIRECT_MODE_INPUT(reg, mask);	// allow it to float
+	delayMicroseconds(70);
+	r = !DIRECT_READ(reg, mask);
+	interrupts();
+	delayMicroseconds(410);
+	return r;
+}
+
+//
+// Write a bit. Port and bit is used to cut lookup time and provide
+// more certain timing.
+//
+void OneWire::write_bit(uint8_t v)
+{
+	IO_REG_TYPE mask IO_REG_MASK_ATTR = bitmask;
+	volatile IO_REG_TYPE *reg IO_REG_BASE_ATTR = baseReg;
+
+	if (v & 1) {
+		noInterrupts();
+		DIRECT_WRITE_LOW(reg, mask);
+		DIRECT_MODE_OUTPUT(reg, mask);	// drive output low
+		delayMicroseconds(10);
+		DIRECT_WRITE_HIGH(reg, mask);	// drive output high
+		interrupts();
+		delayMicroseconds(55);
+	} else {
+		noInterrupts();
+		DIRECT_WRITE_LOW(reg, mask);
+		DIRECT_MODE_OUTPUT(reg, mask);	// drive output low
+		delayMicroseconds(65);
+		DIRECT_WRITE_HIGH(reg, mask);	// drive output high
+		interrupts();
+		delayMicroseconds(5);
+	}
+}
+
+//
+// Read a bit. Port and bit is used to cut lookup time and provide
+// more certain timing.
+//
+uint8_t OneWire::read_bit(void)
+{
+	IO_REG_TYPE mask IO_REG_MASK_ATTR = bitmask;
+	volatile IO_REG_TYPE *reg IO_REG_BASE_ATTR = baseReg;
+	uint8_t r;
+
+	noInterrupts();
+	DIRECT_MODE_OUTPUT(reg, mask);
+	DIRECT_WRITE_LOW(reg, mask);
+	delayMicroseconds(3);
+	DIRECT_MODE_INPUT(reg, mask);	// let pin float, pull up will raise
+	delayMicroseconds(10);
+	r = DIRECT_READ(reg, mask);
+	interrupts();
+	delayMicroseconds(53);
+	return r;
+}
+
+//
+// Write a byte. The writing code uses the active drivers to raise the
+// pin high, if you need power after the write (e.g. DS18S20 in
+// parasite power mode) then set 'power' to 1, otherwise the pin will
+// go tri-state at the end of the write to avoid heating in a short or
+// other mishap.
+//
+void OneWire::write(uint8_t v, uint8_t power /* = 0 */) {
+    uint8_t bitMask;
+
+    for (bitMask = 0x01; bitMask; bitMask <<= 1) {
+	OneWire::write_bit( (bitMask & v)?1:0);
+    }
+    if ( !power) {
+	noInterrupts();
+	DIRECT_MODE_INPUT(baseReg, bitmask);
+	DIRECT_WRITE_LOW(baseReg, bitmask);
+	interrupts();
+    }
+}
+
+void OneWire::write_bytes(const uint8_t *buf, uint16_t count, bool power /* = 0 */) {
+  for (uint16_t i = 0 ; i < count ; i++)
+    write(buf[i]);
+  if (!power) {
+    noInterrupts();
+    DIRECT_MODE_INPUT(baseReg, bitmask);
+    DIRECT_WRITE_LOW(baseReg, bitmask);
+    interrupts();
+  }
+}
+
+//
+// Read a byte
+//
+uint8_t OneWire::read() {
+    uint8_t bitMask;
+    uint8_t r = 0;
+
+    for (bitMask = 0x01; bitMask; bitMask <<= 1) {
+	if ( OneWire::read_bit()) r |= bitMask;
+    }
+    return r;
+}
+
+void OneWire::read_bytes(uint8_t *buf, uint16_t count) {
+  for (uint16_t i = 0 ; i < count ; i++)
+    buf[i] = read();
+}
+
+//
+// Do a ROM select
+//
+void OneWire::select(const uint8_t rom[8])
+{
+    uint8_t i;
+
+    write(0x55);           // Choose ROM
+
+    for (i = 0; i < 8; i++) write(rom[i]);
+}
+
+//
+// Do a ROM skip
+//
+void OneWire::skip()
+{
+    write(0xCC);           // Skip ROM
+}
+
+void OneWire::depower()
+{
+	noInterrupts();
+	DIRECT_MODE_INPUT(baseReg, bitmask);
+	interrupts();
+}
+
+#if ONEWIRE_SEARCH
+
+//
+// You need to use this function to start a search again from the beginning.
+// You do not need to do it for the first search, though you could.
+//
+void OneWire::reset_search()
+{
+  // reset the search state
+  LastDiscrepancy = 0;
+  LastDeviceFlag = false;
+  LastFamilyDiscrepancy = 0;
+  for(int i = 7; ; i--) {
+    ROM_NO[i] = 0;
+    if ( i == 0) break;
+  }
+}
+
+// Setup the search to find the device type 'family_code' on the next call
+// to search(*newAddr) if it is present.
+//
+void OneWire::target_search(uint8_t family_code)
+{
+   // set the search state to find SearchFamily type devices
+   ROM_NO[0] = family_code;
+   for (uint8_t i = 1; i < 8; i++)
+      ROM_NO[i] = 0;
+   LastDiscrepancy = 64;
+   LastFamilyDiscrepancy = 0;
+   LastDeviceFlag = false;
+}
+
+//
+// Perform a search. If this function returns a '1' then it has
+// enumerated the next device and you may retrieve the ROM from the
+// OneWire::address variable. If there are no devices, no further
+// devices, or something horrible happens in the middle of the
+// enumeration then a 0 is returned.  If a new device is found then
+// its address is copied to newAddr.  Use OneWire::reset_search() to
+// start over.
+//
+// --- Replaced by the one from the Dallas Semiconductor web site ---
+//--------------------------------------------------------------------------
+// Perform the 1-Wire Search Algorithm on the 1-Wire bus using the existing
+// search state.
+// Return TRUE  : device found, ROM number in ROM_NO buffer
+//        FALSE : device not found, end of search
+//
+bool OneWire::search(uint8_t *newAddr, bool search_mode /* = true */)
+{
+   uint8_t id_bit_number;
+   uint8_t last_zero, rom_byte_number;
+   bool    search_result;
+   uint8_t id_bit, cmp_id_bit;
+
+   unsigned char rom_byte_mask, search_direction;
+
+   // initialize for search
+   id_bit_number = 1;
+   last_zero = 0;
+   rom_byte_number = 0;
+   rom_byte_mask = 1;
+   search_result = false;
+
+   // if the last call was not the last one
+   if (!LastDeviceFlag) {
+      // 1-Wire reset
+      if (!reset()) {
+         // reset the search
+         LastDiscrepancy = 0;
+         LastDeviceFlag = false;
+         LastFamilyDiscrepancy = 0;
+         return false;
+      }
+
+      // issue the search command
+      if (search_mode == true) {
+        write(0xF0);   // NORMAL SEARCH
+      } else {
+        write(0xEC);   // CONDITIONAL SEARCH
+      }
+
+      // loop to do the search
+      do
+      {
+         // read a bit and its complement
+         id_bit = read_bit();
+         cmp_id_bit = read_bit();
+
+         // check for no devices on 1-wire
+         if ((id_bit == 1) && (cmp_id_bit == 1)) {
+            break;
+         } else {
+            // all devices coupled have 0 or 1
+            if (id_bit != cmp_id_bit) {
+               search_direction = id_bit;  // bit write value for search
+            } else {
+               // if this discrepancy if before the Last Discrepancy
+               // on a previous next then pick the same as last time
+               if (id_bit_number < LastDiscrepancy) {
+                  search_direction = ((ROM_NO[rom_byte_number] & rom_byte_mask) > 0);
+               } else {
+                  // if equal to last pick 1, if not then pick 0
+                  search_direction = (id_bit_number == LastDiscrepancy);
+               }
+               // if 0 was picked then record its position in LastZero
+               if (search_direction == 0) {
+                  last_zero = id_bit_number;
+
+                  // check for Last discrepancy in family
+                  if (last_zero < 9)
+                     LastFamilyDiscrepancy = last_zero;
+               }
+            }
+
+            // set or clear the bit in the ROM byte rom_byte_number
+            // with mask rom_byte_mask
+            if (search_direction == 1)
+              ROM_NO[rom_byte_number] |= rom_byte_mask;
+            else
+              ROM_NO[rom_byte_number] &= ~rom_byte_mask;
+
+            // serial number search direction write bit
+            write_bit(search_direction);
+
+            // increment the byte counter id_bit_number
+            // and shift the mask rom_byte_mask
+            id_bit_number++;
+            rom_byte_mask <<= 1;
+
+            // if the mask is 0 then go to new SerialNum byte rom_byte_number and reset mask
+            if (rom_byte_mask == 0) {
+                rom_byte_number++;
+                rom_byte_mask = 1;
+            }
+         }
+      }
+      while(rom_byte_number < 8);  // loop until through all ROM bytes 0-7
+
+      // if the search was successful then
+      if (!(id_bit_number < 65)) {
+         // search successful so set LastDiscrepancy,LastDeviceFlag,search_result
+         LastDiscrepancy = last_zero;
+
+         // check for last device
+         if (LastDiscrepancy == 0) {
+            LastDeviceFlag = true;
+         }
+         search_result = true;
+      }
+   }
+
+   // if no device found then reset counters so next 'search' will be like a first
+   if (!search_result || !ROM_NO[0]) {
+      LastDiscrepancy = 0;
+      LastDeviceFlag = false;
+      LastFamilyDiscrepancy = 0;
+      search_result = false;
+   } else {
+      for (int i = 0; i < 8; i++) newAddr[i] = ROM_NO[i];
+   }
+   return search_result;
+  }
+
+#endif
+
+#if ONEWIRE_CRC
+// The 1-Wire CRC scheme is described in Maxim Application Note 27:
+// "Understanding and Using Cyclic Redundancy Checks with Maxim iButton Products"
+//
+
+#if ONEWIRE_CRC8_TABLE
+// Dow-CRC using polynomial X^8 + X^5 + X^4 + X^0
+// Tiny 2x16 entry CRC table created by Arjen Lentz
+// See http://lentz.com.au/blog/calculating-crc-with-a-tiny-32-entry-lookup-table
+static const uint8_t PROGMEM dscrc2x16_table[] = {
+	0x00, 0x5E, 0xBC, 0xE2, 0x61, 0x3F, 0xDD, 0x83,
+	0xC2, 0x9C, 0x7E, 0x20, 0xA3, 0xFD, 0x1F, 0x41,
+	0x00, 0x9D, 0x23, 0xBE, 0x46, 0xDB, 0x65, 0xF8,
+	0x8C, 0x11, 0xAF, 0x32, 0xCA, 0x57, 0xE9, 0x74
+};
+
+// Compute a Dallas Semiconductor 8 bit CRC. These show up in the ROM
+// and the registers.  (Use tiny 2x16 entry CRC table)
+uint8_t OneWire::crc8(const uint8_t *addr, uint8_t len)
+{
+	uint8_t crc = 0;
+
+	while (len--) {
+		crc = *addr++ ^ crc;  // just re-using crc as intermediate
+		crc = pgm_read_byte(dscrc2x16_table + (crc & 0x0f)) ^
+		pgm_read_byte(dscrc2x16_table + 16 + ((crc >> 4) & 0x0f));
+	}
+
+	return crc;
+}
+#else
+//
+// Compute a Dallas Semiconductor 8 bit CRC directly.
+// this is much slower, but a little smaller, than the lookup table.
+//
+uint8_t OneWire::crc8(const uint8_t *addr, uint8_t len)
+{
+	uint8_t crc = 0;
+
+	while (len--) {
+#if defined(__AVR__)
+		crc = _crc_ibutton_update(crc, *addr++);
+#else
+		uint8_t inbyte = *addr++;
+		for (uint8_t i = 8; i; i--) {
+			uint8_t mix = (crc ^ inbyte) & 0x01;
+			crc >>= 1;
+			if (mix) crc ^= 0x8C;
+			inbyte >>= 1;
+		}
+#endif
+	}
+	return crc;
+}
+#endif
+
+#if ONEWIRE_CRC16
+bool OneWire::check_crc16(const uint8_t* input, uint16_t len, const uint8_t* inverted_crc, uint16_t crc)
+{
+    crc = ~crc16(input, len, crc);
+    return (crc & 0xFF) == inverted_crc[0] && (crc >> 8) == inverted_crc[1];
+}
+
+uint16_t OneWire::crc16(const uint8_t* input, uint16_t len, uint16_t crc)
+{
+#if defined(__AVR__)
+    for (uint16_t i = 0 ; i < len ; i++) {
+        crc = _crc16_update(crc, input[i]);
+    }
+#else
+    static const uint8_t oddparity[16] =
+        { 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0 };
+
+    for (uint16_t i = 0 ; i < len ; i++) {
+      // Even though we're just copying a byte from the input,
+      // we'll be doing 16-bit computation with it.
+      uint16_t cdata = input[i];
+      cdata = (cdata ^ crc) & 0xff;
+      crc >>= 8;
+
+      if (oddparity[cdata & 0x0F] ^ oddparity[cdata >> 4])
+          crc ^= 0xC001;
+
+      cdata <<= 6;
+      crc ^= cdata;
+      cdata <<= 1;
+      crc ^= cdata;
+    }
+#endif
+    return crc;
+}
+#endif
+
+#endif

+ 182 - 0
lib/OneWire/OneWire.h

@@ -0,0 +1,182 @@
+#ifndef OneWire_h
+#define OneWire_h
+
+#ifdef __cplusplus
+
+#include <stdint.h>
+
+#if defined(__AVR__)
+#include <util/crc16.h>
+#endif
+
+#if ARDUINO >= 100
+#include <Arduino.h>       // for delayMicroseconds, digitalPinToBitMask, etc
+#else
+#include "WProgram.h"      // for delayMicroseconds
+#include "pins_arduino.h"  // for digitalPinToBitMask, etc
+#endif
+
+// You can exclude certain features from OneWire.  In theory, this
+// might save some space.  In practice, the compiler automatically
+// removes unused code (technically, the linker, using -fdata-sections
+// and -ffunction-sections when compiling, and Wl,--gc-sections
+// when linking), so most of these will not result in any code size
+// reduction.  Well, unless you try to use the missing features
+// and redesign your program to not need them!  ONEWIRE_CRC8_TABLE
+// is the exception, because it selects a fast but large algorithm
+// or a small but slow algorithm.
+
+// you can exclude onewire_search by defining that to 0
+#ifndef ONEWIRE_SEARCH
+#define ONEWIRE_SEARCH 1
+#endif
+
+// You can exclude CRC checks altogether by defining this to 0
+#ifndef ONEWIRE_CRC
+#define ONEWIRE_CRC 1
+#endif
+
+// Select the table-lookup method of computing the 8-bit CRC
+// by setting this to 1.  The lookup table enlarges code size by
+// about 250 bytes.  It does NOT consume RAM (but did in very
+// old versions of OneWire).  If you disable this, a slower
+// but very compact algorithm is used.
+#ifndef ONEWIRE_CRC8_TABLE
+#define ONEWIRE_CRC8_TABLE 1
+#endif
+
+// You can allow 16-bit CRC checks by defining this to 1
+// (Note that ONEWIRE_CRC must also be 1.)
+#ifndef ONEWIRE_CRC16
+#define ONEWIRE_CRC16 1
+#endif
+
+// Board-specific macros for direct GPIO
+#include "util/OneWire_direct_regtype.h"
+
+class OneWire
+{
+  private:
+    IO_REG_TYPE bitmask;
+    volatile IO_REG_TYPE *baseReg;
+
+#if ONEWIRE_SEARCH
+    // global search state
+    unsigned char ROM_NO[8];
+    uint8_t LastDiscrepancy;
+    uint8_t LastFamilyDiscrepancy;
+    bool LastDeviceFlag;
+#endif
+
+  public:
+    OneWire() { }
+    OneWire(uint8_t pin) { begin(pin); }
+    void begin(uint8_t pin);
+
+    // Perform a 1-Wire reset cycle. Returns 1 if a device responds
+    // with a presence pulse.  Returns 0 if there is no device or the
+    // bus is shorted or otherwise held low for more than 250uS
+    uint8_t reset(void);
+
+    // Issue a 1-Wire rom select command, you do the reset first.
+    void select(const uint8_t rom[8]);
+
+    // Issue a 1-Wire rom skip command, to address all on bus.
+    void skip(void);
+
+    // Write a byte. If 'power' is one then the wire is held high at
+    // the end for parasitically powered devices. You are responsible
+    // for eventually depowering it by calling depower() or doing
+    // another read or write.
+    void write(uint8_t v, uint8_t power = 0);
+
+    void write_bytes(const uint8_t *buf, uint16_t count, bool power = 0);
+
+    // Read a byte.
+    uint8_t read(void);
+
+    void read_bytes(uint8_t *buf, uint16_t count);
+
+    // Write a bit. The bus is always left powered at the end, see
+    // note in write() about that.
+    void write_bit(uint8_t v);
+
+    // Read a bit.
+    uint8_t read_bit(void);
+
+    // Stop forcing power onto the bus. You only need to do this if
+    // you used the 'power' flag to write() or used a write_bit() call
+    // and aren't about to do another read or write. You would rather
+    // not leave this powered if you don't have to, just in case
+    // someone shorts your bus.
+    void depower(void);
+
+#if ONEWIRE_SEARCH
+    // Clear the search state so that if will start from the beginning again.
+    void reset_search();
+
+    // Setup the search to find the device type 'family_code' on the next call
+    // to search(*newAddr) if it is present.
+    void target_search(uint8_t family_code);
+
+    // Look for the next device. Returns 1 if a new address has been
+    // returned. A zero might mean that the bus is shorted, there are
+    // no devices, or you have already retrieved all of them.  It
+    // might be a good idea to check the CRC to make sure you didn't
+    // get garbage.  The order is deterministic. You will always get
+    // the same devices in the same order.
+    bool search(uint8_t *newAddr, bool search_mode = true);
+#endif
+
+#if ONEWIRE_CRC
+    // Compute a Dallas Semiconductor 8 bit CRC, these are used in the
+    // ROM and scratchpad registers.
+    static uint8_t crc8(const uint8_t *addr, uint8_t len);
+
+#if ONEWIRE_CRC16
+    // Compute the 1-Wire CRC16 and compare it against the received CRC.
+    // Example usage (reading a DS2408):
+    //    // Put everything in a buffer so we can compute the CRC easily.
+    //    uint8_t buf[13];
+    //    buf[0] = 0xF0;    // Read PIO Registers
+    //    buf[1] = 0x88;    // LSB address
+    //    buf[2] = 0x00;    // MSB address
+    //    WriteBytes(net, buf, 3);    // Write 3 cmd bytes
+    //    ReadBytes(net, buf+3, 10);  // Read 6 data bytes, 2 0xFF, 2 CRC16
+    //    if (!CheckCRC16(buf, 11, &buf[11])) {
+    //        // Handle error.
+    //    }     
+    //          
+    // @param input - Array of bytes to checksum.
+    // @param len - How many bytes to use.
+    // @param inverted_crc - The two CRC16 bytes in the received data.
+    //                       This should just point into the received data,
+    //                       *not* at a 16-bit integer.
+    // @param crc - The crc starting value (optional)
+    // @return True, iff the CRC matches.
+    static bool check_crc16(const uint8_t* input, uint16_t len, const uint8_t* inverted_crc, uint16_t crc = 0);
+
+    // Compute a Dallas Semiconductor 16 bit CRC.  This is required to check
+    // the integrity of data received from many 1-Wire devices.  Note that the
+    // CRC computed here is *not* what you'll get from the 1-Wire network,
+    // for two reasons:
+    //   1) The CRC is transmitted bitwise inverted.
+    //   2) Depending on the endian-ness of your processor, the binary
+    //      representation of the two-byte return value may have a different
+    //      byte order than the two bytes you get from 1-Wire.
+    // @param input - Array of bytes to checksum.
+    // @param len - How many bytes to use.
+    // @param crc - The crc starting value (optional)
+    // @return The CRC16, as defined by Dallas Semiconductor.
+    static uint16_t crc16(const uint8_t* input, uint16_t len, uint16_t crc = 0);
+#endif
+#endif
+};
+
+// Prevent this name from leaking into Arduino sketches
+#ifdef IO_REG_TYPE
+#undef IO_REG_TYPE
+#endif
+
+#endif // __cplusplus
+#endif // OneWire_h

+ 64 - 0
lib/OneWire/docs/issue_template.md

@@ -0,0 +1,64 @@
+Please use this form only to report code defects or bugs.
+
+For any question, even questions directly pertaining to this code, post your question on the forums related to the board you are using.
+
+Arduino: forum.arduino.cc
+Teensy: forum.pjrc.com
+ESP8266: www.esp8266.com
+ESP32: www.esp32.com
+Adafruit Feather/Metro/Trinket: forums.adafruit.com
+Particle Photon: community.particle.io
+
+If you are experiencing trouble but not certain of the cause, or need help using this code, ask on the appropriate forum.  This is not the place to ask for support or help, even directly related to this code.  Only use this form you are certain you have discovered a defect in this code!
+
+Please verify the problem occurs when using the very latest version, using the newest version of Arduino and any other related software.
+
+
+----------------------------- Remove above -----------------------------
+
+
+
+### Description
+
+Describe your problem.
+
+
+
+### Steps To Reproduce Problem
+
+Please give detailed instructions needed for anyone to attempt to reproduce the problem.
+
+
+
+### Hardware & Software
+
+Board
+Shields / modules used
+Arduino IDE version
+Teensyduino version (if using Teensy)
+Version info & package name (from Tools > Boards > Board Manager)
+Operating system & version
+Any other software or hardware?
+
+
+### Arduino Sketch
+
+```cpp
+// Change the code below by your sketch (please try to give the smallest code which demonstrates the problem)
+#include <Arduino.h>
+
+// libraries: give links/details so anyone can compile your code for the same result
+
+void setup() {
+}
+
+void loop() {
+}
+```
+
+
+### Errors or Incorrect Output
+
+If you see any errors or incorrect output, please show it here.  Please use copy & paste to give an exact copy of the message.  Details matter, so please show (not merely describe) the actual message or error exactly as it appears.
+
+

+ 112 - 0
lib/OneWire/examples/DS18x20_Temperature/DS18x20_Temperature.ino

@@ -0,0 +1,112 @@
+#include <OneWire.h>
+
+// OneWire DS18S20, DS18B20, DS1822 Temperature Example
+//
+// http://www.pjrc.com/teensy/td_libs_OneWire.html
+//
+// The DallasTemperature library can do all this work for you!
+// https://github.com/milesburton/Arduino-Temperature-Control-Library
+
+OneWire  ds(10);  // on pin 10 (a 4.7K resistor is necessary)
+
+void setup(void) {
+  Serial.begin(9600);
+}
+
+void loop(void) {
+  byte i;
+  byte present = 0;
+  byte type_s;
+  byte data[9];
+  byte addr[8];
+  float celsius, fahrenheit;
+  
+  if ( !ds.search(addr)) {
+    Serial.println("No more addresses.");
+    Serial.println();
+    ds.reset_search();
+    delay(250);
+    return;
+  }
+  
+  Serial.print("ROM =");
+  for( i = 0; i < 8; i++) {
+    Serial.write(' ');
+    Serial.print(addr[i], HEX);
+  }
+
+  if (OneWire::crc8(addr, 7) != addr[7]) {
+      Serial.println("CRC is not valid!");
+      return;
+  }
+  Serial.println();
+ 
+  // the first ROM byte indicates which chip
+  switch (addr[0]) {
+    case 0x10:
+      Serial.println("  Chip = DS18S20");  // or old DS1820
+      type_s = 1;
+      break;
+    case 0x28:
+      Serial.println("  Chip = DS18B20");
+      type_s = 0;
+      break;
+    case 0x22:
+      Serial.println("  Chip = DS1822");
+      type_s = 0;
+      break;
+    default:
+      Serial.println("Device is not a DS18x20 family device.");
+      return;
+  } 
+
+  ds.reset();
+  ds.select(addr);
+  ds.write(0x44, 1);        // start conversion, with parasite power on at the end
+  
+  delay(1000);     // maybe 750ms is enough, maybe not
+  // we might do a ds.depower() here, but the reset will take care of it.
+  
+  present = ds.reset();
+  ds.select(addr);    
+  ds.write(0xBE);         // Read Scratchpad
+
+  Serial.print("  Data = ");
+  Serial.print(present, HEX);
+  Serial.print(" ");
+  for ( i = 0; i < 9; i++) {           // we need 9 bytes
+    data[i] = ds.read();
+    Serial.print(data[i], HEX);
+    Serial.print(" ");
+  }
+  Serial.print(" CRC=");
+  Serial.print(OneWire::crc8(data, 8), HEX);
+  Serial.println();
+
+  // Convert the data to actual temperature
+  // because the result is a 16 bit signed integer, it should
+  // be stored to an "int16_t" type, which is always 16 bits
+  // even when compiled on a 32 bit processor.
+  int16_t raw = (data[1] << 8) | data[0];
+  if (type_s) {
+    raw = raw << 3; // 9 bit resolution default
+    if (data[7] == 0x10) {
+      // "count remain" gives full 12 bit resolution
+      raw = (raw & 0xFFF0) + 12 - data[6];
+    }
+  } else {
+    byte cfg = (data[4] & 0x60);
+    // at lower res, the low bits are undefined, so let's zero them
+    if (cfg == 0x00) raw = raw & ~7;  // 9 bit resolution, 93.75 ms
+    else if (cfg == 0x20) raw = raw & ~3; // 10 bit res, 187.5 ms
+    else if (cfg == 0x40) raw = raw & ~1; // 11 bit res, 375 ms
+    //// default is 12 bit resolution, 750 ms conversion time
+  }
+  celsius = (float)raw / 16.0;
+  fahrenheit = celsius * 1.8 + 32.0;
+  Serial.print("  Temperature = ");
+  Serial.print(celsius);
+  Serial.print(" Celsius, ");
+  Serial.print(fahrenheit);
+  Serial.println(" Fahrenheit");
+}

+ 74 - 0
lib/OneWire/examples/DS2408_Switch/DS2408_Switch.ino

@@ -0,0 +1,74 @@
+#include <OneWire.h>
+
+/*
+ * DS2408 8-Channel Addressable Switch
+ *
+ * Writte by Glenn Trewitt, glenn at trewitt dot org
+ *
+ * Some notes about the DS2408:
+ *   - Unlike most input/output ports, the DS2408 doesn't have mode bits to
+ *       set whether the pins are input or output.  If you issue a read command,
+ *       they're inputs.  If you write to them, they're outputs.
+ *   - For reading from a switch, you should use 10K pull-up resisters.
+ */
+
+OneWire net(10);  // on pin 10
+
+
+void PrintBytes(const uint8_t* addr, uint8_t count, bool newline=false) {
+  for (uint8_t i = 0; i < count; i++) {
+    Serial.print(addr[i]>>4, HEX);
+    Serial.print(addr[i]&0x0f, HEX);
+  }
+  if (newline)
+    Serial.println();
+}
+
+
+void setup(void) {
+  Serial.begin(9600);
+}
+
+void loop(void) {
+  byte addr[8];
+
+  if (!net.search(addr)) {
+    Serial.print("No more addresses.\n");
+    net.reset_search();
+    delay(1000);
+    return;
+  }
+
+  if (OneWire::crc8(addr, 7) != addr[7]) {
+    Serial.print("CRC is not valid!\n");
+    return;
+  }
+
+  if (addr[0] != 0x29) {
+    PrintBytes(addr, 8);
+    Serial.print(" is not a DS2408.\n");
+    return;
+  }
+
+  Serial.print("  Reading DS2408 ");
+  PrintBytes(addr, 8);
+  Serial.println();
+
+  uint8_t buf[13];  // Put everything in the buffer so we can compute CRC easily.
+  buf[0] = 0xF0;    // Read PIO Registers
+  buf[1] = 0x88;    // LSB address
+  buf[2] = 0x00;    // MSB address
+  net.write_bytes(buf, 3);
+  net.read_bytes(buf+3, 10);     // 3 cmd bytes, 6 data bytes, 2 0xFF, 2 CRC16
+  net.reset();
+
+  if (!OneWire::check_crc16(buf, 11, &buf[11])) {
+    Serial.print("CRC failure in DS2408 at ");
+    PrintBytes(addr, 8, true);
+    return;
+  }
+  Serial.print("  DS2408 data = ");
+  // First 3 bytes contain command, register address.
+  Serial.println(buf[3], BIN);
+}
+

+ 75 - 0
lib/OneWire/examples/DS250x_PROM/DS250x_PROM.ino

@@ -0,0 +1,75 @@
+/*
+DS250x add-only programmable memory reader w/SKIP ROM.
+
+ The DS250x is a 512/1024bit add-only PROM(you can add data but cannot change the old one) that's used mainly for device identification purposes
+ like serial number, mfgr data, unique identifiers, etc. It uses the Maxim 1-wire bus.
+
+ This sketch will use the SKIP ROM function that skips the 1-Wire search phase since we only have one device connected in the bus on digital pin 6.
+ If more than one device is connected to the bus, it will fail.
+ Sketch will not verify if device connected is from the DS250x family since the skip rom function effectively skips the family-id byte readout.
+ thus it is possible to run this sketch with any Maxim OneWire device in which case the command CRC will most likely fail.
+ Sketch will only read the first page of memory(32bits) starting from the lower address(0000h), if more than 1 device is present, then use the sketch with search functions.
+ Remember to put a 4.7K pullup resistor between pin 6 and +Vcc
+
+ To change the range or ammount of data to read, simply change the data array size, LSB/MSB addresses and for loop iterations
+
+ This example code is in the public domain and is provided AS-IS.
+
+ Built with Arduino 0022 and PJRC OneWire 2.0 library http://www.pjrc.com/teensy/td_libs_OneWire.html
+
+ created by Guillermo Lovato <glovato@gmail.com>
+ march/2011
+
+ */
+
+#include <OneWire.h>
+OneWire ds(6);                    // OneWire bus on digital pin 6
+void setup() {
+  Serial.begin (9600);
+}
+
+void loop() {
+  byte i;                         // This is for the for loops
+  boolean present;                // device present var
+  byte data[32];                  // container for the data from device
+  byte leemem[3] = {              // array with the commands to initiate a read, DS250x devices expect 3 bytes to start a read: command,LSB&MSB adresses
+    0xF0 , 0x00 , 0x00   };       // 0xF0 is the Read Data command, followed by 00h 00h as starting address(the beginning, 0000h)
+  byte ccrc;                      // Variable to store the command CRC
+  byte ccrc_calc;
+
+  present = ds.reset();           // OneWire bus reset, always needed to start operation on the bus, returns a 1/TRUE if there's a device present.
+  ds.skip();                      // Skip ROM search
+
+  if (present == true) {          // We only try to read the data if there's a device present
+    Serial.println("DS250x device present");
+    ds.write(leemem[0],1);        // Read data command, leave ghost power on
+    ds.write(leemem[1],1);        // LSB starting address, leave ghost power on
+    ds.write(leemem[2],1);        // MSB starting address, leave ghost power on
+
+    ccrc = ds.read();             // DS250x generates a CRC for the command we sent, we assign a read slot and store it's value
+    ccrc_calc = OneWire::crc8(leemem, 3);  // We calculate the CRC of the commands we sent using the library function and store it
+
+    if ( ccrc_calc != ccrc) {      // Then we compare it to the value the ds250x calculated, if it fails, we print debug messages and abort
+      Serial.println("Invalid command CRC!");
+      Serial.print("Calculated CRC:");
+      Serial.println(ccrc_calc,HEX);    // HEX makes it easier to observe and compare
+      Serial.print("DS250x readback CRC:");
+      Serial.println(ccrc,HEX);
+      return;                      // Since CRC failed, we abort the rest of the loop and start over
+    }
+    Serial.println("Data is: ");   // For the printout of the data
+    for ( i = 0; i < 32; i++) {    // Now it's time to read the PROM data itself, each page is 32 bytes so we need 32 read commands
+      data[i] = ds.read();         // we store each read byte to a different position in the data array
+      Serial.print(data[i]);       // printout in ASCII
+      Serial.print(" ");           // blank space
+    }
+    Serial.println();
+    delay(5000);                    // Delay so we don't saturate the serial output
+  }
+  else {                           // Nothing is connected in the bus
+    Serial.println("Nothing connected");
+    delay(3000);
+  }
+}
+
+

+ 38 - 0
lib/OneWire/keywords.txt

@@ -0,0 +1,38 @@
+#######################################
+# Syntax Coloring Map For OneWire
+#######################################
+
+#######################################
+# Datatypes (KEYWORD1)
+#######################################
+
+OneWire	KEYWORD1
+
+#######################################
+# Methods and Functions (KEYWORD2)
+#######################################
+
+reset	KEYWORD2
+write_bit	KEYWORD2
+read_bit	KEYWORD2
+write	KEYWORD2
+write_bytes	KEYWORD2
+read	KEYWORD2
+read_bytes	KEYWORD2
+select	KEYWORD2
+skip	KEYWORD2
+depower	KEYWORD2
+reset_search	KEYWORD2
+search	KEYWORD2
+crc8	KEYWORD2
+crc16	KEYWORD2
+check_crc16	KEYWORD2
+
+#######################################
+# Instances (KEYWORD2)
+#######################################
+
+
+#######################################
+# Constants (LITERAL1)
+#######################################

+ 61 - 0
lib/OneWire/library.json

@@ -0,0 +1,61 @@
+{
+    "name": "OneWire",
+    "description": "Control 1-Wire protocol (DS18S20, DS18B20, DS2408 and etc)",
+    "keywords": "onewire, 1-wire, bus, sensor, temperature, ibutton",
+    "authors": [
+        {
+            "name": "Paul Stoffregen",
+            "email": "paul@pjrc.com",
+            "url": "http://www.pjrc.com",
+            "maintainer": true
+        },
+        {
+            "name": "Jim Studt"
+        },
+        {
+            "name": "Tom Pollard",
+            "email": "pollard@alum.mit.edu"
+        },
+        {
+            "name": "Derek Yerger"
+        },
+        {
+            "name": "Josh Larios"
+        },
+        {
+            "name": "Robin James"
+        },
+        {
+            "name": "Glenn Trewitt"
+        },
+        {
+            "name": "Jason Dangel",
+            "email": "dangel.jason AT gmail.com"
+        },
+        {
+            "name": "Guillermo Lovato"
+        },
+        {
+            "name": "Ken Butcher"
+        },
+        {
+            "name": "Mark Tillotson"
+        },
+        {
+            "name": "Bertrik Sikken"
+        },
+        {
+            "name": "Scott Roberts"
+        }
+    ],
+    "repository": {
+        "type": "git",
+        "url": "https://github.com/PaulStoffregen/OneWire"
+    },
+    "version": "2.3.7",
+    "homepage": "https://www.pjrc.com/teensy/td_libs_OneWire.html",
+    "frameworks": "Arduino",
+    "examples": [
+        "examples/*/*.pde"
+    ]
+}

+ 10 - 0
lib/OneWire/library.properties

@@ -0,0 +1,10 @@
+name=OneWire
+version=2.3.7
+author=Jim Studt, Tom Pollard, Robin James, Glenn Trewitt, Jason Dangel, Guillermo Lovato, Paul Stoffregen, Scott Roberts, Bertrik Sikken, Mark Tillotson, Ken Butcher, Roger Clark, Love Nystrom
+maintainer=Paul Stoffregen
+sentence=Access 1-wire temperature sensors, memory and other chips.
+paragraph=
+category=Communication
+url=http://www.pjrc.com/teensy/td_libs_OneWire.html
+architectures=*
+

+ 445 - 0
lib/OneWire/util/OneWire_direct_gpio.h

@@ -0,0 +1,445 @@
+#ifndef OneWire_Direct_GPIO_h
+#define OneWire_Direct_GPIO_h
+
+// This header should ONLY be included by OneWire.cpp.  These defines are
+// meant to be private, used within OneWire.cpp, but not exposed to Arduino
+// sketches or other libraries which may include OneWire.h.
+
+#include <stdint.h>
+
+// Platform specific I/O definitions
+
+#if defined(__AVR__)
+#define PIN_TO_BASEREG(pin)             (portInputRegister(digitalPinToPort(pin)))
+#define PIN_TO_BITMASK(pin)             (digitalPinToBitMask(pin))
+#define IO_REG_TYPE uint8_t
+#define IO_REG_BASE_ATTR asm("r30")
+#define IO_REG_MASK_ATTR
+#if defined(__AVR_ATmega4809__)
+#define DIRECT_READ(base, mask)         (((*(base)) & (mask)) ? 1 : 0)
+#define DIRECT_MODE_INPUT(base, mask)   ((*((base)-8)) &= ~(mask))
+#define DIRECT_MODE_OUTPUT(base, mask)  ((*((base)-8)) |= (mask))
+#define DIRECT_WRITE_LOW(base, mask)    ((*((base)-4)) &= ~(mask))
+#define DIRECT_WRITE_HIGH(base, mask)   ((*((base)-4)) |= (mask))
+#else
+#define DIRECT_READ(base, mask)         (((*(base)) & (mask)) ? 1 : 0)
+#define DIRECT_MODE_INPUT(base, mask)   ((*((base)+1)) &= ~(mask))
+#define DIRECT_MODE_OUTPUT(base, mask)  ((*((base)+1)) |= (mask))
+#define DIRECT_WRITE_LOW(base, mask)    ((*((base)+2)) &= ~(mask))
+#define DIRECT_WRITE_HIGH(base, mask)   ((*((base)+2)) |= (mask))
+#endif
+
+#elif defined(__MK20DX128__) || defined(__MK20DX256__) || defined(__MK66FX1M0__) || defined(__MK64FX512__)
+#define PIN_TO_BASEREG(pin)             (portOutputRegister(pin))
+#define PIN_TO_BITMASK(pin)             (1)
+#define IO_REG_TYPE uint8_t
+#define IO_REG_BASE_ATTR
+#define IO_REG_MASK_ATTR __attribute__ ((unused))
+#define DIRECT_READ(base, mask)         (*((base)+512))
+#define DIRECT_MODE_INPUT(base, mask)   (*((base)+640) = 0)
+#define DIRECT_MODE_OUTPUT(base, mask)  (*((base)+640) = 1)
+#define DIRECT_WRITE_LOW(base, mask)    (*((base)+256) = 1)
+#define DIRECT_WRITE_HIGH(base, mask)   (*((base)+128) = 1)
+
+#elif defined(__MKL26Z64__)
+#define PIN_TO_BASEREG(pin)             (portOutputRegister(pin))
+#define PIN_TO_BITMASK(pin)             (digitalPinToBitMask(pin))
+#define IO_REG_TYPE uint8_t
+#define IO_REG_BASE_ATTR
+#define IO_REG_MASK_ATTR
+#define DIRECT_READ(base, mask)         ((*((base)+16) & (mask)) ? 1 : 0)
+#define DIRECT_MODE_INPUT(base, mask)   (*((base)+20) &= ~(mask))
+#define DIRECT_MODE_OUTPUT(base, mask)  (*((base)+20) |= (mask))
+#define DIRECT_WRITE_LOW(base, mask)    (*((base)+8) = (mask))
+#define DIRECT_WRITE_HIGH(base, mask)   (*((base)+4) = (mask))
+
+#elif defined(__IMXRT1052__) || defined(__IMXRT1062__)
+#define PIN_TO_BASEREG(pin)             (portOutputRegister(pin))
+#define PIN_TO_BITMASK(pin)             (digitalPinToBitMask(pin))
+#define IO_REG_TYPE uint32_t
+#define IO_REG_BASE_ATTR
+#define IO_REG_MASK_ATTR
+#define DIRECT_READ(base, mask)         ((*((base)+2) & (mask)) ? 1 : 0)
+#define DIRECT_MODE_INPUT(base, mask)   (*((base)+1) &= ~(mask))
+#define DIRECT_MODE_OUTPUT(base, mask)  (*((base)+1) |= (mask))
+#define DIRECT_WRITE_LOW(base, mask)    (*((base)+34) = (mask))
+#define DIRECT_WRITE_HIGH(base, mask)   (*((base)+33) = (mask))
+
+#elif defined(__SAM3X8E__) || defined(__SAM3A8C__) || defined(__SAM3A4C__)
+// Arduino 1.5.1 may have a bug in delayMicroseconds() on Arduino Due.
+// http://arduino.cc/forum/index.php/topic,141030.msg1076268.html#msg1076268
+// If you have trouble with OneWire on Arduino Due, please check the
+// status of delayMicroseconds() before reporting a bug in OneWire!
+#define PIN_TO_BASEREG(pin)             (&(digitalPinToPort(pin)->PIO_PER))
+#define PIN_TO_BITMASK(pin)             (digitalPinToBitMask(pin))
+#define IO_REG_TYPE uint32_t
+#define IO_REG_BASE_ATTR
+#define IO_REG_MASK_ATTR
+#define DIRECT_READ(base, mask)         (((*((base)+15)) & (mask)) ? 1 : 0)
+#define DIRECT_MODE_INPUT(base, mask)   ((*((base)+5)) = (mask))
+#define DIRECT_MODE_OUTPUT(base, mask)  ((*((base)+4)) = (mask))
+#define DIRECT_WRITE_LOW(base, mask)    ((*((base)+13)) = (mask))
+#define DIRECT_WRITE_HIGH(base, mask)   ((*((base)+12)) = (mask))
+#ifndef PROGMEM
+#define PROGMEM
+#endif
+#ifndef pgm_read_byte
+#define pgm_read_byte(addr) (*(const uint8_t *)(addr))
+#endif
+
+#elif defined(__PIC32MX__)
+#define PIN_TO_BASEREG(pin)             (portModeRegister(digitalPinToPort(pin)))
+#define PIN_TO_BITMASK(pin)             (digitalPinToBitMask(pin))
+#define IO_REG_TYPE uint32_t
+#define IO_REG_BASE_ATTR
+#define IO_REG_MASK_ATTR
+#define DIRECT_READ(base, mask)         (((*(base+4)) & (mask)) ? 1 : 0)  //PORTX + 0x10
+#define DIRECT_MODE_INPUT(base, mask)   ((*(base+2)) = (mask))            //TRISXSET + 0x08
+#define DIRECT_MODE_OUTPUT(base, mask)  ((*(base+1)) = (mask))            //TRISXCLR + 0x04
+#define DIRECT_WRITE_LOW(base, mask)    ((*(base+8+1)) = (mask))          //LATXCLR  + 0x24
+#define DIRECT_WRITE_HIGH(base, mask)   ((*(base+8+2)) = (mask))          //LATXSET + 0x28
+
+#elif defined(ARDUINO_ARCH_ESP8266)
+// Special note: I depend on the ESP community to maintain these definitions and
+// submit good pull requests.  I can not answer any ESP questions or help you
+// resolve any problems related to ESP chips.  Please do not contact me and please
+// DO NOT CREATE GITHUB ISSUES for ESP support.  All ESP questions must be asked
+// on ESP community forums.
+#define PIN_TO_BASEREG(pin)             ((volatile uint32_t*) GPO)
+#define PIN_TO_BITMASK(pin)             (1 << pin)
+#define IO_REG_TYPE uint32_t
+#define IO_REG_BASE_ATTR
+#define IO_REG_MASK_ATTR
+#define DIRECT_READ(base, mask)         ((GPI & (mask)) ? 1 : 0)    //GPIO_IN_ADDRESS
+#define DIRECT_MODE_INPUT(base, mask)   (GPE &= ~(mask))            //GPIO_ENABLE_W1TC_ADDRESS
+#define DIRECT_MODE_OUTPUT(base, mask)  (GPE |= (mask))             //GPIO_ENABLE_W1TS_ADDRESS
+#define DIRECT_WRITE_LOW(base, mask)    (GPOC = (mask))             //GPIO_OUT_W1TC_ADDRESS
+#define DIRECT_WRITE_HIGH(base, mask)   (GPOS = (mask))             //GPIO_OUT_W1TS_ADDRESS
+
+#elif defined(ARDUINO_ARCH_ESP32)
+#include <driver/rtc_io.h>
+#define PIN_TO_BASEREG(pin)             (0)
+#define PIN_TO_BITMASK(pin)             (pin)
+#define IO_REG_TYPE uint32_t
+#define IO_REG_BASE_ATTR
+#define IO_REG_MASK_ATTR
+
+static inline __attribute__((always_inline))
+IO_REG_TYPE directRead(IO_REG_TYPE pin)
+{
+#if CONFIG_IDF_TARGET_ESP32C3
+    return (GPIO.in.val >> pin) & 0x1;
+#else // plain ESP32
+    if ( pin < 32 )
+        return (GPIO.in >> pin) & 0x1;
+    else if ( pin < 46 )
+        return (GPIO.in1.val >> (pin - 32)) & 0x1;
+#endif
+
+    return 0;
+}
+
+static inline __attribute__((always_inline))
+void directWriteLow(IO_REG_TYPE pin)
+{
+#if CONFIG_IDF_TARGET_ESP32C3
+    GPIO.out_w1tc.val = ((uint32_t)1 << pin);
+#else // plain ESP32
+    if ( pin < 32 )
+        GPIO.out_w1tc = ((uint32_t)1 << pin);
+    else if ( pin < 46 )
+        GPIO.out1_w1tc.val = ((uint32_t)1 << (pin - 32));
+#endif
+}
+
+static inline __attribute__((always_inline))
+void directWriteHigh(IO_REG_TYPE pin)
+{
+#if CONFIG_IDF_TARGET_ESP32C3
+    GPIO.out_w1ts.val = ((uint32_t)1 << pin);
+#else // plain ESP32
+    if ( pin < 32 )
+        GPIO.out_w1ts = ((uint32_t)1 << pin);
+    else if ( pin < 46 )
+        GPIO.out1_w1ts.val = ((uint32_t)1 << (pin - 32));
+#endif
+}
+
+static inline __attribute__((always_inline))
+void directModeInput(IO_REG_TYPE pin)
+{
+#if CONFIG_IDF_TARGET_ESP32C3
+    GPIO.enable_w1tc.val = ((uint32_t)1 << (pin));
+#else
+    if ( digitalPinIsValid(pin) )
+    {
+#if ESP_IDF_VERSION_MAJOR < 4      // IDF 3.x ESP32/PICO-D4
+        uint32_t rtc_reg(rtc_gpio_desc[pin].reg);
+
+        if ( rtc_reg ) // RTC pins PULL settings
+        {
+            ESP_REG(rtc_reg) = ESP_REG(rtc_reg) & ~(rtc_gpio_desc[pin].mux);
+            ESP_REG(rtc_reg) = ESP_REG(rtc_reg) & ~(rtc_gpio_desc[pin].pullup | rtc_gpio_desc[pin].pulldown);
+        }
+#endif
+	// Input
+        if ( pin < 32 )
+            GPIO.enable_w1tc = ((uint32_t)1 << pin);
+        else
+            GPIO.enable1_w1tc.val = ((uint32_t)1 << (pin - 32));
+    }
+#endif
+}
+
+static inline __attribute__((always_inline))
+void directModeOutput(IO_REG_TYPE pin)
+{
+#if CONFIG_IDF_TARGET_ESP32C3
+    GPIO.enable_w1ts.val = ((uint32_t)1 << (pin));
+#else
+    if ( digitalPinIsValid(pin) && pin <= 33 ) // pins above 33 can be only inputs
+    {
+#if ESP_IDF_VERSION_MAJOR < 4      // IDF 3.x ESP32/PICO-D4
+        uint32_t rtc_reg(rtc_gpio_desc[pin].reg);
+
+        if ( rtc_reg ) // RTC pins PULL settings
+        {
+            ESP_REG(rtc_reg) = ESP_REG(rtc_reg) & ~(rtc_gpio_desc[pin].mux);
+            ESP_REG(rtc_reg) = ESP_REG(rtc_reg) & ~(rtc_gpio_desc[pin].pullup | rtc_gpio_desc[pin].pulldown);
+        }
+#endif
+        // Output
+        if ( pin < 32 )
+            GPIO.enable_w1ts = ((uint32_t)1 << pin);
+        else // already validated to pins <= 33
+            GPIO.enable1_w1ts.val = ((uint32_t)1 << (pin - 32));
+    }
+#endif
+}
+
+#define DIRECT_READ(base, pin)          directRead(pin)
+#define DIRECT_WRITE_LOW(base, pin)     directWriteLow(pin)
+#define DIRECT_WRITE_HIGH(base, pin)    directWriteHigh(pin)
+#define DIRECT_MODE_INPUT(base, pin)    directModeInput(pin)
+#define DIRECT_MODE_OUTPUT(base, pin)   directModeOutput(pin)
+// https://github.com/PaulStoffregen/OneWire/pull/47
+// https://github.com/stickbreaker/OneWire/commit/6eb7fc1c11a15b6ac8c60e5671cf36eb6829f82c
+#ifdef  interrupts
+#undef  interrupts
+#endif
+#ifdef  noInterrupts
+#undef  noInterrupts
+#endif
+#define noInterrupts() {portMUX_TYPE mux = portMUX_INITIALIZER_UNLOCKED;portENTER_CRITICAL(&mux)
+#define interrupts() portEXIT_CRITICAL(&mux);}
+//#warning "ESP32 OneWire testing"
+
+#elif defined(ARDUINO_ARCH_STM32)
+#define PIN_TO_BASEREG(pin)             (0)
+#define PIN_TO_BITMASK(pin)             ((uint32_t)digitalPinToPinName(pin))
+#define IO_REG_TYPE uint32_t
+#define IO_REG_BASE_ATTR
+#define IO_REG_MASK_ATTR
+#define DIRECT_READ(base, pin)          digitalReadFast((PinName)pin)
+#define DIRECT_WRITE_LOW(base, pin)     digitalWriteFast((PinName)pin, LOW)
+#define DIRECT_WRITE_HIGH(base, pin)    digitalWriteFast((PinName)pin, HIGH)
+#define DIRECT_MODE_INPUT(base, pin)    pin_function((PinName)pin, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, 0))
+#define DIRECT_MODE_OUTPUT(base, pin)   pin_function((PinName)pin, STM_PIN_DATA(STM_MODE_OUTPUT_PP, GPIO_NOPULL, 0))
+
+#elif defined(__SAMD21G18A__)
+#define PIN_TO_BASEREG(pin)             portModeRegister(digitalPinToPort(pin))
+#define PIN_TO_BITMASK(pin)             (digitalPinToBitMask(pin))
+#define IO_REG_TYPE uint32_t
+#define IO_REG_BASE_ATTR
+#define IO_REG_MASK_ATTR
+#define DIRECT_READ(base, mask)         (((*((base)+8)) & (mask)) ? 1 : 0)
+#define DIRECT_MODE_INPUT(base, mask)   ((*((base)+1)) = (mask))
+#define DIRECT_MODE_OUTPUT(base, mask)  ((*((base)+2)) = (mask))
+#define DIRECT_WRITE_LOW(base, mask)    ((*((base)+5)) = (mask))
+#define DIRECT_WRITE_HIGH(base, mask)   ((*((base)+6)) = (mask))
+
+#elif defined(__ASR6501__)
+#define PIN_IN_PORT(pin)    (pin % PIN_NUMBER_IN_PORT)
+#define PORT_FROM_PIN(pin)  (pin / PIN_NUMBER_IN_PORT)
+#define PORT_OFFSET(port)   (PORT_REG_SHFIT * port)
+#define PORT_ADDRESS(pin)   (CYDEV_GPIO_BASE + PORT_OFFSET(PORT_FROM_PIN(pin)))
+
+#define PIN_TO_BASEREG(pin)             (0)
+#define PIN_TO_BITMASK(pin)             (pin)
+#define IO_REG_TYPE uint32_t
+#define IO_REG_BASE_ATTR
+#define IO_REG_MASK_ATTR
+#define DIRECT_READ(base, pin)          CY_SYS_PINS_READ_PIN(PORT_ADDRESS(pin)+4, PIN_IN_PORT(pin))
+#define DIRECT_WRITE_LOW(base, pin)     CY_SYS_PINS_CLEAR_PIN(PORT_ADDRESS(pin), PIN_IN_PORT(pin))
+#define DIRECT_WRITE_HIGH(base, pin)    CY_SYS_PINS_SET_PIN(PORT_ADDRESS(pin), PIN_IN_PORT(pin))
+#define DIRECT_MODE_INPUT(base, pin)    CY_SYS_PINS_SET_DRIVE_MODE(PORT_ADDRESS(pin)+8, PIN_IN_PORT(pin), CY_SYS_PINS_DM_DIG_HIZ)
+#define DIRECT_MODE_OUTPUT(base, pin)   CY_SYS_PINS_SET_DRIVE_MODE(PORT_ADDRESS(pin)+8, PIN_IN_PORT(pin), CY_SYS_PINS_DM_STRONG)
+
+#elif defined(RBL_NRF51822)
+#define PIN_TO_BASEREG(pin)             (0)
+#define PIN_TO_BITMASK(pin)             (pin)
+#define IO_REG_TYPE uint32_t
+#define IO_REG_BASE_ATTR
+#define IO_REG_MASK_ATTR
+#define DIRECT_READ(base, pin)          nrf_gpio_pin_read(pin)
+#define DIRECT_WRITE_LOW(base, pin)     nrf_gpio_pin_clear(pin)
+#define DIRECT_WRITE_HIGH(base, pin)    nrf_gpio_pin_set(pin)
+#define DIRECT_MODE_INPUT(base, pin)    nrf_gpio_cfg_input(pin, NRF_GPIO_PIN_NOPULL)
+#define DIRECT_MODE_OUTPUT(base, pin)   nrf_gpio_cfg_output(pin)
+
+#elif defined(__arc__) /* Arduino101/Genuino101 specifics */
+
+#include "scss_registers.h"
+#include "portable.h"
+#include "avr/pgmspace.h"
+
+#define GPIO_ID(pin)			(g_APinDescription[pin].ulGPIOId)
+#define GPIO_TYPE(pin)			(g_APinDescription[pin].ulGPIOType)
+#define GPIO_BASE(pin)			(g_APinDescription[pin].ulGPIOBase)
+#define DIR_OFFSET_SS			0x01
+#define DIR_OFFSET_SOC			0x04
+#define EXT_PORT_OFFSET_SS		0x0A
+#define EXT_PORT_OFFSET_SOC		0x50
+
+/* GPIO registers base address */
+#define PIN_TO_BASEREG(pin)		((volatile uint32_t *)g_APinDescription[pin].ulGPIOBase)
+#define PIN_TO_BITMASK(pin)		pin
+#define IO_REG_TYPE			uint32_t
+#define IO_REG_BASE_ATTR
+#define IO_REG_MASK_ATTR
+
+static inline __attribute__((always_inline))
+IO_REG_TYPE directRead(volatile IO_REG_TYPE *base, IO_REG_TYPE pin)
+{
+    IO_REG_TYPE ret;
+    if (SS_GPIO == GPIO_TYPE(pin)) {
+        ret = READ_ARC_REG(((IO_REG_TYPE)base + EXT_PORT_OFFSET_SS));
+    } else {
+        ret = MMIO_REG_VAL_FROM_BASE((IO_REG_TYPE)base, EXT_PORT_OFFSET_SOC);
+    }
+    return ((ret >> GPIO_ID(pin)) & 0x01);
+}
+
+static inline __attribute__((always_inline))
+void directModeInput(volatile IO_REG_TYPE *base, IO_REG_TYPE pin)
+{
+    if (SS_GPIO == GPIO_TYPE(pin)) {
+        WRITE_ARC_REG(READ_ARC_REG((((IO_REG_TYPE)base) + DIR_OFFSET_SS)) & ~(0x01 << GPIO_ID(pin)),
+			((IO_REG_TYPE)(base) + DIR_OFFSET_SS));
+    } else {
+        MMIO_REG_VAL_FROM_BASE((IO_REG_TYPE)base, DIR_OFFSET_SOC) &= ~(0x01 << GPIO_ID(pin));
+    }
+}
+
+static inline __attribute__((always_inline))
+void directModeOutput(volatile IO_REG_TYPE *base, IO_REG_TYPE pin)
+{
+    if (SS_GPIO == GPIO_TYPE(pin)) {
+        WRITE_ARC_REG(READ_ARC_REG(((IO_REG_TYPE)(base) + DIR_OFFSET_SS)) | (0x01 << GPIO_ID(pin)),
+			((IO_REG_TYPE)(base) + DIR_OFFSET_SS));
+    } else {
+        MMIO_REG_VAL_FROM_BASE((IO_REG_TYPE)base, DIR_OFFSET_SOC) |= (0x01 << GPIO_ID(pin));
+    }
+}
+
+static inline __attribute__((always_inline))
+void directWriteLow(volatile IO_REG_TYPE *base, IO_REG_TYPE pin)
+{
+    if (SS_GPIO == GPIO_TYPE(pin)) {
+        WRITE_ARC_REG(READ_ARC_REG(base) & ~(0x01 << GPIO_ID(pin)), base);
+    } else {
+        MMIO_REG_VAL(base) &= ~(0x01 << GPIO_ID(pin));
+    }
+}
+
+static inline __attribute__((always_inline))
+void directWriteHigh(volatile IO_REG_TYPE *base, IO_REG_TYPE pin)
+{
+    if (SS_GPIO == GPIO_TYPE(pin)) {
+        WRITE_ARC_REG(READ_ARC_REG(base) | (0x01 << GPIO_ID(pin)), base);
+    } else {
+        MMIO_REG_VAL(base) |= (0x01 << GPIO_ID(pin));
+    }
+}
+
+#define DIRECT_READ(base, pin)		directRead(base, pin)
+#define DIRECT_MODE_INPUT(base, pin)	directModeInput(base, pin)
+#define DIRECT_MODE_OUTPUT(base, pin)	directModeOutput(base, pin)
+#define DIRECT_WRITE_LOW(base, pin)	directWriteLow(base, pin)
+#define DIRECT_WRITE_HIGH(base, pin)	directWriteHigh(base, pin)
+
+#elif defined(__riscv)
+
+/*
+ * Tested on highfive1
+ *
+ * Stable results are achieved operating in the
+ * two high speed modes of the highfive1.  It
+ * seems to be less reliable in slow mode.
+ */
+#define PIN_TO_BASEREG(pin)             (0)
+#define PIN_TO_BITMASK(pin)             digitalPinToBitMask(pin)
+#define IO_REG_TYPE uint32_t
+#define IO_REG_BASE_ATTR
+#define IO_REG_MASK_ATTR
+
+static inline __attribute__((always_inline))
+IO_REG_TYPE directRead(IO_REG_TYPE mask)
+{
+    return ((GPIO_REG(GPIO_INPUT_VAL) & mask) != 0) ? 1 : 0;
+}
+
+static inline __attribute__((always_inline))
+void directModeInput(IO_REG_TYPE mask)
+{
+    GPIO_REG(GPIO_OUTPUT_XOR)  &= ~mask;
+    GPIO_REG(GPIO_IOF_EN)      &= ~mask;
+
+    GPIO_REG(GPIO_INPUT_EN)  |=  mask;
+    GPIO_REG(GPIO_OUTPUT_EN) &= ~mask;
+}
+
+static inline __attribute__((always_inline))
+void directModeOutput(IO_REG_TYPE mask)
+{
+    GPIO_REG(GPIO_OUTPUT_XOR)  &= ~mask;
+    GPIO_REG(GPIO_IOF_EN)      &= ~mask;
+
+    GPIO_REG(GPIO_INPUT_EN)  &= ~mask;
+    GPIO_REG(GPIO_OUTPUT_EN) |=  mask;
+}
+
+static inline __attribute__((always_inline))
+void directWriteLow(IO_REG_TYPE mask)
+{
+    GPIO_REG(GPIO_OUTPUT_VAL) &= ~mask;
+}
+
+static inline __attribute__((always_inline))
+void directWriteHigh(IO_REG_TYPE mask)
+{
+    GPIO_REG(GPIO_OUTPUT_VAL) |= mask;
+}
+
+#define DIRECT_READ(base, mask)          directRead(mask)
+#define DIRECT_WRITE_LOW(base, mask)     directWriteLow(mask)
+#define DIRECT_WRITE_HIGH(base, mask)    directWriteHigh(mask)
+#define DIRECT_MODE_INPUT(base, mask)    directModeInput(mask)
+#define DIRECT_MODE_OUTPUT(base, mask)   directModeOutput(mask)
+
+#else
+#define PIN_TO_BASEREG(pin)             (0)
+#define PIN_TO_BITMASK(pin)             (pin)
+#define IO_REG_TYPE unsigned int
+#define IO_REG_BASE_ATTR
+#define IO_REG_MASK_ATTR
+#define DIRECT_READ(base, pin)          digitalRead(pin)
+#define DIRECT_WRITE_LOW(base, pin)     digitalWrite(pin, LOW)
+#define DIRECT_WRITE_HIGH(base, pin)    digitalWrite(pin, HIGH)
+#define DIRECT_MODE_INPUT(base, pin)    pinMode(pin,INPUT)
+#define DIRECT_MODE_OUTPUT(base, pin)   pinMode(pin,OUTPUT)
+#warning "OneWire. Fallback mode. Using API calls for pinMode,digitalRead and digitalWrite. Operation of this library is not guaranteed on this architecture."
+
+#endif
+
+#endif

+ 55 - 0
lib/OneWire/util/OneWire_direct_regtype.h

@@ -0,0 +1,55 @@
+#ifndef OneWire_Direct_RegType_h
+#define OneWire_Direct_RegType_h
+
+#include <stdint.h>
+
+// Platform specific I/O register type
+
+#if defined(__AVR__)
+#define IO_REG_TYPE uint8_t
+
+#elif defined(__MK20DX128__) || defined(__MK20DX256__) || defined(__MK66FX1M0__) || defined(__MK64FX512__)
+#define IO_REG_TYPE uint8_t
+
+#elif defined(__IMXRT1052__) || defined(__IMXRT1062__)
+#define IO_REG_TYPE uint32_t
+
+#elif defined(__MKL26Z64__)
+#define IO_REG_TYPE uint8_t
+
+#elif defined(__SAM3X8E__) || defined(__SAM3A8C__) || defined(__SAM3A4C__)
+#define IO_REG_TYPE uint32_t
+
+#elif defined(__PIC32MX__)
+#define IO_REG_TYPE uint32_t
+
+#elif defined(ARDUINO_ARCH_ESP8266)
+#define IO_REG_TYPE uint32_t
+
+#elif defined(ARDUINO_ARCH_ESP32)
+#define IO_REG_TYPE uint32_t
+#define IO_REG_MASK_ATTR
+
+#elif defined(ARDUINO_ARCH_STM32)
+#define IO_REG_TYPE uint32_t
+
+#elif defined(__SAMD21G18A__)
+#define IO_REG_TYPE uint32_t
+
+#elif defined(__ASR6501__)
+#define IO_REG_TYPE uint32_t
+
+#elif defined(RBL_NRF51822)
+#define IO_REG_TYPE uint32_t
+
+#elif defined(__arc__) /* Arduino101/Genuino101 specifics */
+#define IO_REG_TYPE uint32_t
+
+#elif defined(__riscv)
+#define IO_REG_TYPE uint32_t
+
+#else
+#define IO_REG_TYPE unsigned int
+
+#endif
+#endif

+ 46 - 0
lib/README

@@ -0,0 +1,46 @@
+
+This directory is intended for project specific (private) libraries.
+PlatformIO will compile them to static libraries and link into executable file.
+
+The source code of each library should be placed in a an own separate directory
+("lib/your_library_name/[here are source files]").
+
+For example, see a structure of the following two libraries `Foo` and `Bar`:
+
+|--lib
+|  |
+|  |--Bar
+|  |  |--docs
+|  |  |--examples
+|  |  |--src
+|  |     |- Bar.c
+|  |     |- Bar.h
+|  |  |- library.json (optional, custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html
+|  |
+|  |--Foo
+|  |  |- Foo.c
+|  |  |- Foo.h
+|  |
+|  |- README --> THIS FILE
+|
+|- platformio.ini
+|--src
+   |- main.c
+
+and a contents of `src/main.c`:
+```
+#include <Foo.h>
+#include <Bar.h>
+
+int main (void)
+{
+  ...
+}
+
+```
+
+PlatformIO Library Dependency Finder will find automatically dependent
+libraries scanning project source files.
+
+More information about PlatformIO Library Dependency Finder
+- https://docs.platformio.org/page/librarymanager/ldf.html

+ 15 - 0
platformio.ini

@@ -0,0 +1,15 @@
+; PlatformIO Project Configuration File
+;
+;   Build options: build flags, source filter
+;   Upload options: custom upload port, speed and extra flags
+;   Library options: dependencies, extra library storages
+;   Advanced options: extra scripting
+;
+; Please visit documentation for the other options and examples
+; https://docs.platformio.org/page/projectconf.html
+
+[env:uno]
+platform = atmelavr
+board = uno
+framework = arduino
+build_type = release

+ 66 - 0
src/Toaster.cpp

@@ -0,0 +1,66 @@
+//////////////////////////////////////////////////////////////////////
+//                                                                  //
+// Programmname: <Bitte einen treffenden Namen>                     //
+// Datum: TT.MM.JJJJ                                                //
+// Beschreibung: <Kurze Beschreibung des Programms>                 //
+//                                                                  //
+// 1. Autor: Vorname Name, Matrikel, Matrikel-Nr.                   //
+// 2. Autor: Vorname Name, Matrikel, Matrikel-Nr.                   //
+//                                                                  //
+//////////////////////////////////////////////////////////////////////
+
+//////////           Inkludierte Header-Dateien             //////////
+#include "Toaster.h"
+
+//////////                Globale Variablen                 //////////
+DS18B20 Tempsensor = DS18B20(TEMPSENSOR_PIN);
+LiquidCrystal Display = LiquidCrystal(13, 12, 10, 9, 8, 7);
+
+
+//////////                 Setup-Funktion                   //////////
+
+void setup(void) { // put your setup code here, to run once:
+
+  //////////            Lokale Variablen            //////////
+
+
+  //////////               GPIO Setup               //////////
+  Serial.begin(BAUDRATE);
+  Display.begin(16,2);
+
+  //////////         Einmalige Anweisungen          //////////
+  
+
+}
+
+
+//////////                  Loop-Funktion                   //////////
+
+void loop(void) { // put your main code here, to run repeatedly:
+
+  //////////            Lokale Variablen            //////////
+
+
+  //////////              Hauptprogramm             //////////
+
+}
+
+//////////              Unterfunktionen / ISR               //////////
+
+void lcd(float temp_in_c, int tact_in_s, int tmax_in_s) {
+  Display.setCursor(0, 0);
+  Display.print("Temp=");
+  Display.print(temp_in_c);
+  Display.print("*C ");
+  Display.setCursor(0, 1);
+  Display.print("t=");
+  Display.print(tact_in_s);
+  Display.print("s");
+  Display.print(" tmax=");
+  Display.print(tmax_in_s);
+  Display.print("s");
+}
+
+float get_temp(void) {
+  return Tempsensor.getTempC();
+}

+ 11 - 0
test/README

@@ -0,0 +1,11 @@
+
+This directory is intended for PlatformIO Test Runner and project tests.
+
+Unit Testing is a software testing method by which individual units of
+source code, sets of one or more MCU program modules together with associated
+control data, usage procedures, and operating procedures, are tested to
+determine whether they are fit for use. Unit testing finds problems early
+in the development cycle.
+
+More information about PlatformIO Unit Testing:
+- https://docs.platformio.org/en/latest/advanced/unit-testing/index.html