0.2.4 RS485

This commit is contained in:
rob tillaart 2023-02-05 20:00:17 +01:00
parent abbb4bf1f3
commit 9a4286492f
13 changed files with 163 additions and 34 deletions

View File

@ -6,7 +6,7 @@ jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- uses: arduino/arduino-lint-action@v1
with:
library-manager: update

View File

@ -8,7 +8,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- uses: ruby/setup-ruby@v1
with:
ruby-version: 2.6

View File

@ -10,7 +10,7 @@ jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: json-syntax-check
uses: limitusus/json-syntax-check@v1
with:

View File

@ -5,7 +5,7 @@
// DATE: 2020-08-26
// PURPOSE: ASCII control characters
// URL: https://github.com/RobTillaart/RS485
//
#define NUL 0x00 // NULL char
#define SOH 0x01 // Start Of Header
@ -41,5 +41,6 @@
#define US 0x1F // Unit Separator
#define DEL 0x7F // DELete
// -- END OF FILE --

View File

@ -6,6 +6,13 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/).
## [0.2.4] - 2023-02-05
- update readme.md
- added messages.md to give som ideas about handshakes/protocols.
- update GitHub actions
- update license 2023
## [0.2.3] - 2022-11-23
- add changelog.md
- add RP2040 to build-CI
@ -13,15 +20,14 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
- update keywords.txt
- minor edits
## [0.2.2] - 2022-05-25
## [0.2.2] - 2022-05-25
- rewrite blocking write(uint8_t \* array, length).
- added write(char \* array, length). (convenience)
## [0.2.1] - 2022-05-24
- add setTXmode(), setRXmode(), getMode().
## [0.2.0] - 2022-05-24
## [0.2.0] - 2022-05-24
- first published version
----

View File

@ -1,6 +1,6 @@
MIT License
Copyright (c) 2017-2022 Rob Tillaart
Copyright (c) 2017-2023 Rob Tillaart
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

106
libraries/RS485/MESSAGES.MD Normal file
View File

@ -0,0 +1,106 @@
# Messages
Examples of command/answer protocols.
(to be elaborated)
#### Guidelines
- Keep protocols as simple as possible.
- be aware of implications of future expansion.
#### ASCII codes
Possible useful char codes.
| commando | value | meaning |
|:----------:|:-------:|:----------|
| SOH | 0x01 | start of header
| STX | 0x02 | start of text
| ETX | 0x03 | end of text
| EOT | 0x04 | end of transmission
| ACK | 0x06 | ACKnowledge
| NAK | 0x15 | Not Acknowledge
| CAN | 0x18 | CANcel
----
## example 1
A minimal message protocol consisting of 1 byte commands
command = (0x80 | 7 bits command)
answer = (0x00 | 7 bits answer)*
All command are coded in a single byte with 0x80 bit set.
All answers bytes 0 or more (sender knows how many to expect, or a specific end char.
requirement:
- All devices listen to a disjunct command set.
## example 2
using a device id to send the command to.
command :=
SOH start of header, (attention new command)
deviceID to (is it for me?)
command (if so, exec command)
bytes expected (to generate the bytes)
answer :=
bytes requested bytes (send them back)
## example 3
command and answer have same layout.
Uses device ID's to address specific device.
SOH start of header 0x01
deviceID to
deviceID sender
length length of message
message idem in ASCII
optional extend with:
checksum optional
EOT optional (end of transmission)
## example 4
More complex package with multiple fields and crc per message.
SOH start of header
deviceID to
deviceID sender
fields 0 or more
length length of field 1
STX start of text
message idem
CHECKSUM idem, message only!
ETX end of text
length length of field 2
STX start of text
message idem
CHECKSUM idem, message only!
ETX end of text
...
EOT end of transmission
----
## Future
- binary protocols
- example code

View File

@ -8,7 +8,7 @@
# RS485
Arduino library for RS485.
Arduino library for RS485 communication.
## Description
@ -18,7 +18,8 @@ The library implements the Stream interface so the user can use
**print()** and **write()** calls just like one does with **Serial**.
Preferably the library is to be used with a hardwareSerial as these
can buffer incoming characters in the background.
can buffer incoming characters in the background.
A software Serial that uses pin interrupts would also work quite well.
The 0.2.0 version of the library has no (tested) protocol for multi-byte
messages so the user must implement such on top of this class.
@ -26,6 +27,11 @@ messages so the user must implement such on top of this class.
## Interface
```cpp
#include "RS485.h"
```
#### Base
- **RS485(Stream stream, uint8_t sendPin, uint8_t deviceID = 0)** constructor.
@ -34,7 +40,7 @@ The stream is typically Serial, and the baud rate, timeout etc. should be set
via the Serial class.
The sendPin is the pin that connects to the transmit/receive enable pins.
The library sets the pinMode and defaults it to LOW (receiving mode).
- **void setMicrosPerByte(uint32_t baudRate)** set the delay per character needed.
- **void setMicrosPerByte(uint32_t baudRate)** set the delay per character needed.
This gives the hardware enough time to flush the buffer.
- **uint32_t getMicrosPerByte()** returns the current delay in micros used.
- **void setTXmode()** explicitly set mode to transmitting / sending.
@ -58,7 +64,7 @@ All variations of **print()**, **println()** and **write()** can be used,
the library calculates the time needed to set the RS485 chip in transmit mode.
An important command from the stream interface is the **setTimeOut()** as
this allows reads on the RS485 bus that are limited
this allows reads on the RS485 bus that are limited.
## Operation
@ -74,7 +80,7 @@ resumes with listening.
Do not forget to use one pull up (A line) and one pull down (B line)
at only one end of the bus.
Values depend on the length of the cables, start with 1 KΩ.
Values depend on the length of the cables, start with 1 KΩ (kilo ohm)
#### Wires
@ -100,12 +106,12 @@ To enable **yield()** uncomment the following line in **RS485.cpp**
// #define RS485_YIELD_ENABLE 1
or use this flag in the compile line option
or set this flag in the command line compile option.
Note: the **yield()** calling version is substantial slower, depending
on the baud rate. Use with care.
TODO: to be tested on ESP32 - RTOS .
TODO: to be tested on ESP32 - RTOS.
#### Protocol design
@ -115,10 +121,12 @@ response of one module would trigger another module to also send a response.
Of course these two responses interacted quite consistent but wrong.
It took some time to find the cause and to redesign the protocol used.
Lesson learned was to spend more time designing the protocol.
Lesson learned was to spend more time designing the protocol up front.
And keep commands and responses 100% disjunct.
An example of a simple byte protocol could use commands all with
bit 7 set to 1, and all responses with bit 7 set to 0 (E.g ASCII).
Would allow 127 different 1 byte commands.
#### Useful links
@ -130,18 +138,24 @@ bit 7 set to 1, and all responses with bit 7 set to 0 (E.g ASCII).
## Future
#### must
#### Must
- improve documentation
#### should
#### Should
- setUsPerByte() parameter does not feel 100% (investigate)
#### could
#### Could
- add **send()** and **receive()** for longer messages.
- which handshake?
- dynamic buffer size?
- should this be a sort of message class / struct. fixed size?
- add examples
- add unit tests
- investigate yield() on ESP32/RTOS behaviour
#### Wont

View File

@ -2,7 +2,7 @@
// FILE: RS485.cpp
// AUTHOR: Rob Tillaart
// DATE: 30-okt-2017
// VERSION: 0.2.3
// VERSION: 0.2.4
// PURPOSE: Arduino library for RS485 modules (MAX485)
// URL: https://github.com/RobTillaart/RS485
@ -116,20 +116,21 @@ void RS485::setMicrosPerByte(uint32_t baudRate)
//
///////////////////////////////////////////////////////
//
// commando value meaning
// commando value meaning
//
// SOH 0x01 start of header
// STX 0x02 start of text
// ETX 0x03 end of text
// EOT 0x04 end of transmission
//
// optional
// optional
// ACK 0x06 ACKnowledge
// NAK 0x15 Not Acknowledge
// CAN 0x18 CANcel
//
///////////////////////////////////////////////////////
//
// A message has the following layout
// A message has the following layout
//
// SOH start of header
// deviceID to
@ -142,7 +143,6 @@ void RS485::setMicrosPerByte(uint32_t baudRate)
// EOT end of transmission
//
void RS485::send(uint8_t receiverID, uint8_t msg[], uint8_t len)
{
uint8_t CHKSUM = 0;
@ -186,7 +186,7 @@ bool RS485::receive(uint8_t &senderID, uint8_t msg[], uint8_t &msglen)
case 0:
if (v == SOH)
{
_bidx = 0; // start new packet
_bidx = 0; // start new packet
state = 1;
}
break;
@ -223,7 +223,7 @@ bool RS485::receive(uint8_t &senderID, uint8_t msg[], uint8_t &msglen)
state = 6;
break;
}
// error handling if v not ascii ?
// error handling if v not ASCII ?
_buffer[_bidx++] = v;
CHKSUM ^= v;
length--;
@ -266,12 +266,11 @@ bool RS485::receive(uint8_t &senderID, uint8_t msg[], uint8_t &msglen)
}
//////////////////////////////////////////////////
//
// PRIVATE
//
// -- END OF FILE --
// -- END OF FILE --

View File

@ -3,7 +3,7 @@
// FILE: RS485.h
// AUTHOR: Rob Tillaart
// DATE: 30-okt-2017
// VERSION: 0.2.3
// VERSION: 0.2.4
// PURPOSE: Arduino library for RS485 modules
// URL: https://github.com/RobTillaart/RS485
@ -11,7 +11,7 @@
#include "Arduino.h"
#include "ASCII_CONTROL.h"
#define RS485_LIB_VERSION (F("0.2.3"))
#define RS485_LIB_VERSION (F("0.2.4"))
class RS485 : public Stream
@ -66,5 +66,5 @@ private:
};
// -- END OF FILE --
// -- END OF FILE --

View File

@ -15,7 +15,7 @@
"type": "git",
"url": "https://github.com/RobTillaart/RS485"
},
"version": "0.2.3",
"version": "0.2.4",
"license": "MIT",
"frameworks": "arduino",
"platforms": "*",

View File

@ -1,5 +1,5 @@
name=RS485
version=0.2.3
version=0.2.4
author=Rob Tillaart <rob.tillaart@gmail.com>
maintainer=Rob Tillaart <rob.tillaart@gmail.com>
sentence=RS485 library for Arduino.

View File

@ -41,6 +41,7 @@ unittest_setup()
fprintf(stderr, "RS485_LIB_VERSION: %s\n", (char *) RS485_LIB_VERSION);
}
unittest_teardown()
{
}
@ -99,4 +100,6 @@ unittest(test_communication_mode)
unittest_main()
// --------
// -- END OF FILE --