Ich möchte für die bidirektionelle Kommunikation die RS485_protocol lib von Nick Gammon verwenden. https://www.gammon.com.au/forum/?id=11428
Die gibt mir folgende Warnungen:
/Arduino/libraries/RS485_protocol/RS485_protocol.cpp:115:24: warning: 'current_byte' may be used uninitialized in this function [-Wmaybe-uninitialized]
current_byte <<= 4;
^
/Arduino/libraries/RS485_protocol/RS485_protocol.cpp:71:8: note: 'current_byte' was declared here
byte current_byte;
^
/Arduino/libraries/RS485_protocol/RS485_protocol.cpp:107:11: warning: 'first_nibble' may be used uninitialized in this function [-Wmaybe-uninitialized]
if (first_nibble)
^
/Arduino/libraries/RS485_protocol/RS485_protocol.cpp:70:8: note: 'first_nibble' was declared here
bool first_nibble;
^
/Arduino/libraries/RS485_protocol/RS485_protocol.cpp:122:22: warning: 'input_pos' may be used uninitialized in this function [-Wmaybe-uninitialized]
if (crc8 (data, input_pos) != current_byte)
^
/Arduino/libraries/RS485_protocol/RS485_protocol.cpp:69:8: note: 'input_pos' was declared here
byte input_pos;
^
/arduino-1.8.15/hardware/tools/avr/bin/avr-objcopy -O ihex -j .eeprom --set-section-flags=.eeprom=alloc,load --no-change-warnings --change-section-lma .eeprom=0 /tmp/arduino_build_647469/sketch_nov23c.ino.elf /tmp/arduino_build_647469/sketch_nov23c.ino.eep
/Arduino/libraries/RS485_protocol/RS485_protocol.cpp:120:11: warning: 'have_etx' may be used uninitialized in this function [-Wmaybe-uninitialized]
if (have_etx)
^
/Arduino/libraries/RS485_protocol/RS485_protocol.cpp:68:8: note: 'have_etx' was declared here
bool have_etx;
^
Was versteht der Compiler anders, als es soll und wie lösen?
Der lib-Code ist schön kurz:
#include <RS485_protocol.h>
const byte STX = '\2';
const byte ETX = '\3';
// calculate 8-bit CRC
static byte crc8 (const byte *addr, byte len)
{
byte crc = 0;
while (len--)
{
byte inbyte = *addr++;
for (byte i = 8; i; i--)
{
byte mix = (crc ^ inbyte) & 0x01;
crc >>= 1;
if (mix)
crc ^= 0x8C;
inbyte >>= 1;
} // end of for
} // end of while
return crc;
} // end of crc8
// send a byte complemented, repeated
// only values sent would be (in hex):
// 0F, 1E, 2D, 3C, 4B, 5A, 69, 78, 87, 96, A5, B4, C3, D2, E1, F0
void sendComplemented (WriteCallback fSend, const byte what)
{
byte c;
// first nibble
c = what >> 4;
fSend ((c << 4) | (c ^ 0x0F));
// second nibble
c = what & 0x0F;
fSend ((c << 4) | (c ^ 0x0F));
} // end of sendComplemented
// send a message of "length" bytes (max 255) to other end
// put STX at start, ETX at end, and add CRC
void sendMsg (WriteCallback fSend, const byte * data, const byte length)
{
fSend (STX); // STX
for (byte i = 0; i < length; i++)
sendComplemented (fSend, data [i]);
fSend (ETX); // ETX
sendComplemented (fSend, crc8 (data, length));
} // end of sendMsg
// receive a message, maximum "length" bytes, timeout after "timeout" milliseconds
// if nothing received, or an error (eg. bad CRC, bad data) return 0
// otherwise, returns length of received data
byte recvMsg (AvailableCallback fAvailable, // return available count
ReadCallback fRead, // read one byte
byte * data, // buffer to receive into
const byte length, // maximum buffer size
unsigned long timeout) // milliseconds before timing out
{
unsigned long start_time = millis ();
bool have_stx = false;
// variables below are set when we get an STX
bool have_etx;
byte input_pos;
bool first_nibble;
byte current_byte;
while (millis () - start_time < timeout)
{
if (fAvailable () > 0)
{
byte inByte = fRead ();
switch (inByte)
{
case STX: // start of text
have_stx = true;
have_etx = false;
input_pos = 0;
first_nibble = true;
start_time = millis (); // reset timeout period
break;
case ETX: // end of text
have_etx = true;
break;
default:
// wait until packet officially starts
if (!have_stx)
break;
// check byte is in valid form (4 bits followed by 4 bits complemented)
if ((inByte >> 4) != ((inByte & 0x0F) ^ 0x0F) )
return 0; // bad character
// convert back
inByte >>= 4;
// high-order nibble?
if (first_nibble)
{
current_byte = inByte;
first_nibble = false;
break;
} // end of first nibble
// low-order nibble
current_byte <<= 4;
current_byte |= inByte;
first_nibble = true;
// if we have the ETX this must be the CRC
if (have_etx)
{
if (crc8 (data, input_pos) != current_byte)
return 0; // bad crc
return input_pos; // return received length
} // end if have ETX already
// keep adding if not full
if (input_pos < length)
data [input_pos++] = current_byte;
else
return 0; // overflow
break;
} // end of switch
} // end of incoming data
} // end of while not timed out
return 0; // timeout
} // end of recvMsg
Die Zeilennumern oben passen zu dieser, um den Kommentarblock gekürzte, Version. Die Headerdatei als Attachment.
RS485_protocol.h (579 Bytes)