diff --git a/pkg/Kconfig b/pkg/Kconfig index 04a9f49996..83b9b1517e 100644 --- a/pkg/Kconfig +++ b/pkg/Kconfig @@ -6,6 +6,7 @@ # menu "Packages" +rsource "arduino_sdi_12/Kconfig" rsource "c25519/Kconfig" rsource "cayenne-lpp/Kconfig" rsource "cifra/Kconfig" diff --git a/pkg/arduino_sdi_12/Kconfig b/pkg/arduino_sdi_12/Kconfig new file mode 100644 index 0000000000..9ff459a2e5 --- /dev/null +++ b/pkg/arduino_sdi_12/Kconfig @@ -0,0 +1,4 @@ +config PACKAGE_ARDUINO_SDI_12 + bool "Arduino SDI-12 package" + depends on TEST_KCONFIG + depends on PACKAGE_ARDUINO_API diff --git a/pkg/arduino_sdi_12/Makefile b/pkg/arduino_sdi_12/Makefile new file mode 100644 index 0000000000..bc4e253f62 --- /dev/null +++ b/pkg/arduino_sdi_12/Makefile @@ -0,0 +1,11 @@ +PKG_NAME=arduino_sdi_12 +PKG_URL=https://github.com/EnviroDIY/Arduino-SDI-12 +PKG_VERSION=fd9699b390edeac3a8681e2a6d4fe2ba8b1f9a51 +PKG_LICENSE=BSD-3-Clause + +GITAMFLAGS = --3way + +include $(RIOTBASE)/pkg/pkg.mk + +all: + $(QQ)"$(MAKE)" -C $(PKG_SOURCE_DIR)/src -f $(RIOTBASE)/Makefile.base MODULE=$(PKG_NAME) diff --git a/pkg/arduino_sdi_12/Makefile.dep b/pkg/arduino_sdi_12/Makefile.dep new file mode 100644 index 0000000000..d1f5055aab --- /dev/null +++ b/pkg/arduino_sdi_12/Makefile.dep @@ -0,0 +1,4 @@ +FEATURES_REQUIRED += periph_gpio_irq +USEMODULE += atmega_pcint + +USEPKG += arduino_api diff --git a/pkg/arduino_sdi_12/Makefile.include b/pkg/arduino_sdi_12/Makefile.include new file mode 100644 index 0000000000..0dc824d92c --- /dev/null +++ b/pkg/arduino_sdi_12/Makefile.include @@ -0,0 +1 @@ +INCLUDES += -I$(PKGDIRBASE)/arduino_sdi_12/src diff --git a/pkg/arduino_sdi_12/doc.txt b/pkg/arduino_sdi_12/doc.txt new file mode 100644 index 0000000000..465a7694a1 --- /dev/null +++ b/pkg/arduino_sdi_12/doc.txt @@ -0,0 +1,6 @@ +/** + * @defgroup pkg_arduino_sdi_12 Arduino library for SDI-12 communication + * @ingroup pkg + * @brief Implements support for the SDI-12 serial communications protocol + * @see https://github.com/EnviroDIY/Arduino-SDI-12 + */ diff --git a/pkg/arduino_sdi_12/patches/0001-Use-RIOT-s-gpio-to-handle-pin-change-interrupts.patch b/pkg/arduino_sdi_12/patches/0001-Use-RIOT-s-gpio-to-handle-pin-change-interrupts.patch new file mode 100644 index 0000000000..947ebabf4b Binary files /dev/null and b/pkg/arduino_sdi_12/patches/0001-Use-RIOT-s-gpio-to-handle-pin-change-interrupts.patch differ diff --git a/tests/pkg_arduino_sdi_12/Makefile b/tests/pkg_arduino_sdi_12/Makefile new file mode 100644 index 0000000000..cd66097236 --- /dev/null +++ b/tests/pkg_arduino_sdi_12/Makefile @@ -0,0 +1,10 @@ +include ../Makefile.tests_common + +USEPKG += arduino_sdi_12 + +BOARD_WHITELIST := \ + arduino-leonardo \ + arduino-mega2560 \ + # + +include $(RIOTBASE)/Makefile.include diff --git a/tests/pkg_arduino_sdi_12/README.md b/tests/pkg_arduino_sdi_12/README.md new file mode 100644 index 0000000000..0f4cde0083 --- /dev/null +++ b/tests/pkg_arduino_sdi_12/README.md @@ -0,0 +1,42 @@ +The purpose of this test program is to verify that the `arduino_sdi_12` package +works. + +To test it you will need a SDI-12 sensor. The SDI-12 protocol uses 3 wires: +power, ground, and data. Use the D13 pin for the data line. + +The program will loop forever. In every loop it: + +- Tries to find the address of the attached sensor (sends the `?!` command); +- Asks the sensor to identify itself (sends the `aI!` command); +- Asks the sensor to start a measurement (sends the `aM!` command); +- Waits for as many seconds as the sensor said in its response to the + measurement command; +- Asks the sensor for the data, the result of the measurement (sends the `aD0!` + command); +- Waits 5 seconds and starts the loop again. + +This is an example, with the Arduino Mega2560 board and the Decagon CTD-10 +sensor: + + $ BOARD=arduino-mega2560 make -C tests/pkg_arduino_sdi_12 all flash term + [...] + 2021-09-28 12:14:57,492 # main(): This is RIOT! (Version: 2021.10-devel-776-gc7af21-sdi12) + 2021-09-28 12:14:57,496 # Testing the Arduino-SDI-12 package + 2021-09-28 12:14:57,995 # + 2021-09-28 12:14:58,007 # Send: ?! + 2021-09-28 12:14:58,352 # Recv: 0 + 2021-09-28 12:14:58,364 # Send: 0I! + 2021-09-28 12:14:58,749 # Recv: 013DECAGON CTD-103991059303507 + 2021-09-28 12:14:58,761 # Send: 0M! + 2021-09-28 12:14:59,118 # Recv: 00013 + 2021-09-28 12:15:00,129 # Send: 0D0! + 2021-09-28 12:15:00,502 # Recv: 0+35+26.4+0 + 2021-09-28 12:15:05,507 # + 2021-09-28 12:15:05,519 # Send: ?! + 2021-09-28 12:15:05,863 # Recv: 0 + 2021-09-28 12:15:05,875 # Send: 0I! + 2021-09-28 12:15:06,260 # Recv: 013DECAGON CTD-103991059303507 + 2021-09-28 12:15:06,268 # Send: 0M! + 2021-09-28 12:15:06,629 # Recv: 00013 + 2021-09-28 12:15:07,641 # Send: 0D0! + 2021-09-28 12:15:08,013 # Recv: 0+36+26.4+0 diff --git a/tests/pkg_arduino_sdi_12/main.cpp b/tests/pkg_arduino_sdi_12/main.cpp new file mode 100644 index 0000000000..9919703ffd --- /dev/null +++ b/tests/pkg_arduino_sdi_12/main.cpp @@ -0,0 +1,114 @@ +/* + * Copyright (C) 2021 J. David Ibáñez + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup tests + * @{ + * + * @file + * @brief Tests the Arduino-SDI-12 package + * + * @author J. David Ibáñez + * + * @} + */ + +#include +#include + +#ifndef SDI12_DATA_PIN +#define SDI12_DATA_PIN 13 +#endif + +SDI12 sdi12(SDI12_DATA_PIN); + +void sendCommand(const char *cmd) +{ + print_str("Send: "); + print_str(cmd); + print_str("\n"); + sdi12.clearBuffer(); + sdi12.sendCommand(cmd); + delay(300); +} + +void readResponse(char *buffer) +{ + int i = 0; + while (sdi12.available()) { + char c = sdi12.read(); + if (c == '\0') { + continue; + } + + buffer[i++] = c; + } + buffer[i] = '\0'; + + print_str("Recv: "); + print_str(buffer); + + // Responses from SDI-12 end by \r\n + if (buffer[0] == '\0') { + print_str("\n"); + } +} + +int main(void) +{ + char cmd[10]; + char out[50]; + + print_str("Testing the Arduino-SDI-12 package\n"); + + sdi12.begin(); + delay(500); // allow things to settle + + while (1) { + print_str("\n"); + + // Address query command (?!) + sendCommand("?!"); + readResponse(out); + if (strlen(out) == 0) { + continue; + } + + // For the rest of the loop the first command char will always be the + // device address + cmd[0] = out[0]; + + // Identification command (aI!) + cmd[1] = 'I'; + cmd[2] = '!'; + cmd[3] = '\0'; + sendCommand(cmd); + readResponse(out); + + // Start measurement (aM!) + cmd[1] = 'M'; + sendCommand(cmd); + readResponse(out); // atttn + + // Wait ttt seconds + unsigned int ttt; + ttt = (out[1] - '0') * 100 + (out[2] - '0') * 10 + (out[3] - '0'); + delay(ttt * 1000); + + // Data command (aD0!) + cmd[1] = 'D'; + cmd[2] = '0'; + cmd[3] = '!'; + cmd[4] = '\0'; + sendCommand(cmd); + readResponse(out); + + // Repeat in 5 seconds + delay(5000); + } +}