Browse Source

this does *not* work

Signed-off-by: Stephan Richter <s.richter@srsoftware.de>
main
Stephan Richter 1 year ago
parent
commit
add1624f97
  1. 220
      SoftRS485.cpp
  2. 3
      SoftRS485.h
  3. 6
      examples/ReceiveDemo/ReceiveDemo.ino
  4. 18
      examples/SendAndReceive/SendAndReceive.ino

220
SoftRS485.cpp

@ -7,11 +7,18 @@ @@ -7,11 +7,18 @@
#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 = 100;
long _pulse_len = 850;
// Receive vars
boolean _recv_bit = false;
@ -21,6 +28,28 @@ int _recv_pos = 0; @@ -21,6 +28,28 @@ 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();
@ -28,22 +57,36 @@ void interrupt485(){ @@ -28,22 +57,36 @@ 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<count; i++){
#ifdef DEBUG
Serial.print(_recv_bit);
Serial.println(" <=");
#endif
if (_recv_idx == 0) {
_recv_msg[_recv_pos] = (!_recv_bit);
_recv_msg[_recv_pos] = (_recv_bit);
} else {
_recv_msg[_recv_pos] |= (!_recv_bit)<<_recv_idx;
_recv_msg[_recv_pos] |= (_recv_bit)<<_recv_idx;
}
_recv_idx++;
if (_recv_idx == 8){
#ifdef DEBUG
Serial.print("0x");
Serial.print(_recv_msg[_recv_pos],HEX);
Serial.print(" recevied / ");
Serial.println((char)_recv_msg[_recv_pos]);
#endif
_recv_idx = 0;
if (_recv_msg[_recv_pos] == 0x00){
_avail = _recv_pos != 0;
@ -55,6 +98,102 @@ void interrupt485(){ @@ -55,6 +98,102 @@ void interrupt485(){
}
}
ISR(TIMER1_COMPA_vect){
OCR1A += TIMER; // Advance The COMPA Register
boolean echo = digitalRead(_RO);
if (_send_state == SENT){
if (echo != _send_bit){
digitalWrite(_DE,LOW);
_send_state = WAIT;
#ifdef DEBUG
Serial.println(F("Collision"));
#endif
} else {
digitalWrite(_DE,LOW);
_send_message[0] = 0x00;
_send_state = IDLE;
disableSendTimer();
#ifdef DEBUG
Serial.println(F("Transmission complete"));
#endif
}
return;
}
if (_send_state == SEND){
if (echo != _send_bit){
digitalWrite(_DE,LOW);
_send_state = WAIT;
#ifdef DEBUG
Serial.println(F("Collision"));
#endif
return;
}
char c = _send_message[_send_pos];
_send_bit = c & (1 << _send_idx);
digitalWrite(_DI,_send_bit);
#ifdef DEBUG
if (!_send_idx) {
Serial.print("Sending "); Serial.print(c); Serial.print(" / 0x"); Serial.println(c,HEX);
}
Serial.print("<--- "); Serial.println(_send_bit);
#endif
_send_idx++;
if (_send_idx == 8) {
_send_idx = 0;
_send_pos++;
if (c == 0x00 || _send_pos == MSG_LEN){
_send_state = SENT;
}
}
}
if (_send_state == WAIT){
long diff = micros() - _last_flip; // µs
long idle_count = diff / _pulse_len;
if (idle_count > 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;
@ -73,7 +212,7 @@ void init485(int RO, int nRE, int DE, int DI){ @@ -73,7 +212,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 = "));
@ -88,15 +227,6 @@ void init485(int RO, int nRE, int DE, int DI){ @@ -88,15 +227,6 @@ void init485(int RO, int nRE, int DE, int DI){
_last_flip = micros();
}
void speed485(long baudrate){
#ifndef DEBUG
_pulse_len = 1e6 / baudrate;
#else
_pulse_len = 1000;
Serial.print(F("Set pulse_len to ")); Serial.print(_pulse_len); Serial.println(F("µs"));
#endif
}
boolean available485(){
return _avail;
}
@ -106,59 +236,29 @@ String get485message(){ @@ -106,59 +236,29 @@ String get485message(){
return String((char*)_recv_msg);
}
boolean writeBit(boolean bit){
digitalWrite(_DI,!bit);
delayMicroseconds(5);
if (_recv_bit != bit){ // collision!
digitalWrite(_DE,LOW);
boolean send485(String message){
if (_send_message[0] != 0x00) {
#ifdef DEBUG
Serial.println(F("Collision!"));
Serial.println("Busy!");
#endif
return false;
return false; // we already have a queued message, abort!
}
delayMicroseconds(_pulse_len-5);
return true;
}
boolean send485(char message[]){
#ifdef DEBUG
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());
Serial.print(F("Preparing to send ")); Serial.println(message);
#endif
while (_recv_bit || (micros() - _last_flip) < (20 * _pulse_len)) {
delayMicroseconds(20*_pulse_len);
const char* buf = message.c_str();
for (int idx = 0; idx<MSG_LEN; idx++){
_send_message[idx] = buf[idx]; // copy message
if (_send_message[idx] == 0x00) break;
}
if (_send_message[0] == 0x00) return false; // message is empty
#ifdef DEBUG
Serial.println(F("enabling driver…"));
#endif
digitalWrite(_DE,HIGH); // enable driver
if (!writeBit(HIGH)) return false;
int pos = -1;
boolean good = true;
do {
pos++;
#ifdef DEBUG
Serial.print(F("sending character ")); Serial.println(message[pos]);
#endif
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
#ifdef DEBUG
Serial.println(F("disabled driver…"));
Serial.print(F("Message copied to send buffer: "));
Serial.println(_send_message);
#endif
return good;
_send_state = WAIT;
enableSendTimer();
return true;
}

3
SoftRS485.h

@ -9,8 +9,7 @@ @@ -9,8 +9,7 @@
#include "Arduino.h"
extern void init485(int RO, int nRE, int DE, int DI);
extern void speed485(long pulse_length);
extern boolean available485();
extern String get485message();
extern boolean send485(char message[]);
extern boolean send485(String message);
#endif

6
examples/ReceiveDemo/ReceiveDemo.ino

@ -7,6 +7,7 @@ @@ -7,6 +7,7 @@
void setup() {
Serial.begin(115200);
Serial.println(F("This is ReceiveDemo, version 0.1"));
init485(2,3,4,5); // library initialization:
// connect pin 2 to RO of Max485
@ -17,8 +18,5 @@ void setup() { @@ -17,8 +18,5 @@ void setup() {
}
void loop(){
if (available485()){ // check if we have received anything
Serial.print("messageReceived: ");
Serial.println(get485Message()); // read the received message
}
if (available485()) Serial.println("Received: "+get485message());
}

18
examples/SendAndReceive/SendAndReceive.ino

@ -2,17 +2,17 @@ @@ -2,17 +2,17 @@
void setup() {
Serial.begin(115200);
init485(2,3,4,5);
speed485(8000);
boolean sent = false;
while (!sent) {
sent = send485("This message is sent and received!");
}
Serial.println("This is SendAndReceive 0.1");
init485(2,3,4,5); // library initialization:
// connect pin 2 to RO of Max485
// connect pin 3 to ^RE of Max485
// connect pin 4 to DE of Max485
// connect pin 5 to DI of Max485
while (send485("Hello World!")) {}
}
void loop() {
// put your main code here, to run repeatedly:
if (available485()){
Serial.println("Received "+get485message());
}
if (available485()) Serial.println("Received "+get485message());
}

Loading…
Cancel
Save