SoftwareSerial(rxPin, txPin);
Using software serial, if I want just a TX, can I use a value such as 0 or -1 to just have TX. (Same for RX)
For example: SoftwareSerial(5, 0);
SoftwareSerial(rxPin, txPin);
Using software serial, if I want just a TX, can I use a value such as 0 or -1 to just have TX. (Same for RX)
For example: SoftwareSerial(5, 0);
No. There is no way to disable transmit or receive functionality. You will have to assign RX (or TX) to a pin that you are otherwise not using.
Actually, you can use a non-existent pin, such as -1. Just make sure that you don't try to send if you do not use a valid transmit pin.
Any data that the device you are talking to tries to send will not actually get to the Arduino if you do not connect its TX pin to the Arduino, so use a non-existent pin for the receive pin to not actually listen to the device.
I have serial output from the board for debugging, and no need to RX at all, so this saves me a valuable pin.
Much appreciated.
PaulS:
Actually, you can use a non-existent pin, such as -1. Just make sure that you don't try to send if you do not use a valid transmit pin.
Using a non-existent pin is not a good idea. pinMode and digitalWrite are called for the two pins. Neither function performs enough validation to be reliable when a non-existent pin number is passed.
void SoftwareSerial::setTX(uint8_t tx)
{
pinMode(tx, OUTPUT);
digitalWrite(tx, HIGH);
...
}
void SoftwareSerial::setRX(uint8_t rx)
{
pinMode(rx, INPUT);
if (!_inverse_logic)
digitalWrite(rx, HIGH); // pullup for normal logic!
...
}
So what negative effect might this actually have?
Let's walk through the code and try to determine what happens...
We'll work with pinMode(tx, OUTPUT); (the other calls are very similar for the sake of this discussion). The essence of the call is this... *reg |= bit; ...where reg was obtained by calling portModeRegister and bit was obtained by calling digitalPinToBitMask. portModeRegister reads a 16 bit value from Flash memory and casts the value to a pointer. When the parameter passed to portModeRegister is in range (when the pin number is valid), the 16 bit value is read from the port_to_mode_PGM array. When the parameter is not in range, an arbitrary location anywhere in Flash can be read which means an essentially "random" value is returned.
The net result is that a "random" location in SRAM is modified. It's not much different than dereferencing and uninitialized pointer. Not a good thing.
I don't completely follow the explanation, but shouldn't the option to disable TX or RX be written into SoftSerial?
Sounds reasonable to me. Please add the suggestion here...
http://code.google.com/p/arduino/issues/list
So if I have the situation you describe above, and some random memory is written, shouldn't I be seeing crashes?
I have one sketch running for months now where I assigned TX to -1, and it has not failed.
I assume no damage - just random crashes would be the effect.
Also, what if I have an output for an LED - lets say pin 5, and I assign 5 to TX also. If I never send any TX data, is there a specific problem with that?
db2db:
So if I have the situation you describe above, and some random memory is written, shouldn't I be seeing crashes?
You may see "crashes". They are other possible outcomes including running without symptoms.
I have one sketch running for months now where I assigned TX to -1, and it has not failed.
Good for you.
I assume no damage - just random crashes would be the effect.
There are some outcomes that could cause damage. For example, if you have a peripheral connected (like an op-amp) that drives a pin and the pin is inadvertently switched to an output the result would very likely damage the processor.
Also, what if I have an output for an LED - lets say pin 5, and I assign 5 to TX also. If I never send any TX data, is there a specific problem with that?
Nope. With the exception that the LED will be lit until you turn it off in setup. Unless you want the LED to start life lit. In which case it's a perfect solution.
Thanks for the info!
Since it's interrupt driven, you should be able to disable the pin change interrupt (PCMSKx) for the Rx pin. That should free up the pin.
How would I go about doing that?
db2db:
How would I go about doing that?
Completely untested but assuming you assign the Rx pin to pin 6, bit 6 of PCMSK2 controls whether the pin change interrupt is enabled for PCINT22 (D6) so simply clearing the bit
bitClear(PCMSK2,6);
should disable the interrupt and free up the pin.