|
|
@ -6,60 +6,112 @@ |
|
|
|
#include "Arduino.h" |
|
|
|
#include "Arduino.h" |
|
|
|
#include "SoftRS485.h" |
|
|
|
#include "SoftRS485.h" |
|
|
|
|
|
|
|
|
|
|
|
//#define DEBUG
|
|
|
|
//#define SEND
|
|
|
|
#define MSG_LEN 64 |
|
|
|
#define MSG_LEN 64 |
|
|
|
|
|
|
|
|
|
|
|
// Pins
|
|
|
|
// Pins
|
|
|
|
int _RO, _RE, _DE, _DI; |
|
|
|
int _RO, _RE, _DE, _DI; |
|
|
|
long _pulse_len = 105; |
|
|
|
long _pulse_len = 616;// 1232; // Pulslänge von 1250µs - 18µs Zeit für Operationen
|
|
|
|
|
|
|
|
long _break = _pulse_len * 20; |
|
|
|
// Receive vars
|
|
|
|
// Receive vars
|
|
|
|
boolean _recv_bit = false; |
|
|
|
boolean _line = LOW; |
|
|
|
long _last_flip; // this is the time when the bus switched to logical zero
|
|
|
|
long _last_flip = 0; // this is the time when the bus switched to logical zero
|
|
|
|
byte _recv_msg[MSG_LEN]; |
|
|
|
byte _recv_msg[MSG_LEN]; |
|
|
|
int _recv_pos = 0; |
|
|
|
|
|
|
|
int _recv_idx = 0; |
|
|
|
|
|
|
|
boolean _avail = false; |
|
|
|
boolean _avail = false; |
|
|
|
|
|
|
|
long _diff = 0; |
|
|
|
|
|
|
|
long _now = 0; |
|
|
|
|
|
|
|
int _pos = 0; |
|
|
|
|
|
|
|
int _idx = 0; |
|
|
|
|
|
|
|
long _count = 0; |
|
|
|
|
|
|
|
boolean _reset = false; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void interrupt485(){ |
|
|
|
void interrupt485(){ |
|
|
|
_recv_bit = !digitalRead(_RO); // HIGH level = logical zero and vice versa
|
|
|
|
_line = !digitalRead(_RO); // HIGH level = logical zero and vice versa
|
|
|
|
long now = micros(); |
|
|
|
_now = micros(); |
|
|
|
long diff = now - _last_flip; |
|
|
|
_diff = _now - _last_flip; |
|
|
|
_last_flip = now; |
|
|
|
_last_flip = _now; |
|
|
|
if (diff > 20*_pulse_len){ // we received a start bit
|
|
|
|
|
|
|
|
#ifdef DEBUG |
|
|
|
#ifdef RECV |
|
|
|
Serial.print(F("State changed to ")); Serial.println(_recv_bit); |
|
|
|
Serial.print(!_line); |
|
|
|
Serial.println(F("received start bit")); |
|
|
|
Serial.print("-("); |
|
|
|
|
|
|
|
Serial.print(_diff); |
|
|
|
|
|
|
|
Serial.print("µs)→"); |
|
|
|
|
|
|
|
Serial.print(_line); |
|
|
|
|
|
|
|
Serial.print(" "); |
|
|
|
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (_diff > _break){ |
|
|
|
|
|
|
|
_pos = 0; |
|
|
|
|
|
|
|
_idx = 0; |
|
|
|
|
|
|
|
_reset = true; |
|
|
|
|
|
|
|
#ifdef RECV |
|
|
|
|
|
|
|
Serial.println("==RESET=="); |
|
|
|
#endif |
|
|
|
#endif |
|
|
|
_recv_pos = 0; |
|
|
|
|
|
|
|
_recv_idx = 0; |
|
|
|
|
|
|
|
_last_flip+=_pulse_len; |
|
|
|
|
|
|
|
} else { |
|
|
|
} else { |
|
|
|
long count = diff/_pulse_len; |
|
|
|
_count = _pulse_len>>1; |
|
|
|
for (int i=0; i<count; i++){ |
|
|
|
while (_count < _diff){ |
|
|
|
if (_recv_idx == 0) { |
|
|
|
_count += _pulse_len; |
|
|
|
_recv_msg[_recv_pos] = (!_recv_bit); |
|
|
|
if (_idx){ |
|
|
|
|
|
|
|
_recv_msg[_pos] |= !_line << _idx; |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
_recv_msg[_pos] = !_line; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if (_reset){ |
|
|
|
|
|
|
|
_reset = false; |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
_recv_msg[_recv_pos] |= (!_recv_bit)<<_recv_idx; |
|
|
|
_idx++; |
|
|
|
} |
|
|
|
} |
|
|
|
_recv_idx++; |
|
|
|
#ifdef RECV |
|
|
|
if (_recv_idx == 8){ |
|
|
|
Serial.print(_line); |
|
|
|
_recv_idx = 0; |
|
|
|
#endif |
|
|
|
if (_recv_msg[_recv_pos] == 0x00){ |
|
|
|
if (_idx == 8){ |
|
|
|
_avail = _recv_pos != 0; |
|
|
|
if (_recv_msg[_pos] == 0x00){ |
|
|
|
return; |
|
|
|
_avail = true; |
|
|
|
} |
|
|
|
} |
|
|
|
_recv_pos++; |
|
|
|
_pos++; |
|
|
|
|
|
|
|
_idx=0; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
#ifdef RECV |
|
|
|
|
|
|
|
Serial.println(); |
|
|
|
|
|
|
|
#endif |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void init485(int RO, int nRE, int DE, int DI){ |
|
|
|
void init485(int RO, int nRE, int DE, int DI){ |
|
|
|
_RO=RO; |
|
|
|
_RO=RO; |
|
|
|
_RE=nRE; |
|
|
|
_RE=nRE; |
|
|
|
_DE=DE; |
|
|
|
_DE=DE; |
|
|
|
_DI=DI; |
|
|
|
_DI=DI; |
|
|
|
|
|
|
|
_avail = false; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#if defined SEND || defined RECV |
|
|
|
|
|
|
|
Serial.begin(115200); |
|
|
|
|
|
|
|
Serial.print(F("RO = ")); |
|
|
|
|
|
|
|
Serial.println(_RO); |
|
|
|
|
|
|
|
Serial.print(F("^RE = ")); |
|
|
|
|
|
|
|
Serial.println(_RE); |
|
|
|
|
|
|
|
Serial.print(F("DE = ")); |
|
|
|
|
|
|
|
Serial.println(_DE); |
|
|
|
|
|
|
|
Serial.print(F("DI = ")); |
|
|
|
|
|
|
|
Serial.println(_DI); |
|
|
|
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef RECV |
|
|
|
|
|
|
|
Serial.println("RECV enabled"); |
|
|
|
|
|
|
|
#endif |
|
|
|
|
|
|
|
#ifdef SEND |
|
|
|
|
|
|
|
Serial.println("SEND enabled"); |
|
|
|
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
|
|
pinMode(_RO,INPUT); |
|
|
|
pinMode(_RO,INPUT); |
|
|
|
|
|
|
|
|
|
|
@ -73,18 +125,6 @@ void init485(int RO, int nRE, int DE, int DI){ |
|
|
|
digitalWrite(_DI,LOW); // output line = LOW
|
|
|
|
digitalWrite(_DI,LOW); // output line = LOW
|
|
|
|
|
|
|
|
|
|
|
|
attachInterrupt(digitalPinToInterrupt(_RO),interrupt485,CHANGE); |
|
|
|
attachInterrupt(digitalPinToInterrupt(_RO),interrupt485,CHANGE); |
|
|
|
|
|
|
|
|
|
|
|
#ifdef DEBUG |
|
|
|
|
|
|
|
Serial.begin(115200); |
|
|
|
|
|
|
|
Serial.print(F("RO = ")); |
|
|
|
|
|
|
|
Serial.println(_RO); |
|
|
|
|
|
|
|
Serial.print(F("^RE = ")); |
|
|
|
|
|
|
|
Serial.println(_RE); |
|
|
|
|
|
|
|
Serial.print(F("DE = ")); |
|
|
|
|
|
|
|
Serial.println(_DE); |
|
|
|
|
|
|
|
Serial.print(F("DI = ")); |
|
|
|
|
|
|
|
Serial.println(_DI); |
|
|
|
|
|
|
|
#endif |
|
|
|
|
|
|
|
_last_flip = micros(); |
|
|
|
_last_flip = micros(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -100,56 +140,57 @@ String get485message(){ |
|
|
|
boolean writeBit(boolean bit){ |
|
|
|
boolean writeBit(boolean bit){ |
|
|
|
digitalWrite(_DI,!bit); |
|
|
|
digitalWrite(_DI,!bit); |
|
|
|
delayMicroseconds(5); |
|
|
|
delayMicroseconds(5); |
|
|
|
if (_recv_bit != bit){ // collision!
|
|
|
|
if (_line != bit){ // collision!
|
|
|
|
digitalWrite(_DE,LOW); |
|
|
|
digitalWrite(_DE,LOW); |
|
|
|
#ifdef DEBUG |
|
|
|
#ifdef SEND |
|
|
|
Serial.println(F("Collision!")); |
|
|
|
Serial.println(F("Collision!")); |
|
|
|
#endif |
|
|
|
#endif |
|
|
|
return false; |
|
|
|
return false; |
|
|
|
} |
|
|
|
} |
|
|
|
delayMicroseconds(_pulse_len-12); |
|
|
|
delayMicroseconds(_pulse_len-5); |
|
|
|
return true; |
|
|
|
return true; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
boolean writeByte(byte b){ |
|
|
|
|
|
|
|
return writeBit(b & 0x01) |
|
|
|
|
|
|
|
&& writeBit(b & 0x02) |
|
|
|
|
|
|
|
&& writeBit(b & 0x04) |
|
|
|
|
|
|
|
&& writeBit(b & 0x08) |
|
|
|
|
|
|
|
&& writeBit(b & 0x10) |
|
|
|
|
|
|
|
&& writeBit(b & 0x20) |
|
|
|
|
|
|
|
&& writeBit(b & 0x40) |
|
|
|
|
|
|
|
&& writeBit(b & 0x80); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
boolean send485(char message[]){ |
|
|
|
boolean send485(char message[]){ |
|
|
|
#ifdef DEBUG |
|
|
|
#ifdef SEND |
|
|
|
Serial.print(F("preparing to send ")); |
|
|
|
Serial.print(F("preparing to send ")); |
|
|
|
Serial.print(message); |
|
|
|
Serial.print(message); |
|
|
|
Serial.print(F(": line state = ")); |
|
|
|
Serial.print(F(": line state = ")); |
|
|
|
Serial.print(_recv_bit); |
|
|
|
Serial.print(_line); |
|
|
|
Serial.print(F(" / last_flip = ")); |
|
|
|
Serial.print(F(" / last_flip = ")); |
|
|
|
Serial.print(_last_flip); |
|
|
|
Serial.print(_last_flip); |
|
|
|
Serial.print(F(" / micros = ")); |
|
|
|
Serial.print(F(" / micros = ")); |
|
|
|
Serial.println(micros()); |
|
|
|
Serial.println(micros()); |
|
|
|
#endif |
|
|
|
#endif |
|
|
|
while (_recv_bit || (micros() - _last_flip) < (20 * _pulse_len)) { |
|
|
|
while (_line || (micros() - _last_flip) < (20 * _pulse_len)) { |
|
|
|
delayMicroseconds(20*_pulse_len); |
|
|
|
delayMicroseconds(20*_pulse_len); |
|
|
|
} |
|
|
|
} |
|
|
|
#ifdef DEBUG |
|
|
|
#ifdef SEND |
|
|
|
Serial.println(F("enabling driver…")); |
|
|
|
Serial.println(F("enabling driver…")); |
|
|
|
#endif |
|
|
|
#endif |
|
|
|
|
|
|
|
digitalWrite(_DI,LOW); |
|
|
|
digitalWrite(_DE,HIGH); // enable driver
|
|
|
|
digitalWrite(_DE,HIGH); // enable driver
|
|
|
|
if (!writeBit(HIGH)) return false; |
|
|
|
int pos = -1; // increment pos prior to sending char!
|
|
|
|
int pos = -1; |
|
|
|
boolean sync = writeBit(0); |
|
|
|
boolean good = true; |
|
|
|
|
|
|
|
do { |
|
|
|
do { |
|
|
|
pos++; |
|
|
|
pos++; |
|
|
|
#ifdef DEBUG |
|
|
|
sync = sync && writeByte(message[pos]); |
|
|
|
Serial.print(F("sending character ")); Serial.println(message[pos]); |
|
|
|
} while (sync && message[pos]); |
|
|
|
#endif |
|
|
|
digitalWrite(_DI,LOW); |
|
|
|
good = writeBit(message[pos] & 0x01) |
|
|
|
|
|
|
|
&& writeBit(message[pos] & 0x02) |
|
|
|
|
|
|
|
&& writeBit(message[pos] & 0x04) |
|
|
|
|
|
|
|
&& writeBit(message[pos] & 0x08) |
|
|
|
|
|
|
|
&& writeBit(message[pos] & 0x10) |
|
|
|
|
|
|
|
&& writeBit(message[pos] & 0x20) |
|
|
|
|
|
|
|
&& writeBit(message[pos] & 0x40) |
|
|
|
|
|
|
|
&& writeBit(message[pos] & 0x80); |
|
|
|
|
|
|
|
} while (good && message[pos]); |
|
|
|
|
|
|
|
if (good) writeBit(1); |
|
|
|
|
|
|
|
digitalWrite(_DE,LOW); // disable driver
|
|
|
|
digitalWrite(_DE,LOW); // disable driver
|
|
|
|
#ifdef DEBUG |
|
|
|
#ifdef SEND |
|
|
|
Serial.println(F("disabled driver…")); |
|
|
|
Serial.println(F("disabled driver…")); |
|
|
|
#endif |
|
|
|
#endif |
|
|
|
return good; |
|
|
|
return sync; |
|
|
|
} |
|
|
|
} |
|
|
|