
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.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | /*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/







