BayEOSArduino Library
Functions
Reading from the SDI-12 Buffer

These functions are for reading incoming data stored in the SDI-12 buffer. More...

Functions

int SDI12::available () override
 Return the number of bytes available in the Rx buffer. More...
 
int SDI12::peek () override
 Reveal next byte in the Rx buffer without consuming it. More...
 
void SDI12::clearBuffer ()
 Clear the Rx buffer by setting the head and tail pointers to the same value. More...
 
int SDI12::read () override
 Return next byte in the Rx buffer, consuming it. More...
 
void SDI12::flush () override
 Wait for sending to finish - because no TX buffering, does nothing.
 
long SDI12::parseInt (LookaheadMode lookahead=SKIP_ALL, char ignore=NO_IGNORE_CHAR)
 Return the first valid (long) integer value from the current position. More...
 
float SDI12::parseFloat (LookaheadMode lookahead=SKIP_ALL, char ignore=NO_IGNORE_CHAR)
 Return the first valid float value from the current position. More...
 
int SDI12::peekNextDigit (LookaheadMode lookahead, bool detectDecimal)
 Return the next numeric digit in the stream or -1 if timeout. More...
 

Detailed Description

These functions are for reading incoming data stored in the SDI-12 buffer.

The buffer is used to store characters from the SDI-12 data line. Characters are read into the buffer when an interrupt is received on the data line. The buffer uses a circular implementation with pointers to both the head and the tail. All SDI-12 instances share the same buffer.

The default buffer size is the maximum length of a response to a normal SDI-12 command, which is 81 characters:

For more information on circular buffers: http://en.wikipedia.org/wiki/Circular_buffer

Note
peakNextDigit(), parseInt() and parseFloat() are fully implemented in the parent Stream class but we don't want to them use as they are inherited. Although they are not virtual and cannot be overridden, recreating them here hides the stream default versions to allow for a custom timeout return value. The default value for the Stream class is to return 0. This makes distinguishing timeouts from true zero readings impossible. Therefore the default value has been set to -9999 in the being function. The value returned by a timeout (SDI12::TIMEOUT) is a public variable and can be changed dynamically within a program by calling mySDI12.TIMEOUT = (int) newValue or using SDI12::setTimeoutValue(int16_t value).

Function Documentation

◆ available()

int SDI12::available ( void  )
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_BUFFER_SIZE - _rxBufferHead) % SDI12_BUFFER_SIZE; accomplishes this task, we will use a few examples.

To start take the buffer below that has SDI12_BUFFER_SIZE = 10. The message "abc" has been wrapped around (circular buffer).

_rxBufferTail = 1 // points to the '-' after c
_rxBufferHead = 8 // points to 'a'

[ 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.

_rxBufferTail = 4 // points to the '-' after c
_rxBufferHead = 1 // points to 'a'

[ 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.

◆ clearBuffer()

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.

◆ parseFloat()

float SDI12::parseFloat ( LookaheadMode  lookahead = SKIP_ALL,
char  ignore = NO_IGNORE_CHAR 
)

Return the first valid float value from the current position.

lookahead determines how parseInt looks ahead in the stream. See LookaheadMode enumeration at the top of the file. Lookahead is terminated by the first character that is not a valid part of an integer. Once parsing commences, 'ignore' will be skipped in the stream.

Parameters
lookaheadthe mode to use to look ahead in the stream, default is LookaheadMode::SKIP_ALL
ignorea character to ignore in the stream, default is '\x01'
Returns
long The first valid float in the stream
Note
This function hides the Stream class function to allow a custom value to be returned on timeout. It cannot overwrite the Stream function because it is not virtual.
See also
SDI12::LookaheadMode

◆ parseInt()

long SDI12::parseInt ( LookaheadMode  lookahead = SKIP_ALL,
char  ignore = NO_IGNORE_CHAR 
)

Return the first valid (long) integer value from the current position.

lookahead determines how parseInt looks ahead in the stream. See LookaheadMode enumeration at the top of the file. Lookahead is terminated by the first character that is not a valid part of an integer. Once parsing commences, 'ignore' will be skipped in the stream.

Parameters
lookaheadthe mode to use to look ahead in the stream, default is LookaheadMode::SKIP_ALL
ignorea character to ignore in the stream, default is '\x01'
Returns
long The first valid integer in the stream
Note
This function hides the Stream class function to allow a custom value to be returned on timeout. It cannot overwrite the Stream function because it is not virtual.
See also
SDI12::LookaheadMode

◆ peek()

int SDI12::peek ( void  )
override

Reveal next byte in the Rx buffer without consuming it.

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.

◆ peekNextDigit()

int SDI12::peekNextDigit ( LookaheadMode  lookahead,
bool  detectDecimal 
)
protected

Return the next numeric digit in the stream or -1 if timeout.

Parameters
lookaheadthe mode to use to look ahead in the stream
detectDecimalTrue to accept a decimal point ('.') as part of a number
Returns
int The next numeric digit in the stream

◆ read()

int SDI12::read ( void  )
override

Return next byte in the Rx buffer, consuming it.

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();