
Az ATMega328 chipet tartalmazó Arduino lapok egyetlen hardware UART-ot (soros portot) tartalmaznak. De mit lehet tenni, ha második soros portra is szükség van? Egyszerű: a SoftwareSerial eljárással létrehozunk annyit, amennyi csak kell. De mi ezzel a probléma?
A probléma, hogy hiányzik a közvetlen hardware támogatás és a SoftwareSerial folyamatosan ciklikusan figyeli a változásokat és az eközben eltelt időből számolható a fogadott/küldött adat. Erre csak akkor van mód, ha a megszakítások letiltásra kerülhetnek – különben elcsúszik az időzítés és széthullik a kommunikáció. Ez így elég nagy felfordulást okoz az időzítésérzékeny folyamatokban. Ha egynél több UART-ra van szükség, akkor az Arduino Mega vagy a Leonardo lehet megfelelő választás. Így az USB porton marad az illesztés (Mega) vagy a chip integrált USB-je biztosítja a soros kommunikációt. Mindenképp marad így szabadon hardware soros port.
De mikor lehet használni a SoftwareSerial vagy a NewSoftwareSerial eljárásokat?
Amikor a szoftver UART pl. debug információt küld, és megengedhető a megszakítások miatti csúszás vagy a megszakítások tiltása. A küldés során a SoftSerial eljárások használatából fakadóan előforduló időzítéscsúszást még tolerálnak a vevőáramkörök, ugyanakkor a SoftSerial vételre való használata a megszakítások kiszámíthatatlansága miatt erősen bizonytalan működést eredményez!
A NewSoftserial az Arduino-0022 verziójához jelent meg először, majd az Arduino-1.0 kiadásában a SoftSerial ejárás kicserélésre is került. Azaz az Arduino 1.0-ban már SoftSerial néven a NewSoftSerial található meg.
Ami a NewSoftSerial előnye a SoftSerialhoz képest:
- 4-600 byte SRAM megtakarítás, mivel a print osztályt használja. Így nem szükséges duplikált kódrészlet.
- A vétel (Rx) ugyanúgy bufferelésre kerül, mint a hardware sorosport esetén.
- A Tx kivezetés bármelyik szabad I/O láb lehet, míg vétel esetén az Arduino Uno, Dieclimila/Duemilanove (ATMega168/328) esetén a 0..13 mellett az A0…A5 is megfelel Rx kivezetésnek. Ám Arduino Mega esetén csak az alábbi kivezetésekre kerülhet a szoftveres Rx láb: 10, 11, 12, 13, 50, 51, 52, 53, 62, 63, 64, 65, 66, 67, 68, 69. Leonardo (ATMega32U4) esetén ugyanilyen kötöttség a 8, 9, 10, 11, 14 (MISO), 15 (SCK), 16 (MOSI) kivezetések használhatósága Rx esetén. A megkötések oka, hogy a NewSoftSerial megszakításkezelést használ az adatok fogadásának detektálására – így csökkentve az adatvesztések kockázatát.
- Egyidőben több SoftwareSerial is használható a programon belül.
- A 8, 16 és 20 MHz processzorok is támogatottak.
- A szoftveres soros port begin() párja az end() is elérhető. A kivezetés a felszabadítás után standard I/O kivezetésként használható.
Fontos! A 300,600, 1200 bps sebesség használata a millis() függvény futásában fennakadást okozhat. Nagyobb sebességek esetén a túl gyakori megszakítás adatvesztést okozhat. Így a 38.4kbps, 57.6kbps és a 115.2kbps sebesség kerülendő.
Adáskor nincsen bufferelés, és feltartja a program futását!
SoftwareSerial mintakód
A hardware sorosport lábait használjuk, azonban szoftveres sorosortként. A bejövő karaktert visszaküldjük a porton át, minden beérkező karakter átbillenti az alaplapi LED állapotát az ellenkezőjébe.
/*Software serial test
*/
// include the SoftwareSerial library so you can use its functions:
#include <SoftwareSerial.h>
#define rxPin 0
#define txPin 1
#define ledPin 13
// set up a new serial port
SoftwareSerial mySerial = SoftwareSerial(rxPin, txPin);
byte pinState = 0;
void setup() {
// define pin modes for tx, rx, led pins:
pinMode(rxPin, INPUT);
pinMode(txPin, OUTPUT);
pinMode(ledPin, OUTPUT);
// set the data rate for the SoftwareSerial port
mySerial.begin(9600);
//Serial.begin(9600);
mySerial.println("Hello World - SoftwareSerial");
}
void loop() {
if (mySerial.available() > 0){
// listen for new serial coming in:
char someChar = mySerial.read();
// print out the character:
mySerial.print(someChar);
// toggle an LED just so you see the thing's alive.
// this LED will go on with every OTHER character received:
toggle(ledPin);
}
}
void toggle(int pinNum) {
// set the LED pin using the pinState variable:
digitalWrite(pinNum, pinState);
// if pinState = 0, set it to 1, and vice versa:
pinState = !pinState;
}
Hol használható a szoftveres sorosport?
Minden olyan helyen, ahol a soros kommunikációs sebessége nem több mint 19200 bps. Például GPS vevőkkel való kommunikációra, másik Arduinoval való összekötésre vagy akár RS-485 busz használatára. A fokozott megszakításkezelés miatt a főprogramban nem lehet sok idővesztességet okozó programrészlet, megszakításba beágyazva nem lehet időigényes művelet (pl. várakozás, LCD kezelés, soros porti adás/vétel, 1-Wire busz kezelés, stb.). Érdemes kerülni a többszörös SoftwareSerial használatot, mert egymást is feltartják!
De a lehetőségek szerint Arduino Mega áramkör ekkor az igazi, vagy a soros porti kommunikáció kiváltása például TWI/Wire vagy SPI kapcsolódással.
Tipp: A szoftveres soros port 64 byte SRAM bufferrel rendelkezik, azaz ha nem tudjuk azonnal kiolvasni/feldolgozni – akkor sem vesznek el az adatok.
Mintaprogramok találhatóak az Arduino keretrendszerben a Fájl > Minták > SoftwareSerial alatt.
Felhasznált források:
- http://arduiniana.org/libraries/newsoftserial/
- http://www.arduino.cc/en/Reference/SoftwareSerial
- http://arduiniana.org/libraries/NewSoftSerial/