Kysymys:
Kuinka Arduino voi antaa tietyn (ts. 56 kHz) kantotaajuuden?
jlbnjmn
2014-02-24 06:55:35 UTC
view on stackexchange narkive permalink

Työskentelen ilmaisen avaruusoptiikkaprojektin kanssa, joka lähettää dataa langattomasti kahden pisteen välillä. Tämän saavuttamiseksi käytän IR-LEDiä, joka on kytketty Arduino Unoon, joka sykkii lähettimelle 56 kHz: n kantotaajuudella ja toista Arduinoa 56 kHz: n IR-ilmaisimoduulilla vastaanottimelle.

Yritin käyttämällä delayMicroseconds () -tappien korkeiden ja pienten komentojen välillä kantoaaltotaajuuden luomiseksi. Tällainen toimii, mutta taajuus ei ole aina sama, ja mahdolliset lisäviiveet signaalin pulsseille (ts. Funktion kutsumiseen ja vähennykseen tarvittava aika) voivat muuttaa sitä.

ATmega328 näyttää olevan tapa asettaa tarkempi pulssi sirun ajastimilla. Onko se mahdollista, ja jos on, miten luot 56 kHz: n pulssin ajastimilla?

Kuinka tarkkaa tarvitset 56 kHz: n taajuudellesi? Eli. mikä taajuusalue on hyväksyttävä projektissasi? Kysyn, koska pelkällä Arduino-ajastimilla tarkkuudella on rajoituksia.
55,5 kHz - 56,5 khz olisi ihanteellinen detektorin korkean reagointitason ylläpitämiseksi.
Viisi vastused:
#1
+10
jfpoilpret
2014-02-25 02:45:44 UTC
view on stackexchange narkive permalink

On todellakin mahdollista luoda 56 kHz: n signaali Arduino ajastimella .

Ajastin voidaan itse asiassa nähdä erityisenä rekisterinä MCU: ssa, joka pitää arvo (alkaen 0: sta), joka kasvaa taajuudella, joka on MCU: n kellotaajuus (16 MHz Arduino Unolla), mahdollisuus jaettuna kertoimella nimeltä prescaler . Kun kyseinen arvo saavuttaa määrittämäsi rajan, jota kutsutaan Vertaa hakua , tapahtuu kaksi asiaa:

  • Ajastinrekisterin arvo palautetaan arvoon 0.
  • Yksi ISR (keskeytä palvelurutiini) -kutsufunktio kutsutaan (voit määrittää sen osoittamaan omaa koodiasi).

Ajatuksena on käyttää että ISR muuttaa loogisen nastan lähdön joka kerta, kun sitä kutsutaan ( HIGH , sitten LOW , sitten HIGH ...).

Jotta voisit luoda 56 kHz: n neliöaallon, sinun on kutsuttava ISR: ääsi 56000 * 2 kertaa sekunnissa ( * 2 koska lähtöarvoa on muutettava kahdesti jaksoa kohden).

Voit valita ajastimelle haluamasi esikalkkioarvon seuraavasta luettelosta:

  • 1 (kellotaajuus ei ole jaettu, siis 16 MHz)
  • 8 (kellotaajuus jaetaan 8: lla, siten 2 MHz)
  • 64
  • 256
  • 1024

Arduino Unossa on kahta kokoa ajastimia / laskureita (ne kutsutaan ajastin / laskuri tosiasiallisesti): 8 bittiä ja 16 bittiä.

Arduino Unossa (ATmega328P) sinulla on yhteensä kolme ajastinta, mutta Arduino-ydin voi käyttää joitain kirjasto tai muut luonnoksissasi käytetyt kirjastot (sinun on tarkistettava se itse):

  • ajastin0 (8-bittinen)
  • ajastin1 (16-bittinen)
  • ajastin2 (8-bittinen): tällä on enemmän esilajitteluvaihtoehtoja (1, 8, 32, 64, 128, 256 ja 1024)

Nyt sinun on Luo 56 kHz aalto 16 MHz: stä, joten sinun ei tarvitse laskea esiskaalausta:

16000000 / (56000 * 2) - 1 = 141,857 ( - 1 koska ajastin laskee 0: sta tähän arvoon ja palauttaa vain jälkeen se on saavutettu)

Tästä laskelmasta voimme tehdä kaksi havaintoa:

  1. 141.857 ei ole kokonaisluku ja näin voitit ' Et pysty tuottamaan tarkalleen 56 kHz: n aaltoa.
  2. Ilman esilajittelua tarvitaan 16-bittinen ajastin, koska 285 ei ole edustettavissa 8-bittisenä allekirjoittamattomana kokonaislukuna.

    Tästä lähtien sinulla on kaksi vaihtoehtoa:

    1. Käytä 16-bittistä ajastinta ( ajastin1 ), käytä prescaler = 1 ja valitse 142 koodi> Vertaa vastaavuutta; joka antaa sinulle seuraavan taajuuden: 16000000 / (2 * (142 + 1)) = 55944 Hz
    2. Käytä 8-bittistä ajastinta ( timer0 ), käytä prescaler = 8 ja valitse 17 Vertaa vastaavuutta; joka antaa vähemmän tarkkuutta seuraavalla taajuudella: 16000000 / (8 * 2 * (17 + 1)) = 55555 Hz , joka on edelleen vaaditulla alueella.

    Mitä tulee luonnoksen kirjoittamiseen siihen, suosittelen tutustumaan tähän ohjeelliseen, joka on erittäin kattava ja erittäin mielenkiintoinen lukea.

    Tietenkin ATmega328P: n täydellinen tietolomake on myös tärkeä, jos haluat ymmärtää pienimmissäkin yksityiskohdissa, mitä olet tekemässä.

    Joitakin tärkeitä huomautuksia:

    • ISR suoritetaan vammaisilla keskeytyksillä, ja sen on siten oltava mahdollisimman lyhyt. Erityisesti Arduino-kirjastosta löytyy useita toimintoja, joita ei tarvitse kutsua ISR: stä.
    • Arduino Uno -kello ei ole kovin tarkka (se käyttää keraamista resonaattoria kvartsin sijasta, mikä olisi ollut paljon tarkempi), joten tämä tarkoittaa, että lähtötaajuus siirtyy edelleen.
Myös kun määritetty raja on saavutettu, * laitteisto * voi vaihtaa nastaa. Siksi ei ole tarvetta käyttää ISR: itä. ISR: llä on aina * värinää *, koska käskyä ei voida keskeyttää sen alkamisen jälkeen. Laitteisto kuitenkin vaihtaa aina tapin halutulla nopeudella.
On jonkin verran yllättävää, että Arduino Uno käyttää keraamista resonaattoria, mutta sen lähde on * [Arduino UNO FAQ] (https://learn.adafruit.com/arduino-tips-tricks-and-techniques/arduino-uno- usein kysytyt kysymykset) * (lähellä * "Käyttääkö Uno resonaattoria tai kristallia prosessorin kellossa?" *).
#2
+3
Peter Bloomfield
2014-02-24 18:02:05 UTC
view on stackexchange narkive permalink

Olen havainnut, että tone () on hyödyllinen korkean taajuuden pulssien tuottamiseksi mille tahansa pinille. Sen pitäisi pystyä käsittelemään 56 KHz. (Muokkaa: Kuten jfpoilpret on todennut, lähin 16 MHz: n Arduinolle saatava hinta on noin 55,944 KHz)

Ongelmana on ilmeisesti sen yhdistäminen datasignaaliin. En usko, että voit tehdä sen ohjelmistossa turvautumatta matalan tason koodiin. Sen pitäisi olla melko helppoa laitteistossa, koska se on digitaalinen.

Sinun tarvitsee vain lähettää datasignaali eri nastalle ja yhdistää se sitten operaattoriin AND-porttia käyttämällä. Yhdistetty signaali voi mennä suoraan infrapunalähettimeen.

Jos sinulla ei ole AND-porttia kätevää, on melko helppoa tehdä oma transistoriparisi avulla. Etsi vain verkosta "transistori ja portti".

Vastaanottajilla on usein aktiiviset matalat lähdöt. Jos kytket LEDin yläosan 56 kHz: iin ja alimman datatappiin, kun datanasta menee matalalle, saat IR-lähdön, jonka pitäisi saada vastaanotin menemään matalaksi. Ei ja porttia tarvitaan, vain led ja vastus. Ainoa ongelma on rajoitettu mihin tahansa nykyiseen io-nastaa voi ajaa.
#3
+2
zzz
2014-04-01 09:10:47 UTC
view on stackexchange narkive permalink

Jfpoilpretin hyväksytty vastaus on hyvin kirjoitettu, täysin pätevä ja teen 99 prosentissa tapauksista juuri sen, mitä hän selittää. Hänen ratkaisunsa ovat hyvin määriteltyjen parametrien sisällä, joten niiden pitäisi toimia erittäin hyvin. Mutta mikä on parempi kuin " erittäin hyvin "? Täydellisyys! Loppujen lopuksi kysymys on tarkan arvon luomisesta. Kuten sanottiin, riittävän lähellä on useimmissa tapauksissa hyvä (todennäköisesti kaikki), ja vaikka tekisit jotain kellona, ​​kun 1 sekunnin on oltava 1 sekunti, joudut kärsimään perittyjen osien puutteista.

Mitä minä ehdottaa, ei ole aina mahdollista. Joissakin tapauksissa se on mahdollista, mutta paljon enemmän vaivaa ja vaivaa kuin tässä tapauksessa. Onko se sen arvoinen, riippuu tapauskohtaisesti. Tavoitteenani on enimmäkseen näyttää vaihtoehto myöhemmille viitteille, joka on parempi hieman syrjäisissä tapauksissa. Tämä on kirjoitettu aloittelevien Arduinon käyttäjien mielestä, joilla ei ole laajaa kokemusta elektroniikasta.

Edistyneemmille ihmisille tämä näyttää todennäköisesti liian yksityiskohtaiselta ja tyhmältä. Mutta uskon, että samat ihmiset todennäköisesti jo tietävät sen eivätkä tarvitse tätä vastausta. Tämä pätee myös kaikkiin mikro-ohjaimiin, kaikkiin valmistajiin ja arkkitehtuureihin. Mutta muille mikro-ohjaimille sinun on käytettävä oikeaa tietolomaketta selvittääksesi oikeat rekisterit ja esiasteikon nimet ja arvot.

Sinun tapauksessasi tarvitset tietyn taajuuden ja siinä on mukava asia, että täsmälleen 56 kHz voidaan saavuttaa todella helposti (lukuun ottamatta osien käytännön puutteita). Joten tämä on myös täydellinen esimerkkitapaus.

Signaalin tuottaminen riippuu mikro-ohjaimen ajastimista ja kellolähteestä, kuten jfpoilpret selittää. Hänen vastauksensa käsittelee vain yhden näkökulman ongelmaa, joka on ajastimien kanssa. Mutta voit hämmentää myös kellolähdettä tai jopa parempi molempien kanssa synergian ja mahtavien tulosten saavuttamiseksi. Muuttamalla ympäristön parametreja, tässä tapauksessa hakkeroimalla järjestelmää ja korvaamalla kellolähde, voimme käsitellä tiettyä ongelmaa paljon, paljon helpommin ja yksinkertaisemmin.

Ensinnäkin muistutettava vaihtamisen takia. pin-tilassa, sinun on suoritettava ISR kaksi kertaa enemmän kuin signaalin taajuus. Tämä on 112000 kertaa sekunnissa. 56 000 ja 16 000 000 eivät ole kovin hienoja, kuten jo todettiin. Meidän on muutettava joko signaalitaajuutta tai tahdistustaajuutta. Nyt käsitellään muuttumattomalla signaalitaajuudella ja löydetään parempi kellotaajuus.

Olisi suoraviivaisinta valita kello, jonka suuruusluokka on suurempi kuin 56 kHz (tai 112 kHz, mutta se on käytännössä sama), koska lisäät vain nollia ja tällainen matematiikka on yksinkertaisin useimmille ihmisille. Valitettavasti kaikki tässä maailmassa on jonkinlainen kompromissi johonkin. Kaikki arvot eivät toimi.

Ensimmäinen esimerkki on liian alhainen taktisen generaattorin nopeus.

Jos valitset 56 000 Hz: n kellon, et voi tehdä mitään samalla tavalla täytyy soittaa ISR: ään joka sykli eikä voi tehdä mitään muuta. Se on täysin hyödytöntä. Jos valitset 10 kertaa nopeamman nopeuden (560 kHz), sinulla on 9 (10 sykliä, jotta ajastin saavuttaa maksimiarvonsa - yksi sykli ISR-toiminnon kutsumiseksi) mikrokontrollerisykliä työn tekemiseen, ja tämä ei täysin riitä. Tarvitset usein enemmän laskentatehoa.

Jos valitset toisaalta aivan liian suuren arvon, koska 56 MHz mikro-ohjain ei yksinkertaisesti voi toimia sen kanssa. Se on aivan liian nopeaa. Joten yksinkertaisesti valitsemalla suurin arvo kaupassa, se ei myöskään vähennä sitä.

Alkuperäisen Arduino Uno R3: n varastokello on 16 MHz, joten kaikki hitaampi, mikä toimii. Seuraava arvo, joka on suuruusluokkaa suurempi kuin 56 ja alle 16 MHz, on 5,6 MHz. Tämä johtaa siihen, että pystyt soittamaan ISR: ään 50 jakson välein ja luo täydellisen 112 000 Hz: n ajastintaajuuden. Ja signaali on tarkalleen 56 kHz. Sinulla on 49 MCU-jaksoa ohjelman suorittamiseen ISR-puheluiden välillä, mutta se on silti noin 1/3 alkuperäisen kellonopeudesta. Voidaan käyttää 112 tukiasemana ja käyttää 11,2 MHz kelloa, mikä antaa noin 2/3 varastosta 16 MHz resonaattorin. ISR-toimintoa kutsutaan 100 syklin välein ja se tuottaa edelleen täydellisen 56 kHz: n signaalin.

Näillä arvoilla on kuitenkin kaksi suurta ongelmaa.

  • Ensimmäinen ongelma riippuu suuresti tarpeistasi: Uhritat noin 1/3 (11,2 MHz: llä) suurimmasta laskentatehostasi saadaksesi tarkan signaalitaajuuden, joka käyttää helposti löydettävää rekisteriarvoa (OCR iirc ). Saatat olla kunnossa tai et.

  • Toinen ongelma on kova showstopper : Arvojen löytäminen on erittäin helppoa, mutta erittäin usein niitä ei yksinkertaisesti ole olemassa valmistettuna kellolähteenä. Tämä on Farnellin resonaattorisivusto , jolta puuttuu yksinkertaisesti sekä 5,6 MHz että 11,2 MHz.

Tämän kiertämiseksi voimme tarkastele käytettävissä olevia resonaattoriarvoja ja selvitä jotain muuta, jota voidaan käyttää tuottamaan tarkalleen halutut arvot. Jos jaamme 56 neljällä, saadaan 14 ja onneksi on 14 MHz: n resonaattori. Tämä tarjoaa meille paljon suuremman nopeuden ja enemmän tehoa sekä yhtä helposti löydettävän rekisteriarvon. ISR: n soittamiseksi 112 000 kertaa sekunnissa meidän on lisättävä desimaalin 124 tai heksadesimaalin 0x7C arvo OCR-rekisteriin, joten kun laskemme 124 sykliä + 1 ISR: n kutsumiseksi, saamme haluamasi täydellisen arvon.

Huom.

  1. ISR - keskeytä palvelurutiini (tämä koodi suoritetaan vain generoiduille keskeytyksille)
  2. Kuinka suuri ohjelmasi voi olla, riippuu muistin koosta! Sillä ei ole mitään tekemistä kellonopeuden kanssa, eikä sillä ole mitään tekemistä sen kanssa, kuinka usein soitat ISR: ään.
  3. Kun mikrokontrolleri alkaa ohjelmakomennolla, laskuri kasvaa. Jos keskeytys syntyy, kutsutaan ISR ja tämä arvo tallennetaan erityiseen rekisteriin. Kun ISR-koodi on valmis, ohjelmalaskurin arvo palautetaan tästä erityisestä rekisteristä ja ohjelma jatkuu siitä kohdasta, missä se keskeytyi ikään kuin sitä ei olisi koskaan tapahtunut.

    Annan erittäin hämmentävän esimerkin . Jos olet puristi, varoitan sinua: Nenä- ja silmäverenvuotoja voi esiintyä.

    Kuvittele, että sinun täytyy kävellä jonnekin jonnekin. Vaiheittaiset reittiohjeet ovat pääohjelma ja sen komennot. Kuinka nopeasti kävelet tai juokset, riippuu "kellonopeudesta", mutta ei reittiohjeista (30 askelta eteenpäin, 1 käännös 90 grad. Vasemmalle, 10 askelta eteenpäin, 45 grad. Oikealle jne.) Ne ovat aina samat . Kuvittele nyt, että pieni lapsi tai ahne korruptoitunut paikallinen poliitikko irrottaa kenkäsi tällöin. Tämä on tapahtuma, joka tuottaa keskeytyksen. Sitten pysähdyt viimeisen askeleesi jälkeen, polvistut ja sitoit kenkäsi uudelleen. Tämä on sinun ISR-ohjelmasi.

    Sitten jatkat pysähtyneestä paikasta; et aloita alusta. Kun kävelet ilman huolta maailmassa ja koko ajan, et välitä, vaikka joudutkin sitomaan kenkäsi joka toinen askel. Jos kuitenkin teet sen aikarajoitteilla, kuten juoksemalla 100 metriä olympialaisilla (tai juoksemalla nälkäiseltä lihaa syövältä saalistajalta), kenkiesi pysäyttämisellä ja sitomalla voi olla vakavia seurauksia. Sama on mikrokontrollereiden kanssa. Vaikka suoritat vain yhden koodirivin, ohjelma jatkuu, vaikkakin hitaasti. Jos et välitä nopeudesta lainkaan, se ei ole ongelma. Jos joudut tekemään jonkin aikaa, kuten käyttämään muita ajastimesta riippuvia toimintoja, häiriöt voivat olla hyvin ei-toivottuja ja ongelmallisia.

  4. Vähemmän on enemmän! Nopeampi kello ei ole aina parempi. Hitaammin kellotetut laitteet käyttävät huomattavasti vähemmän virtaa. Tämä voi olla tärkeä kohta paristokäyttöisessä laitteessa.

  5. Tarvittavat jaksot johdetaan seuraavista kaavoista:
    (kellonopeus / (esikalkkikoneen arvo * tarvitaan ISR) soittotaajuus)) - 1

TLDR: Poista keraaminen 16 MHz: n oskillaattori ja korvaa se uudella, joka sallii * täsmälleen * 56 kHz: n kokonaislukijaolla (esim. 14 MHz ja jako 250: llä).
#4
  0
kiwiron
2014-03-31 14:51:33 UTC
view on stackexchange narkive permalink

Voit kytkeä kantoaallon päälle ja pois päältä yksinkertaisesti vaihtamalla kantoaaltatilan lähdön ja tulon välillä. Olen käyttänyt tätä ohjaamaan lämpöpumppua 37 kHz: n infrapunaportin (kaukosäädin) kautta.

#5
  0
kiwiron
2014-04-01 13:12:01 UTC
view on stackexchange narkive permalink

Operaattorin luomisessa ei tarvitse käyttää ISR: ää. Aseta vain ajastin tuottamaan 50% PWM-lähtö vaaditulla kantoaaltotaajuudella. Tällöin ISR vastaa vain kantoaallon moduloinnista - tyypillisesti 0,5 tai 1 ms: n välein - paljon mukavammasta nopeudesta. Kokemukseni mukaan suurin osa IR-vastaanottimista sietää kantoaaltotaajuuden 5%: n virheen. Käytin Freetronics EtherMega 2560 (jossa on paljon ajastimia), mutta olen varma, että muut suorittimet pärjäävät yhtä hyvin.

Kuinka kantoaallon modulointi toteutetaan sitten? Vaihdetaanko ajastimen ulostulon sieppausnastan tilaa tulon (kantoaalto pois päältä) ja lähdön (kantoaalto päällä) välillä?


Tämä Q & A käännettiin automaattisesti englanniksi.Alkuperäinen sisältö on saatavilla stackexchange-palvelussa, jota kiitämme cc by-sa 3.0-lisenssistä, jolla sitä jaetaan.
Loading...