
Totul a început cu achiziția de către autor, pe piața secundară, a unui dispozitiv interesant — Smart Response XE (). Acesta este destinat școlilor: fiecare elev din clasă primește un dispozitiv asemănător cu un caiet electronic sau un traducător din anii '90, profesorul pune o întrebare, iar elevii tastează răspunsurile pe tastaturile dispozitivelor, care sunt transmise prin canal radio (802.15.4) către un receptor conectat la PC-ul profesorului.
Suportul pentru aceste dispozitive a fost oprit cu câțiva ani în urmă, iar ceea ce școlile achiziționau cu 100-200 de dolari bucata, acum apare pe eBay cu 10 dolari sau chiar mai puțin. „Hardware”-ul este extrem de potrivit pentru experimente geek:
- o tastatură cu 60 de taste
- un display cu o rezoluție de 384×136, 2 biți pe pixel — similar cu BK, CGA, dar 4 nu culori, ci nuanțe de luminozitate
- un microcontroler ATmega128RFA1 (128 kB memorie flash, 4 kB EEPROM, 16 kB SRAM, transceiver standard 802.15.4)
- memorie flash externă (în raport cu microcontrolerul, nu cu întregul dispozitiv) de 1 megabit (128 kilobytes) cu interfață SPI
- un compartiment pentru 4 elemente AAA.
Din denumirea microcontrolerului, este clar că aparține familiei AVR, așadar, a face dispozitivul compatibil cu Arduino este o sarcină mai mult decât trivială...
Din știrea de pe autorul a aflat că aceasta (la același link este explicat unde să se conecteze), având posibilitatea de a rula jocuri pentru Arduboy:

Dar autorul este mai interesat de posibilitatea de a studia dispozitivul, nu de a juca:
- memorie flash cu interfață secvențială SPI
- bootloadere pentru AVR
- standardul 802.15.4
Autorul a început să scrie (GPL v3), care permite inițializarea display-ului, afișarea textului și a dreptunghiurilor, precum și accesul la memoria flash cu interfață SPI. Apoi, a început să conceapă idei de utilizare practică a dispozitivului: un terminal portabil compatibil cu VT-100, jocuri multiplayer. După ce a modificat trei dispozitive, a decis să le „învățe” să primească sketch-uri „aerian”. Ce ar fi nu doar interesant, ci și foarte convenabil: deschiderea carcasa dispozitivului este dificilă de fiecare dată, iar sub capacul compartimentului pentru baterii se află doar orificii care permit conectarea unui programator JTAG la placă.

Este suficient pentru a încărca bootloaderul Arduino, dar nu și sketch-ul — portul serial nu este accesibil, fără a deschide carcasa nu se poate. De asemenea, liniile TX0 și RX0 ale primului port serial sunt combinate cu liniile de interogare ale matricei de tastatură, și anume — cele prin care sunt interogate tastele funcționale de pe laturile ecranului. Dar ce să facem — autorul a construit următoarea soluție:

Acolo a scos liniile JTAG, și acum nu mai este necesar să deschidem compartimentul bateriei. Iar pentru a putea încărca și sketch-uri, a scos pe acest conector și cele două porturi seriale, adăugând și un comutator, deoarece cu bateriile instalate, dispozitivul nu poate fi stins fizic în alt mod.
A fost nevoie să lucrez destul de mult cu un pistol de lipit, un cuțit de birou și un pistol de lipit. În general, a încărca sketch-uri „pe aer” este mult mai convenabil, trebuie urgent să inventez ceva pentru asta.
Arduino IDE folosește programul . Acesta interacționează cu microcontrolerul prin protocolul , care permite transferul de fișiere în ambele direcții. Este slab compatibil cu canalele unde pot apărea întârzieri variabile, distorsionare și pierdere de date. Dacă în canalul serial ceva nu funcționează sau se aude zgomote, poți să înnebunești căutând cauza. Odată, autorul a suferit jumătate de zi până când a înțeles că totul se datora unui cablu defect, precum și unui convertor de interfață CP2102 capricios. Chiar și un microcontroler cu convertor de interfață incorporat, de exemplu, ATmega32u4, poate uneori să se comporte ciudat. Fiecare utilizator Arduino a observat că erorile la încărcarea sketch-urilor nu sunt atât de rare. Uneori, înregistrarea decurge normal, iar la citirea de verificare apare o eroare. Asta nu înseamnă că a fost o eroare la înregistrare — a fost o defecțiune la citire. Și acum imaginați-vă că, lucrând „pe aer”, se va întâmpla același lucru, dar mult mai des.
După ce am încercat diferite metode de a depăși această problemă, autorul a găsit următoarea soluție. Dispozitivul are o memorie flash de 128 kilobyte cu interfață SPI — primim datele pe fire (să ne amintim că autorul are deja un dispozitiv cu un conector pe lateral), folosim această memorie ca buffer, și trimitem datele prin canal radio către un alt dispozitiv. Un salut de la Cybiko.
După scrierea codului pentru a lucra cu canalul radio, precum și a fontului, încărcătorul a devenit mai lung de 4 kilobiți. Prin urmare, valoarea HFUSE a trebuit schimbată de la 0xDA la 0xD8. Acum, încărcătorul poate avea o lungime de până la 8 kilobiți, iar adresa de început a devenit 0x1E000. Acest lucru este reflectat în Makefile, dar trebuie avut în vedere și la încărcare. folosind avrdude.
Transceptorul standard 802.15.4 în ATmega128RFA1 a fost inițial conceput pentru a funcționa pe protocolul , care este destul de complex, așa că autorul a decis să transmită pur și simplu pachete. Acest lucru este implementat hardware în ATmega128RFA1, așa că va fi nevoie de puțin cod. De asemenea, pentru a simplifica, autorul a decis să folosească un canal fix, fără a permite chiar și alegerea manuală. Standardul 802.15.4 suportă 16 canale numite de la 11 la 26. Acestea sunt destul de aglomerate, unele suprapunându-se cu canalele WiFi (canalele ZigBee sunt marcate cu roșu, iar cele WiFi cu albastru, verde și galben).

S-a dovedit că cele mai puțin afectate de interferențele WiFi sunt canalele 15 și 26. Autorul a ales canalul 26. Disclaimer: traducătorul nu știe dacă este permis să simplifice astfel ZigBee. Poate că ar trebui să programeze puțin mai mult și să-l implementeze complet?
Pe primul dintre dispozitive trebuie implementat un automat finit care transmite date prin protocolul STK500. În mare parte, mesajele trimise și primite sunt autoconținute, dar unele sunt legate de cele care au trecut anterior prin canal. Descrierea dialogului este oferită. .
O componentă importantă a acestui dialog este transmiterea pachetelor destinate scrierii în memoria flash a dispozitivului de destinație. La microcontrolerele simple din familia AVR, dimensiunea paginii este de 128 de biți, dar la ATmega128RFA1 este de 256. Iar pentru acea memorie flash care se conectează prin protocolul SPI, este aceeași. Programul din primul dispozitiv, atunci când încarcă un sketch, nu îl trimite imediat la al doilea, ci îl scrie în această memorie. Atunci când Arduino IDE verifică corectitudinea scrierii, i se trimite ceea ce a fost scris acolo. Acum, trebuie să transmitem datele obținute prin canalul radio către al doilea dispozitiv. În acest proces, comutarea de la recepție la transmisie și invers se întâmplă destul de des. Protocolul STK500 este indiferent la întârzieri, dar nu suportă pierderi de date (ciudat, având în vedere că mai sus s-a spus că întârzierile în transmiterea datelor au efecte). Și pierderile în transmiterea wireless sunt inevitabile. În ATmega128RFA1 există o implementare hardware a solicitărilor de retransmitere în caz de îndoieli asupra corectitudinii transmiterii, dar autorul a decis să implementeze același lucru programatic. El a dezvoltat un protocol prin care, într-o direcție, trec mult mai multe date decât în cealaltă.
Nu este ideal, dar totul funcționează. Pagina de 256 de biți este împărțită în patru segmente, fiecare dintre ele fiind transmis prin canalul radio sub formă de pachet. Pachetul poate conține până la 125 de biți de date plus un biit - lungimea și două - CRC. Astfel, fragmentele cu lungimea de 64 de biți, împreună cu numerele paginilor și segmentelor (de la 0 la 3), sunt incluse acolo. În dispozitivul receptor este prevăzută o variabilă care permite urmărirea câtor segmente au fost primite, iar când vin toate cele patru, dispozitivul de transmitere primește o confirmare că întreaga pagină a fost primită. Fără confirmare (dacă CRC nu coincide) - trimitem întreaga pagină din nou. Viteza obținută este chiar mai mare decât în cazul transmiterii prin cablu. Vedeți:

Dar, în general, ar fi bine să se prevadă o modalitate convenabilă de conectare a dispozitivelor cu un cablu pentru încărcarea sketch-urilor și prin acesta. De exemplu, să se plaseze în interior un astfel de convertor de interfețe pe CP2102, ca în fotografie, și să fie lipit pe placă astfel încât să suporte forța de conectare și deconectare a cablului Micro USB.

De asemenea, acesta dispune de un stabilizator de 3,3 volți (și cum să-l aplici într-un dispozitiv cu alimentare de 6 volți – doar dacă există un stabilizator similar, și se pot adăuga două diode pentru a alege automat de la care să primească alimentarea dispozitivul). De pe placa converterului de interfață trebuie să se scoată cele trei LED-uri, altfel acestea vor încărca suplimentar bateriile când se lucrează cu ele, și vor împiedica interogarea tastaturii și funcționarea memoriei flash cu interfața SPI.
Urmărirea scopului s-a dovedit a fi chiar mai interesantă decât atingerea acestuia (și nu trebuie să spunem anecdota aceea despre autobuz). Autorul a învățat multe lucruri noi despre bootloade-urile pentru AVR, memoria flash cu interfața SPI, protocolul STK500 și standardul 802.15.4.
Toată restul codului în plus față de biblioteca descrisă mai sus – , și acesta este de asemenea sub GPL v3. Twitter-ul autorului – .
Sursa: habr.com
