PÄIVITTÄÄ: Työtä Arduinon sääasemalla jatkettiin tämän artikkelin julkaisemisen jälkeen, mikä huipentui Avoin sääasema (OWS) . Katso lisää päivityksiä, resursseja, koodia ja uusia opetusohjelmia.
Liitolainelautailua on yksi riippuvuutta aiheuttavista urheilulajeista maailmassa. Tarvitaan vain leijalauta, vesistö ja muutama lisävaruste. Se on hieno tapa ottaa yhteyttä luontoon, vapauttaa mieltäsi ja käyttää. Lisäksi voit todella hulluksi sen kanssa.
Voi, unohdin yhden olennaisen vaatimuksen: tuulen. Ja siellä meillä on ongelma: et koskaan tiedä, tuleeko tuulta vai ei, ellet asu aivan suosikkilohikylttipaikkasi vieressä.
asun Cordoba Argentiina , noin 130 kilometrin (~ 80 mailin) päässä järvestä, jossa leijailen. Se on suunnilleen kahden tunnin ajomatka, jonka pystyn käsittelemään. Mutta en pysty käsittelemään sitä, että sääennusteet ovat epätarkkoja. Ja missä asun, hyvät tuuliolosuhteet kestävät vain pari tuntia. Viimeinen asia, jonka haluat tehdä, on selvittää maanantai-aikataulusi mennä kitesurfingiin ja löytää itsesi kiroamassa jumalia tuulettomalla järvellä kahden tunnin ajon jälkeen.
Minun piti tietää suosikki leijalautailupaikkani tuuliolosuhteet - reaaliajassa. Joten päätin rakentaa oman sääaseman.
Tavoitteena oli toimittaa reaaliaikaiset säätiedot selaimelle kotona:
Ennen kuin perehdyn yksityiskohtiin, harkitsemme hetken tämänkaltaisen projektin avainkysymyksiä ja varoituksia:
Saatat ajatella, että käsine on olemassa, jotta asema näyttäisi ystävällisemmältä; mutta sitä käytetään tosiasiallisesti barometrisen anturin testaamiseen (käsineen paine kasvaa täytetyn käsineen sisällä). Oikealla näet aseman sen lopullisessa paikassa lähellä olevan tornin päällä.
Suunnittelin ja ohjelmoin myös a leijalautailusta , joka sisältää a reaaliaikainen kaavio aseman mittauksista auttaa kitesurfing-yhteisöä. Lopuksi loin kitesurfing-ryhmä Facebookissa .
Käsittelen jokaista kohtaa vuorotellen:
Tämä oli kriittinen tekijä ja monin tavoin ajoi muun suunnitteluprosessin. Useimmat valmiiksi valmistetut asemat 2000 dollarin linjan alapuolella edellyttivät a USB-yhteys tietokoneeseen . Jos varas huomasi, että asemalla oli tietokone vieressä, se olisi asian loppu, koska tietokoneen ja aseman vaihtokustannukset ylittäisivät henkilökohtaisen budjettini. Siksi päätin testata useita laitteistoalustoja aseman toteuttamiseksi alusta alkaen, halvemmalla.
Tuin yksin tämän sivuprojektin kustannuksia ja tein kaiken työn vapaa-ajallaani, joten tämä oli tietysti suuri huolenaihe. Aloitin suositusta PIC32 ja joitain valmiiksi koottuja mikrosirun Ethernet-moduuleja, mutta kustannukset eivät olleet niin pieniä kuin olin odottanut, ja laitteiston kokoonpanoon ja laajennukseen liittyi aivan liian paljon yleiskustannuksia. Sitten aloin tutkia Arduino : avoimen lähdekoodin laitteisto ja ohjelmisto elektroniikan prototyyppien tekoon C-kieltä käyttäen. Tätä halusin, ja voin ostaa moduuleja DealeXtreme . Pystyin aloittamaan pelaamisen vain 15 dollarin menoilla ja kahdella päivällä ajastani.
Tietenkin Arduino on myös rajoituksia: vain 2 kt tavua RAM-muistia ja 32 kt tavua käännetylle ohjelmistolleni - tämä ei jätä paljon tilaa hienoille merkkijonoille tai hyödyttömille muuttujilleyksi.
Tällä hetkellä asemani voi mitata: tuulen nopeutta, tuulenpuuskaa, tuulen suuntaa, lämpötilaa, kosteutta, sadetta ja ilmanpaineita. Muutama kirjasto hoitaa lämpötilaa, kosteutta ja painetta, mikä helpotti elämää paljon.
Tuulen nopeuden ja sateen mittaaminen oli hieman sotkuista. Anturit toimivat avaamalla ja sulkemalla kytkin ( ruokokytkin ). Minun oli siis toteutettava laitteistokatkokset, jotta anturi saadaan kiinni heti, kun se laukaisee tulon. Eli minun piti kutsua jokin menetelmä:
attachInterrupt(RAINGAUGE_PIN, countRainCycles, FALLING);
Tämä keskeytys rikkoo normaalin koodin suorituksen ja kutsuu countAnemometerCycles- tai countRainCycles-toimintoja heti, kun kytkin kokee laskevan reunan, joka syntyy sulkemalla tai avaamalla piiri. Muutama muuttuja kasvaa kytkimen jokaisessa liipaisimessa. (Punnitset myöhemmin nämä muuttujat yksikkömuunnosten huomioon ottamiseksi.)
void countRainCycles() { rainCyclesCounter++; // This is easy! And it actually works. }
Mutta ei niin nopeasti! Tämä prosessi tuottaa satoja vääriä laukaisimia seurauksena kytkimen palautumisvaikutuksesta, joka on ominaista laitteistokytkimelle. Onneksi tähän ongelmaan on sekä laitteisto- että ohjelmistoratkaisuja.
Pomppiva vaikutus tapahtuu seurauksena siitä, että kytkin avaa tai sulkee fyysisesti koskettimensa, jotka muodostavat kosketuksen muun piirin kanssa. Kun koskettimet alkavat erota (avaavat kytkimen) tai yhdistyvät (sulkevat kytkimen), voi syntyä pieniä sähkökaaria sekä piirin mekaaninen joustavuus, joka laukaisee piirin päälle ja pois muutaman millisekunnin ajan. Kun käännät valokytkintä, tämä vaikutus ei ole ilmeinen. mutta kun kiinnität keskeytyksen signaalin putoavaan reunaan, tämä pomppiva vaikutus laukaisee tonnia keskeytyksiä. Lisää tässä .
Olen toteuttanut sekä laitteiston purkamispiirin että vastaavan version ohjelmistossa. Mutta kuinka tarkalleen otat käyttöön ohjelmistoversiot? Helppo! Ensimmäisen odotetun laukaisun jälkeen 'odota' riittävästi aikaa palautumisen laskeutumiseen, ennen kuin aloitat uusien keskeytysten kuuntelun. Tämä voidaan suorittaa muutamalla rivillä C:
void countRainCycles() { if (nextTimeRainIterrupt == 0 || nextTimeRainIterrupt Millis () -funktio palauttaa nykyisen suoritusajan millisekunteina Arduinon käynnistämisen jälkeen. On myös syytä huomata, että nämä muuttujat on määriteltävä haihtuviksi, jotta kääntäjää kehotetaan olemaan optimoimatta suoritusta ja välttämään siten epätarkkoja arvoja laitteiston keskeytysten aikana.
Jotenkin tarvitsin aseman tallentamaan kertyneet tiedot ja lähettämään nämä mittaukset ajoittain MySQL-tietokantaan. Joten lisäsin Ethernet-moduulin, jossa on SD-paikka, arvojen kirjaamiseksi ja hakemiseksi aina, kun käyttäjä (palvelin) muodostaa yhteyden asemalle. Kotitestauksen aikana ADSL-yhteyksien kanssa tämä toimi hämmästyttävän hyvin - mutta melkein menetti hiukseni, kun testasin tätä 'kentällä' 3G-Internetin avulla (käyttäen 3G-modeemia), koska asema palautti itsensä satunnaisesti, kun yritin hakea mitat! Merkittävän testauksen jälkeen huomasin lopulta, että Internetin kautta toimitetut esimerkit, jotka kuvaavat datan 'palvelemista' yhdistetylle asiakkaalle, eivät pitäneet yhteyttä niin huonona, että yhteys asiakkaaseen saattoi menettää pakettien välissä, mikä ulostulopuskuri olisi ylivuoto. Mutta miksi yhteys katkesi aiheuttavan puskurin ylivuotoa? No, sanokaa, että lähetysistunto alkaa ja asema alkaa täyttää lähtöpuskuria datalla. Ihannetapauksessa asiakas kuluttaa tämän puskurin nopeammin kuin täyttyy. Näin ei kuitenkaan ollut, kun muodostat yhteyden 3G-modeemiin! Yhteys asiakkaaseen oli aivan liian huono, joten puskuri täyttyi nopeammin kuin kulutettiin, mikä aiheutti sekä puskurin ylivuotoa että äkillisen uudelleenkäynnistyksen asemalle.
Minun oli lisättävä toiminto ongelman ratkaisemiseksi Ethernet-kirjasto toimitettiin Arduinolla, joka meni jotain tältä:
int EthernetClient::free() { if (_sock != MAX_SOCK_NUM) return W5100.getTXFreeSize(_sock); return 0; }
Sitten pystyin tarkistamaan, onko asiakkaalla tilaa puskurissa, ennen kuin yritin täyttää sitä enemmän tiedoilla:
while (file.available() > 0) { if (client.free() > 0) { // This was key to solving the issue c = file.read(); client.print((char)c); } else { // No free buffer? Ok, I'll wait a couple of millis... delay(50); } } file.close();
Muuten, jos olet kiinnostunut ohjelmoimaan Arduinon, tässä hieno opas.
Toinen mielenkiintoinen tehtävä oli LIFO-lokin käyttöönotto. Miksi tämä oli välttämätöntä? No, tyypillisesti, kun tallennan mittaukset tiettyyn tiedostoon, lähestymistapa on yksinkertainen: avaa tiedosto, liitä uudet näytteet loppuun ja sulje tiedosto. Mutta sanon, että haluan hakea uusimmat 1000 mittausta kronologisesti lajiteltuina. Nämä mittaukset ovat tiedoston lopussa; Joten minun pitäisi avata tiedosto, siirtää kohdistin loppuun, tuottaa viimeisimmät mittaukset, sitten palauttaa tiedostokohdistin takaisin edelliseen mittaukseen ja lähtöön etsimällä näyteerotinta havaitsemaan, mistä aloittaa ja lopettaa. Arduinolla ei ole tarpeeksi RAM-muistia eikä prosessoritehoa tämän prosessin suorittamiseksi nopeasti, joten tarvitsin toisen lähestymistavan. Sen sijaan päätin tulostaa tiedoston päinvastaisessa järjestyksessä palvelimelle ja palauttaa sitten merkkijonon literaalit takaisin palvelimen puolelle:
unsigned long filePosition = file.size(); file.seek(filePosition); while (filePosition >= 0) { if (client.free() > 0){ file.seek(filePosition); c = file.peek(); if (c != -1) { client.print((char)c); } if (filePosition <= 0) { break; } filePosition--; } }
Kaikilla kokemuksilla PHP-kehittäjänä on helppo saada uusimmat näytteet, joissa merkit ovat oikeassa järjestyksessä:
// $output has the reversed string measures, each sample is delimited by ; $rows = split(';', trim($output)); array_walk_recursive($rows, 'reverseString'); if (strlen($rows[0]) == 0) { array_shift($rows); // Remove the first line if empty } function reverseString(&$row, $key) { $row = trim(strrev($row)); } // $rows is now the array of the latest samples :)
Palvelinpuolella asetan sitten cron-prosessin hakemaan uusimmat mittaukset kahden minuutin välein ja lisäämään tiedot MySQL-moottoriin. Luodakseni tiedot näytetään www.kitesurfcordoba.com.ar ja käytti jQueryä päivittämään kaaviot (jotka itse luodaan käyttämällä pChart v2.0 , loistava avoimen lähdekoodin kirjasto).
Asioiden toimimiseen tarvitaan joukko muita temppuja, jotka liittyvät sekä ohjelmisto- että laitteistotekniikkaan, mutta olen kestänyt tarpeeksi kauan - joten puhutaan huollon minimoinnista.
'Kuinka voin vähentää ylläpidon (lähes) nollaan?'
Tämä oli suuri huolenaihe, koska minun ei todellakaan ole helppoa päästä asemalle - jos olisin halunnut ajaa kahden tunnin päässä vain korjataakseni pienen toimintahäiriön, en olisi joutunut saattamaan häntä ensin (minä ei maininnut tätä aiemmin, mutta loppujen lopuksi olemme käyneet läpi, asema on itse asiassa 'hän', ja hänen nimensä on Dorothy).
Joten millaisista virheistä puhumme täällä? No, esimerkiksi: ohjelmisto saattaa jumittua, verkko saattaa menettää yhteyden, energiansyöttö voi epäonnistua (ja se katoaa) jne.
Pohjimmiltaan aseman on suoritettava mahdollisimman paljon itsensä palautumista. Siksi käytin sekä pehmeää että kovaa vahtikoirat . Tuntemattomille vahtikoira on ohjelmisto tai laitteisto, joka tarkistaa, toimiiko järjestelmä oikein, ja jos ei, yrittää herättää sen takaisin elämään. Arduinossa on upotettu vahtikoira, jota voit käyttää. Asetin sen odottamaan 8 sekuntia: jos puhelu kestää pidempään kuin aikaraja, ohjelmiston valvontakoira nollaa kortin.
wdt_enable(WDTO_8S); // 'wdt' stands for 'watchdog timer'
Rakastan tätä toimintoa. On kuitenkin tilanteita, joissa levy nollataan ja Ethernet-moduuli ei. Miksi? No, tämä on suhteellisen edullinen prototyyppikortti, ei kovin kallis, vikasuojattu laite (sinun ei todellakaan pitäisi rakentaa sydämentahdistinta sen kanssa). Tämän haitan voittamiseksi jouduin hakkeroimaan Arduinon kytkemällä ristikytkentä laitteiston palautustuloon itse levyn digitaalilähtöön. Nollaussilmukan välttämiseksi on myös lisättävä pari riviä koodia:
void setup() { digitalWrite(RESET_ARDUINO_PIN, HIGH); // Set it to HIGH immediately on boot pinMode(RESET_ARDUINO_PIN, OUTPUT); // We declare it an output ONLY AFTER it's HIGH digitalWrite(RESET_ARDUINO_PIN, HIGH); // Default to HIGH, set to LOW to HARD RESET ...
Sen jälkeen pystyin palauttamaan laitteiston palautuksen Arduinoon ja kaikkiin sen päällä oleviin moduuleihin (mukaan lukien Ethernet-moduuli) yksinkertaisesti soittamalla digitalWrite(RESET_ARDUINO_PIN, LOW)
, mikä herätti Dorothyn takaisin elämään muutaman sekunnin kuluttua.
Lisäksi levy käynnistyy automaattisesti uudelleen energian menetyksen jälkeen. Ja jos Internet-yhteys epäonnistuu, hyödynnämme SD-kortin tallennusominaisuuksia (tietoja voidaan tallentaa kortille yli viikon ajan, ja palvelin voi hakea vanhoja tietoja palauttamaan puuttuvat näytteet). Kaikkien näiden ominaisuuksien yhdistäminen antaa meille erittäin vankan sääaseman, joka selviää vihamielisistä olosuhteista, jotka se on rakennettu valvomaan. Yhteensä tämä asia maksoi minulle vain noin 300 dollaria.

Ja lopulta
Asema on toiminut joulukuusta 2012 lähtien. Toistaiseksi se ei ole epäonnistunut (tai jos onnistuikin, asema toipui tarpeeksi nopeasti, jotta kitesurfing-yhteisö ja minä en huomanneet). Noin 500 leijalautailijaa tarkistaa sääaseman säännöllisesti ennen matkalle lähtöä. Joten lukuun ottamatta palkintoa vaikeiden teknisten haasteiden ratkaisemisesta, minulla on ollut myös mahdollisuus tarjota joukko ihmisille miellyttävämpi kitesurfing-kokemus.
yksiAlun perin käytin Arduino uno . Myöhemmin vaihdoin Arduino Mega lisääntyneen RAM-muistin ja flash-muistin tarpeen vuoksi.
Liittyvät: Työskentely ESP32-ääninäytteen kanssa