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:
commit
e53efa3e7f
@ -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
|
||||
|
||||
@ -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
4
pkg/arduino_api/Kconfig
Normal 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
11
pkg/arduino_api/Makefile
Normal 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)
|
||||
1
pkg/arduino_api/Makefile.dep
Normal file
1
pkg/arduino_api/Makefile.dep
Normal file
@ -0,0 +1 @@
|
||||
USEMODULE += arduino
|
||||
3
pkg/arduino_api/Makefile.include
Normal file
3
pkg/arduino_api/Makefile.include
Normal file
@ -0,0 +1,3 @@
|
||||
INCLUDES += -I$(PKGDIRBASE)/arduino_api/api
|
||||
|
||||
CXXEXFLAGS += -std=c++11
|
||||
6
pkg/arduino_api/doc.txt
Normal file
6
pkg/arduino_api/doc.txt
Normal 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
|
||||
*/
|
||||
@ -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 = ¶m;
|
||||
- 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
|
||||
|
||||
4
pkg/arduino_sdi_12/Kconfig
Normal file
4
pkg/arduino_sdi_12/Kconfig
Normal file
@ -0,0 +1,4 @@
|
||||
config PACKAGE_ARDUINO_SDI_12
|
||||
bool "Arduino SDI-12 package"
|
||||
depends on TEST_KCONFIG
|
||||
depends on PACKAGE_ARDUINO_API
|
||||
11
pkg/arduino_sdi_12/Makefile
Normal file
11
pkg/arduino_sdi_12/Makefile
Normal 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)
|
||||
4
pkg/arduino_sdi_12/Makefile.dep
Normal file
4
pkg/arduino_sdi_12/Makefile.dep
Normal file
@ -0,0 +1,4 @@
|
||||
FEATURES_REQUIRED += periph_gpio_irq
|
||||
USEMODULE += atmega_pcint
|
||||
|
||||
USEPKG += arduino_api
|
||||
1
pkg/arduino_sdi_12/Makefile.include
Normal file
1
pkg/arduino_sdi_12/Makefile.include
Normal file
@ -0,0 +1 @@
|
||||
INCLUDES += -I$(PKGDIRBASE)/arduino_sdi_12/src
|
||||
6
pkg/arduino_sdi_12/doc.txt
Normal file
6
pkg/arduino_sdi_12/doc.txt
Normal 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
|
||||
*/
|
||||
@ -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
|
||||
|
||||
@ -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 */
|
||||
/** @} */
|
||||
|
||||
10
tests/pkg_arduino_sdi_12/Makefile
Normal file
10
tests/pkg_arduino_sdi_12/Makefile
Normal file
@ -0,0 +1,10 @@
|
||||
include ../Makefile.tests_common
|
||||
|
||||
USEPKG += arduino_sdi_12
|
||||
|
||||
BOARD_WHITELIST := \
|
||||
arduino-leonardo \
|
||||
arduino-mega2560 \
|
||||
#
|
||||
|
||||
include $(RIOTBASE)/Makefile.include
|
||||
42
tests/pkg_arduino_sdi_12/README.md
Normal file
42
tests/pkg_arduino_sdi_12/README.md
Normal 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
|
||||
114
tests/pkg_arduino_sdi_12/main.cpp
Normal file
114
tests/pkg_arduino_sdi_12/main.cpp
Normal 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);
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user