From 5d460acf4865ab878b52e17a5257d91ade8e4e61 Mon Sep 17 00:00:00 2001 From: Stephan Richter Date: Mon, 20 Nov 2023 09:59:34 +0100 Subject: [PATCH] renamed _reset to _start, added comments --- SoftRS485.cpp | 88 +++++++++++++++++++++++++-------------------------- 1 file changed, 43 insertions(+), 45 deletions(-) diff --git a/SoftRS485.cpp b/SoftRS485.cpp index 8377e92..d512761 100644 --- a/SoftRS485.cpp +++ b/SoftRS485.cpp @@ -14,30 +14,26 @@ int _RO, _RE, _DE, _DI; const long _pulse_len = 616; const long _break = _pulse_len * 20; -boolean _line = LOW; -long _last_flip = 0; -long _diff = 0; -long _now = 0; -long _count = 0; -boolean _reset = false; +boolean _line = LOW; // current state of the transmission line +long _last_flip = 0; // timestamp since last flip of line state +boolean _start = false; // indicates whether a start bit shall be ignored // Receive vars -byte _recv_msg[MSG_LEN]; -boolean _avail = false; -int _pos = 0; -int _idx = 0; - - - - - +byte _recv_msg[MSG_LEN]; // message buffer +boolean _avail = false; // indicates, wheter a message has been received +int _pos = 0; // character position within the buffer +int _idx = 0; // bit position within the current character +// variables, that could be local, but are stored globally for speed optimization +long _diff = 0; // time difference between last flips +long _now = 0; // current time +long _count = 0; // helper for bit iteration void interrupt485(){ _line = !digitalRead(_RO); // HIGH level = logical zero and vice versa - _now = micros(); - _diff = _now - _last_flip; - _last_flip = _now; + _now = micros(); // get current time + _diff = _now - _last_flip; // duration of the _previous_ bit + _last_flip = _now; // store time of the current flip #ifdef RECV Serial.print(!_line); @@ -48,36 +44,37 @@ void interrupt485(){ Serial.print(" "); #endif - if (_diff > _break){ - _pos = 0; + if (_diff > _break){ // long break means we are starting with a new transmission + _start = true; // first bit will be ignored on the next edge + _pos = 0; // start writing at the beginning of the message buffer _idx = 0; - _reset = true; #ifdef RECV Serial.println("==RESET=="); #endif } else { - _count = _pulse_len>>1; - while (_count < _diff){ + _count = _pulse_len>>1; // bit lengths may vary in certain bounds. this makes sure we always are in the bounds + while (_count < _diff){ // iterate though each bit _count += _pulse_len; - if (_idx){ - _recv_msg[_pos] |= !_line << _idx; - } else { - _recv_msg[_pos] = !_line; + if (_idx){ // not the first bit + _recv_msg[_pos] |= !_line << _idx; // set the bit of the current character + } else { // first bit + _recv_msg[_pos] = !_line; // reset all bits, set the first bit of the current character } - if (_reset){ - _reset = false; - } else { - _idx++; + if (_start){ // current bit is start bit + _start = false; // ignore by not increasing the bit index + } else { // current bit is not a start bit + _idx++; // advance to the next bit } #ifdef RECV Serial.print(_line); #endif - if (_idx == 8){ - if (_recv_msg[_pos] == 0x00){ - _avail = true; + if (_idx == 8){ // full byte received + if (_recv_msg[_pos] == 0x00){ // received byte is string terminator + _avail = true; // notify about complete transmission +// TODO: prevent writing out of buffer boundaries! } - _pos++; - _idx=0; + _pos++; // advance to nect character of buffer + _idx=0; // start with first bit of that character } } #ifdef RECV @@ -90,13 +87,12 @@ void interrupt485(){ void init485(int RO, int nRE, int DE, int DI){ - _RO=RO; + _RO=RO; // save the pin numbers _RE=nRE; _DE=DE; _DI=DI; _avail = false; - #if defined SEND || defined RECV Serial.begin(115200); Serial.print(F("RO = ")); @@ -116,7 +112,7 @@ void init485(int RO, int nRE, int DE, int DI){ Serial.println("SEND enabled"); #endif - pinMode(_RO,INPUT); + pinMode(_RO,INPUT); // we are reading on line _RO pinMode(_RE,OUTPUT); digitalWrite(_RE,LOW); // enable reading @@ -143,12 +139,12 @@ String get485message(){ boolean writeBit(boolean bit){ digitalWrite(_DI,!bit); delayMicroseconds(5); - if (_line != bit){ // collision! - digitalWrite(_DE,LOW); + if (_line != bit){ // collision! + digitalWrite(_DE,LOW); // abort transmission immediately #ifdef SEND Serial.println(F("Collision!")); #endif - return false; + return false; // notify caller } delayMicroseconds(_pulse_len-5); return true; @@ -176,8 +172,10 @@ boolean send485(char message[]){ Serial.print(F(" / micros = ")); Serial.println(micros()); #endif - while (_line || (micros() - _last_flip) < (20 * _pulse_len)) { - delayMicroseconds(20*_pulse_len); + + // if the line is busy: wait for it to get free + while (_line || (micros() - _last_flip) < _break) { + delayMicroseconds(_break); } #ifdef SEND Serial.println(F("enabling driver…")); @@ -187,7 +185,7 @@ boolean send485(char message[]){ int pos = -1; // increment pos prior to sending char! boolean sync = writeBit(0); do { - pos++; + pos++; // incrementation at beginning of loop in order to allow post-loop condition! sync = sync && writeByte(message[pos]); } while (sync && message[pos]); digitalWrite(_DI,LOW);