Taula de continguts:

Arduino personalitzat per mantenir botons del volant CAN amb un equip de música nou: 9 passos (amb imatges)
Arduino personalitzat per mantenir botons del volant CAN amb un equip de música nou: 9 passos (amb imatges)

Vídeo: Arduino personalitzat per mantenir botons del volant CAN amb un equip de música nou: 9 passos (amb imatges)

Vídeo: Arduino personalitzat per mantenir botons del volant CAN amb un equip de música nou: 9 passos (amb imatges)
Vídeo: CS50 2015 - Week 7 2024, Desembre
Anonim
Arduino personalitzat per mantenir botons del volant CAN amb un estèreo de cotxe nou
Arduino personalitzat per mantenir botons del volant CAN amb un estèreo de cotxe nou
Arduino personalitzat per mantenir botons del volant CAN amb un estèreo de cotxe nou
Arduino personalitzat per mantenir botons del volant CAN amb un estèreo de cotxe nou
Arduino personalitzat per mantenir botons del volant CAN amb un estèreo de cotxe nou
Arduino personalitzat per mantenir botons del volant CAN amb un estèreo de cotxe nou

Vaig decidir substituir l'estèreo del cotxe original del meu Volvo V70 -02 per un equip estèreo nou, de manera que podré gaudir de mp3, bluetooth i mans lliures.

El meu cotxe té alguns comandaments del volant per a l’equip estèreo que m’agradaria poder utilitzar encara. No esperava que això fos un problema perquè hi ha diversos adaptadors al mercat que se suposa que són compatibles amb el meu cotxe. Tot i així aviat vaig saber que no ho eren. (Sembla que els adaptadors del V70 poden tenir problemes amb els cotxes -02 a causa d'un protocol CAN lleugerament diferent).

Què fer llavors? Voleu conservar el vell equip de música? Voleu viure amb botons que no funcionen? És clar que no! Si no hi ha cap adaptador de treball al mercat, haurem de fabricar-ne un.

Aquesta instrucció es pot aplicar (amb algunes adaptacions) als cotxes on els botons del volant es comuniquen a través del bus CAN.

Pas 1: esbrineu com enviar ordres a l'estèreo

Esbrineu com enviar comandes a l'estèreo
Esbrineu com enviar comandes a l'estèreo
Esbrineu com enviar comandes a l'estèreo
Esbrineu com enviar comandes a l'estèreo

El primer que heu de fer és esbrinar quin tipus d’entrada remota espera l’estèreo. Normalment, els fabricants no us ho diran i probablement tampoc no teniu accés a controls remots de treball per a enginyeria inversa.

El comandament a distància del meu nou equip estèreo (Kenwood) consta d’un sol cable i no he pogut conèixer cap informació sobre el seu funcionament. Tanmateix, també té una presa de 3,5 mm per a entrada remota. Tampoc vaig saber res d’això. Però hi ha informació sobre un jack de 3,5 mm per a altres marques que suggereix que s’identifiquen diferents ordres aplicant una resistència específica entre punta i màniga (i opcionalment entre anell i màniga). Per exemple. https://forum.arduino.cc/index.php?topic=230068.0. Així que vaig decidir provar-ho, equipat amb una placa de control, un munt de resistències i un endoll de 3,5 mm endollat a l'estèreo i connectat a la placa de control. Al principi no es va reconèixer res, però l’estèreo té un menú “mode d’aprenentatge” i allà es podrien configurar correctament les ordres mentre s’apliquessin diverses resistències. Èxit!

Tanmateix, més endavant vaig descobrir que vaig cometre un error aquí: no totes les ordres que semblaven aprendre l'estèreo funcionarien. Per exemple. Es va trobar 30 kOhm en mode d'aprenentatge, però no va funcionar més tard i, per a algunes de les ordres que vaig configurar, la diferència de resistència va ser tan petita que més tard es va activar l'ordre incorrecta.

Per tant, us recomano que utilitzeu una placa de resolució amb resistències i botons de commutació per a totes les ordres remotes que vulgueu gestionar i proveu que totes funcionin.

Si el vostre equip de música no pot rebre l'entrada de la mateixa manera, haureu d'esbrinar com funciona per adaptar aquesta solució. Si no ho podeu entendre, teniu un problema.

Pas 2: esbrineu on connectar-vos al bus CAN

Esbrineu on connectar-vos al bus CAN
Esbrineu on connectar-vos al bus CAN

Heu d’ubicar un bon lloc per connectar-vos al bus CAN. Com que substituïu un equip estèreo antic que comunica per CAN, hauríeu de poder trobar-lo darrere de l'estèreo. El bus CAN consisteix en un parell de cables trenats (CAN-L i CAN_H). Consulteu un esquema de cablejat per assegurar-vos que el vostre cotxe.

Pas 3: Enginyeria inversa de missatges CAN

Enginyeria inversa de missatges CAN
Enginyeria inversa de missatges CAN

A menys que Google us pugui dir quins missatges CAN heu d’escoltar, haureu de connectar-vos al bus CAN i fer una enginyeria inversa. He utilitzat un Arduino Uno i un escut CAN. (Realment no necessiteu el blindatge CAN, com veureu més endavant, podeu utilitzar alguns components barats en una taula de treball).

Consulteu Google per saber quina velocitat de transmissió heu d’utilitzar quan us connecteu al cotxe. (Normalment trobareu que hi ha una xarxa CAN d'alta velocitat i una velocitat baixa. Us connecteu a la xarxa de baixa velocitat.)

També haureu de programar l'Arduino per registrar tots els missatges CAN a través de la interfície sèrie per poder desar-los en un fitxer de registre de l'ordinador. L’IDE Arduino estàndard no desarà dades en un fitxer de registre, però podeu utilitzar per exemple Masilla al seu lloc.

Abans de començar a escriure el vostre programa, heu d’instal·lar la biblioteca CAN_BUS_Shield.

Aquí teniu alguns pseudocodi per ajudar-vos a començar amb el programa:

setup ()

{init serial connection init CAN library} loop () {si es rep un missatge CAN {llegeix entrada de registre de format de missatge CAN escriu entrada de registre a sèrie}}

Consells:

Utilitzarà una instància de la classe MCP_CAN per accedir a la funcionalitat de la biblioteca CAN:

MCP_CAN m_can;

CAN inicial:

while (m_can.begin ()! = CAN_OK)

{endarreriment (1000); }

Comproveu i llegiu missatges CAN:

while (m_can.checkReceive () == CAN_MSGAVAIL)

{// Obteniu identificador CAN, longitud del missatge i dades del missatge m_can.readMsgBufID (& m_canId, & m_msgLen, m_msgBuf); // Feu alguna cosa amb les dades del missatge aquí}

Si necessiteu més ajuda, podeu trobar un enllaç al meu programa en un pas posterior. La biblioteca de protecció CAN també inclou un exemple. O comproveu la instrucció de mviljoen2 que inclou un pas similar.

Primer necessitareu un fitxer de referència per ajudar-vos a filtrar les dades. Canvieu l’encesa al mode de ràdio i registreu-ho tot durant un parell de minuts sense tocar cap botó.

A continuació, per a cadascun dels botons, comenceu a registrar, premeu el botó i atureu el registre.

Quan hàgiu acabat, heu de filtrar tot el que hi ha al registre de referència dels registres de botons per trobar els vostres candidats. Vaig descobrir que encara quedaven molts missatges, de manera que vaig fer més registres i vaig exigir que "els candidats a l'ordre A haguessin de ser tots els fitxers botó-A i cap dels fitxers de referència". Això em va deixar només algunes possibilitats per provar.

Els registres contindran molts missatges, de manera que haureu d’escriure algun programa per a això o, possiblement, utilitzar Excel. (He utilitzat un programa amb condicions codificades molt dures per a les meves necessitats, així que em temo que no puc oferir un programa que pugueu utilitzar.)

Una advertència: no podeu estar segur que un botó sempre produeixi un missatge idèntic. Alguns dels bits poden contenir comptadors incrementals, etc. (Podeu excepte que l'identificador del missatge sigui el mateix).

Si teniu un Volvo V70 -02, això és el que busqueu:

  • Identificador de missatge: 0x0400066 Byte0: 0x00, 0x40, 0x80 o 0xc0 (no m'importa)
  • Byte1: 0x00 (no m'importa)
  • Byte2: 0x00 (no m'importa)
  • Byte3: 0x00-0x07 (no m'importa)
  • Byte4: 0x1f (no m'importa)
  • Byte5: 0x40 (no m'importa)
  • Byte6: 0x40 (no m'importa)
  • Byte7: identificador de botó: 0x77 = augment de volum, 0x7b = baixada de volum, 0x7d = pista següent, 0x7e = pista anterior.

Quan creieu que heu trobat les ordres, pot ser una bona idea modificar el programa perquè només registri els missatges interessants. Mireu la finestra del registre de sèrie mentre premeu els botons per verificar que heu identificat els missatges correctes.

Pas 4: el prototip de maquinari

El prototip de maquinari
El prototip de maquinari

El vostre maquinari ha de ser capaç de:

  1. Identifiqueu les ordres rebudes al bus CAN
  2. Enviar comandes en un altre format a l'estèreo

Si teniu prou espai, podeu utilitzar un Arduino i un escut CAN per a la primera part i adjuntar algun maquinari addicional per a la segona. No obstant això, hi ha alguns inconvenients:

  • Cost de l'escut CAN
  • Mida
  • La font d’alimentació Arduino no estarà satisfeta si està connectada directament als vostres cotxes de 12V (probablement funcionarà, però probablement s’acortarà la vida útil).

Per tant, he utilitzat el següent:

  • Atmega 328, el "cervell Arduino". (Hi ha algunes variants, obtingueu la que és igual a la d'Arduino Uno. Podeu comprar-la amb o sense el carregador d'Arduino.)
  • Cristall de 16 MHz + condensadors per al senyal del rellotge.
  • Transceptor CAN MCP2551.
  • Controlador CAN MCP2515.
  • TSR1-2450, converteix 6,5-36V a 5V. (No s'utilitza al prototip perquè al programari no li importarà la font d'alimentació).
  • Commutador CD4066B que s'utilitzarà en enviar comandes a l'estèreo.
  • Un parell de resistències. (Els valors es poden trobar als esquemes Eagle en un pas posterior.)

Una bona cosa d’aquesta configuració és que és totalment compatible amb l’Arduino i la biblioteca CAN shield.

Si voleu gestionar més de quatre botons, us recomanem que utilitzeu una altra cosa que el CD4066B. El CD4066B es pot descriure com quatre commutadors en un, controlats cadascun per un dels pins Atmegas GPIO. A cada commutador hi ha una resistència connectada que es pot utilitzar per controlar la resistència utilitzada com a entrada a l'estèreo. Així, es pot utilitzar fàcilment per enviar quatre ordres diferents. Si es combinen, es poden obtenir valors de resistència addicionals. Aquí és on intervé l'error que he esmentat anteriorment. Tinc quatre botons, però tenia previst implementar-ne dos amb una pulsació llarga i curta per donar-me sis ordres diferents. Però al final vaig descobrir que no podia trobar una combinació de resistències que em donés sis combinacions de treball. Probablement seria possible connectar un senyal de sortida analògica a l'estèreo (punta de 3,5 mm). (Tingueu en compte que l'Atmega no té autèntics pins de sortida analògics, de manera que caldria disposar de maquinari addicional.)

A efectes de proves, també he creat un senzill simulador de "cotxe i estèreo" per connectar-me al meu prototip. Facilita la depuració i, tret que us agradi seure al cotxe i programar, us ho puc recomanar.

El prototip està il·lustrat per la taula de visualització inferior de la imatge. Per a la font d’alimentació, programació i registre en sèrie, s’adjunta a un Arduino Uno on s’ha retirat el xip Atmega.

La placa superior és el simulador de cotxe + estèreo que s’utilitzarà per a les proves inicials del prototip.

El simulador de prototip + està pensat per funcionar així:

  • Premeu un dels botons de commutació de la placa del simulador. (Aquests són els botons del volant.)
  • Quan el programa del simulador detecti que premeu un botó, enviarà el missatge CAN corresponent cada 70 ms sempre que es prem el botó. (Com que els registres que vaig agafar anteriorment indicaven que funciona al meu cotxe.) També enviarà molts missatges CAN "brossa" per simular altres trànsits al bus.
  • Els missatges CAN s’envien al bus CAN.
  • El prototip rep missatges CAN.
  • El MCP2515 llança tots els missatges no relacionats en funció de l'identificador de missatge.
  • Quan l'MCP2515 rep un missatge que s'hauria de gestionar, indicarà que té un missatge en cua.
  • L'Atmega llegirà el missatge i decidirà quin botó s'hauria de considerar actiu.
  • L'Atmega també farà un seguiment de quan es va rebre l'últim missatge, al cap d'un temps determinat es considerarà que el botó està alliberat. (Els missatges CAN només indiquen que un botó està baixat, no que s'hagi premut o alliberat).
  • Si un botó es considera actiu, s'activaran un o més commutadors del CD4066B.
  • El simulador (ara actua com el vostre equip estèreo) detectarà que s’aplica una resistència entre la punta i la màniga. (La punta està connectada a 3,3 V i mitjançant una resistència a un pin d'entrada analògica. Quan no hi ha cap ordre activa, aquest pin llegirà 3,3 V, quan una ordre estigui activa, el valor baixarà i identificarà l'ordre.
  • Mentre una ordre està activa, el led corresponent també s'activarà. (Hi ha sis leds perquè tenia previst utilitzar una pressió llarga / curta diferent per a dos dels meus botons.)

Per obtenir més detalls sobre el prototip de maquinari, consulteu els esquemes Eagle en un pas posterior.

Detalls addicionals sobre el maquinari de la placa del simulador:

  • Cristall de 16 MHz
  • Condensadors de 22 pF
  • Les resistències LED s’han de seleccionar segons les propietats del LED
  • Resistència connectada a A7 i 3,3 V, seleccioneu per exemple 2kOhm (no crític).
  • Els resistors connectats a MCP2551 i MCP2515 són pull-up / pull-down. Seleccioneu per exemple 10 kOhm.

(O bé podeu utilitzar el blindatge CAN per a la "part CAN" del simulador si ho preferiu.)

És important que sàpiga com es mapen els pins Atmega als pins Arduino quan dissenyeu el maquinari.

(No connecteu cap led directament al CD 4066B, només pot manejar un corrent baix. Vaig provar-ho quan vaig provar la sortida i el xip es va tornar inútil. El millor és que n'havia comprat un parell només perquè són tan barats.)

Pas 5: programació de fusibles

Potser heu notat al pas anterior que el prototip no té components separats per generar el senyal de rellotge al MCP2515. Això es deu al fet que ja hi ha un cristall de 16 MHz utilitzat com a senyal de rellotge Atmega que podem utilitzar. Però no podem connectar-lo directament a l'MCP2515 i, per defecte, no hi ha cap senyal de sortida de rellotge a l'Atmega.

(Si ho preferiu, podeu ometre aquest pas i afegir el maquinari de rellotge addicional.)

No obstant això, podem utilitzar una cosa anomenada "programació de fusibles" per habilitar un senyal de sortida de rellotge en un dels pins GPIO.

Primer haureu de localitzar un fitxer anomenat "boards.txt" utilitzat pel vostre IDE Arduino. Haureu de copiar l'entrada d'Arduino Uno, donar-li un nom nou i canviar el valor de low_fuses.

El meu nou tauler té aquest aspecte:

####################################################### ############# Basat en Arduino Uno # Canvis: # low_fuses canviat de 0xff a 0xbf per habilitar el rellotge de 16 MHz # a Atmega PB0 / pin 14 = Arduino D8

clkuno.name = Rellotge (Arduino Uno)

clkuno.upload.protocol = arduino clkuno.upload.maximum_size = 32256 clkuno.upload.speed = 115200 clkuno.bootloader.low_fuses = 0xbf clkuno.bootloader.high_fuses = 0xde clkuno.bootloader.extended_fuses = 0xd.bootloader.file = optiboot_atmega328.hex clkuno.bootloader.unlock_bits = 0xff clkuno.bootloader.lock_bits = 0xcf clkuno.build.mcu = atmega328p clkuno.build.f_cpu = 16000000L clkuno.build.core = arduino clkuno

##############################################################

Tingueu en compte que el rellotge s’activa configurant el bit de control a 0.

Quan hàgiu creat la nova placa al fitxer de configuració de taules, haureu de gravar un carregador d'arrencada nou a l'Atmega. Hi ha diverses maneres de fer-ho, he utilitzat el mètode descrit a

Un cop fet això, recordeu de seleccionar el vostre nou tipus de placa i no l'Arduino Uno quan pengeu un programa a l'Atmega.

Pas 6: el programari

El programari
El programari

És hora de fer intel·ligent el maquinari ximple afegint algun programari.

Aquí hi ha alguns pseudocodi per al prototip:

lastReceivedTime = 0

lastReceivedCmd = none cmdTimeout = 100 setup () {enable watchdog configure pins D4-D7 as output pins init CAN setup CAN filter} loop () {reset watchdog if (CAN message is received) {for each button command {if message CAN Pertany a l'ordre del botó {lastReceivedTime = now lastReceivedCmd = cmd}}} if now> lastReceivedTime + cmdTimeout {lastReceivedCmd = none} per a cada ordre de botó {if lastReceivedCmd is button command {set command pin output = on} else {set command pin output = off }}}

cmdTimeout decideix quant de temps hem d'esperar abans de considerar l'últim botó actiu llançat. Com que les ordres de missatge CAN del botó s’envien aproximadament cada 70 ms, ha de ser més gran que aquella amb un cert marge. Però si és gran, hi haurà una experiència de retard. Per tant, 100 ms semblen un bon candidat.

Però, què és un gos de vigilància? És una petita característica útil de maquinari que ens pot estalviar en cas de fallada. Imagineu que tenim un error que fa que el programa es bloquegi mentre l'ordre augmentar el volum està actiu. Aleshores acabaríem amb l’estèreo en volum màxim! Però si el gos de vigilància no es restableix durant el temps concret, decidirà que hagi passat alguna cosa inesperada i simplement restablirà.

configuració nul·la ()

{// permet 250 ms com a màxim per al bucle wdt_enable (WDTO_250MS); // altres coses inicials} bucle buit () {wdt_reset (); // fer coses}

POT filtrar? Bé, podeu configurar el controlador CAN per descartar tots els missatges que no coincideixin amb el filtre, de manera que el programari no ha de perdre el temps en missatges que no ens interessen.

màscara llarga sense signar = 0x1fffffff; // Inclou els 29 bits de capçalera a la màscara

filterId llarg sense signar = 0x0400066; // Només ens importa aquest identificador de missatge CAN m_can.init_Mask (0, CAN_EXTID, màscara); // La màscara 0 s'aplica al filtre 0-1 m_can.init_Mask (1, CAN_EXTID, màscara); // La màscara 1 s'aplica al filtre 2-5 m_can.init_Filt (0, CAN_EXTID, filterId); m_can.init_Filt (1, CAN_EXTID, filterId); m_can.init_Filt (2, CAN_EXTID, filterId); m_can.init_Filt (3, CAN_EXTID, filterId); m_can.init_Filt (4, CAN_EXTID, filterId); m_can.init_Filt (5, CAN_EXTID, filterId);

Consulteu el codi de la biblioteca CAN i la documentació del controlador CAN per obtenir més informació sobre com configurar filtre + màscara.

També podeu configurar el controlador CAN per generar una interrupció quan es rep un missatge (que no està filtrat). (No s'inclou a l'exemple anterior, però hi ha algun codi al meu programa.) En aquest cas, realment no aporta cap valor i pot resultar confús si no esteu acostumat a programar.

Per tant, aquest era el prototip de programari en resum. Però també necessitem algun codi per a la placa del simulador:

lastSentTime = 0

minDelayTime = 70 setup () {configurar els pins A0-A5 com a pins de sortida configurar els pins D4-D7 com a pins d’entrada amb extracció interna. init CAN} loop () {enviar "brossa" pot msg set activeButton = cap per a cada botó {si es prem el botó {establir activeButton = botó}} si activeButton! = cap {si ara> lastSentTime + minDelayTime {la comanda del botó d'enviament pot enviar missatges } set lastSentTime = now} inval = read pin A7 foreach (cmd) {if (min <inval <max) {led on} else {led off}} espereu 1 ms}

Això enviarà contínuament missatges CAN "brossa" aproximadament cada ms i mentre es prem un botó, l'ordre corresponent cada 70 ms.

És possible que hàgiu de registrar l'entrada al pin A7 mentre premeu els diferents botons per esbrinar els valors adequats per a les variables mínima i màxima de cada botó. (O podeu calcular-lo, però en llegir la entrada us donaran valors més precisos).

Heu de tenir una mica de precaució quan esteu programant els modes pin. Si definiu accidentalment els pins destinats a utilitzar el control intern com a pins de sortida, crearà una drecera potencial que danyarà el vostre Arduino quan configureu la sortida com a alta.

Si voleu consultar els meus programes, es poden descarregar aquí:

  • Programa de registre de missatges CAN
  • Programa per a la placa del simulador
  • Programa per prototip / tauler final

Heu de tenir en compte que aquests programes no coincideixen realment amb el pseudocodi, ja que contenen moltes coses "addicionals" que no són realment necessàries i, si no esteu familiaritzats amb la programació orientada a objectes, pot ser que sigui una mica difícil de llegir.

Pas 7: el maquinari final

El maquinari final
El maquinari final
El maquinari final
El maquinari final
El maquinari final
El maquinari final

Quan esteu satisfet amb el vostre programa (recordeu provar el prototip al cotxe després de fer la prova final amb la placa del simulador) és hora de construir el maquinari real.

Aquí teniu tres opcions:

  • Ràpid i brut: soldeu les coses juntes en un tauler prototip de PCB.
  • Bricolatge dur: graveu el vostre propi PCB.
  • De manera mandrosa: demaneu a un PCB professional que soldi els components.

Si no teniu pressa, us puc recomanar l’última opció. Si només necessiteu un petit PCB com aquest, és molt barat demanar-lo a la Xina. (I després probablement obtindreu deu peces més o menys perquè pugueu permetre alguns errors de soldadura).

Per demanar PCBs haureu d’enviar el vostre disseny en format Gerber. Hi ha diversos programes per a això. He utilitzat Eagle, que puc recomanar. Podeu esperar unes quantes hores per aprendre-ho, però després funciona bé. Per a tauletes petites com aquesta, podeu utilitzar-la de forma gratuïta.

Aneu amb compte quan feu el disseny. No voleu esperar quatre setmanes al lliurament només per saber que heu fet alguna cosa malament.

(Si teniu bones habilitats de soldadura, podeu dissenyar components muntats a la superfície i obtenir un adaptador molt petit. No ho he fet.)

A continuació, feu una comanda a, per exemple, https://www.seeedstudio.com/fusion_pcb.html. Seguiu les instruccions per generar els fitxers Gerber a partir del vostre disseny. També podeu obtenir una previsualització del resultat per assegurar-vos que està bé.

(Al final vaig haver de seleccionar altres resistències per a R4-R7 que les que apareixen a la imatge esquemàtica. En lloc d'això, vaig utilitzar 2k, 4.7k, 6.8k i 14.7k.)

I recordeu: no confongueu la numeració de pins Atmega amb la numeració de pins Arduino.

Us recomano que no soldeu el xip Atmega directament, sinó que utilitzeu un sòcol. A continuació, podeu eliminar-lo fàcilment en cas que hàgiu de reprogramar-lo.

Pas 8: muntatge del cotxe

Muntatge de cotxe
Muntatge de cotxe
Muntatge de cotxe
Muntatge de cotxe

Ara fins a la part més divertida: munteu-lo al cotxe i comenceu a utilitzar-lo. (Un cop hàgiu creat / comprat una funda).

Si ja heu provat completament el prototip del vostre cotxe, tot hauria de funcionar perfectament.

(Com he esmentat anteriorment, no ho vaig fer, així que vaig haver de substituir algunes resistències i fer alguns canvis al meu programa).

Penseu també en el cas de muntar-lo darrere de l'estèreo o en algun altre lloc. Vaig trobar un bon lloc a sobre de la meva guantera on puc arribar-hi des de dins de la guantera sense desmuntar res. Això pot ser útil si decideixo actualitzar-lo més endavant.

Finalment, els meus botons tornen a funcionar. Com podria sobreviure durant dos mesos sense ells?

Pas 9: millores futures

Com he esmentat, si en faig una versió 2.0, substituiré el 4066B per una altra cosa (probablement un potenciòmetre digital) per obtenir una major flexibilitat.

També hi ha moltes altres coses que podeu fer. Per exemple. afegiu un mòdul bluetooth i feu una aplicació de control remot per al vostre telèfon. O un mòdul GPS, quan estigueu a prop de casa, podreu augmentar automàticament el volum i enviar el missatge CAN "windows down" perquè tots els vostres veïns puguin gaudir de la vostra meravellosa música.

Recomanat: