Lämpötilaohjattu askelmoottori

Iltaa

Haaveissa / ajatuksena olisi rakennella lämpötilaohjattu askelmittari. Tiedän että se on mahdollista, mutta olen täysin alottelija ja en tiedä mistä aloitella.

Aloitin jokatapauksessa miettimällä mitä haluan “laitteen” tekevän. Haluan että kyseinen laitos tarkistaa lämpötila-anturilta (esim 1-wire laitteista tuttu Dallas DS18S20) lämpötilan, vertaa sitä toisen anturin lukemaan ja tämän mukaan tekee päätöksen mitä tekee.

Esim:

  • Mittaa lämpötilan anturilta 1, lämpötila -10c
  • Mittaa lämpötilan anturilta 2, lämpötila +40
  • Tarkistaa tallennetusta “tietokannasta” mitä halutaan anturi 2 lämpötilaksi KUN anturi 1 lämpötila -10c
  • Kääntää askelmoottoria x-määrän päätöksen mukaan
  • Odottaa tunnin, tekee saman uusiksi.

Tuonne tallennettuu “tietokantaan” voisi sitten syöttää vaikka aste kerrallaan TAI astevälit, esim:
Anturi 1: -5 … +5, Anturi 2 pyritään saamaan +40
Anturi 1: -6 … -10, Anturi 2 pyritään saamaan +45
Anturi 1: -11 … -15, Anturi 2 pyritään saamaan +50

Lisähienoutta tietysti toisi se, että Anturi 1 mittaus tehtäisinn esim 60min välein, mutta Anturi 2 mittaus tehtäisiin 15min välein, ja tämän mukaan moottoria käskytettäisiin.

Nämä luvuthan on vain lukuja, niitä voi tarvittaessa muutella mutta itse laitteen muu toiminta tarvitsisi saada aluille.

Jos joku ihmettelee mihin käyttöön tämä tulee, niin vesikiertoisen patterilämmityksen patteriverkoston veden lämpötilan säätöön. Säätö tehdään pannuhuoneen päästä, pattereissa tietysti omat termostaattinsa. Ideana siis se, että säästyy energiaa kun pattereihin ei turhan kuumaa vettä kierrätetä, ja nykyisin energia on rahaa. Vastaavia laitoksia on saatavilla valmiinakin, mutta nikkarointi on aina kivaa ja jos tällä saisi vaikka mukavasti harrastuksen alkuun.

Suoria mielipiteitä, olenko ottamassa liian isoa projektia heti aluksi? Onko halukkaita auttamaan / opastamaan?


Tuomo

Hienoa, hyödyllinen ja toteutuskelpoinen projekti. :sunglasses:

En ehdi nyt ottamaan kantaa toteutustapaan, mutta siirsin viestiketjun Ideat ja projektit -alueelle.

Tätä aihetta olen itsekin tekemässä. Oma opinnäytetyöni käsittelee myös hyvin samanlaista keissiä, mutta on paljon laajempi.

Eli mistähän aloittaisin. Ajatellaan kolme pistettä: -20,50 -15:40 -5:35 ja haluat kivan tasaisen lämpötilan verkkoon. Noiden kahden väliin voidaan piirtää kaksi janaa, a1X + b1 = Y, kun X <= -15 ja a2X +b2 = Y, kun X >= -15. Yhtäläisyys merkit tarkoittavat, että a1X +b1 = a2X + b2, kun X= -15. Tämän ongelman ratkaiseminen on triviaali. MAOL, tai muu kaavakirja käteen. Toinen ehto voisi olla myös mukava olla olemassa. Y = Y kun +10 < Y < +95, muulloin raja-arvo ettei pyydetä aivan mahdottomia.

Tämän jälkeen laitetaan tuohon X:n paikalle laitetaan mitattu ulkolämpötila ja saadaan kohdearvo.

Mittaus kannattaa tehdä kymmenen kertaa nopeammin kuin säätö ja keskiarvoittaa siitä. Esimerkiksi jos mitataan sisäilman lämpötilaa eteisestä, aukinainen ovi hetkauttaa sopivasti tilannetta poskelleen. Ulkolämpötilaa mitattaessa heitto voi tapahtua toiseen suuntaan. Itse ihmettelin kahden viikon aikana olevaa kummaa kuumotusta omassa uökolämpömittarissa. Musta filmipurkki aina varjossa saikin yllättävän auringonpaisteen, kun naapurin peltiladosta heijatui aurinko siihen.

Mutta takaisin mittaukseen. Kun meillä on tavoitearvo, voidaan sille tehdä säädin. Jos englanti sujuu niin aivan loistava säädin on tarjolla: eetimes.com/design/embedded/ … hout-a-PhD

Tuolla sitten säädetään hanaa. 6 minuutin välein haetaan mittaustulokset, lasketaan keskiarvoa. veden lämpötilaa ei kannata mitata joka kuudes sekunti vaan tyytyä yksittäiseen mittaukseen ja säätää sen mukaan. Homma saadaan kontrolliin pitämällä kertoimet kurissa säätimessä.

Itse jouduin järkeilemään tämän homman aikoinaan ja tein järjestelmän, joka antaa virheeksi 1:n ja sitten ohjaus vaikuttaa siihen 0.1 verran. Ja jotta pystyin hahmotamaan mitä tuo säätimeni teki ja käyttäytyi tulostin roskaa ja piirsin kaavioita ja tungin ne AVIin. PID säädin erilaisilla kertoimilla

Niin ja tuon säätimen ulostulon voi sitten syöttää sopivasti viritettynä ollessa suoraan askelmoottorille, että ota N askelta. Ja sitten sellainen temppu kannattaa tehdä, että estää I-komponentin keräämästä aivan hulluja määriä itseensä, kun askelmoottori on avannut tappiin ja homma ei säädykkään. Lisäksi tarvitsee pitää tietoa yllä missä kohtaa hana on menossa.

Viimeiseksi kysyn, mistä järjestelmä tietää, milloin hanan säätövara tulee vastaan? Oikeasti järjestelmän ei tarvitse tietää tätä, vaan se hakee oikean paikkansa. Kuitenkin -70 asteen pakkasella hana töksähtää vasten rajaansa ja moottori leipoo kokoajan lisää avoimuuttta sille, kunnes palaa tai jotain hajoaa.

Ja numeroista sen verran, että ne ovat vain numeroita, jotka eivät liity mitenkään todellisuuteen vaan ovat helpottamassa ongelman hahmottamista. Tässä ajattelun aihetta. Voin auttaa kyllä kun keksit millaista ratkaisua haet.

Samoilla linjoilla Vuokon kanssa, eli PI(D)-säädin lienee paras. Sopivasti keskiarvoistettuna ja sopivalla mittausvälillä saadaan aikaan varsin tarkka säätö, itse lähtisin jonkin verran nopeampaan kuin alun “speksissä”, eli vaikkapa vartin keskiarvo molemmista, kiertovedelle kenties nopeampikin.

Sitten vaan käyrää suunnittelemaan (etsimään) ja siitä sopiva matemaattinen lauseke, jolla lasketaan missä asennossa askelmoottorin kuuluu olla milläkin lämpötilalla. Eli ulkolämpötilalla “asetetaan” haluttu lämpötila kiertovedelle ja PID-säädin huolehtii, että kiertovesi säädellään oikeaksi.

Jos pyörittelyyn ei tarvita hirmuisen laajaa aluetta, vaihtaisin myöskin askelmoottorin servoon. Tällöin saa (omasta mielestäni) luotettavammin huolehdittua sen, että asento on oikea.

//E: Itselläni ollut hieman samantyylistä projektia, tässä tosin ohjataan vain suoraan lämmityskattilan sähköjä sen mukaan, onko jokin lämpöanturi liian kylmä (ts. pakkasvahti). Lisänä valojen jne ohjailut myöskin. http://koti.kapsi.fi/kipe/asdf1.png

Mitäs tuossa on tapahtunut? Lämmitys on selkeästi käynyt puoli tuntia, vaikka käppyrät antavat ilmaista, että syytä moiseen ei ole ollut. Tietenkään en tiedä kaikkia logiikan päätökseen vaikuttavia tekijöitä, mutta mietin vain.

Netti on mokkulan varassa ja mokkula ei tykkää olla pitkiä aikoja putkeen päällä → “hätäratkaisuna” vetästään koneesta virrat pois vartiksi tuohon aikaan. Samalla, kun PC katoaa, menee toki lämmitys päälle. Pitäisi jaksaa rakennella relekytkentä mokkulan usb-piuhan katkomiseen, ei tarvitsisi turhaan konetta käyttää alhaalla. Tai sitten vaihtaa paremmin toimiva mokkula :stuck_out_tongue:

Tuossa lämpötilojen mittauksessa ei vain parane olla liian hätäinen.

Lämpötilat kun tullaan mittaamaan putkien kyljestä, eristettynä tietysti ympäröivästä ilmasta, mutta silti se kestää hetken ennenkuin putken sisällä menevä esim. 5c muutos näkyy putken ulkosyrjällä olevassa anturissa. Tuolla PID ohjaimella (luin jutun ja luulin ymmärtäväni) saadaan kyllä nopeasti pääsy sinne tavoitearvoon, mutta jos anturi ei putken lämpeämisen johdosta lämpeä ja anna oikeaa lukemaa, niin moottori se vain syöttää liikaa ja tästä päästään jälleen aaltoliikkeeseen. Ei johtuen PID ohjaimesta, vaan johtuen fysiikan laista.

Tuo ulkolämpöjen nopea mittaus ja keskiarvon mukaan säätäminen on hyvä idea, jos todellakin sattuu jokin heijastus jostain anturille niin ei sitten mene täysin sekaisin tai vaikka vikalukema. Anturin sijoitus tulee olemaan räystään alla, varjopuolella jolloin saadaan mahdollisimman lähellä oikeaa lukemaa. Tottakai talon tarvittavaan lämpöön vaikuttaa tuulisuus ja auringonpaistekin, mutta muuttuvia tekijöitä on niin paljon ettei niistä parane nyt tässä vaiheessa vielä murehtia.

Eli nyt jos muutetaan projektin ideaa näin:

  • Mittaa esim. 3min välein lämpötilan ulkoa
  • Laskee jokaisen mittauksen jälkeen esim. 5 viimeisen mittauksen keskiarvon, ottaa tämän luvun ulkolämpötilaksi
  • pyrkii säätämään pattereihin lähtevän veden lämpötilaan haluttuun arvoon suhteessa ulkoilmaan, säätöporras esim MAX 2 astetta / 30min tai jokin vastaava rajoitus. Liekö sitten kannattavaa rajoittaa säätämistä ajan kanssa vai moottorin liikkeen perusteella.

Käytännössä tämä operaatio olisi hyvä saada toimimaan niin nopealla kertauksella kuin se on patteriverkkoon lähtevän putken ulkopinnanlämmön avulla mahdollista, mutta ne nyt on jälleen taas vain lukuja kuinka usein mitäkin mitataan ja milloin lasketaan keskiarvoa.

Servoa tuossa voisi myös käyttää. Liike on loppupeleissä todella pientä mitä halutaan, joten pitkällä sarvella saa helposti voimaakin servoon, mutta jääkö servo vääntämään kokoajaksi VAI saako sen ohjelmoitua liikkumaan kohtaan X ja “sammumaan” ?

Todellinen liike jota tarvitaan, on luokkaa 30 astetta MAX liike +40c ja +65c välillä.

Lämpövaihtoehtoja voisi pitää projektissa vaikka +40c, +50c, +60c, +65c.

Elikkäs. Nyt on luettu tuon PID säätimen toimintaperiaate. Mistä tässä nyt seuraavaksi kannattaa lähteä alkuun?

Omat elektroniikka osaamiset kun rajoittuu lähinnä juottamiseen valmiin ohjeen mukaan. Ohjelmointia on tullut harrastettua pienissä määrin C++, Pascal, PHP, HTML, SQL.

Mitä tarvitsen ensimmäisenä? Jonkin softan jolla koodaan ja jolla ajan koodin piirille? Softalla ilmeisesti voi alkaa vääntämään ja debuggaamaan koodia ILMAN piiriäkin(kö?).

Te halukkaat olette nyt vähän niinkuin opettamassa possulle höyrypannun rakennusta ja käyttöönottoa… :smiley:


Tuomo

Meillä tuo lämmönmittaus on tehty juurikin kuvatulla tavalla, eli ottamalla mittaus putkenpinnasta lämpöanturilla (DS1820). Ei siinä viivettä ole juuri mitään, kattilan oma mittari ja lämpöanturi näyttää aina täysin samaa. Toki jos virtausta on rajoitettu, viivettä tulee enemmän.

Servoahan ohjataan pulssisignaalilla, eli ohjauspiirille lähetetään tietyn taajuinen signaali ja servo pitää sen asennon, jonka signaali määrää. Itse valitsisin servon sen takia, että saadaan määrättyä “oletusarvo”, jos signaalia ei tule lainkaan. Tällöin jos prossu menee syystä tai toisesta jumiin/joku osa kärähtää, aukaisee servo hanat.

Se, mitä tarvitset, riippuu siitä minkä alustan valitset toteutukseesi. Yksi helpoimmista lienee Arduino, sillä on helpot ja yksinkertaiset kirjastot homman hoitoon. Launchpad ja Atmelin prossut suoraan soveltuu myös hommaan, mutta ovat hieman vaikeampia ohjelmoida. Launchpadissa ja Arduinossa tulee kaikki tarvittava valmiina, ts. ohjelmointipiiri on sisällytetty laitteeseen. Suoraan Atmelille ohjelmoidessa tarvitset ohjelmointilaitteen, joita löytyy laidasta laitaan.

Atmel ja Launchpad käyttävät ohjelmointikielenään C:tä. Arduino on myös C:tä muistuttavaa, mutta laajojen omien kirjastojen käytön vuoksi eroaa jonkin verran. Arduinolle voi toki koodata myös C:llä.

Jos sulautetuille ohjelmoinnista ei ole kokemusta, Arduino lienee helpoin lähtökohta, mutta sille ohjelmoidessa ei oikein opi sulautettujen perushommia, eli rekisteriarvojen asetuksia jne. ellei itse todella halua niitä opetella.

Noniin… Idea alkaa hahmottumaan.

Seuraavaksi sinun tulee päättää mitä haluat. Haluatko näytön, millaisen käyttöliitymän, blinkenlichtejä ja maailmaa koskevan kolmion: Hyvä, Halpa, Nopeasti. Valitse noista kaksi.

Hyvä ja nopeasti: Oumannin valmis säädin.
Halpa, nopeasti: Mikrokontrolleri ja stepperi/servo + oma mekaniikka. kovakoodattuna reikälevylle.
Halpa ja hyvä: Valmis sähköventtiili ja jokin valmis mikrokontrollerilankku, esim olimexin AVR128-MT.
Hyvä ja halpa: hanki molemmat.

Oma lähestyminen tähän olisi etsiä jokin servoventtiili ja ajaa sitä juurikin tuolla Olimexin lankulla. Laittaisin sen koteloon ja toisin nappulat pihalle. Virtaledi ja lämpötilat näkyville näyttöön.

Ohjaus tapahtuisi jollain valmiilla toimilaitteella. 0-10V ohjauksella. Yksinkertaisimmillaan 10V regulointi, 47 ohmin vastus suojaamaan regulaattoria liialliselta virralta (20mA saadaan maksimiksi) transistori maihin, kollektori elkon plussaan ja - maihin. Konkan jälkeen diodi ja sen jälkeen jännitteen jako (2x 4k7) 0-5 välille ja kontrollerin ADC:lle. Vielä kun laittaisi kondensaattorin napojen väliin vastuksen.

Aivan täyttä 10V ei tuosta saa, koska diodi pudottaa jännitettä, joten se tarvitsee kompensoida. Piirsin samalla ajatukseni 1-wire mittauksesta tarjoamalla sille liittimen. Tuosta puuttuu virran syöttö ja pari muuta pientä juttua. Lisäksi tilan säästämiseksi laitoin ATMega8 kontrollerin kuvaan. Asentoviestin voi joistain saada 0-10V viestillä.

Ja mitä softan puoleen tulee voit alkaa kokeilemaan algoritmejä hyvinkin yksinkertaisella tavalla. Oletan, että sinulla on PC:lle C++ kehitysympärristö ja voit tehdä konsoli ohjelmia. C koodaus on vain sitä, että unohdat luokat ja oliot. tulostus on printf() ja fgets() voi lukea rivin ja sscanf() paloitella sen sitten oikeisiin paikkoihin #include<stdio.h> niin voit alkaa kokeilemaan ensin hello worldia, sitten syötteen lukemista jne. Kaiketi jopa windowsissa onnistuu jokin tämän tyylinen temppu. saato.exe <lampotilat.txt >ohjaus.txt Tuon lampotilan voi luoda vaikka openofficella ja tallentaa CSV:ksi jossa kentät on erotettu välilyönnillä. Samaten ohjauksen datat voi tulostaa samaan muotoon ja piirtää hienoja presentaatioita ja miettiä mikä meni pieleen.

Kun ohjelma on mielestäsi toimiva ja hieno ja kaikkea sellaista, on aika suunnata mikrokontrollerien pariin. AVR-Studio tai muu kehitysympäristö tulille. WinAVR koneeseen ja dokumentaatiota lukemaan http://www.nongnu.org/avr-libc/ Lisäksi tarvitset ohjelmointilaitteen.

Oliko tässä nyt hieman alkuun ajatuksia?

EDIT: Niin ja tuon Olimexin lankun tapauksessa tuo häkkyrä menee vähän peukaloa isommalle reikälevylle ja siitä lähtee viisi johtoa kohti venttiiliä ja tulee maa ja esim 12V syöttö regulaattorille ja nauhakaapeli liittimellä tuonne kehityslautaan. Loppu onkin softaa.

Tätä ominaisuutta tietysti voi puolustaa ja haukkua. Vesikierron veden lämpötilaa säätäessä olisi hyvä että servo jäisi juuri siihen missä se viimeksi on ollut, siis vikatilanteessa. Jos esim. avaa hanat, tulee liian kuumaa → talo hetkessä liian kuuma. Vastaavasti jos oletuspisteen pistää alemmas niin kovilla pakkasilla jumitustilanteessa se vähentää lämpöä ja talo viilenee. No, tuota ominaisuuttahan ei välttämättä tarvitse heti ottaa käyttöön, joten mikään ei siis estä servon käyttöä.

Tavoitteena hyvä (ja halvemi kuin oumannin 800€ maksava). Käytännössä mikä tahansa muutaman kerran päivässä reagoiva systeemi on parempi kuin nykyinen muutaman päivän välein käsinsäätö.

Itsellä verkostossa on siis käytössä jo 3-tie shuntti johon ajattelin välitykset moottorilta / servolta tehdä. Lisäksi käsikäytölle vipu jolla saa esim. laitteen sammuttaessa käsin käännettyä shunttia. Putkimiestä ei viitsisi tämänlaisen oman “harrastuksen aloituksen” takia käskeä, joten mieluusti nykyisellä säädöllä mennään, servoventtiili täytyy siis unohtaa…

Mitä itse laitteen käyttöön tulee, niin putkistosta löytyy jo analogiset mittarit, joten näyttökään itsessään ei ole välttämätön. Mutta blinblinb on kivaa ja laitteen toiminnan tarkkailun helpottamiseksi näyttö, joka ilmoittaa lämpötilat olisi mukava. Ei käytännössä tarvitsisi olla edes omaa näyttöä vaan jokin kommunikointi tietokoneen välilläkin riittää. Lisäksi versio 1:ssä ei tarvitse olla asetusten muuttamista / virtakatkasijaa tai muuta vastaavaa. Kun laite toimii niin se toimii. versio 1.2 tms voi sitten kehittää käyttöliittymää… Uskon että menee liian isoksi projektiksi jos aloitusprojektina suunnittelee paremman laitteen mitä ouman myy…

Jep, selvitti aika hyvin mistä lähdetään. Alan tässä iltojen iloksi väsäilemään tiedostoja ja käyriä ja testailemaan ohjelmapuolta…

Kannattaakos tuota ohjelmapuolta tehdä juuri niin, että se lukee lämpötiloja tiedostosta JA lukee sitten asetusta tiedostosta? Saako tuon DS1820 lukemat tuollaisella piirillä sitten tallentamaan tietonsa tiedostoon josta ne osataan lukea, vai miten homma käytännössä sitten piirillä ja laitteessa toteutetaan? Heitetäänkö arvoja kahvoihin, lasketaan sieltä, luetaan sieltä. Jolloin laitteen sammuttaessa / resetoidessa sen ensimmäiset säädöt tehdään vasta x-ajan kuluttua kun tarvittavaa dataa on saatavilla?


Tuomo

Lähinnä ajattelin, että on helpompi saada järjelliseen tilaan noita laitteita, jos on näkyvissä, mitä dataa tulee ja mitä lähtee. Tosin mikäli tunnet riittäväksi väyläksi esimerkiksi sarjaportin niin miettimään vain sen käyttöä.

Huupsista… Tuli huonosti neuvottua. Eli tekstin tulostaminen ja tiedostosta lukeminen on hyvä, kun tutkii jonkin algoritmin toimintaa PC:n puolella. PC:n pällä voi helposti rääkätä algoritmia aivan luonnottomasti. Algoritmihän kannattaa kirjoittaa sitten yhteen funktioon ja tulostella asioita ennen ja jälkeen funktioon menemisen. Tämä, siksi, että mitä vähemmän on hankalia riippuvuuksia koodissa, sen helpompi se on kopipaisteta sulautetun kehitysympäristöön.

http://www.nongnu.org/avr-libc/user-manual/group__demo__project.html Hello world tyylinen esimerkki puhtaalla AVR:llä.
Kun taas PC:llä hello world on
#include<stdio.h>int main(){printf(“Hello World\n”);return 0;}
Eli lyhyempi kuin tuon ylemmän URLI

Ehkä se arduino vosi olla parempi, ettet heti säikähdä. Sama asia tehtynä arduinolla:
http://arduino.cc/en/Tutorial/Fade

1-wire on sarjaliityntä ja DS1820 juttelee ei nyt ihan helpointa sarjaprotokollaa. Tähän löytää kyllä jonkun kirjaston. Nyt ei tule mieleen mikä ja mistä. Mitähän muuta neuvoin hassusti?

Jos ei ole pakko käyttää Onewire-antureita, niin ei välttämättä niillä kannata lähteä. Analogiset anturit on huomattavasti helpompia käsitellä, mutta Onewire-antureissa tulee sitten etuna, että saadaan useita antureita samaan linjaan. En tosin ole Arduinon Onewire-käsittelyyn tutustunut, mutta Atmelille tarjolla olevat kirjastot ovat ainakin aika kaameita Onewire-antureille.

Ja jos jollain sattuu hyvään Onewire-kirjastoon olemaan linkkiä, se otetaan vastaan. Lämpöantureihin löytyy jo, mutten ole jaksanut edes miettiä DS2406:n jne käyttöä…

Taas on tullut asiaa pohdittua lisää…

Antureiden ei ole missään nimessä pakko olla DS1820, mikä tahansa homman hoitava anturi käy. Itsellä vain ei tietämystä niidenkään suhteen, joten heitin esimerkillä tuon jo tuntemani anturityypin.

C++ koodamisen avulla tullut palautettua koodausta tajuntaan. Vaikka se nyt ei täysin sama olekkaan, saa sillä “koodausajatusmaailman” taas käyntiin.

Lisäksi piirtelin OpenOfficella karkean, simppelin kuvan josta pystyy havainnollistamaan veden lämpötilan suhteen ulkolämpötilaan. Mitään loogista laskukaavaa en ole vielä keksinyt millä pystyisi mistä tahansa ulkolämpötilasta laskemaan tarvittavan veden lämpötilan, mutta mietitään jahka keritään.

Tässä kuvatus:

Tilannehan on siitä jännä, että edes +10 asteen keleillä ei voida lämpöjä laskea alle 40c. Pannuhuoneesta lämpö tuodaan lämpökanaalia pitkin joka ottaa osan energiasta, pattereihin pitää saada kuitenkin huomattavasti lämpeämpää vettä kuin +25 jotta sillä olisi jotain vaikutusta.

Luvut on käytännössä todettu suunnilleen toimiviksi, nämähän ovat talokohtaisia “asetuksia”. Todellisuus sen sitten näyttää kun JOS joskus saa laitteen kiinni ja koneen vaikka loggeriksi ulkolämmöille, veden lämmöille ja sisälämmöille.

Ja ohjelmistokieleksi tulossa melkoisen varmasti käsittääkseni se helpoin, arduino


Tuomo

Kokeilepa ihan piruuttaankin seuraavaa:

[code]#include <stdio.h>

int saatopiiri(int lampotila){

if(lampotila < -25){
return 65;
}
if(lampotila >0){
return 40;
}else{
return -1 * lampotila + 40;
}
}

int main(){

int ulkolampo;

for(ulkolampo= -35;ulkolampo < 30;ulkolampo += 2){
printf(“Ulkona on %d ja putkissa kohisee %d\n”,ulkolampo,
saatopiiri(ulkolampo));
}

}[/code]

Toimii. Enpä hokannut tuota ettei lämpötilojen tietysti tarvitse olla tarkasti tuolla tienoin, vaan sinnepäin ja muutaman asteen heitoilla ei väliä.

Koitin nyt kikkailla käppyröillä…

Mulla on CSV tiedosto jossa on noin vuoden mittaiset varaajan ylä- ja alalämmöt, savukaasut ja ulkolämpötilan mittaukset, mittausvälit 1min - 3min (riippuen mitä asetusta milloinkin ollut).

Koitin nyt saada luettua CSV tiedostoa, onnistuinkin netissä olleiden ohjeiden mukaan mutta taito loppui kesken kun yritin kääntää homman niin että koodi näyttäisi / tallettaisi VAIN ulkolämpötilan arvon.

Tällaisen koodinpätkän löysin ja siitä koitin miettiä / kehittää…

#include <iostream>
#include <sstream>
#include <fstream>
#include <vector>
#include <string>

using namespace std;

int main ()
{
    ifstream inFile ("laitoin tähän tiedostonimen");
    string line;
    int linenum = 0;
    while (getline (inFile, line))
    {
        linenum++;
        cout << "\nLine #" << linenum << ":" << endl;
        istringstream linestream(line);
        string item;
        int itemnum = 0;
        while (getline (linestream, item, ','))
        {
            itemnum++;
            cout << "Item #" << itemnum << ": " << item << endl;
        }
    }

    return 0;
}

tuo koodi toimi mainiosti. Koitin oman osaamisen / ajatusmaailman rajoissa muokata rivejä niin, että vain neljäs arvo luetaan CSV tiedostosta, mutta eipä siitä mitään tullut. Ideana tässä siis ottaa CSV tiedostosta olleet lämpötilat ja sen mukaan piirrellä käyrät sekä lämmöistä että patterilämmöistä. Ei varsinaisesti pakollinen, saisin saman tehtyä OpenOfficella, mutta ajattelin ettei koodausharjoitus ainakaan pahitteeksi ole.
Ajattelin myös että koska minulla on nyt jo olemassaoleva lämpötilanmittaus, voisin tehdä mittauskoneelle komentoriviohjelman joka päivittäisi itseään esim. 5min välein ja kertoisi mikä olisi hyvä lämpötila patteriverkoston vedelle. Voin siinä sitten pannuhuoneessa käydessä katsoa koneen ruudusta ja putkiston analogisesta mittarista pitääkö asia paikkansa. “Manuaalista, haitatonta testausta”. Saattaa kuulostaa hullulta, mutta kun käytännössä tyhjältä pohjalta aletaan tällaista projektia vääntämään, en uskalla heti ottaa riskiä että laitteet ja koodit ohjailee lämmitystä…


Tuomo

No tuosta ei sitten tarvitsekaan kuin pulauttaa se säätävälle eläimelle. joka laskee hanan uuden asennon. Tai sitten sulla on vain tyhmää liimalogiikkaa, joka tottelee mittausten perässä PC:tä.

Noinhan se lähtee liikkeelle. Ihan vain huvin vuoksi tuossa joskus naksuttelin tuollaista turhaa tilastotietoa tuottavaa roskaa. Ehkä siitä saa jotain käsitystä johonkin. http://vuokko.nukku.net/maailman_kovin_lottokone.tar.gz

Hittolainen…

Luulin eilen vastanneeni tähän, mutta ilmeisesti on sitten jäänyt vastaamatta…

Tein eilen koodinpätkän, ja uskoisin että ymmärrän jokaisen rivin siitä:

#include <iostream>
#include <fstream>
#include <windows.h>

float lampo;
int kerta = 0;

using namespace std;

int main ()
{
    do
    {
fstream File("1B000801D55DD010.txt",ios::in);
static float lampo; //tästä en ole varma pitääkö tämä olla, koska tuo lampo on jo ylempänäkin "alustettu"
File.seekg(-7,ios::end); 
File >> lampo;
File.close();
kerta++;
system("cls");
cout << "Lampotilan laskentakerta: " << kerta << endl;

cout << "Ulkolampotilan ollessa " << lampo << " astetta" << endl;

if(lampo < -25.00)
{
       cout << "Patteriverkoston vesi olisi hyva olla 65 (lampo <-25c)" << endl;
}
if(lampo > 0.00)
{
       cout << "Patteriverkoston vesi olisi hyva olla 40 (lampo >0c)" << endl;
}
else
{
       cout << "Patteriverkoston vesi olisi hyva olla " << -1 * lampo + 40 << " astetta" << endl;
}
cout << "Odota, taukoa 5min. Voit pystayttaa scriptin painamalla CTRL + C " << endl;
Sleep(300000);

}

while (lampo != 99);
system("pause");
return 0;
}

Tuon laitoin pannuhuoneessa olevalle kannettavalle, jossa pyörii LogTemp. Aamulla softa oli edelleen päällä, muistinkäyttö 1396kt.

Nyt itsellä tuon suhteen muutama ongelma johon voisin ottaa vinkkejä vastaan…
Ongelma 1:
Kohdassa File.seekg(-7,ios::end); hypätään tiedoston loppuun ja luetaan lopusta alkuunpäin x-määrä merkkejä. No, mittaustulokset on tämännäköisiä:
04.02.2011; 21:58:29;0.00
04.02.2011; 22:01:38;0.00
04.02.2011; 22:04:48;0.06
04.02.2011; 22:07:57;0.06

En oikein päässyt jyvälle tuosta miksi -7 toimii, kun asteita on esim -1.00. Tuossahan on lopusta päin 5 merkkiä jotka luetaan. Miksi -7? Netistä jostain löysin lauseen jossa perusteltiin että tiedoston loppuminen vie heti yhden merkin, no se olisi sitten 6, mutta ei vieläkään 7. Voisiko joku valaista?

Lisäksi kun nyt mittaan tuolla -7 arvolla, niin kaikki toimii mainiosti kunnes mennään tämän tyylisiin arvoihin:
30.01.2011; 19:27:55;-10.81
30.01.2011; 19:31:00;-10.75
30.01.2011; 19:34:04;-10.63
30.01.2011; 19:37:14;-10.25

Koodi kun lukee vain x-määrän merkkejä lopustapäin, kun merkkien määrä lisääntyykin niin koodi kaatuu pepulleen…

Millä saisin tuon viimisen arvon lukemisen onnistumaan tuosta ; merkistä taaksepäin, riippumatta kuinka suuri luku siellä takana on, ja onko positiivinen vai negatiivinen?

Ongelma 2:
Kun Ongelma 1 saan jotenkin ratkaistua, voisi kehitellä koodinpätkän joka ottaa viimeiset arvot, esimerkiksi viideltä viimeiseltä riviltä ja tallentaa ne eri muuttujiin. Tämän jälkeen uskoisin osaavani lisätä ne tuonne looppiin, laskea keskiarvot ja käyttää keskiarvoa lämpötilan laskemisessa.

Ongelma 3:
Millä saan ääkköset näkymään?

Mielipidekysymys:
Olisiko tuo Lämpötilan laskentakerta järkevämpää / muistia vähemmän kuluttavampaa tallettaa tiedostoon ja lukea sieltä. Jolloin itse ohjelma ei käsittääkseni kasva ja ajan myötä hörppää enempää muistia?

Saatan poistella tästä ongelmakohtia mikäli löydän itse niihin vastausta, ennenkuin niihin vastataan…

Jos joku haluaa testailla koodinpätkää tai jotain muuta, niin tuo tiedosto josta lämmöt otan on ladattavissa täältä.


Tuomo

Hetken meni miettiessä miten tää C++ toimikaan. Mutta joo.
Ainakin tuo sinun lampo on kahteen kertaan määritelty. ensin globaaliksi ja sitten staattiseksi tuolla do…while loopissa.

http://www.cplusplus.com/reference/iostream/istream/seekg/
kertoo, että tulisi käyttää ios_base::end

Ja mitäs sanoisin tuohon ongelmaa. mene ensin vaikka seekg(-30,ios_base::end); ja sitten getline(jonnekin turhaan jonka dumppaat.) ja seuraava getline antaa sinulle oikean rivin. Voit käyttää myös getlinen leikkausmerkkinä ; jolloin saat sen lämpötilan lopuksi luettua.

Niin joo ja vastaus oli se, että alkuperäisessä lukutilanteessa et voinut tietää kuinka pitkälti tarvitsi lukea.

Eikös se onnistu jotenkin niin, että ensin getlinetät alun pois ja sitten muutuja<<virta?

Jaa-a harvemmin konsolissa tulee suomeksi koodattua juuri tuon takia ja sitten QT osaa tehdä temput oikein.

Nyt putosin kärryiltä. Tiedosto avataan, luetaan lopusta datat, suljetaan tiedosto, lasketaan keskiarvot, ohjaukset jne.

Tarvitset ne viisi muuttujaa joihin lasket ne datat sisään. ja muistia ei varata dynaamisesti, jolloin tuon ei pitäisi paisua.

Ja jälleen projektikoodauspäivitystä…

Tein tänään hieman rukauksia koodiin jolla beta-testailen…

Koodin on vielä ns. pitkässä muodossa… Lausekkeilla saa sitä reilusti lyhennettyä, mutta näin alottelijana oli helpompi lähteä tästä…

Nyt siis virhetilanteiden vähentämiseksi koodi nappaa itselleen ensin 5min välein mittaustuloksen. Viiden mittauksen (eli 25min) jälkeen laskee keskiarvon mittauksista ja keskiarvon perusteella ilmoittaa patteriveden lämpötilan. Tästä eteenpäin jokaisen mittauksen jälkeen (eli siis 5min välein) lasketaan viiden edellisen mittauksen keskiarvo ja tämän mukaan suositellaan patteriveden lämpötilaan.

Uskoisin että tämäntyylinen koodi alkaisi vaikuttamaan jo melkoisen hyvältä itse laitteessakin. Tietysti lyhennettynä ja oikealla kielellä koodattuna. Koodissa edelleen ongelmana se, ettei ymmärrä jos siirrytään -9.99 asteesta enempiin pakkaslukemiin…

Tänään en ehdi, mutta teen koodiin vielä muutamat rivit, jotka tallentaa mittaukset, lasketun keskiarvon ja lasketun patteriveden tiedostoon sekä yritän pähkäillä tuon maagisen -10 asteen rajan kuntoon…

Nyt kun mielestäni koodi alkaa olla oikeanlainen (lähes), niin mitä seuraavaksi? Arduino alusta ja muutama piiri tilaukseen? Koekytkentälevy + läjä komponentteja kaveriksi? Onko ohjelmaa arduinolle johon voisin koittaa alkaa kirjoittamaan vastaavaa koodia arduinon kielellä ja debuggaamaan sekä testaamaan sitä itse ohjelmassa?

Tässä vielä nykyhetkessä pörräävä koodinpätkä:

#include <iostream>
#include <fstream>
#include <windows.h>

float lampo1;
float lampo2;
float lampo3;
float lampo4;
float lampo5;
float yhteen;
float keskiarvo;
float quit;

int kerta = 0;

using namespace std;

int main ()
{
// Ekat mittaukset niin, että tulee 5 mittausta ennen keskiarvon laskentaa
// Tämä siksi, että olisi virhemahdollisuus pienempi. Laiteen resetin jälkeen otetaan
// 5 mittausta, vasta tämän jälkeen toimitaan. Jos toimittaisiin heti ensimmäisen mittauksen 
// jälkeen ja tulos olisikin "virhemittaus" voisi lämpötilat olla huuhaata.

// Eka kerta
fstream File("1B000801D55DD010.txt",ios::in);
File.seekg(-7,ios::end); 
File >> lampo1;
kerta++;
system("cls");
cout << "Lampotilan laskentakerta: " << kerta << "/5 ennen keskiarvoa" << endl;
cout << "Ulkolampotila " << lampo1 << " astetta. Keskiarvoa ei viela laskettu." << endl;
cout << "Voit pysayttaa scriptin milloin tahansa painamalla CTRL + C." << endl;
Sleep(300000);

// Toka kerta
File.seekg(-7,ios::end); 
File >> lampo2;
kerta++;
system("cls");
cout << "Lampotilan laskentakerta: " << kerta << "/5 ennen keskiarvoa" << endl;
cout << "Ulkolampotila " << lampo2 << " astetta. Keskiarvoa ei viela laskettu." << endl;
cout << "Voit pysayttaa scriptin milloin tahansa painamalla CTRL + C." << endl;
Sleep(300000);

// Kolmas kerta
File.seekg(-7,ios::end); 
File >> lampo3;
kerta++;
system("cls");
cout << "Lampotilan laskentakerta: " << kerta << "/5 ennen keskiarvoa" << endl;
cout << "Ulkolampotila " << lampo3 << " astetta. Keskiarvoa ei viela laskettu." << endl;
cout << "Voit pysayttaa scriptin milloin tahansa painamalla CTRL + C." << endl;
Sleep(300000);

// Neljäs kerta
File.seekg(-7,ios::end); 
File >> lampo4;
kerta++;
system("cls");
cout << "Lampotilan laskentakerta: " << kerta << "/5 ennen keskiarvoa" << endl;
cout << "Ulkolampotila " << lampo4 << " astetta. Keskiarvoa ei viela laskettu." << endl;
cout << "Voit pysayttaa scriptin milloin tahansa painamalla CTRL + C." << endl;
Sleep(300000);

//Viides kerta
File.seekg(-7,ios::end); 
File >> lampo5;
kerta++;

//Lasketaan keskiavro
yhteen = lampo1+lampo2+lampo3+lampo4+lampo5;
keskiarvo = yhteen/5;

system("cls");
cout << "Lampotilan laskentakerta: " << kerta << endl;
cout << "Ulkolampotila " << lampo5 << " astetta. Keskiarvoa " << keskiarvo << "astetta" << endl;
if(keskiarvo < -25.00)
    {
           cout << "Patteriverkoston vesi olisi hyva olla 65 (lampo <-25c)" << endl;
    }
    if(keskiarvo > 0.00)
    {
           cout << "Patteriverkoston vesi olisi hyva olla 40 (lampo >0c)" << endl;
    }
    else
    {
           cout << "Patteriverkoston vesi olisi hyva olla " << -1 * keskiarvo + 40 << " astetta" << endl;
    }
    cout << "Patteriverkon lampotila laskettu viiden edellisen mittauksen keskiarvolla." << endl;
    cout << "Odota, taukoa 5min. Voit pystayttaa scriptin painamalla CTRL + C " << endl;

Sleep(300000);
    do
    {

cout << "Lampotilan laskentakerta: " << kerta << endl;

// Eka kerta
fstream File("1B000801D55DD010.txt",ios::in);
File.seekg(-7,ios::end); 
File >> lampo1;
kerta++;
system("cls");
//Lasketaan keskiavro
yhteen = lampo1+lampo2+lampo3+lampo4+lampo5;
keskiarvo = yhteen/5;

cout << "Lampotilan laskentakerta: " << kerta << endl;
cout << "Ulkolampotila " << lampo1 << " astetta. Keskiarvoa " << keskiarvo << "astetta" << endl;
if(keskiarvo < -25.00)
    {
           cout << "Patteriverkoston vesi olisi hyva olla 65 (lampo <-25c)" << endl;
    }
    if(keskiarvo > 0.00)
    {
           cout << "Patteriverkoston vesi olisi hyva olla 40 (lampo >0c)" << endl;
    }
    else
    {
           cout << "Patteriverkoston vesi olisi hyva olla " << -1 * keskiarvo + 40 << " astetta" << endl;
    }
    cout << "Patteriverkon lampotila laskettu viiden edellisen mittauksen keskiarvolla." << endl;
    cout << "Odota, taukoa 5min. Voit pystayttaa scriptin painamalla CTRL + C " << endl;
Sleep(300000);

// Toka kerta
File.seekg(-7,ios::end); 
File >> lampo2;
kerta++;
system("cls");
//Lasketaan keskiavro
yhteen = lampo1+lampo2+lampo3+lampo4+lampo5;
keskiarvo = yhteen/5;

cout << "Lampotilan laskentakerta: " << kerta << endl;
cout << "Ulkolampotila " << lampo2 << " astetta. Keskiarvoa " << keskiarvo << "astetta" << endl;
if(keskiarvo < -25.00)
    {
           cout << "Patteriverkoston vesi olisi hyva olla 65 (lampo <-25c)" << endl;
    }
    if(keskiarvo > 0.00)
    {
           cout << "Patteriverkoston vesi olisi hyva olla 40 (lampo >0c)" << endl;
    }
    else
    {
           cout << "Patteriverkoston vesi olisi hyva olla " << -1 * keskiarvo + 40 << " astetta" << endl;
    }
    cout << "Patteriverkon lampotila laskettu viiden edellisen mittauksen keskiarvolla." << endl;
    cout << "Odota, taukoa 5min. Voit pystayttaa scriptin painamalla CTRL + C " << endl;
Sleep(300000);

// Kolmas kerta
File.seekg(-7,ios::end); 
File >> lampo3;
kerta++;
system("cls");
//Lasketaan keskiavro
yhteen = lampo1+lampo2+lampo3+lampo4+lampo5;
keskiarvo = yhteen/5;

cout << "Lampotilan laskentakerta: " << kerta << endl;
cout << "Ulkolampotila " << lampo3 << " astetta. Keskiarvoa " << keskiarvo << "astetta" << endl;
if(keskiarvo < -25.00)
    {
           cout << "Patteriverkoston vesi olisi hyva olla 65 (lampo <-25c)" << endl;
    }
    if(keskiarvo > 0.00)
    {
           cout << "Patteriverkoston vesi olisi hyva olla 40 (lampo >0c)" << endl;
    }
    else
    {
           cout << "Patteriverkoston vesi olisi hyva olla " << -1 * keskiarvo + 40 << " astetta" << endl;
    }
    cout << "Patteriverkon lampotila laskettu viiden edellisen mittauksen keskiarvolla." << endl;
    cout << "Odota, taukoa 5min. Voit pystayttaa scriptin painamalla CTRL + C " << endl;
Sleep(300000);

// Neljäs kerta
File.seekg(-7,ios::end); 
File >> lampo4;
kerta++;
system("cls");
//Lasketaan keskiavro
yhteen = lampo1+lampo2+lampo3+lampo4+lampo5;
keskiarvo = yhteen/5;

cout << "Lampotilan laskentakerta: " << kerta << endl;
cout << "Ulkolampotila " << lampo4 << " astetta. Keskiarvoa " << keskiarvo << "astetta" << endl;
if(keskiarvo < -25.00)
    {
           cout << "Patteriverkoston vesi olisi hyva olla 65 (lampo <-25c)" << endl;
    }
    if(keskiarvo > 0.00)
    {
           cout << "Patteriverkoston vesi olisi hyva olla 40 (lampo >0c)" << endl;
    }
    else
    {
           cout << "Patteriverkoston vesi olisi hyva olla " << -1 * keskiarvo + 40 << " astetta" << endl;
    }
    cout << "Patteriverkon lampotila laskettu viiden edellisen mittauksen keskiarvolla." << endl;
    cout << "Odota, taukoa 5min. Voit pystayttaa scriptin painamalla CTRL + C " << endl;
Sleep(300000);

//Viides kerta
File.seekg(-7,ios::end); 
File >> lampo5;
File.close();
kerta++;
system("cls");
//Lasketaan keskiavro
yhteen = lampo1+lampo2+lampo3+lampo4+lampo5;
keskiarvo = yhteen/5;

cout << "Lampotilan laskentakerta: " << kerta << endl;
cout << "Ulkolampotila " << lampo5 << " astetta. Keskiarvoa " << keskiarvo << "astetta" << endl;
if(keskiarvo < -25.00)
    {
           cout << "Patteriverkoston vesi olisi hyva olla 65 (lampo <-25c)" << endl;
    }
    if(keskiarvo > 0.00)
    {
           cout << "Patteriverkoston vesi olisi hyva olla 40 (lampo >0c)" << endl;
    }
    else
    {
           cout << "Patteriverkoston vesi olisi hyva olla " << -1 * keskiarvo + 40 << " astetta" << endl;
    }
    cout << "Patteriverkon lampotila laskettu viiden edellisen mittauksen keskiarvolla." << endl;
    cout << "Odota, taukoa 5min. Voit pystayttaa scriptin painamalla CTRL + C " << endl;

Sleep(300000);
}

while (quit != 99);
system("pause");
return 0;
}

EDIT:
Lisätään nyt selvennykseksi, että seuraavaksi ei tosiaankaan tarvitse vielä lähteä koko laitetta kasaamaan. Seuraavaksi voi tehdä vaikka “ledinvilkutus” tai “releen napsutus” ohjelmointeja, jotta pääsee itse ohjelmointiin käsiksi.

Lähinnä nyt siis ideana se, että mitä tavaraa kannattaa tilata? Onko tämä projekti nyt helpompi toteuttaa / projektia kehittää AVR pohjalla vai arduinolla? AVR ilmeisesti vaikeampi, mutta löytyykö siihen ohjeita / oppaita että sen kanssa tulisi toimeen?

Olen käsittänyt ettei näihin piireihin ja ohjelmointipalikoihin nyt sentään satasia uppoa, rakentelu ja ohjelmointi ei ole vain tätä projektia varten eli laajalla skaalalla ajateltuna: Millä kannattaisi aloitella / Mikä kannattaisi opetella?


Tuomo

Pistetääs tämän kehitys hetkeksi tauolle.

Nyt tutkiskelen hetken arduinoalustoja, alustavaa pohjatutkimusta.

Tilaukseen menee melkoisen varmasti Adruino Uno ja Arduinon “aloituspaketti” niin saa johtimia ja peruskomponentteja, sitten alkaa se ledin välkytys yms.


Tuomo