Browse Source

renamed _reset to _start, added comments

main
Stephan Richter 1 year ago
parent
commit
5d460acf48
  1. 88
      SoftRS485.cpp

88
SoftRS485.cpp

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

Loading…
Cancel
Save