#include <src/SDI12.h>
SDI12
class
The main class for SDI 12 instances.
Public types
- enum SDI12_LINE_EVENT: uint8_t { SDI12_LINE_EVENT_NONE = 0x00, SDI12_LINE_EVENT_BREAK_THRESHOLD_REACHED = 0x01, SDI12_LINE_EVENT_BREAK_COMPLETED = 0x02, SDI12_LINE_EVENT_MARKING_THRESHOLD_REACHED = 0x04, SDI12_LINE_EVENT_MARKING_COMPLETED = 0x08 }
- Line-condition events published by the transport ISR.
- enum SDI12_RECEIVE_EVENT: uint8_t { SDI12_RECEIVE_EVENT_NONE = 0x00, SDI12_RECEIVE_EVENT_START_BIT_OBSERVED = 0x01, SDI12_RECEIVE_EVENT_CHARACTER_COMPLETED = 0x02, SDI12_RECEIVE_EVENT_MESSAGE_COMPLETED = 0x04, SDI12_RECEIVE_EVENT_FRAMING_ERROR = 0x08, SDI12_RECEIVE_EVENT_BUFFER_OVERFLOW = 0x10, SDI12_RECEIVE_EVENT_COMMAND_COMPLETED = 0x20 }
- Character-receive events published by the transport ISR.
-
using SDI12_LINE_EVENT = enum SDI12::
SDI12_LINE_EVENT - Line-condition events published by the transport ISR.
-
using SDI12_RECEIVE_EVENT = enum SDI12::
SDI12_RECEIVE_EVENT - Character-receive events published by the transport ISR.
Public static functions
- static uint8_t parity_even_bit(uint8_t v) -> uint8_t
- Calculate the parity value for a character using even parity.
- static void publishEvent(volatile uint8_t& flags, uint8_t event)
- Atomically publish an ISR-owned event flag.
- static uint8_t takeEvents(volatile uint8_t& flags) -> uint8_t
- Atomically consume and clear a set of ISR-owned event flags.
Public functions
- void setPinInterrupts(bool enable)
- Set the pin interrupts to be on (enabled) or off (disabled).
- void setLineState(SDI12_LINE_STATE state)
- Set the the state of the SDI12 object.
-
void resetEdgeState(bool listening,
sdi12timer_
t timerTime, uint8_t pinLevel) - Reset edge-history state when listening begins or line ownership changes.
-
uint8_t observeLineEdge(sdi12timer_
t timerTime, uint8_t pinLevel) -> uint8_t - Classify the line interval ending at one captured edge.
- void routeEdge()
- Route one captured edge to line observation and character decoding.
- void forceHold()
- Set line state to SDI12_HOLDING.
- void forceListen()
- Set line state to SDI12_LISTENING.
- void startBreak()
- Begin driving a recorder break without waiting for it to complete.
- void startMarking()
- Begin driving recorder marking without waiting for it to complete.
- uint8_t takeLineEvents() -> uint8_t
- Atomically consume all pending line-condition events.
- uint8_t takeReceiveEvents() -> uint8_t
- Atomically consume all pending character-receive events.
- void serviceLineConditions()
- Service continuous line conditions that can reach a threshold without an edge.
- uint16_t calculateCRC(String& resp) -> uint16_t
- Calculates the 16-bit Cyclic Redundancy Check (CRC) for an SDI-12 message.
- uint16_t calculateCRC(const char* resp) -> uint16_t
- Calculates the 16-bit Cyclic Redundancy Check (CRC) for an SDI-12 message.
- uint16_t calculateCRC(FlashString resp) -> uint16_t
- Calculates the 16-bit Cyclic Redundancy Check (CRC) for an SDI-12 message.
- String crcToString(uint16_t crc) -> String
- Converts a numeric 16-bit CRC to an ASCII String.
- bool verifyCRC(String& respWithCRC) -> bool
- Verifies that the CRC returned at the end of an SDI-12 message matches that of the content of the message.
Constructor, Destructor, Begins, and Setters
These functions set up the SDI-12 object and prepare it for use.
- int16_t TIMEOUT
- The value to return if a parse or read times out with no return from the sensor.
- SDI12()
- Construct a new SDI12 instance with no data pin set.
- SDI12(int8_t dataPin) explicit
- Construct a new SDI12 with the data pin set.
- ~SDI12()
- Destroy the SDI12 object.
- void begin()
- Begin the SDI-12 object.
- void begin(int8_t dataPin)
- Set the SDI12::_datapin and begin the SDI-12 object.
- void end()
- Disable the SDI-12 object (but do not destroy it).
- int16_t getTimeoutValue() -> int16_t
- Get the current value that will be returned IF a parse int or parse float times out with no return from the sensor.
- void setTimeoutValue(int16_t value)
- Set the value to return if a parse int or parse float times out with no return from the sensor.
- int8_t getDataPin() -> int8_t
- Get the data pin for the current SDI-12 instance.
- void setDataPin(int8_t dataPin)
- Set the data pin for the current SDI-12 instance.
Reading from the SDI-12 Buffer
These functions are for reading incoming data stored in the SDI-12 buffer.
- int available() -> int override
- Return the number of bytes available in the Rx buffer.
- int peek(bool use_parity) -> int
- Reveal the next byte in the Rx buffer without consuming it.
- int peek() -> int override
- Reveal the next byte (7E1) in the Rx buffer without consuming it.
- int peekBinary(void) -> int
- Reveal the next byte (8N1) at the head of the Rx buffer without consuming it.
- void clearBuffer()
- Clear the Rx buffer by setting the head and tail pointers to the same value.
- int read(bool use_parity) -> int
- Return next byte in the Rx buffer, consuming it.
- int read() -> int override
- Return next byte in the Rx buffer excluding parity bit, consuming it.
- int readBinary(void) -> int
- Return the next byte in the Rx buffer including the 8th bit, consuming it.
- size_t readBinary(char* output, size_t length) -> size_t
- Return up to
lengthbytes before timeout and store them inoutput. - int timedReadBinary(void) -> int
- Reads the next byte from the buffer (and moves the index ahead) with timeout.
- void flush() override
- Wait for sending to finish - because no TX buffering and the write function is blocking, we don't need to do anything.
- unsigned long getTimeout() -> unsigned long
- Get the current stream timeout time.
-
long parseInt(LookaheadMode = SKIP_
NONE, char = '+') -> long - Return the first valid (long) integer value from the current position.
-
float parseFloat(LookaheadMode = SKIP_
NONE, char = '+') -> float - Return the first valid float value from the current position.
Using more than one SDI-12 Object
Functions needed for multiple instances of the SDI12 class.
This library is allows for multiple instances of itself running on the same or different pins. SDI-12 can support up to 62 sensors on a single pin/bus, so it is not necessary to use an instance for each sensor.
Because we are using pin change interrupts there can only be one active object at a time (since this is the only reliable way to determine which pin the interrupt occurred on). The active object is the only object that will respond properly to interrupts. However promoting another instance to Active status does not automatically remove the interrupts on the other pin. For proper behavior it is recommended to use this pattern:
Waking Up and Talking To Sensors
These functions are needed to communicate with SDI-12 sensors (slaves) or an SDI-12 data logger (master).
- size_t write(uint8_t byte) -> size_t virtual
- Write out a byte using 7E1 parity on the SDI-12 line.
- size_t write(const uint8_t* buffer, size_t size) -> size_t virtual
- Write out multiple bytes using 7E1 parity on the SDI-12 line.
-
template<typename T>size_t writeBytes(T value) -> size_t
- Write out number of bytes on the SDI-12 line, least significant byte first (little-endian transmission).
- void sendCommand(String& cmd, int8_t extraWakeTime = 0) deprecated
- Send a command out on the data line, acting as a data logger (master).
- void sendCommand(const char* cmd, int8_t extraWakeTime = 0) deprecated
- Send a command out on the data line, acting as a data logger (master).
- void sendCommand(FlashString cmd, int8_t extraWakeTime = 0) deprecated
- Send a command out on the data line, acting as a data logger (master).
- void sendResponse(String& resp, bool addCRC = false) deprecated
- Send a response out on the data line (for slave use).
- void sendResponse(const char* resp, bool addCRC = false) deprecated
- Send a response out on the data line (for slave use).
- void sendResponse(FlashString resp, bool addCRC = false) deprecated
- Send a response out on the data line (for slave use).
Interrupt Service Routine
Functions for handling interrupts - responding to changes on the data line and converting them to characters in the Rx buffer.
- static void handleInterrupt()
- Intermediary used by the ISR - passes off responsibility for the interrupt to the active object.
Enum documentation
enum SDI12:: SDI12_LINE_EVENT: uint8_t
Line-condition events published by the transport ISR.
Events are coalescing flags. The basic SDI12 class publishes them, and recorder or sensor classes consume all pending flags with takeLineEvents(). The events do not carry timestamps: Completion events flags are set when the interrupt service routine catches an edge. Threshold events event flags are set when the sensor or recorder calls the serviceLineConditions() function to check for them.
| Enumerators | |
|---|---|
| SDI12_LINE_EVENT_NONE |
No line event is pending. |
| SDI12_LINE_EVENT_BREAK_THRESHOLD_REACHED |
Continuous spacing reached the minimum break duration. |
| SDI12_LINE_EVENT_BREAK_COMPLETED |
A spacing interval reached the break minimum and ended. |
| SDI12_LINE_EVENT_MARKING_THRESHOLD_REACHED |
Continuous marking reached the pre-character minimum. |
| SDI12_LINE_EVENT_MARKING_COMPLETED |
A marking interval reached the required minimum and ended. |
enum SDI12:: SDI12_RECEIVE_EVENT: uint8_t
Character-receive events published by the transport ISR.
Events describe observed transport facts, not retry or protocol-role policy. They are coalescing flags consumed by takeReceiveEvents().
| Enumerators | |
|---|---|
| SDI12_RECEIVE_EVENT_NONE |
No receive event is pending. |
| SDI12_RECEIVE_EVENT_START_BIT_OBSERVED |
A start bit was observed. |
| SDI12_RECEIVE_EVENT_CHARACTER_COMPLETED |
A character was reconstructed. |
| SDI12_RECEIVE_EVENT_MESSAGE_COMPLETED |
A CR LF response terminator was seen. |
| SDI12_RECEIVE_EVENT_FRAMING_ERROR |
An incomplete character was reset. |
| SDI12_RECEIVE_EVENT_BUFFER_OVERFLOW |
A character could not enter the buffer. |
| SDI12_RECEIVE_EVENT_COMMAND_COMPLETED |
An exclamation-point command terminator was seen. |
Typedef documentation
typedef enum SDI12:: SDI12_LINE_EVENT SDI12:: SDI12_LINE_EVENT
Line-condition events published by the transport ISR.
Events are coalescing flags. The basic SDI12 class publishes them, and recorder or sensor classes consume all pending flags with takeLineEvents(). The events do not carry timestamps: Completion events flags are set when the interrupt service routine catches an edge. Threshold events event flags are set when the sensor or recorder calls the serviceLineConditions() function to check for them.
typedef enum SDI12:: SDI12_RECEIVE_EVENT SDI12:: SDI12_RECEIVE_EVENT
Character-receive events published by the transport ISR.
Events describe observed transport facts, not retry or protocol-role policy. They are coalescing flags consumed by takeReceiveEvents().
Function documentation
static uint8_t SDI12:: parity_even_bit(uint8_t v)
Calculate the parity value for a character using even parity.
| Parameters | |
|---|---|
| v | uint8_t (char) the character to calculate the parity of |
| Returns | uint8_t The input character with the 8th bit set to the even parity value for that character |
Sets up parity and interrupts for different processor types - that is, imports the interrupts and parity for the AVR processors where they exist.
This function is defined in the Arduino core for AVR processors, but must be defined here for SAMD and ESP cores.
static void SDI12:: publishEvent(volatile uint8_t& flags,
uint8_t event)
Atomically publish an ISR-owned event flag.
| Parameters | |
|---|---|
| flags | The coalescing flag byte to update. |
| event | The event bits to publish. |
static uint8_t SDI12:: takeEvents(volatile uint8_t& flags)
Atomically consume and clear a set of ISR-owned event flags.
| Parameters | |
|---|---|
| flags | The coalescing flag byte to consume. |
| Returns | uint8_t The pending event bits before the flag byte was cleared. |
void SDI12:: setPinInterrupts(bool enable)
Set the pin interrupts to be on (enabled) or off (disabled).
| Parameters | |
|---|---|
| enable | True to enable pin interrupts |
A private helper function to turn pin interrupts on or off
void SDI12:: setLineState(SDI12_LINE_STATE state)
Set the the state of the SDI12 object.
| Parameters | |
|---|---|
| state | The state the SDI-12 object should be set to, from the SDI12_LINE_STATE enum. |
This is a private function, and only used internally.
void SDI12:: resetEdgeState(bool listening,
sdi12timer_ t timerTime,
uint8_t pinLevel)
Reset edge-history state when listening begins or line ownership changes.
| Parameters | |
|---|---|
| listening | True when a new listening interval is beginning. |
| timerTime | The selected timer count at the start of that interval. |
| pinLevel | The physical data-line level at the start of that interval. |
uint8_t SDI12:: observeLineEdge(sdi12timer_ t timerTime,
uint8_t pinLevel)
Classify the line interval ending at one captured edge.
| Parameters | |
|---|---|
| timerTime | The selected SDI-12 timer count at the edge. |
| pinLevel | The new physical data-line level. |
| Returns | uint8_t A bitwise combination of SDI12_ |
void SDI12:: forceHold()
Set line state to SDI12_HOLDING.
A public function which forces the line into a "holding" state. This is generally unneeded, but for deployments where interference is an issue, it should be used after all expected bytes have been returned from the sensor.
void SDI12:: forceListen()
Set line state to SDI12_LISTENING.
A public function which forces the line into a "listening" state. This may be needed for implementing a slave-side device, which should relinquish control of the data line when not transmitting.
void SDI12:: startBreak()
Begin driving a recorder break without waiting for it to complete.
This low-level operation takes ownership of the data line and drives spacing. The caller is responsible for maintaining the break for the required duration and following it with marking before transmitting a command.
void SDI12:: startMarking()
Begin driving recorder marking without waiting for it to complete.
This low-level operation takes ownership of the data line and drives marking. The caller is responsible for maintaining marking for the required duration.
uint8_t SDI12:: takeLineEvents()
Atomically consume all pending line-condition events.
| Returns | uint8_t A bitwise combination of SDI12_ |
|---|
Multiple occurrences of the same event coalesce until this method is called. The recorder or sensor application must call this method outside an ISR.
uint8_t SDI12:: takeReceiveEvents()
Atomically consume all pending character-receive events.
| Returns | uint8_t A bitwise combination of SDI12_ |
|---|
Multiple occurrences of the same event coalesce until this method is called. The recorder or sensor application must call this method outside an ISR.
void SDI12:: serviceLineConditions()
Service continuous line conditions that can reach a threshold without an edge.
The recorder or sensor application calls this method outside the ISR. It reads only the board-selected bit timer. Call it often enough that the timer cannot complete an unobserved rollover after a threshold is reached. Once a break or marking minimum is latched, later timer rollover cannot undo it; the edge ending that interval consumes the latch.
This method or the ending-edge classifier sets each latch. Latches are reset when listening begins, line ownership changes, an ending edge consumes them, a message completes, or a framing or buffer-overflow condition invalidates receive state.
The 8 MHz, 8-bit Timer2 configuration cannot span either required minimum and remains a documented deferred exception.
uint16_t SDI12:: calculateCRC(String& resp)
Calculates the 16-bit Cyclic Redundancy Check (CRC) for an SDI-12 message.
| Parameters | |
|---|---|
| resp | The message to calculate the CRC for. |
| Returns | uint16_t The calculated CRC |
uint16_t SDI12:: calculateCRC(const char* resp)
Calculates the 16-bit Cyclic Redundancy Check (CRC) for an SDI-12 message.
| Parameters | |
|---|---|
| resp | The message to calculate the CRC for. |
| Returns | uint16_t The calculated CRC |
uint16_t SDI12:: calculateCRC(FlashString resp)
Calculates the 16-bit Cyclic Redundancy Check (CRC) for an SDI-12 message.
| Parameters | |
|---|---|
| resp | The message to calculate the CRC for. |
| Returns | uint16_t The calculated CRC |
String SDI12:: crcToString(uint16_t crc)
Converts a numeric 16-bit CRC to an ASCII String.
| Parameters | |
|---|---|
| crc | The 16-bit CRC |
| Returns | String An ASCII string for the CRC |
From the SDI-12 Specifications:
The 16 bit CRC is encoded as three ASCII characters
using the following algorithm:
1st character = 0x40 OR (CRC shifted right 12 bits)
2nd character = 0x40 OR ((CRC shifted right 6 bits) AND 0x3F)
3rd character = 0x40 OR (CRC AND 0x3F)
bool SDI12:: verifyCRC(String& respWithCRC)
Verifies that the CRC returned at the end of an SDI-12 message matches that of the content of the message.
| Parameters | |
|---|---|
| respWithCRC | The full SDI-12 message, including the CRC at the end. |
| Returns | bool True if the CRC matches and the message is valid, false if the CRC doesn't match and the message could be retried. |
SDI12:: SDI12()
Construct a new SDI12 instance with no data pin set.
Before using the SDI-12 instance, the data pin must be set with SDI12::setDataPin(dataPin) or SDI12::begin(dataPin). This empty constructor is provided for easier integration with other Arduino libraries.
When the constructor is called it resets the buffer overflow status to FALSE.
SDI12:: ~SDI12()
Destroy the SDI12 object.
When the destructor is called, it's main task is to disable any interrupts that had been previously assigned to the pin, so that the pin will behave as expected when used for other purposes. This is achieved by putting the SDI-12 object in the SDI12_DISABLED state. After disabling interrupts, the pointer to the current active SDI-12 instance is set to null if it had pointed to the destroyed object. Finally, for AVR board, the timer prescaler is set back to whatever it had been prior to creating the SDI-12 object.
void SDI12:: begin()
Begin the SDI-12 object.
This is called to begin the functionality of the SDI-12 object. It sets the object as the active object, sets the stream timeout to 150ms to match SDI-12 specs, sets the timeout return value to SDI12::
void SDI12:: begin(int8_t dataPin)
Set the SDI12::_datapin and begin the SDI-12 object.
| Parameters | |
|---|---|
| dataPin | The data pin's digital pin number |
This is called to begin the functionality of the SDI-12 object. It sets the object as the active object, sets the stream timeout to 150ms to match SDI-12 specs, sets the timeout return value to SDI12::
void SDI12:: end()
Disable the SDI-12 object (but do not destroy it).
Set the SDI-12 state to disabled, set the pointer to the current active instance to null, and then, for AVR boards, unset the timer prescaler.
This can be called to temporarily cease all functionality of the SDI-12 object. It is not as harsh as destroying the object with the destructor, as it will maintain the memory buffer.
int16_t SDI12:: getTimeoutValue()
Get the current value that will be returned IF a parse int or parse float times out with no return from the sensor.
| Returns | int16_t The current timeout value The timeout return for parseInt and parseFloat of an Arduino stream object when no character is available in the Rx buffer is "0." For environmental sensors (the typical SDI-12 users) 0 is a common result value. To better distinguish between a timeout because of no sensor response and a true zero return, the timeout should be set to some value that is NOT a possible return from that sensor. If the timeout is not set, -9999 is used. |
|---|
void SDI12:: setTimeoutValue(int16_t value)
Set the value to return if a parse int or parse float times out with no return from the sensor.
| Parameters | |
|---|---|
| value | the value to return on timeout The timeout return for parseInt and parseFloat of an Arduino stream object when no character is available in the Rx buffer is "0." For environmental sensors (the typical SDI-12 users) 0 is a common result value. To better distinguish between a timeout because of no sensor response and a true zero return, the timeout should be set to some value that is NOT a possible return from that sensor. If the timeout is not set, -9999 is used. |
int8_t SDI12:: getDataPin()
Get the data pin for the current SDI-12 instance.
| Returns | int8_t The data pin number |
|---|
void SDI12:: setDataPin(int8_t dataPin)
Set the data pin for the current SDI-12 instance.
| Parameters | |
|---|---|
| dataPin | The data pin's digital pin number |
int SDI12:: available() override
Return the number of bytes available in the Rx buffer.
| Returns | int The number of characters in the buffer |
|---|
available() is a public function that returns the number of characters available in the Rx buffer.
To understand how: _rxBufferTail + SDI12_ accomplishes this task, we will use a few examples.
To start take the buffer below that has SDI12_. The message "abc" has been wrapped around (circular buffer).
[ c ] [ - ] [ - ] [ - ] [ - ] [ - ] [ - ] [ - ] [ a ] [ b ]
The number of available characters is (1 + 10 - 8) % 10 = 3
The '' or modulo operator finds the remainder of division of one number by another. In integer arithmetic 3 / 10 = 0, but has a remainder of 3. We can only get the remainder by using the the modulo ''. 3 % 10 = 3. This next case demonstrates more clearly why the modulo is used.
[ a ] [ b ] [ c ] [ - ] [ - ] [ - ] [ - ] [ - ] [ - ] [ - ]
The number of available characters is (4 + 10 - 1) % 10 = 3
If we did not use the modulo we would get either ( 4 + 10 - 1 ) = 13 characters or ( 4 + 10 - 1 ) / 10 = 1 character. Obviously neither is correct.
If there has been a buffer overflow, available() will return -1.
int SDI12:: peek(bool use_parity)
Reveal the next byte in the Rx buffer without consuming it.
| Parameters | |
|---|---|
| use_parity | True to verify parity and return a character that excludes the parity bit. If use_parity is set to true and the next character fails the parity check, -1 will be returned. |
| Returns | int The next byte in the character buffer. |
peek() is a public function that allows the user to look at the character that is at the head of the buffer. Unlike read() it does not consume the character (i.e. the index addressed by _rxBufferHead is not changed). peek() returns -1 if there are no characters to show.
int SDI12:: peek() override
Reveal the next byte (7E1) in the Rx buffer without consuming it.
| Returns | int The next byte in the character buffer, or -1 if the buffer is empty or the next byte in the buffer doesn't pass parity check. |
|---|
int SDI12:: peekBinary(void)
Reveal the next byte (8N1) at the head of the Rx buffer without consuming it.
| Returns | int The next byte in the character buffer, or -1 if the buffer is empty. |
|---|
void SDI12:: clearBuffer()
Clear the Rx buffer by setting the head and tail pointers to the same value.
clearBuffer() is a public function that clears the buffers contents by setting the index for both head and tail back to zero.
int SDI12:: read(bool use_parity)
Return next byte in the Rx buffer, consuming it.
| Parameters | |
|---|---|
| use_parity | True to verify parity and return a character that excludes the parity bit. If use_parity is set to true and the next character fails the parity check, -1 will be returned. |
| Returns | int The next byte in the character buffer. |
read() returns the character at the current head in the buffer after incrementing the index of the buffer head. This action 'consumes' the character, meaning it can not be read from the buffer again. If you would rather see the character, but leave the index to head intact, you should use peek();
int SDI12:: read() override
Return next byte in the Rx buffer excluding parity bit, consuming it.
| Returns | int The next byte in the character buffer, 7E1, excluding parity. |
|---|
This is used for standard SDI-12 7E1 characters.
int SDI12:: readBinary(void)
Return the next byte in the Rx buffer including the 8th bit, consuming it.
| Returns | int The next byte in the character buffer, 8N1, including 8th bit!. |
|---|
size_t SDI12:: readBinary(char* output,
size_t length)
Return up to length bytes before timeout and store them in output.
| Parameters | |
|---|---|
| output out | Location in memory where the bytes will be stored. |
| length in | Maximum number of bytes to read from the buffer. |
| Returns | size_t The number of bytes read from the buffer. |
readBinary(char* output, size_length bytes by incrementing the index of the buffer head using
int SDI12:: timedReadBinary(void)
Reads the next byte from the buffer (and moves the index ahead) with timeout.
| Returns | int Byte data from buffer or -1 if buffer is empty or timeout during read |
|---|
unsigned long SDI12:: getTimeout()
Get the current stream timeout time.
| Returns | unsigned long The current timeout time in milliseconds. |
|---|
long SDI12:: parseInt(LookaheadMode = SKIP_ NONE,
char = '+')
Return the first valid (long) integer value from the current position.
| Returns | long The next valid integer in the stream or -9999 if there is a timeout or the next character is not part of an integer. |
|---|
This function is customized to only return numbers as they are passed in the data command responses.
A data command response is structured [addr][values][CR][LF] or [addr][values][CRC][CR][LF] the value portion must be structred as pd.d
- p - the polarity sign (+ or -)
- d - numeric digits before the decimal place
- . - the decimal point (optional)
- d - numeric digits after the decimal point
- the maximum number of digits for a data value is 7, even without a decimal point
- the minimum number of digits for a data value (excluding the decimal point) is 1
- the maximum number of characters in a data value is 9 (the (polarity sign + 7 digits + the decimal point))
- The polarity symbol (+ or -) acts as a delimeter between the numeric values
Because of the well codified structure of the response, we know that we can always set the LookaheadMode to not skip any characters (LookaheadMode::SKIP_NONE), we accept a + or - only as the first character, and we should not ignore any other characters.
float SDI12:: parseFloat(LookaheadMode = SKIP_ NONE,
char = '+')
Return the first valid float value from the current position.
| Returns | float The first valid float in the stream or -9999 if there is a timeout or the next character is not part of an float. |
|---|
This is identical to SDI12::
bool SDI12:: setActive()
Set this instance as the active SDI-12 instance.
| Returns | bool True indicates that the current SDI-12 instance was not formerly the active one and now is. False indicates that the current SDI-12 instance is already the active one and the state was not changed. |
|---|
A method for setting the current object as the active object; returns TRUE if the object was not formerly the active object and now is.
- Promoting an inactive to the active instance will start it in the SDI12_HOLDING state and return TRUE.
- Otherwise, if the object is currently the active instance, it will remain unchanged and return FALSE.
bool SDI12:: isActive()
Check if this instance is active.
| Returns | bool True indicates that the curren SDI-12 instance is the active one. |
|---|
isActive() is a method for checking if the object is the active object. Returns true if the object is currently the active object, false otherwise.
size_t SDI12:: write(uint8_t byte) virtual
Write out a byte using 7E1 parity on the SDI-12 line.
| Parameters | |
|---|---|
| byte | The character to write |
| Returns | size_t The number of characters written |
Sets the state to transmitting, writes a character, and then sets the state back to listening.
size_t SDI12:: write(const uint8_t* buffer,
size_t size) virtual
Write out multiple bytes using 7E1 parity on the SDI-12 line.
| Parameters | |
|---|---|
| buffer | The data to write |
| size | The size of the data buffer to write |
| Returns | size_t The number of characters written |
Sets the state to transmitting, writes multiple characters, and then sets the state back to listening.
template<typename T>
size_t SDI12:: writeBytes(T value)
Write out number of bytes on the SDI-12 line, least significant byte first (little-endian transmission).
| Template parameters | |
|---|---|
| T | ['value type'] |
| Parameters | |
| value | Data to be converted to byte chunks |
| Returns | size_t sizeof( T ), number of bytes written out |
Sets the state to transmitting, starts writing byte chunks of value from least significant byte to most significant byte, and then sets the state back to listening.
void SDI12:: sendCommand(String& cmd,
int8_t extraWakeTime = 0) deprecated
Send a command out on the data line, acting as a data logger (master).
| Parameters | |
|---|---|
| cmd | the command to send |
| extraWakeTime | The amount of additional time in milliseconds that the sensor takes to wake before being ready to receive a command. Default is 0ms - meaning the sensor is ready for a command by the end of the 12ms break. Per protocol, the wake time must be less than 100 ms. |
A publicly accessible function that sends a break to wake sensors and sends out a command byte by byte on the data line.
void SDI12:: sendCommand(const char* cmd,
int8_t extraWakeTime = 0) deprecated
Send a command out on the data line, acting as a data logger (master).
| Parameters | |
|---|---|
| cmd | The null-terminated command to send. |
| extraWakeTime | Additional sensor wake time in milliseconds. |
void SDI12:: sendCommand(FlashString cmd,
int8_t extraWakeTime = 0) deprecated
Send a command out on the data line, acting as a data logger (master).
| Parameters | |
|---|---|
| cmd | The flash-resident command to send. |
| extraWakeTime | Additional sensor wake time in milliseconds. |
void SDI12:: sendResponse(String& resp,
bool addCRC = false) deprecated
Send a response out on the data line (for slave use).
| Parameters | |
|---|---|
| resp | the response to send |
| addCRC | True to append a CRC to the outgoing response |
A publicly accessible function that sends out an 8.33 ms marking and a response byte by byte on the data line. This is needed if the Arduino is acting as an SDI-12 device itself, not as a recorder for another SDI-12 device.
void SDI12:: sendResponse(const char* resp,
bool addCRC = false) deprecated
Send a response out on the data line (for slave use).
| Parameters | |
|---|---|
| resp | The null-terminated response to send. |
| addCRC | True to append a CRC to the outgoing response. |
void SDI12:: sendResponse(FlashString resp,
bool addCRC = false) deprecated
Send a response out on the data line (for slave use).
| Parameters | |
|---|---|
| resp | The flash-resident response to send. |
| addCRC | True to append a CRC to the outgoing response. |
static void SDI12:: handleInterrupt()
Intermediary used by the ISR - passes off responsibility for the interrupt to the active object.
On espressif boards (ESP8266 and ESP32), the ISR must be stored in IRAM
Variable documentation
int16_t SDI12:: TIMEOUT
The value to return if a parse or read times out with no return from the sensor.
The timeout return for parseInt and parseFloat of an Arduino stream object when no character is available in the Rx buffer is "0." For environmental sensors (the typical SDI-12 users) 0 is a common result value. To better distinguish between a timeout because of no sensor response and a true zero return, the timeout should be set to some value that is NOT a possible return from that sensor. If the timeout is not set, -9999 is used.