Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Sets 1 at the specified bit position.
Sets 1 at the specified bit position.
Parameters can be specified as a variable number of arguments, each parameter specifying a 0..31 integer that specifies a bit position. For example, specifying pack_bits(1,3,6)
returns ((1UL<<1)|(1UL<<3)|(1UL<<6))
.
constexpr
will expand constants at compile time if computation by constants is possible.
There are situations where values are referenced and set in various bitmaps, such as the status of IO ports (DI, DO), to simplify the description.
Generating bitmaps with specified order.
Obtains the value of a specified bit position from an integer and creates a bitmap of the specified order.
The value corresponding to the bit position 0..31 specified by the subsequent variable number parameter is extracted from the value specified in the parameter bm. The extracted values are arranged in parameter order and returned as a bitmap.
The bitmap is ordered with the first parameter as the upper bit and the last parameter as bit 0.
In the example, taking out bits 4,2,1,0 of b1 yields (1,0,1,0). This is calculated as 0x10 as b1010.
There are situations where values are referenced and set in various bitmaps, such as the status of IO ports (DI, DO), in order to simplify the description.
Printf utils
The mwx library uses an implementation of printf, which is commonly used in C, for formatting output. Function definitions for several functions are available.
mwx_printf()
prints a printf output to the Serial object. It is the same process as Serial.printfmt()
.
mwx_snprintf()` prints a snprintf to a buffer.
Array class [smplbuf](... /... /classes/smplbuf/), you can use mwx::stream to generate data.
Byte array utils
Get uint16_t
, uint32_t
values from the byte array as uint8_t,
big-endian sequence.
p
is incremented by the number of bytes read.
Write uint8_t
, big-endian uint16_t
and uint32_t
values to the byte array specified by pointer q
.
q
is incremented by the number of bytes written.
To simplify operations when generating and disassembling the data payload of wireless packets.
More simplified pack_bytes()
and expand_bytes()
are also available.
functions for calculating checksums.
This value is often used in checksum calculations.
CRC8_u8CalcU16(), CRC8_u8CalcU32()
computes CRC8 using u16c, u32c
as big-endian sequence.
There are different types of CRC8 depending on the calculation formula, initial value, etc. This library uses a polynomial formula of X^8+X^5+X^4+1
(Polynomial Value is 0x31). This is sometimes called CRC8-CCITT or CRC8-Maxim.
XOR is the exclusive OR XOR of each element.
LRC calculates the sum of the values of each element and takes the two's complement of the lower 8 bits. The result is zero when all elements, including the checksum, are added together.
Added as a library procedure because it is used to check data strings in wireless packets, checksums (LRC) in ASCII format, and various sensors.
Decompose a sequence of bytes and store it in a variable.
Decompose a sequence of bytes and store it in a variable.
The expand_bytes()
parameter is a combination of iterators of type uint8_t*
. This specifies the next iterator after the beginning and end of the parsed target. If the parsing proceeds to the e
position, nullptr
is returned.
If there is no error in expansion, the next iterator to be read is returned.
The variable number parameters can be the following
In this example, a 4-byte string is read out first. Here, make_pair()
is used to explicitly read 4 bytes of data.
The next data is read out based on the returned iterator np
. The next data is of type uint8_t
, followed by five more of type uint16_t
.
To simplify the description of byte arrays of type uint8_t
used in generating data payloads and extracting data from non-volatile packets.
Generates a sequence of bytes by arranging element data.
Generates a sequence of bytes by arranging element data.
pack_bytes
takes a begin()
,end()
iterator of the container class as a parameter and writes the data specified by the following parameters to the container as a sequence of bytes.
The data given for the variable argument parameters are as follows
The pack_bytes
takes a container object as a parameter and writes the data specified by the subsequent parameters as a sequence of bytes into the container. It is appended to the end by the container's .push_back()
method.
The data given as variable argument parameters is shown below.
In this example, each attribute and payload of the received packet is re-stored in a separate buffer buf
.
To simplify the description of byte arrays of type uint8_t
used in the generation of data payloads and extraction of data in non-volatile packets.
CRC8, XOR, LRC() calculations.
Byte count | Data length | Explanation |
---|
The above is the simplest description, but it can be read from a byte array using as follows
Data Type | Number of Bytes | Description |
---|
Data Type | Number of Bytes | Description |
---|
The above is the simplest description, but byte arrays can be generated using as follows.
| 1 |
| 2 | Expand as a big-endian sequence |
| 4 | Expand as a big-endian sequence |
| N | Fixed-length array of type |
| N | Pairs of an array of type |
| 1 |
| 2 | Stored in big-endian order |
| 4 | Stored in big-endian order |
| N | Fixed-length array of type |
| N | A pair of an array of type |
| 1 |
| 2 | Stored in big-endian order |
| 4 | Stored in big-endian order |
| N | Fixed-length array of type |
| N | A pair of an array of type |
|
| smplbuf<> |
pnew() - Simplify the description of placement new
Simplifies the description of placement new (placement new).
For example, use the following Constructor arguments can also be given.
Since the constructor of the global object is not called due to compiler constraints, one way to initialize it is to use placement new. However, since the syntax of placement new (placement new) appears to be complicated.
Another method is to use std::unique_ptr
(or eastl::unique_ptr
).
scaling function between 0..1000 and 0..255.
Scale (expand and contract) with 8-bit values (0..25, etc.) and user-friendly 0..1000 (thousandths, ‰) values. Approximate computation by multiplication and bit shift instead of division (x*1000/255
) for low computational cost.
Scale 0..1000 to 0..127. Approximate calculation using (16646*x+65000)>>17
.
Scale 0..127 to 0..1000. Approximate calculation using (2064000UL*x+131072)>>18
.
Scales 0..1000 to 0..255. Approximate calculation using (33423*x+65000)>>17
.
Scales 0..255 to 0..1000. Approximate calculation using (1028000UL*uint32_t(x)+131072)>>18
.
Scales 0..1000 to 0..256. Approximate calculation using (33554*x+66000) >> 17
.
Note: x=999,1000 returns 255 as the range of uint8_t
even though the calculated value is 256.
Scale 0..256 to 0..1000. Approximate calculation using (1028000UL*uint32_t(x)+131072)>>18
.
Values to be set in hardware are often based on binary numbers such as 0...255, while numbers to be handled in user applications are easier to handle based on decimal numbers such as 0...1000. We defined an expression that does not perform division for these scale conversions.
Fast divisions by 10, 100 or 1000.
The quotient divided by 10, 100 or 1000 and the remainder Calculate the quotient and remainder.
In some cases, such as sensor values, the value multiplied by 100 may be passed as a uint16_t
type, but since calculation processing on a microcontroller without a division circuit takes a reasonable amount of time, the calculation is performed by approximate calculation and correction using addition, subtraction, multiplication and bit shift.
Pass val
as the value to be calculated, rem
as the variable to store the remainder, and neg
as the variable to store the sign.
The return value is the quotient value (always positive), rem
stores the remainder value (always positive), and neg
is true
if negative.
The constraints of the calculation algorithm (overflow) determine the range of possible values for div100()
and div1000()
. The div100()
corresponds to values from -9999999 to 9999999, and the div1000()
corresponds to values from -999999999 to 99999999.
Approximate formula to obtain the quotient
Approx. 10 times faster.
The div_result_i32
class, which stores the result of division, has a format()
method to obtain a _div_chars
class object. The _div_chars()
class object contains a string buffer and has methods to access the string buffer as const char*
type. It also implements the <<
operator for Serial
objects.
The first parameter dig_quo
of the format()
method specifies the number of output digits (not including the sign part). If the number of output digits is not sufficient (hereafter referred to as missing digits
), it is filled with blanks or 0
. The second parameter opt
specifies the format.
Since division is a costly operation in the TWELITE wireless microcontroller, we added a division algorithm with a limited purpose.
In the library, some sensor values such as temperature and humidity are expressed using 100 times the value (2512 for 25.12°C), so we defined a simple procedure to obtain the quotient divided by 100 and the remainder.
As for dev_result_i32::format()
, it is to avoid complications when formatting output.
opt parameter | content |
---|
| Standard output, with missing digits filled in with spaces and |
| Missing digits are filled with |
| A |
| Missing digits are filled with |
| For positive values, a space is added in place of the |
| Missing digits are filled with |