Programfeltöltés ATtiny85 alaplapra (…és egyéb problémák)

Tartalom:

  • ATtiny85 alaplap felépítése és fontosabb tulajdonságai
  • Programozáshoz szükséges digistump alaplapkezelő telepítése és használata
  • ATtiny85 alaplap USB port driver telepítés Windows10-re
  • Kivezetések használatával kapcsolatos problémák, tanácsok
  • Digistump programkönyvtárakkal kapcsolatos anomáliák, chip belső eeprom használat problémái

Olyan egyszerű szerkezet fejlesztésébe kezdtem, amihez elméletileg nem lenne szükség Ardunino Uno vagy nano alaplapra, mert elég néhány kivezetés, és sokkal kevesebb program memória is elég. Már régebben rendeltem egy ATtiny85 USB portos modult, itt az ideje megismerkedni ezzel is. A kis kivezetésszám miatt kicsit másként kell kezelni. Mint kiderült, a program rátöltéshez kell egy kis előkészület, ennek részleteiről készült az alábbi leírás.

Elősször néhány jellemző az alaplapról:

A képen látható, hogy kétféle kivitel létezik, nekem az USB kábellel csatlakoztatható kivitel a szimpatikusabb, mert ha az alaplapot beépítem egy dobozba, akkor sem kell azt kiépíteni, laptopról programozható a helyszínen is. Illetve USB hosszabbító nem kell hozzá, ami nem mindig van kéznél.

Fontosabb adatok:

  • ATtiny85 processzor 16,5 MHz órajellel
  • Micro USB csatlakozó
  • 8KB flash memória, 6K maradék felhasználható programterülettel
  • 6 digitális I/O, ebből összesen 3 PWM kimenet lehet illetve 4 analóg bemenet. A kivezetések egyike RESET láb, ami bemenetként másra nem használható, kimenetként pedig erősen korlátozott paraméterekkel bír (kisebb maximális áram és kisebb kimenő feszültség HIGH szintnél)
  • I2C és SPI interfész megadott I/O kivezetéseken
  • Külső megszakítási képesség
  • Maximális áram a kivezetéseken 20mA (kivéve RESET, ott 1mA)
  • RAM 512 byte, EEPROM 512 byte
  • Órajel sebesség 16,5 Mhz
  • Beépített led az 1-es kivezetéshez csatlakoztatva
  • Méret 25 x 19 mm

Az ATtiny85 chip 1,8V és 5,5V közötti feszültséggel működik. Az adatlap szerint azonban nagyobb órajel frekvenciákon (10Mhz felett) már csak 2,7-5,5V lehet a feszültség tartomány. Egy lítium gombelem, vagy lítium aksi pont jó lehet. A modul tartalmaz egy feszültségszabályzót, és egy plusz bemenetet VIN jelöléssel, ahová 7-12V feszültséget kapcsolhatunk. Olvastam az egyik leírásban, hogy a maximális feszültség akár 24V-is lehet, de ha a kimenetek nagy áramot hajtanak meg, akkor a táp IC melegedhet. Azonban a 12V is nagyon kényelmes feszültség. Még nem próbáltam ki, de mivel a modulon más aktív elem nincs, várhatóan sleep módban nagyon kicsi lesz az áramfelvétel. Sajnos az Arduino nano és Arduino UNO alaplap nem rendelkezik ezzel a kedvező tulajdonsággal, sleep módban is jelentős áramot vesznek fel, hiszen van rajtuk egy USB soros átalakító, ami folyamatosan áram alatt van, és fogyaszt. Igaz, ez csak néhány milliamper, de így évekig biztosan nem tud működni elemről, esetleg csak hetekig. A modul nagy előnye egyébként a szerelhető méret és az USB csatlakozó, amin keresztül könnyen lehet programot feltölteni. A modul csatlakozó kiosztása a következő:

Oldalsó 3 kivezetés:

  • 5V  = 3V -5,5V bemenet, vagy 5V kimenetként használható, ha VIN bemenetre 7-12V feszültséget kötünk
  • GND = Földhöz csatlakozik
  • VIN = 7V – 12V bemenő feszültség, de akár 24V is lehet.

Panel végén található kivezetések:

  • P0 = Digitális I/O 0, PWM, I2C (SDA), SPI (MOSI)
  • P1 = Digitális I/O 1, PWM, SPI (MISO)
  • P2 = Digitális I/O 2, Analóg bemenet 1, I2C (SCL), SPI (SCK)
  • P3 = Digitális I/O 3, Analóg bemenet 3, USB
  • P4 = Digitális I / O 4, Analóg bemenet 2, USB / PWM
  • P5 = Digitális I/O 5, Analóg bemenet 0, Reset bemenet (aktív LOW)

A modul a P3 és P4 kivezetéseket használja az USB kommunikációhoz. A P3 kivezetés 1,5K felhúzó ellenállással rendelkezik, ha programozást követően használjuk ezt a kivezetést valami másnak is, akkor ezt figyelembe kell venni. Itt az áramkörben 3,6V-os zener védődiódák is vannak, amik többféle meglepetést is okozhatnak. Programozás ideje alatt az egyéb külső áramkörök zavart is okozhatnak, erre is figyelni kell, tehát a kivezetések esetleg legyenek leválaszthatók a program csere idejére, vagy le kell forrasztani azokat.

A modul kapcsolási rajza:

Mivel az áramkörre nem szereltek USB interface áramkört, mint az Arduino UNO vagy nano alaplapokra, a bootloader is másként működik. Ennek részleteiről nem sokt tudok, bevallom nem érdekelt nagyon. Annyit hámoztam ki a leírásokból, hogy a modul tápfeszre kapcsolása után 5 másodpercig várja, hogy legyen az USB porton valami kapcsolat. Gondolom órajelet figyel, és ha van valami, akkor elvégzi a programozást. Tehát nem elég a RESET, mint az UNO vagy nano esetén. Ezért aztán nem lehet pusztán szoftverből programozni, ahogyan azt megszoktuk. Ki kell húzni a PC USB csatlakozójából a modult, lekapcsolni az esetleges külső tápfeszt, és a megfelelő pillanatban be kell majd dugni a PC USB csatlakozójába. A megfelelő pillanatot az Arduino IDE szoftver fogja előállítani, mert feltöltéskor (program lefordítása után) 60 másodpercet vár arra, hogy az USB porton megjelenjen az ATtiny85, és kommunikáljon. Nem igazán kényelmetlen, csak más, mint ahogy megszoktunk. Ehhez a folyamathoz kell néhány új dolog. Első lépésként le kell tölteni az Arduino IDE számára az új alaplap illesztő szoftvereket. Ehhez menjünk be a file / beállítások menüpontba, és nyomjuk meg a „További alaplap-kezelő URL-ek” mögötti kis ikont:

A megjelenő ablakban egy új sorba ezt kell beírni:  http://digistump.com/package_digistump_index.json

Nálam már volt egy sor, mert az ATmega8 programozása miatt használtam a MiniCore alaplapkezelőt is, ezért hozzáadni akartam egy sort. Ha nincs még itt semmi megadva, akkor elég a beállítások ablakban simán beírni.

Ezt követően indítsuk el az Eszközök menüben az alaplapkezelőt:

Az alaplap kezelőben kezdjük el keresni a „digistump” szótöredéket, és meg is találjuk:

Bocsi, de a képet utólag csináltam, ezért nekem már azt jelzi, hogy telepítve van. Ha neked még nincs, akkor telepítsd!

Azt hiszem újra kell indítani az Arduino IDE-t és majdnem készen is vagyunk! Ha megnézzük a rendelkezésre álló alaplapokat, megjelent ami nekünk kelleni fog:

Már csak annyi kell, hogy az USB portunk is felismerje, hogy mit dugtak rá. Windows 10 alatt ehhez kell a driver. Itt lehet letölteni: http://github.com/digistump/DigistumpArduino/releases

A letöltött ZIP állományt ki kell bontani, és a benne található DPinst64.exe programot kell elindítani (32 bites Windows esetén a DPinst.exe-t):

Elindul a telepítő és boldogan nyomkodhatjuk a next, akarom, igen, nem stb. gombokat!

Ha minden készen van, még vessünk egy pillantást az eszközkezelőre, és persze közben dugjuk be a az USB-be az alaplapunkat:

FIGYELEM! Ha a modul P3 vagy P4 kivezetését beforrasztod egy külső áramkörbe, rákötsz valamit pl. LED-et stb. akkor előfordulhat, hogy a számítógép nem fogja felismerni az eszközt, amikor bedugod az USB portba a programfeltöltéshez. Tehát visszafelé is igaz a probléma, nem csak az USB port zavarhatja meg a modul működését, a modulra kötött kiegészítők is megzavarhatják az USB portot. Programozáskor azt a két kivezetést lehetőleg ne csatlakoztasd sehová!

Ha telepítettük a drivert és szeretnénk kipróbálni a működést, és miért ne szeretnénk, akkor gyorsan töltsünk rá valamilyen programot. Vegyük elő pl. a kedvenc blink programot a példák közül. Kicsit át kell alakítani, mert nem fogja a LED_BUILTIN constanst felismerni ez az alaplap, helyette a kimenet számát át kell átírni 1-re. Ugyanis az 1-es kivezetésen van a LED!

void setup() {
  pinMode(1, OUTPUT);
}

void loop() {
  digitalWrite(1, HIGH);   
  delay(1000);                      
  digitalWrite(1, LOW);    
  delay(1000);                    
}

Feltöltés előtt még ellenőrizzük, hogy jól állítottuk-e be az alaplap típusát:

Máris láthatjuk, hogy nem lehet Port-ot beállítani (szürke a menüpont), mert nem com porton keresztül fog menni a kommunikáció, és egyébként ebben a pillanatban még nincs is a com portra dugva az alaplap! Vagy ha mégis, akkor most húzzuk ki!

Indítsuk el a feltöltést. A szokásos módon lefordul a program, de egy kicsit más üzenet jelenik meg alul:

Látható a képen, hogy most arra vár az Arduino IDE, hogy 60 másodpercen belül bedugjuk a modult. Ha ez megtörténik, máris mennek az adatok:

.. és ha most ránézünk az alaplapunkra, akkor azt látjuk, hogy örömünket villogással jelzi!!

Amikor elkezdtem dolgozni ezzel az alaplappal, úgy gondoltam, hogy a rákapcsolt áramkörök csak speciális esetben okozhatnak problémát. Pl. ha az egyik bemenetre egy nyomógombot kötök felhúzó ellenállással, akkor az nem fog problémát okozni. Sajnos ez nem így van! A 4. kivezetést bemenetnek szerettem volna használni és rákötöttem egy nyomógombot felhúzó ellenállással. Amikor rá akartam tölteni a programot, az USB portot a PC nem ismerte fel bedugáskor! Pl. a 3. lábra szintén egy nyomógombot kötöttem, ettől lehetett programozni, viszont amikor működött a program, és az USB-ről kapta a tápfeszt, a nyomógomb megnyomásakor úgy érezte a bemenet, hogy 2-3 másodpercig többször is megnyomtam a nyomógombot.
A tuti módszer az lett, hogy működés közben a tápot egy Arduino UNO-tól loptam el, amit a laptopom másik USB portjába dugtam. Programozáskor ezt ki kellett húzni, és a megfelelő pillanatban bedugni az USB portba az ATtiny85 alaplap-ot! Feltölteni a programot, majd kihúzni onnan ha végeztem és visszadugni az UNO USB kábelét, hogy legyen táp a működéshez. Kicsit kényelmetlen! A fejlesztést érdemes az UNO-val végig csinálni, és amikor kész a végleges algoritmus, akkor rátölteni az ATtiny85-re. Ehhez persze lehetséges, hogy kellenek átalakítások a programban a feltöltés előtt, pl. könyvtárakat kell váltani az LCD kezeléséhez stb.

Néhány megszerzett tapasztalat:

  • A P0 kivezetés foglalt az I2C-nek, ha valamilyen kijelzőt használunk, így az másra nem használható
  • A P1 kivezetésre LED-et kötöttek, így ha azt bemenetként akarjuk használni, érdemes a LED-et levágni a nyáklemezről. Vagy legyen ez biztosan kimenet, annak tuti jó!
  • A P2 kivezetés szintén kell az I2C-hez, tehát kiesik, ha van kijelző!
  • A P3 kivezetés tapasztalatom szerint mindenre jó, simán rá lehet kötni egy rövidzárat adó nyomógombot a bekapcsolt felhúzó ellenállással és jól működik.
  • A P4 kivezetésen az USB port miatt üresen hagyva bemenetként alacsony szintet érzékel. Tehát a klasszikus földre húzó ellenállás itt nem működik. Ha nyomógombot akarunk bekötni, akkor a nyomógomb direktben felhúzhatja a 5V-ra. Persze a program működését is meg kell fordítani, nem az alacsony szint lesz az aktív. 22mA áramot mértem a 5V felé, mivel a 3,5V-os zeneren és a 68ohm-os ellenálláson pont ennyinek kell átfolynia.
  • P5 kivezetés az bemenetként szintén nem használható, mert akkor az reset funkciót lát el, és alacsony szinttel újraindul a vezérlő.

LCD kijelző használata

Szeretnék egy I2C 2×16 karakteres LCD kijelzőt, és egy OLED kijelzőt használni a modullal. Már a karakteres kijelzőhöz is valamilyen módosított könyvtárat kell keresni, mert annak a mérete is nagy. Az OLED könyvtár pedig kapásból 15 kbyte, ennél már fel sem merül, hogy az UNO-n fejlesztett programot egy az egyben áttegyem az ATtiny85-re. Ezeknek az egyszerű eszközöknek az illesztéséhez nem kell túl sokat keresgélni, mert az alaplapkezelővel egy csomó optimálisabban megírt, vagy szerényebb képességű, de kisebb méretű programot is csatoltak. Én ezt az alaplapkezelő letöltéskor még nem tudtam, a neten keresgéltem, és újabb és újabb könyvtárakat töltöttem le magamnak. Fordításkor pedig a fordító hibaüzeneteket küldött arról, hogy egyes függvények duplán vannak meg. Amikor elkezdtem a hibaüzenetekkel foglalkozni, megértettem, hogy az alaplap kezelő egy speciális, „eldugott” helyre rakja a telepített cuccokat. Beidézem azt a képet, amit az LCD kijelző egyik programjának fordításakor kaptam:

Ha alaposan elolvassuk, akkor láthatjuk, hogy az én gépemen a „C:\Users\Zoli\Appdata\Local\Arduino15…” (nem írom ki végig) alkönyvtárban kell keresgélni. Hogy miért pont Arduino15 lett a könyvtárnak a neve azt nem tudom, de ebben vannak az alaplapkezelő által letöltött cuccok. Bele is néztem a képen látható alkönyvtárba, és mit látok:

Van itt minden! Érdemes kinyitogatni a fenti képen látható könyvtárakat, és megnézni a tartalmukat. A használható program kódok a .cpp és .h kiterjesztésű állományokban vannak, ezekből akár a működés is megfejthető. De ugyanitt további alkönyvtárakban példa programok is vannak. Természetesen ezeket a példa programokat megtaláljuk az Arduino IDE-ben is:

Sajnos nem vettem észre azonnal, hiszen a példa programok jegyzéke immár nagyon hosszú, sokat kell görgetni lefelé, fene se gondolta, hogy ott is megvan minden. Újra bebizonyosodott, hogy a figyelmes, körültekintő munkával időt lehet megtakarítani!

Rögtön az első valós programomnál újabb probléma akadt! Az ATtiny85 belső EEPROM-ját szerettem volna használni. Ekkor ugyebár a program így kezdődik:
#include <EEPROM.h>
Természetesen már ezen a soron elhasalt a fordító! Keresgetni kezdtem, hogy mi lehet a baj. Nem kellett hozzá túl sok gondolkodás, hogy esetleg azt a file-t nem találja a fordító. És valóban, a fentebb emlegetett „C:\Users\Zoli\Appdata\Local\Arduino15\packages\gigistump\…” könyvtár alatt nem volt meg. Ugyanitt viszont a „…packages\Arduino..” könyvtárban megtaláltam. Az „Arduino” alkönyvtár alatt vannak az Arduino UNO, nano stb alaplapok hardverspecifikus állományai, és ott persze megtaláltam. Feltételeztem, hogy egy ATmega328 belső EEPROM kezelésben azonos az ATtiny85-el, és ezt az állományt bemásoltam a forráskódommal egy könyvtárba, és máris sikerült a fordítás. Sőt, még a program is működött! Ha a forráskóddal egy könyvtárban több forrás is található, akkor az Arduino IDE több fülecskét nyit, ez ebben az esetben is megtörtént:

Belső eeprom és TinyWireM.h együttes használata

Elérkezett az a pillanat, amikor használtam a belső eeprom-ot, és I2C buszon keresztül szerettem volna adatokat írni egy LCD karakteres kijelzőre. Az eeprom használatát már megoldottam azzal, hogy bemásoltam a programom ino forrása mellé az EEPROM.h állományt. Ekkor a fordító megtalálta az eeprom kezelő függvényeket és lefordult, működött is. Azonban amikor a programban mellé raktam a digistump alaplapkezelő könyvtárral kapott LCD kezelő függvényeket, már nem fordult le a program. Ha viszont csak az LCD-t kezelő függvényeket tettem be a programba, akkor önmagában az is működött, de a kettő együtt nem. Kutatni kezdtem a net-en, és találtam is egy orosz oldalt, ahol erről a problémáról írtak: https://elquanta.ru/novoe/attiny85.html

A cikk végén van pár szó a problémáról. Az ott leírt javítási módszert lényegében értettem, de semmi nem stimmelt a leírt könyvtár nevekből, és végül kísérletezgetéssel fejtettem meg, hogy mit is kell tenni. A dolog végül is nagyon egyszerű. A digistump alaplap kezelővel adott program könyvtárak között nem szerepel semmi, ami a belső eeprom-ot kezelné. Feltehetőleg azért, mert ez ugyanaz, mint egy klasszikus ATmega328 esetén lenne. Ezért is segített, hogy bemásoltam az EEPROM.h állományt a program mellé. A cikk alapján véglegesebb megoldás is van, egész egyszerűen az egész EEPROM könyvtárat kell bemásolni az Arduino könyvtárból a digistump könyvtárba. Amit másolni kell, az Windows 10 esetén a következő könyvtárban található: C:\Users\Zoli\AppData\Local\Arduino15\packages\arduino\hardware\avr\1.8.3\libraries
Ez persze csak ez én gépemen igaz, mert nálam egy „Zoli” nevű felhasználó alatt fejlesztek, és oda telepítette az alaplapkezelő állományokat az Arduino IDE. Ezen a könyvtáron belül pont van egy „EEPROM” nevű alkönyvtár (…és más könyvtárak is):

Ezt az EEPROM nevű könyvtárat egy az egyben átmásoltam ide:
C:\Users\Zoli\AppData\Local\Arduino15\packages\digistump\hardware\avr\1.6.7\libraries
Képpel is mutatom:

Itt már látszik a bemásoltkönyvtár is. Ezzel az EEPROM kérdést meg is oldottuk. Már nem kell bemásolni az EEPROM.h állományt a forrás mellé.

Jöhet a következő probléma, a TinyWireM.h ismert hibája. Nem nagy dologról van szó, meg kell keresni a a fenti képen látható TinyWireM könyvtárat (kékkel karikáztam be), és azon belül a TinyWireM.cpp forrást. Ezt megnyitni pl. egy notepad programmal, és kijavítani benne egy sort. Az érintett sor az 53. a cikk szerint. Nem számoltam meg, hogy tényleg ott volt-e, de tartlama alapján gyorsan megtaláltam. Itt a teljes forrás környezet, miután megcsináltam a javítást. Benne hagytam kikommentezve a régi tartalmat is, hátha valaki érti, hogy mi is történt:

size_t USI_TWI::write(uint8_t data){                  // buffers up data to send
  if (USI_BufIdx >= USI_BUF_SIZE - 1) return 0;       // dont blow out the buffer Ez egy javítás, egy ismert hiba miatt
     //if (USI_BufIdx >= USI_BUF_SIZE) return 0;      // dont blow out the buffer, ez az eredeti programsor
  USI_BufIdx++;                                       // inc for next byte in buffer
  USI_Buf[USI_BufIdx] = data;
  return 1;
}

A file elmentése után a programunk szépen hibák nélkül lefordul!

Mennyire volt hasznos amit olvastál? Értékelés után szövegesen is leírhatod megjegyzéseidet és véleményedet!

Kattints egy csillagra az értékeléshez!

Szövegesen is leírhatod véleményedet! Ha kérdésed van, ne felejtsd el megadni az email címedet!