@martin-kudláček Ok, I just finished to prepare the SD card based on latest UniPian. I will update this thread when I will have some news. Thank you for the support so far.
Best posts made by ntd
-
RE: Internal ModBUS problem
-
RE: Need Some sort of Jumpstart
@knebb said in Need Some sort of Jumpstart:
I am unsure about the "status".
According to the documentation,
status
is the new value of the output and can beTRUE
(to enable it) orFALSE
(to disable it).Here I have no clue for what I would need the nb... does it mean it will read nb bits? To be stored in nb*dest? I would always use the value 1, wouldn't I? If using 2 it would return the value of the second DI 2.2 in the second bit, correct?
Yes to all. This mimics the behavior of the underlying protocol: ModBUS has a Read coils function but does not have Read single coil. You can easily provide your own macro for that, if you really want:
#define read_bit(bus,addr,dst) modbus_read_bits((bus),(addr),1,(dst))
-
RE: How to Read M103 Modbus Doc?
@knebb TL/DR: just use
uint8_t
. This is the right thing to do.There is no differences (because of integer promotion) only when you use that variable in an expression. Incidentally, and for different reasons [1], reading a single bit will work with whatever 0-initialized integer you throw at
modbus_read_bits
, although conceptually wrong. But I can assure you that, when reading multiple channels, using anything butuint8_t
will give you wrong results.[1] Raspberry Pi is little-endian. Setting the first byte of any 0-initialized
uint*
variable to a specific value (e.g.,TRUE
), makes that very same variable initialized to that value, regardless of its type.Here is an example that hopefully will shed some light:
#include <assert.h> #include <stdint.h> #include <string.h> #define TRUE 12 int main() { // Using an union to be able to set the first byte of everything // with only one instruction (m.byte = ...) union { uint8_t byte; uint16_t word; uint32_t dword; uint64_t qword; } m; // Let's set the first byte of 0 initialized memory memset(&m, 0, sizeof m); m.byte = TRUE; assert(m.byte == TRUE); // Ok assert(m.word == TRUE); // Ok on little-endian machines assert(m.dword == TRUE); // Ok on little-endian machines assert(m.qword == TRUE); // Ok on little-endian machines // Now let's try with random initialized memory memset(&m, 3, sizeof m); m.byte = TRUE; assert(m.byte == TRUE); // Ok assert(m.word == TRUE); // Error! assert(m.dword == TRUE); // Error! assert(m.qword == TRUE); // Error! return 0; }
-
RE: How to Read M103 Modbus Doc?
@knebb said:
Would both work?
None of them will. You should really read a ModBUS introduction... I think the wikipedia page should suffice.
The counter is an input register, not a bit, so:
union { uint16_t word[2]; uint32_t dword; } counter; if (modbus_read_registers(bus, 103, 2, counter.word) != 2) { printf("Error\n"); } else { printf("DI2.1 counter is %u\n", counter.dword); }
Not sure which is the less and the most significant word, so if the above gives wrong results just swap
counter.word[0]
andcounter.word[1]
.