mirror of
https://github.com/RobTillaart/Arduino.git
synced 2024-10-03 18:09:02 -04:00
0.2.4 RS485
This commit is contained in:
parent
abbb4bf1f3
commit
9a4286492f
@ -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
|
||||
|
@ -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
|
||||
|
@ -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:
|
||||
|
@ -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 --
|
||||
|
||||
|
@ -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
|
||||
|
||||
----
|
||||
|
@ -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
106
libraries/RS485/MESSAGES.MD
Normal 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
|
||||
|
@ -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
|
||||
|
||||
|
||||
|
@ -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 --
|
||||
|
||||
|
@ -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 --
|
||||
|
||||
|
@ -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": "*",
|
||||
|
@ -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.
|
||||
|
@ -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 --
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user