... or NeoSWSerial.
If you connect the RX pin to a different digital input pin, you can receive characters on the RX pin with AltSoftSerial or NeoSWSerial, and detect the BREAK condition with the other digital input pin.
Here's a sketch that shows how to test it:
static const int RXpin = 2;
static const int TXpin = 3;
static const int breakPin = 4; // break detector, normally connected to RXpin
// For testing, connect the breakPin to the TXpin so we can simulate "sending"
// a BREAK to ourself.
#include <NeoSWSerial.h>
NeoSWSerial testPort( RXpin, TXpin );
static const unsigned long BAUD_RATE = 9600;
static const uint32_t MIN_BREAK_TIME = (13 * 1000000) / BAUD_RATE + 1; // microseconds
// Variables for detecting the BREAK signal on the breakPin
uint32_t lastLow;
bool lastState = false;
bool breakReceived = false;
// Variables for simulating the BREAK signal on the TXpin
uint32_t lastTest;
uint8_t testing = 1;
void setup()
{
Serial.begin( 9600 );
Serial.println( F("Break test") );
Serial.flush();
lastTest = micros();
testPort.begin( BAUD_RATE );
}
void loop()
{
checkForBreak();
simulateBreak();
} // loop
void checkForBreak()
{
bool rxState = digitalRead( breakPin );
if (lastState != rxState) { // breakPin changed?
lastState = rxState;
if (!rxState) {
lastLow = micros(); // Remember when it went LOW
} else {
breakReceived = false; // It went HIGH, clear the break flag
}
} else { // same state
if (!rxState) {
uint32_t lowTime = micros() - lastLow;
if (!breakReceived && (lowTime >= MIN_BREAK_TIME)) {
breakReceived = true; // stays true until line goes high again
Serial.println( F("BREAK") );// do something?
}
}
}
} // checkForBreak
void simulateBreak()
{
uint32_t dt = (micros() - lastTest);
// Once per second, start a BREAK signal
if (dt > 1000000UL) {
startBreak();
} else if (!testing) {
// do nothing from dt = 0..MIN_BREAK_TIME
if (dt > MIN_BREAK_TIME+8) { // plus a little longer
stopBreak();
}
} else { // testing -- send characters
// At 9600 each char sent takes 1.0417ms. Don't send them any faster than that.
static const uint32_t CHAR_INTERVAL = 1043; // us
uint16_t charToSend = dt/CHAR_INTERVAL;
// Send chars until...
if ((dt <= (1000000UL - 3*CHAR_INTERVAL))
// ...it's almost time to start the BREAK, *AND*
&&
(testing != (charToSend & 0xFF))) {
// ...it's time to send another character
testing = charToSend; // `testing` is the current character interval and...
testPort.write( testing ); // ... the byte to send
// Also display the "printable" character we are sending
if ((' ' <= testing) && (testing <= '~')) {
Serial.write( testing );
}
}
}
} // simulateBreak
void startBreak()
{
testPort.end(); // stop sending characters...
pinMode( TXpin, OUTPUT );
digitalWrite( TXpin, LOW ); // ...so we can start the BREAK signal
Serial.println();
lastTest = micros();
testing = 0;
} // startBreak
void stopBreak()
{
digitalWrite( TXpin, HIGH ); // stop the BREAK signal
pinMode( TXpin, INPUT );
testPort.begin( BAUD_RATE );
testing = 2; // wait 2 whole character times before sending test chars
} // stopBreak
When you run it, it should display the following:
Break test
!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~ !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~ !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~ !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~
BREAK
!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~ !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~ !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~ !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~
BREAK
You should see "BREAK" appear once per second. The other characters are just to test that it doesn't detect a legal character as a BREAK condition.
For your sketch, you'll use the same break detection code, but don't use the simulation code. Connect the breakPin
to the RXpin
Using a separate pin to detect the break condition has been discussed several times recently. We keep coming back to using a separate pin so you don't have to modify an existing library (or write your own).