02. Mit ne használjunk Arduino projektekben - SoftwareSerial

Az ATMega328 chipet tartalmazó Arduino lapok egyetlen hardware UART-ot (sorosportot) tartalmaznak. De mit lehet tenni, ha második sorosportra 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 kommunuká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 sorosport 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!
 
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, sorosporti 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 sorosporti kommunikáció kiváltása például TWI/Wire vagy SPI kapcsolódással.
Tipp: A szoftveres soroport 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:
Fájlmelléklet: 

TavIR-Facebook