60 nap alatt Arduino #36 - Shift regiszter

A "60 nap alatt Arduino" tanfolyam házi feladatai és közvetlen témái
Avatar
macsek
Bitmanipulátor
Hozzászólások: 121
Csatlakozott: 2008. december 4. csütörtök, 7:00
Tartózkodási hely: Bp

60 nap alatt Arduino #36 - Shift regiszter

HozzászólásSzerző: macsek » 2012. szeptember 5. szerda, 10:16

Az áramkör

A következő összekötéseket kell megtenni az áramkör használatához:
  • GND (pin 8) a közös földre,
  • Vcc (pin 16) az 5V-ra,
  • OE (pin 13) a közös földre,
  • MR (pin 10) az 5V-ra.
Ezzel a bekötéssel-beállítással a kimenetek folyamatosan aktívak és minden időben címezhetőek. Ha az adatlapot megnézzük, látható, hogy bekapcsoláskor (amikor a rendszert feszültség alá helyezzük), a kimenetek véletlenszerűen állnak be és a LED-ek is világítanak (épp melyik rekeszben mennyi elektron van). Ennek oka, hogy a chip kimenete állandó engedélyezett (OE - Output Enable) és a chip sem nullázott állapotból indul (MR - Master reset - fixen bekötve). Elegánsan természetesen ezeket Arduino lábról is kontrollálhatjuk, de így szabad kivezetést vesztünk..


Vagy egy ellenállással (mondjuk 10k) MR-t a tápra (+5V) kötjük, ugyanakkor MR és a föld közé kis kondenzátort (pl. 33n) rakunk.
Ez a bekapcsoláskor üres kondenzátor rövidzárként viselkedik és MR földpotenciálra kerül, ezzel MR törli a tároló tartalmát, majd rövidesen feltöltődik az ellenálláson keresztül tápfeszültségre, onnantól kikapcsolásig magas szinten marad, biztosítva ezzel a normál működést.

Avatar
Robert
Elektronbűvölő
Hozzászólások: 9973
Csatlakozott: 2005. december 9. péntek, 7:00
Tartózkodási hely: Budapest
Kapcsolat:

HozzászólásSzerző: Robert » 2012. szeptember 5. szerda, 10:20

Gyakorlatibb megoldés:

Az *duino panel RESET kivezetését kötöm rá.
Így ha resetet nyomok, akkor mind az AVR, mind a shift register resetelődik...

Különben csak a _bekapcsolási_ reset van megodva, de ha a AVRt ujrainditom, akkor az utolsó kiküldött adat van a shift regiszterben. Plusz a Arduino nyelven a setup() alatt a shiftregiszter nullázása is a feladat...

Off:
De a RESET és témakörei egy külön fejezet a haladó leckékben :).
- mit keres ott a dióda
- mit tehetek rá
- watchdog vagy egyéb resetjelek...

Avatar
macsek
Bitmanipulátor
Hozzászólások: 121
Csatlakozott: 2008. december 4. csütörtök, 7:00
Tartózkodási hely: Bp

HozzászólásSzerző: macsek » 2012. szeptember 5. szerda, 11:05

Robert írta:Gyakorlatibb megoldés:

Az *duino panel RESET kivezetését kötöm rá.
Így ha resetet nyomok, akkor mind az AVR, mind a shift register resetelődik...
Igen, így még jobb, mert a programletöltés is törli akkor.
De ahogy nézem az Arduino UNO reset-e is így van kötve, csak a 10k mellé 100n és egy bontható átkötés után még 1k és úgy földre. A duemillanove viszont nem, ott az USB illesztő IC (FTDI) 2 lábára megy kondi ill. ellenállás.

Avatar
Robert
Elektronbűvölő
Hozzászólások: 9973
Csatlakozott: 2005. december 9. péntek, 7:00
Tartózkodási hely: Budapest
Kapcsolat:

HozzászólásSzerző: Robert » 2012. szeptember 5. szerda, 11:25

Mintha mind a 2 reset #reset lenne. Azaz ha GNDre kerül, akkor töröl.

Kösd be a tápkivezezés RESET lábára...
AVR-en 3k3 + 100nF van általában...

Avatar
Physix66
Újonc
Újonc
Hozzászólások: 3
Csatlakozott: 2012. szeptember 10. hétfő, 6:00

SPI

HozzászólásSzerző: Physix66 » 2012. szeptember 10. hétfő, 22:10

Üdv!

Ha így átírom a példában kapott kódot, az így jó e egy ATMEGA1284P esetében? Valahogy úgy érzem rosszul fogtam fel valamit...

#36-os leckéből

int SCK = 8;
int SDO = 6;
int CE = 5;

void setup() {
pinMode(CE, OUTPUT);
pinMode(SCK, OUTPUT);
pinMode(SDO, OUTPUT);
}

void loop() {
numberToDisplay 256
for (int numberToDisplay = 0; numberToDisplay = 256; numberToDisplay++)
{
digitalWrite(CE, 0);
shiftOut(SDO, SCK, MSBFIRST, numberToDisplay);
digitalWrite(CE, 1);
delay(500);
}
}

Avatar
Robert
Elektronbűvölő
Hozzászólások: 9973
Csatlakozott: 2005. december 9. péntek, 7:00
Tartózkodási hely: Budapest
Kapcsolat:

HozzászólásSzerző: Robert » 2012. szeptember 11. kedd, 5:32

Igen. De a fordító: Wiring!
Arduino nem támogatja, csak a mega8/mega168/mega328/mega1280/mega2560 chipeket...

Ezt a sort nem értem:
numberToDisplay 256

Avatar
Csoki
DrótVégénSzéndarab
Hozzászólások: 44
Csatlakozott: 2012. június 25. hétfő, 6:00
Tartózkodási hely: Pécs

HozzászólásSzerző: Csoki » 2012. szeptember 11. kedd, 12:21

Én is látok egy gondot:

for (int numberToDisplay = 0; numberToDisplay = 256; numberToDisplay++)

Szerintem ez a ciklus nem fog lefutni.

Avatar
Physix66
Újonc
Újonc
Hozzászólások: 3
Csatlakozott: 2012. szeptember 10. hétfő, 6:00

HozzászólásSzerző: Physix66 » 2012. szeptember 11. kedd, 13:14

Üdv!

Ez volt az eredeti példában:

void loop() {
// 0-tol 255ig vegigszamolas es a LEDeken
meglatszik
// kisebb egyenlő:
numberToDisplay 256
for (int numberToDisplay
= 0; numberToDisplay = 256; numberToDisplay++)
}


Javítva így már igaz lenne?

void loop() {
for (int j = 0; j < 256; j++) {
digitalWrite(CE, 0);
shiftOut(SDO, SCK, MSBFIRST, j);
digitalWrite(CE, 1);
delay(500);
}

Ha jól értettem a #36-os példában a numberToDisplay 1byte-nyi adatot jelöl. A #37-esben ez már j-vel van jelölve.

Robert:
Igen. De a fordító: Wiring!
Arduino nem támogatja, csak a mega8/mega168/mega328/mega1280/mega2560 chipeket...

Ezt a sort nem értem:
numberToDisplay 256


Szerintem csak a kommentből/megjegyzésből maradt a kódban.

Csoki:
Én is látok egy gondot:

for (int numberToDisplay = 0; numberToDisplay = 256; numberToDisplay++)

Szerintem ez a ciklus nem fog lefutni.


A megoldás itt a numberToDisplay < 256 lenne? Vagy mi a gond vele?

Physix66

Avatar
Csoki
DrótVégénSzéndarab
Hozzászólások: 44
Csatlakozott: 2012. június 25. hétfő, 6:00
Tartózkodási hely: Pécs

HozzászólásSzerző: Csoki » 2012. szeptember 11. kedd, 13:28

a for ciklus fejléce 3 részből áll:

for (int x=0; x<10; x++ )
{
utasítások;
}

első rész: int x=0 ->ez a változó deklarálás és inicializálás (kezdeti érték adás)
a 2. rész a tesztelés: ha igaz, akkor akkor a ciklus magja (utasítások) végrehajtódik, pontosabban amíg a tesztelés igaz értéket ad vissza, addig végrehajtódik a ciklus, amikor hamissá válik, akkor akkor kilép a for ciklusból.
3.rész: a változó értékének változtatása. jelen esetben növelése 1 el.

Sajna az aktuális feladatot nem volt alkalmam még kipróbálni, mert nincs még shift regiszterem, emiatt nem tudom megmondani mit is kellene beleírnod.

Avatar
Robert
Elektronbűvölő
Hozzászólások: 9973
Csatlakozott: 2005. december 9. péntek, 7:00
Tartózkodási hely: Budapest
Kapcsolat:

HozzászólásSzerző: Robert » 2012. szeptember 11. kedd, 14:02

A ciklusban a magot int-ként (integer, 0...65535) definiáltad. A ciklus kifejtése

Kód: Egész kijelölése

for (int numberToDisplay = 0; numberToDisplay = 256; NumberToDisplay++)


numberToDisplay a belső számláló, amit integerként definiálsz (0...65535 tartomány), és a kezdeti értéke 0.
a ciklus akkor érjen véget, ha a numberToDisplay = 256
a ciklusban a léptetés a numberToDisplay egyesével lépkedjen.

Avatar
Physix66
Újonc
Újonc
Hozzászólások: 3
Csatlakozott: 2012. szeptember 10. hétfő, 6:00

HozzászólásSzerző: Physix66 » 2012. szeptember 11. kedd, 15:44

Tehát ez a hiba?

void loop() {
for (int j = 0; j < 256; j++) {
digitalWrite(CE, 0);
shiftOut(SDO, SCK, MSBFIRST, j);
digitalWrite(CE, 1);
delay(500);
}

j nem < mint 256 hanem =

Ha jól fogtam fel azért, mert ha j < 256 az mindig igaz lenne (j =0-val kezdünk ami < mint 256 :) ), így nem lenne értelme a j-hez való hozzáadás tehát a loop előröl kezdi (a semmit).

Azt jó értettem meg, hogy a numberToDisplay ill. a módosításomban a j, mind2 belső számlálók? csak másképp vannak elnevezve (kinek ami tetszik alapon).

Avatar
macsek
Bitmanipulátor
Hozzászólások: 121
Csatlakozott: 2008. december 4. csütörtök, 7:00
Tartózkodási hely: Bp

HozzászólásSzerző: macsek » 2012. szeptember 11. kedd, 21:43

Physix66 írta:Tehát ez a hiba?

void loop() {
for (int j = 0; j < 256; j++) {
digitalWrite(CE, 0);
shiftOut(SDO, SCK, MSBFIRST, j);
digitalWrite(CE, 1);
delay(500);
}

j nem < mint 256 hanem =

Ha jól fogtam fel azért, mert ha j < 256 az mindig igaz lenne (j =0-val kezdünk ami < mint 256 :) ), így nem lenne értelme a j-hez való hozzáadás tehát a loop előröl kezdi (a semmit).

Azt jó értettem meg, hogy a numberToDisplay ill. a módosításomban a j, mind2 belső számlálók? csak másképp vannak elnevezve (kinek ami tetszik alapon).


Igen, az a hiba, de a j < 256; a jó változat.
Tehát addig fut a ciklus, amíg IGAZ a feltétel.

Avatar
normen
DrótVégénSzéndarab
Hozzászólások: 26
Csatlakozott: 2012. május 27. vasárnap, 6:00

HozzászólásSzerző: normen » 2012. szeptember 12. szerda, 12:17

Physix66 írta:
Ha jól fogtam fel azért, mert ha j < 256 az mindig igaz lenne (j =0-val kezdünk ami < mint 256 :) ), így nem lenne értelme a j-hez való hozzáadás tehát a loop előröl kezdi (a semmit).


Ez így nem igaz.

Kód: Egész kijelölése

for (j=0; j<256; j++) {
  ...
}


Ez pontosan 256-szor fog lefutni, ha a ciklus belsejében a j változót nem módosítod.

Kód: Egész kijelölése

for (
  j=0; // j-nek a ciklus kezdetekor 0 lesz az értéke. Ennek csak az első teszteléskor van jelentősége
  j<256; // a ciklus addig fut, amíg a feltétel igaz, tehát j kisebb mint 256
  j++ // ciklusmag minden végrehajtását követően növeli j értékét 1-gyel
) { .. }


Tehát a következő (2.) ciklusfeltétel teszelésekor j értéke már 1 lesz, azutáni vizsgálatkor (3.) meg 2, stb....

A FOR ciklus egy előltesztelős ciklus, ami jelen esetben így kerül végrehajtásra:

Kód: Egész kijelölése

1. j=0
2. j<256 (ha nem igaz a feltétel, akkor ugrás a 6. lépéshez)
3. ciklusmagban lévő utasítások végrehajtása
4.  j=j+1
5. visszaugrunk a 2. lépésre
6. kilépünk a ciklusból


Azt jó értettem meg, hogy a numberToDisplay ill. a módosításomban a j, mind2 belső számlálók? csak másképp vannak elnevezve (kinek ami tetszik alapon).


Nem belső számlálonak, hanem ciklus indexnek szokták őket hívni. Az index szóból erendően szokták sokszor erre a célra az [b]i[\b] változót használni. (persze a kód egyszerűsítése vagy értelmezése szempontjából használnak egyéb változóneveket is ciklus indexnek).
A ciklus indexek is mezei változók, melynek értékeit mind a ciklusmagon belül, mind bárhol máshol (az érvényességi területén belül) fel tusz használni.


Üdv.
NorMen

Szerkesztve: macsek által észlelt hibákat javítottam
A hozzászólást 2 alkalommal szerkesztették, utoljára normen 2012. szeptember 12. szerda, 14:04-kor.

Avatar
macsek
Bitmanipulátor
Hozzászólások: 121
Csatlakozott: 2008. december 4. csütörtök, 7:00
Tartózkodási hely: Bp

HozzászólásSzerző: macsek » 2012. szeptember 12. szerda, 12:41

Bocsi, majdnem jó amit írtál, de pontosítok:

normen írta:

Kód: Egész kijelölése

for (
  j=0; // j-nek a ciklus kezdetekor 0 lesz az értéke. Ennek csak az első teszteléskor van jelentősége
  j<256; // a ciklus addig fut, amíg a feltétel igaz, tehát j kisebb mint 256
  j++ // A CIKLUSMAG MINDEN VÉGREHAJTÁSÁT követően növeli j értékét 1-gyel
) { .. }


Tehát a következő (2.) ciklusfeltétel teszelésekor j értéke már 1 lesz, azutáni vizsgálatkor (3.) meg 2, stb....

A FOR ciklus egy előltesztelős ciklus, ami jelen esetben így kerül végrehajtásra:


1. j=0
2. j<256 (ha nem igaz a feltétel, akkor ugrás az 6. lépéshez)
3. ciklusmagban lévő utasítások végrehajtása
4. j=j+1

5. visszaugrunk a 2. lépésre
6. kilépünk a ciklusból

Avatar
normen
DrótVégénSzéndarab
Hozzászólások: 26
Csatlakozott: 2012. május 27. vasárnap, 6:00

HozzászólásSzerző: normen » 2012. szeptember 12. szerda, 13:56

macsek írta:Bocsi, majdnem jó amit írtál, de pontosítok:


Igaz, köszi a pontosítást


Vissza: “60 nap alatt Arduino - Házi feladatok”

Ki van itt

Jelenlévő fórumozók: nincs regisztrált felhasználó valamint 3 vendég