From d79c4c3a209e09757c3b0bb541e21eabd52ad6e5 Mon Sep 17 00:00:00 2001 From: Stephan Richter Date: Mon, 13 Nov 2023 08:22:23 +0100 Subject: [PATCH] Reverted back to delay-based send. Seems to work with single master. Needs to be tested in multi-drop environment Signed-off-by: Stephan Richter --- SoftRS485.cpp | 211 ++++++++++++-------------------------------------- SoftRS485.h | 2 +- 2 files changed, 52 insertions(+), 161 deletions(-) diff --git a/SoftRS485.cpp b/SoftRS485.cpp index 3339dfb..2ecb200 100644 --- a/SoftRS485.cpp +++ b/SoftRS485.cpp @@ -7,18 +7,11 @@ #include "SoftRS485.h" //#define DEBUG - #define MSG_LEN 64 -#define IDLE 0 -#define WAIT 1 -#define SEND 2 -#define SENT 3 -#define TIMER 250 // Pins int _RO, _RE, _DE, _DI; -long _pulse_len = 850; - +long _pulse_len = 105; // Receive vars boolean _recv_bit = false; @@ -28,28 +21,6 @@ int _recv_pos = 0; int _recv_idx = 0; boolean _avail = false; -// Send vars -char _send_message[MSG_LEN]; -int _send_state = IDLE; -int _send_pos = 0; -int _send_idx = 0; -boolean _send_bit = false; - -void enableSendTimer(){ -#ifdef DEBUG - Serial.print(F("Enabling send timer. Old Value: b")); - Serial.println(TIMSK1,BIN); -#endif - TIMSK1 |= B00000010; // Enable Timer COMPA Interrupt -} - -void disableSendTimer(){ -#ifdef DEBUG - Serial.println("Disable send timer"); -#endif - TIMSK1 = TIMSK1 & ~B00000010; // Enable Timer COMPA Interrupt -} - void interrupt485(){ _recv_bit = !digitalRead(_RO); // HIGH level = logical zero and vice versa long now = micros(); @@ -57,36 +28,22 @@ void interrupt485(){ _last_flip = now; if (diff > 20*_pulse_len){ // we received a start bit #ifdef DEBUG + Serial.print(F("State changed to ")); Serial.println(_recv_bit); Serial.println(F("received start bit")); #endif _recv_pos = 0; _recv_idx = 0; _last_flip+=_pulse_len; } else { -#ifdef DEBUG - Serial.print(diff); - Serial.println("µs"); -#endif - long count = diff/_pulse_len; for (int i=0; i MSG_LEN){ - _send_bit = LOW; - digitalWrite(_DE,HIGH); - digitalWrite(_DI,_send_bit); - _send_state = SEND; - _send_idx = 0; - _send_pos = 0; -#ifdef DEBUG - Serial.println(F("Sending start bit (1)")); -#endif - } else { -#ifdef DEBUG - Serial.println(F("Bus busy")); -#endif - return; - } - } - - echo = digitalRead(_RO); - if (echo != _send_bit){ - digitalWrite(_DE,LOW); - _send_state = WAIT; -#ifdef DEBUG - Serial.println(F("Collision")); -#endif - return; - } - -} - -void configureSendTimer(){ - TCCR1A = 0; // Init Timer1A - TCCR1B = 0; // Init Timer1B - TCCR1B |= B00000011; // Prescaler = 1 - OCR1A = TIMER; // Timer Compare1A Register -} - - - void init485(int RO, int nRE, int DE, int DI){ _RO=RO; _RE=nRE; @@ -212,7 +73,7 @@ void init485(int RO, int nRE, int DE, int DI){ digitalWrite(_DI,LOW); // output line = LOW attachInterrupt(digitalPinToInterrupt(_RO),interrupt485,CHANGE); - configureSendTimer(); + #ifdef DEBUG Serial.begin(115200); Serial.print(F("RO = ")); @@ -236,29 +97,59 @@ String get485message(){ return String((char*)_recv_msg); } - -boolean send485(String message){ - if (_send_message[0] != 0x00) { +boolean writeBit(boolean bit){ + digitalWrite(_DI,!bit); + delayMicroseconds(5); + if (_recv_bit != bit){ // collision! + digitalWrite(_DE,LOW); #ifdef DEBUG - Serial.println("Busy!"); + Serial.println(F("Collision!")); #endif - return false; // we already have a queued message, abort! + return false; } + delayMicroseconds(_pulse_len-12); + return true; +} +boolean send485(char message[]){ #ifdef DEBUG - Serial.print(F("Preparing to send ")); Serial.println(message); + Serial.print(F("preparing to send ")); + Serial.print(message); + Serial.print(F(": line state = ")); + Serial.print(_recv_bit); + Serial.print(F(" / last_flip = ")); + Serial.print(_last_flip); + Serial.print(F(" / micros = ")); + Serial.println(micros()); #endif - const char* buf = message.c_str(); - for (int idx = 0; idx