1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2025-12-24 22:13:52 +01:00

Merge pull request #16587 from spectraphilic/sdi12

pkg/arduino_sdi_12: add SDI-12 for Arduino as package
This commit is contained in:
Marian Buschsieweke 2021-10-28 18:21:10 +02:00 committed by GitHub
commit e53efa3e7f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 408 additions and 0 deletions

View File

@ -170,6 +170,22 @@ static const arduino_pwm_t arduino_pwm_list[] = {
#endif
};
/**
* @brief F_CPU defines the CPU frequency in Hz.
*
* This is used in AVR's libc delay.h and setbaud.h
*
* In RIOT delay() has a different implementation using ztimer, and F_CPU is
* already defined when using setbaud.h (see cpu/atmega_common/periph/uart.c)
*
* However Arduino libraries and sketches may expect F_CPU to be defined and
* fail otherwise (for example the Arduino SDI-12 package expects this, for AVR
* cpus). For this reason we define F_CPU here, if not already defined.
*/
#ifndef F_CPU
#define F_CPU CLOCK_CORECLOCK
#endif
#ifdef __cplusplus
}
#endif

View File

@ -6,6 +6,7 @@
#
menu "Packages"
rsource "arduino_sdi_12/Kconfig"
rsource "c25519/Kconfig"
rsource "cayenne-lpp/Kconfig"
rsource "cifra/Kconfig"

4
pkg/arduino_api/Kconfig Normal file
View File

@ -0,0 +1,4 @@
config PACKAGE_ARDUINO_API
bool "Arduino API package"
depends on TEST_KCONFIG
depends on MODULE_ARDUINO

11
pkg/arduino_api/Makefile Normal file
View File

@ -0,0 +1,11 @@
PKG_NAME=arduino_api
PKG_URL=https://github.com/arduino/ArduinoCore-API
PKG_VERSION=e03b65374c614130aa1b11597e07b3b5089a726d
PKG_LICENSE=LGPL-2.1
GITAMFLAGS = --3way
include $(RIOTBASE)/pkg/pkg.mk
all:
$(QQ)"$(MAKE)" -C $(PKG_SOURCE_DIR)/api -f $(RIOTBASE)/Makefile.base MODULE=$(PKG_NAME)

View File

@ -0,0 +1 @@
USEMODULE += arduino

View File

@ -0,0 +1,3 @@
INCLUDES += -I$(PKGDIRBASE)/arduino_api/api
CXXEXFLAGS += -std=c++11

6
pkg/arduino_api/doc.txt Normal file
View File

@ -0,0 +1,6 @@
/**
* @defgroup pkg_arduino_api Hardware independent layer of the Arduino cores
* @ingroup pkg
* @brief Hardware independent layer of the Arduino cores
* @see https://github.com/arduino/ArduinoCore-API
*/

View File

@ -0,0 +1,95 @@
From 450ac61995792240213e2d05ab83039e4ef07df0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?J=2E=20David=20Ib=C3=A1=C3=B1ez?= <jdavid.ibp@gmail.com>
Date: Wed, 13 Oct 2021 09:25:24 +0200
Subject: [PATCH 1/1] Chages for RIOT integration
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
- Fix "has not been declared" errors
- Remove attach/detach interrupt funcions
Signed-off-by: J. David Ibáñez <jdavid.ibp@gmail.com>
---
api/Common.h | 3 ---
api/Interrupts.h | 44 --------------------------------------------
api/Stream.h | 2 +-
3 files changed, 1 insertion(+), 48 deletions(-)
diff --git api/Common.h api/Common.h
index c40a35a..c2d9de4 100644
--- api/Common.h
+++ api/Common.h
@@ -109,9 +109,6 @@ unsigned long pulseInLong(pin_size_t pin, uint8_t state, unsigned long timeout);
void shiftOut(pin_size_t dataPin, pin_size_t clockPin, BitOrder bitOrder, uint8_t val);
uint8_t shiftIn(pin_size_t dataPin, pin_size_t clockPin, BitOrder bitOrder);
-void attachInterrupt(pin_size_t interruptNumber, voidFuncPtr callback, PinStatus mode);
-void attachInterruptParam(pin_size_t interruptNumber, voidFuncPtrParam callback, PinStatus mode, void* param);
-void detachInterrupt(pin_size_t interruptNumber);
void setup(void);
void loop(void);
diff --git api/Interrupts.h api/Interrupts.h
index e306fc7..e69de29 100644
--- api/Interrupts.h
+++ api/Interrupts.h
@@ -1,44 +0,0 @@
-#ifndef W_INTERRUPTS_CPP
-#define W_INTERRUPTS_CPP
-#ifdef __cplusplus
-
-#include <stdlib.h>
-#include <stdbool.h>
-#include <stdint.h>
-#include "Common.h"
-
-namespace arduino {
-
-template <typename T>
-using voidTemplateFuncPtrParam = void (*)(T param);
-
-template<typename T> struct __container__ {
- void* param;
- voidTemplateFuncPtrParam<T> function;
-};
-
-// C++ only overloaded version of attachInterrupt function
-template<typename T> void attachInterrupt(pin_size_t interruptNum, voidTemplateFuncPtrParam<T> userFunc, PinStatus mode, T& param) {
-
- struct __container__<T> *cont = new __container__<T>();
- cont->param = &param;
- cont->function = userFunc;
-
- // TODO: check lambda scope
- // TODO: add structure to delete(__container__) when detachInterrupt() is called
- auto f = [](void* a) -> void
- {
- T param = *(T*)((struct __container__<T>*)a)->param;
- (((struct __container__<T>*)a)->function)(param);
- };
-
- attachInterruptParam(interruptNum, f, mode, cont);
-}
-
-template<typename T> void attachInterrupt(pin_size_t interruptNum, voidTemplateFuncPtrParam<T*> userFunc, PinStatus mode, T* param) {
- attachInterruptParam(interruptNum, (voidFuncPtrParam)userFunc, mode, (void*)param);
-}
-
-}
-#endif
-#endif
diff --git api/Stream.h api/Stream.h
index e81c71b..b22d0b2 100644
--- api/Stream.h
+++ api/Stream.h
@@ -130,4 +130,4 @@ class Stream : public Print
}
-using arduino::Stream;
\ No newline at end of file
+using namespace arduino;
--
2.32.0

View File

@ -0,0 +1,4 @@
config PACKAGE_ARDUINO_SDI_12
bool "Arduino SDI-12 package"
depends on TEST_KCONFIG
depends on PACKAGE_ARDUINO_API

View File

@ -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)

View File

@ -0,0 +1,4 @@
FEATURES_REQUIRED += periph_gpio_irq
USEMODULE += atmega_pcint
USEPKG += arduino_api

View File

@ -0,0 +1 @@
INCLUDES += -I$(PKGDIRBASE)/arduino_sdi_12/src

View File

@ -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
*/

View File

@ -0,0 +1,62 @@
From 03139fbb7f311fa210b9f0dbfd10899a8a336af9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?J=2E=20David=20Ib=C3=A1=C3=B1ez?= <jdavid.ibp@gmail.com>
Date: Thu, 7 Oct 2021 19:35:14 +0200
Subject: [PATCH] Use RIOT's gpio to handle pin change interrupts
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: J. David Ibáñez <jdavid.ibp@gmail.com>
---
src/SDI12.cpp | 8 +++++---
src/SDI12.h | 4 ++--
2 files changed, 7 insertions(+), 5 deletions(-)
diff --git src/SDI12.cpp src/SDI12.cpp
index c71e998..257eb5a 100644
--- src/SDI12.cpp
+++ src/SDI12.cpp
@@ -349,10 +349,11 @@ void SDI12::setPinInterrupts(bool enable) {
// We don't detach the function from the interrupt for AVR processors
}
#else
+ gpio_t pin = arduino_pinmap[_dataPin];
if (enable) {
- return;
+ gpio_init_int(pin, GPIO_IN, GPIO_BOTH, handleInterrupt, NULL);
} else {
- return;
+ gpio_irq_disable(pin);
}
#endif
}
@@ -557,7 +558,8 @@ void ICACHE_RAM_ATTR SDI12::handleInterrupt() {
if (_activeObject) _activeObject->receiveISR();
}
#else
-void SDI12::handleInterrupt() {
+void SDI12::handleInterrupt(void *arg) {
+ (void)arg;
if (_activeObject) _activeObject->receiveISR();
}
#endif
diff --git src/SDI12.h src/SDI12.h
index ec949e3..6469c7b 100644
--- src/SDI12.h
+++ src/SDI12.h
@@ -971,10 +971,10 @@ class SDI12 : public Stream {
*
* On espressif boards (ESP8266 and ESP32), the ISR must be stored in IRAM
*/
- static void handleInterrupt();
+ static void handleInterrupt(void *arg = NULL);
/** on AVR boards, uncomment to use your own PCINT ISRs */
- // #define SDI12_EXTERNAL_PCINT
+ #define SDI12_EXTERNAL_PCINT
/**@}*/
};
--
2.32.0

View File

@ -23,6 +23,7 @@
extern "C" {
#include <stdint.h>
#include "irq.h"
#include "periph/gpio.h"
#include "arduino_board.h"
}
@ -165,5 +166,21 @@ int analogRead(int pin);
void analogWrite(int pin, int value);
#endif
/**
* @brief Enables interrupts
*/
static inline void interrupts(void)
{
irq_enable();
}
/**
* @brief Disables interrupts
*/
static inline void noInterrupts(void)
{
irq_disable();
}
#endif /* ARDUINO_HPP */
/** @} */

View File

@ -0,0 +1,10 @@
include ../Makefile.tests_common
USEPKG += arduino_sdi_12
BOARD_WHITELIST := \
arduino-leonardo \
arduino-mega2560 \
#
include $(RIOTBASE)/Makefile.include

View File

@ -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

View File

@ -0,0 +1,114 @@
/*
* Copyright (C) 2021 J. David Ibáñez <jdavid.ibp@gmail.com>
*
* 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 <jdavid.ibp@gmail.com>
*
* @}
*/
#include <fmt.h>
#include <SDI12.h>
#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);
}
}