Arduino speciális be- és kimenetek

Ebben a részben az arduino speciális be- és kimenetek használatos függvényeket, a tone, noTone, pulseIn, pulseInLong, valamint a shiftIn és shiftOut függvényeket vizsgáljuk meg.

tone()

A tone() függvény első paraméterében meghatározott csapon és a második paraméterben megadott frekvenciájú, 50%-os kitöltési tényezővel rendelkező négyszögjelet generál.

C++
byte pin;
unsigned int frequency;

tone(pin, frequency);

A tone függvény addíg fut, amíg meg nem hívjuk a noTone() függvényt. Opcionálisan megadhatunk egy harmadik paramétert is, ez az időtartam ameddíg a tone() függvénynek futnia kell.

Ha megadjuk az időtartam (duration) paramétert, a vázlatunk végrehajtása azonnal folytatódik, tehát a tone() függvény nem blokkolja az arduinó programunk futását, még akkor sem, ha a hang lejátszása még folyamatban van.

C++
byte pin;
unsigned int frequency;
unsigned long duration;

tone(pin, frequency, duration);

A megadott pinhez csatlakoztathatunk például piezo hangszórót a hangok lejátszásához.

A megadott pinhez csatlakoztathatunk például piezo hangszórót a hangok lejátszásához.

Lássunk ehez egy vázlatot.

C++
// definiáljuk a hangjegyekhez tartozó frekvenciákat (Hz)
#define NOTE_C4 262
#define NOTE_D4 294
#define NOTE_E4 330
#define NOTE_F4 349
#define NOTE_G4 392
#define NOTE_A4 440
#define NOTE_AS4 466
#define NOTE_C5 523


// Erre a pinre csatlakozik a hangszóró
int buzzerPin = 8;


// A melody tömbbe kerül a lejátszandó dallam hangjegyei.
int melody[] = {
  NOTE_C4, NOTE_C4, NOTE_D4, NOTE_C4, NOTE_F4, NOTE_E4,
  NOTE_C4, NOTE_C4, NOTE_D4, NOTE_C4, NOTE_G4, NOTE_F4,
  NOTE_C4, NOTE_C4, NOTE_C5, NOTE_A4, NOTE_F4, NOTE_E4, NOTE_D4,
  NOTE_AS4, NOTE_AS4, NOTE_A4, NOTE_F4, NOTE_G4, NOTE_F4
};


// A hangjegyek lejtszási ideje a noteDurations tömbbe kerül.
int noteDurations[] = {
  4, 4, 4, 4, 4, 2,
  4, 4, 4, 4, 4, 2,
  4, 4, 4, 4, 4, 4, 2,
  4, 4, 4, 4, 4, 2
};


void setup()
{
	// a for ciklus segítségével egyenként végigmegyünk a hangjegyeken
	for (int thisNote = 0; thisNote < 24; thisNote++) 
	{
		//  meghatározzuk a hangjegyek lejátszási idejét
		int noteDuration = 1000 / noteDurations[thisNote];
		
		// a tone() függvény elküldi a piezzo hangszórónak a buzzerPin-re,
		// a melody tömbből kiolvasott hangjegy frekvenciáját,
		// a noteDuration változóban meghatározott ideig.
		tone(buzzerPin, melody[thisNote], noteDuration);


		// meghatározzuk hangjegyek lejátszása közt eltelt időt
		int pauseBetweenNotes = noteDuration * 1.30;
		delay(pauseBetweenNotes);
		
		
		// majd leállítjuk a tone() függvény futását
		noTone(buzzerPin);
	}
}

void loop() {}

A tone() függvénnyel egyszerre csak egy hang generálható. Ha a tone() függvény fut és közben egy másik pinhez hívjuk meg, a második függvényhívás eredménytelen lesz.

Ha különböző hangokat szeretnénk különböző csapokon lejátszani, akkor noTone() függvényt meg kell hívni, mielőtt tone() függvényt ismét meghívnánk.

Azonban ha a tone() függvényt ugyanazon a csaphoz, de más frekvenciával futtatjuk, a hívás beállítja a frekvenciáját.

A tone() használata egyes arduino kártyákon zavarhatja a PWM kimenetet a 3. és 11. érintkezőkön.

Tartalomjegyzék

noTone()

A noTone() függvény leállítja a tone() függvény futását.

C++
noTone(pin)

Ha a tone() függvényt más pinekkel szeretnénk meghívni miközben hangot játszik le, akkor noTone() függvény segítségével le kell állítani, mielőtt tone() függvényt ismét meghívnánk.

Tartalomjegyzék

pulseIn()

A pulseIn() függvény impulzust olvas egy bemeneti tűn. A függvény első paramétere az aktuális pin, amelyről le szeretnénk olvasni az impulzust. A második paraméter a leolvasandó impulzus típusa, ez az érték  HIGH vagy LOW lehet.

Opcionálisan megadhatunk egy harmadik időtúllépés (timeout) paramétert, ez a mikroszekundumok száma, ameddig várni kell egy impulzus méréséig. Ha nem adjuk meg a timeout paraméter, akkor a pulseIn() függvény az alapértelmezett 1 másodpercet használja.

A függvény visszatérési értéke az impulzus hossza mikroszekundumban, vagy 0 ha nem érkezett teljes impulzus a timeout paraméterben megadott időn belül.

Használhatjuk a pulseIn() függvényt aktív megszakításokkal, de az eredmények pontatlanok lehetnek. Azonban ha a megszakítások le vannak tiltva, a millis() pontatlan értéket ad vissza, ezért körültekintően járjunk el!

A pulseIn() függvény rövidebb impulzusokat megbízhatőan olvas be, ha hosszabb impulzusokat szeretnénk mérni, használjuk helyette a pulseInLong() függvényt.

A következő példában a pulseIn() függvény második paramétere HIGH. A pulseIn() függvény figyeli, ha a pin alacsony értékről magasra változik, ekkor elindítja az időzítőt, majd megvárja, amíg a pin ismét alacsony lesz, leállítja az időzítőt, és átadja az impulzus hosszát mikroszekundumban (vagy 0-át) a „period” változónak.

C++
int pulsePin = 6;
unsigned long period;

void setup()
{
  Serial.begin(115200);
  pinMode(pulsePin, INPUT);
}

void loop()
{
  noInterrupts();
  period = pulseIn(pulsePin, HIGH);
  interrupts();
  Serial.println(period);
}

Tartalomjegyzék

pulseInLong()

A pulseInLong() függvény a pulseIn() alternatívája , amely jobban kezeli a hosszabb impulzusokat.

A pulseInLong() függvény 10 mikroszekundum és 3 perc közti impulzusok mérésére használható, és csak akkor használható, ha a megszakítások engedélyezve vannak!

Rövidebb impulzusok esetén hajlamos a hibákra, ebben az esetben használjuk inkább a pulseIn()  függvényt.

C++
int pulsePin = 6;
unsigned long period;

void setup()
{
  Serial.begin(115200);
  pinMode(pulsePin, INPUT);
}

void loop()
{
  period = pulseInLong(pulsePin, HIGH);
  Serial.println(period);
}

Tartalomjegyzék

Arduino Mega 2560 mikrokontroller kártya

Arduino Mega 2560
Arduino Mega 2560 – hirdetés

shiftIn()

A shiftIn() függvény beolvas egy bájt adatot bitenként, majd visszatér a beolvasott bájt értékével. A beolvasás a legnagyobb (MSBFIRST) vagy a legkisebb (LSBFIRST) jelentőségű bittől indul. A shiftIn() függvény minden bitnél a clockPin-t magasra húzza, a következő bitet kiolvassa az adatsorból, majd a clockPin-t ismét alacsonyra húzza.

Az Arduino shiftIn() és shiftOut() függvények az SPI szoftveres megvalósításai. Természetesen az SPI sokkal gyorsabb, de az SPI csak az Arduino néhány speciális tűjén tud működni, míg a shiftIn() és a shiftOut() az Arduino bármely két csapját használhatja.

C++
byte incomingByte;
int dataPin = 2;
int clockPin = 3;
int bitOrder = MSBFIRST;

void setup()
{
    Serial.begin(115200);
	
  	pinMode(dataPin, INPUT);
    pinMode(clockPin, OUTPUT);
}

void loop()
{
  	incomingByte = shiftIn(dataPin, clockPin, bitOrder);
  	Serial.println(incomingByte);
  	delay(1000);
}

A shiftIn() függvény három paraméterrel rendelkezik. A „dataPin” annak a csapnak a száma, amelyre a csatlakoztatott eszközről adatokat olvasunk be.

A „clockPin” annak a tűnek a száma, amely az órajelet adja.

 A „bitOrder” paraméter határozza meg, hogy milyen sorrendben kell eltolni a biteket. MSBFIRST vagy LSBFIRST .

Ha olyan eszközről szeretnénk olvasni, amelynek az órajele emelkedő élekkel működik, akkor a shiftIn() függvény hívása előtt a clockPin-t alacsonyra kell húzni.

C++
byte incomingByte;
int dataPin = 2;
int clockPin = 3;
int bitOrder = MSBFIRST;

void setup()
{
    Serial.begin(115200);
	
  	pinMode(dataPin, INPUT);
    pinMode(clockPin, OUTPUT);
}

void loop()
{
  	digitalWrite(clockPin, LOW);
  	incomingByte = shiftIn(dataPin, clockPin, bitOrder);
  	Serial.println(incomingByte);
  	delay(1000);
}

Tartalomjegyzék

shiftOut()

A shiftOut() függvény egy bájt adatot (küld) tol el bitenként egy meghatározott tűn. A shiftOut() függvénynek nincs visszatérési értéke. A bájt eltolása (küldése) a legnagyobb (MSBFIRST) vagy a legkisebb (LSBFIRST) jelentőségű bittől indul. A shiftOut() függvény minden bitnél a clockPin-t magasra húzza, a következő bitet kitolja, majd a clockPin-t ismét alacsonyra húzza.

C++
int dataPin = 2;
int clockPin = 3;
int bitOrder = MSBFIRST;
byte value = 10010111;

void setup()
{
    pinMode(dataPin, OUTPUT);
    pinMode(clockPin, OUTPUT);

    shiftOut(dataPin, clockPin, bitOrder, value);
}

void loop(){}

A shiftOut() függvény négy paraméterrel rendelkezik. A „dataPin” az a tű, amelyre az egyes biteket ki kell tolni.

A „clockPin” adja az órajelet. Magas, majd alacsony szintet vesz fel, ha a bit elérhető a „dataPin” lábon.

A „bitOrder” változó határozza meg, hogy milyen sorrendben kell eltolni a biteket. MSBFIRST vagy LSBFIRST.

A „value” változó tartalmazza az eltolandó bájt értékét.

Ha olyan eszközre küldünk adatokat, amelynek az órajele emelkedő élekkel működik, akkor a shiftOut() függvény hívása előtt a clockPin-t alacsonyra kell húzni.

C++
int dataPin = 2;
int clockPin = 3;
int bitOrder = MSBFIRST;
byte value = 10010111;

void setup()
{
    pinMode(dataPin, OUTPUT);
    pinMode(clockPin, OUTPUT);

    digitalWrite(clockPin, LOW);
    shiftOut(dataPin, clockPin, bitOrder, value);
}

void loop(){}

Amennyiben 8 bitnél nagyobb értéket kell kitolni a kimenetre, (tehát az érték nagyobb mint 255) a műveletet több lépcsőben kell elvégezni.

C++
// Az érték nagyobb mint 255
int value = 500; 

// Ezért két bájtot küldünk.
// Ha a bitsorrend MSBFIRST, így járjunk el
shiftOut(dataPin, clockPin, MSBFIRST, (value >> 8));
shiftOut(dataPin, clockPin, MSBFIRST, value);

// Vagy ha a bitsorrend LSBFIRST, akkor így járjunk el
shiftOut(dataPin, clockPin, LSBFIRST, value);
shiftOut(dataPin, clockPin, LSBFIRST, (value >> 8));

A következő példában egy 74HC595 shiftregiszter IC-t kapcsolunk az Arduino UNO-hoz és 8 párhuzamos LED-et vezérelünk mindössze 3 arduino pin segítségével.

Készítsük el az alábbi áramkört:

74HC595 shiftregiszter IC-t kapcsolunk az Arduino UNO-hoz és 8 párhuzamos LED-et vezérelünk mindössze 3 arduino pin segítségével

A hozzátartozó arduino vázlat.

C++
int latchPin = 8;   // Arduino 8  pin  -->  74HC595 ST_CP pin
int clockPin = 12;  // Arduino 12 pin  -->  74HC595 SH_CP pin
int dataPin = 11;   // Arduino 11 pin  -->  74HC595 DS pin

void setup()
{
  pinMode(latchPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(dataPin, OUTPUT);
}

void loop()
{
  for (int i = 0; i < 256; i++)
  {
    // A latchPin-t alacsonyan tartjuk amíg tart az átvitel.
    // Ez letiltja a tároló regiszter tartalmának a kiírását a kimeneti lábakra.
    digitalWrite(latchPin, LOW);

    // A  shiftOut() függvény elküldi az aktuális bitet a 74HC595 shiftregiszternek
    shiftOut(dataPin, clockPin, LSBFIRST, i);
    
    // a latch pin magasra húzása jelzi a 74HC595 chipnek, hogy az átvitel befejeződött 
    // és a küldött bitek az tároló regiszterből a kimeneti lábakra kerülhetnek.
    digitalWrite(latchPin, HIGH);

    // majd várunk egy másodpercet, hogy szemmel is látható legyen a kimenet változása.
    delay(1000);
  }
}

Tartalomjegyzék