Datalogning af temperatur

PID regulator, styringer og programmer.
Brugeravatar
admin
Site Admin
Indlæg: 4754
Tilmeldt: 4. dec 2005, 16:25
Geografisk sted: 7080 Børkop

Re: Datalogning af temperatur

Indlæg af admin »

Nimbus39 skrev:Ufedt, men SPI bussen kan tilsyneladende ikke håndtere både min SD-kortlæser og mit (ældre ENC20J60) Ethernet modul.
Der kommer en konflikt når de skal dele MOSI pin på pin 11, så enten skal jeg undvære SD-kortet eller også Ethernet modulet.
Datalogningen virker ellers 100% og uden Ethernet modulet ser koden således ud:

Den er lige nu sat op til at holde øje med minuttallet (men det kan hurtigt ændres) og hver gang det skifter skriver den til sd-kortet.
Den laver en linje i en tekstfil, hvor den skriver "Antal gange føler er aktiveret" (blop i gærrør), Temperaturen på de 2 sensorer, samt dato og klokkeslæt - herefter nulstiller den sammentællingen af blop i gærrøret og begynder at tælle igen.

Nu vil jeg prøve med nogle andre dimser, da jeg har flere RTC'er og et selvstændigt EthernetShield skulle jeg nok kunne finde en løsning.
Kan du ikke bare gemme data på nettet :-) ved https://cosm.com" onclick="window.open(this.href);return false; det har jeg da tænkt mig at gøre - så kan man se temp. data på mobilen.
Mvh.
Jens
Øl og sol er livet....

http://www.fribryg.dk" onclick="window.open(this.href);return false;
http://www.facebook.dk/fribryg" onclick="window.open(this.href);return false;
Brugeravatar
Munkholm
Indlæg: 231
Tilmeldt: 11. feb 2013, 17:13
Geografisk sted: Staby

Re: Datalogning af temperatur

Indlæg af Munkholm »

Nimbus39 skrev:
Munkholm skrev:ebay 2stk for 26kr. incl fragt! :)
'New DS1302 Real Time Clock Module PCB Board For AVR ARM PIC With Battery CR203'
Vær opmærksom på at (så vidt jeg ved) så er DS1302 digital, og kræver digitale input pins, og dem har man ikke for mange af i forvejen.
DS1307 kører på de analoge pins som man ikke bruger til ret meget, man kan selvfølgelig lave de analoge om til digitale pins...
Jeg regner med at det bliver min mega der skal bruges til 'bryg/gær-overvågnings-maskine-2013' :) Den har jeg en touch lcd til, så kan man lave et 'liret' setup! :)
Mvh Jesper

"Virkeligheden er en illusion: forårsaget af mangel på alkohol"
Brugeravatar
Nimbus39
Indlæg: 3392
Tilmeldt: 27. jun 2010, 10:52
Geografisk sted: Greve (Mosede Strand)
Kontakt:

Re: Datalogning af temperatur

Indlæg af Nimbus39 »

Vil lige dele min foreløbige princip skitse for min datalogger:
PrincipSkitseDataloggerStyring.jpg
PrincipSkitseDataloggerStyring.jpg (173.23 KiB) Vist 14871 gange
Jeg har inkluderet muligheden for at aktivere/de-aktivere ethernet og relæerne, da jeg ikke har ethernet der hvor jeg har mit køleskab til undergæring og ikke har køleskab der hvor jeg (normalt) overgærer mine ales.
Det er ikke en "Tænd/sluk" for modulerne, men en parameter som koden kan aflæse og reagere på.
Er endnu ikke helt sikker på om indstillingerne af de 2 kontakter skal aflæses under setup eller i selve programløkken, jeg tror det bliver i selve programløkken for så kan man tænde og slukke for dem efter behov uden at skulle genstarte loggeren.
Jeg har eksperimenteret med Cosm.com til datalogningen men har lidt bøvl med at få forbindelsen til at holde over tid, den kører fint når jeg starter op men efter nogle timer dør forbindelsen - jeg tror det måske er tid til en ny router :-)
Buy a man a beer and he wastes an hour. Teach a man to brew and he wastes a lifetime.
http://bryggeri.landly.dk
http://www.facebook.com/bryggerilandly
http://beersmithrecipes.com/listrecipes/2810/nimbus39
Gajol
Indlæg: 440
Tilmeldt: 16. aug 2011, 23:06
Geografisk sted: Grenaa

Re: Datalogning af temperatur

Indlæg af Gajol »

Nimbus39 skrev: Jeg har eksperimenteret med Cosm.com til datalogningen men har lidt bøvl med at få forbindelsen til at holde over tid, den kører fint når jeg starter op men efter nogle timer dør forbindelsen - jeg tror det måske er tid til en ny router :-)
Ser godt ud :)

når du bruger Cosm.com så husk og lukke din firbindelse når du har sendt din data. har set flere eksepmler på at der bliver åben en forbindelse og sendt data men den bliver ikke lukket igen, når der så skal sendes igen åber man en ny og den bliver heller ikke lukket hvilket gør at man tilsidst har så meget åben at din router ikke kan holde styr på det(lyder til du har en gammel)
Kan tyde på det er der problemet ligger at du åbner for meget men ikke lukker det igen og over belaster din router

/Kim & Co
Brugeravatar
admin
Site Admin
Indlæg: 4754
Tilmeldt: 4. dec 2005, 16:25
Geografisk sted: 7080 Børkop

Sv: Datalogning af temperatur

Indlæg af admin »

Sender den ikke igennem samme port flere gange ? Ellers syntes jeg godt nok det lyder mærkeligt at det skulle være tilfældet med andet ?

Sendt fra min HTC One S med Tapatalk2
Mvh.
Jens
Øl og sol er livet....

http://www.fribryg.dk" onclick="window.open(this.href);return false;
http://www.facebook.dk/fribryg" onclick="window.open(this.href);return false;
Brugeravatar
admin
Site Admin
Indlæg: 4754
Tilmeldt: 4. dec 2005, 16:25
Geografisk sted: 7080 Børkop

Sv: Datalogning af temperatur

Indlæg af admin »

Nimbus du skal købe en repeater i Aldi det har jeg gjort :-)

Sendt fra min HTC One S med Tapatalk2
Mvh.
Jens
Øl og sol er livet....

http://www.fribryg.dk" onclick="window.open(this.href);return false;
http://www.facebook.dk/fribryg" onclick="window.open(this.href);return false;
Brugeravatar
mgades
Indlæg: 144
Tilmeldt: 16. sep 2012, 09:51
Geografisk sted: 6230 Rødekro
Kontakt:

Datalogning af temperatur

Indlæg af mgades »

admin skrev:Sender den ikke igennem samme port flere gange ? Ellers syntes jeg godt nok det lyder mærkeligt at det skulle være tilfældet med andet ?
Njah, du åbner en ny socket; destinationsporten er den samme, source porten er ny (0-64k). NAT tabellen i din router kan sagtens blive "fyldt op" med etablerede TCP sessioner.
--
Morten Gade Sørensen
RDWHAHB
http://beer.gadecs.com
Brugeravatar
Nimbus39
Indlæg: 3392
Tilmeldt: 27. jun 2010, 10:52
Geografisk sted: Greve (Mosede Strand)
Kontakt:

Re: Sv: Datalogning af temperatur

Indlæg af Nimbus39 »

admin skrev:Nimbus du skal købe en repeater i Aldi det har jeg gjort :-)

Sendt fra min HTC One S med Tapatalk2
øhh.... til hvad?

Jeg har et AP som også kan bruges som "klient" og dermed give mig et RJ-45 stik, er det det du tænker på?
Buy a man a beer and he wastes an hour. Teach a man to brew and he wastes a lifetime.
http://bryggeri.landly.dk
http://www.facebook.com/bryggerilandly
http://beersmithrecipes.com/listrecipes/2810/nimbus39
Brugeravatar
admin
Site Admin
Indlæg: 4754
Tilmeldt: 4. dec 2005, 16:25
Geografisk sted: 7080 Børkop

Sv: Datalogning af temperatur

Indlæg af admin »

Ja repeateren i Aldi kan brugs fra trådløs til rj45 så den kan komme på nettet langt fra dit trådløse

Sendt fra min HTC One S med Tapatalk2
Mvh.
Jens
Øl og sol er livet....

http://www.fribryg.dk" onclick="window.open(this.href);return false;
http://www.facebook.dk/fribryg" onclick="window.open(this.href);return false;
Brugeravatar
Nimbus39
Indlæg: 3392
Tilmeldt: 27. jun 2010, 10:52
Geografisk sted: Greve (Mosede Strand)
Kontakt:

Re: Datalogning af temperatur

Indlæg af Nimbus39 »

Så ser det ud til at jeg har et program der fungerer.
Jeg kan nu styre max temp, min temp, pause mellem skift af varme/kulde, mindste tid en kulde/varme kilde skal være tændt.
Derudover kan jeg logføre:
3 temperatur målepunkter (kan nemt udvides til flere), Tidspunkt der er tændt/slukket for hhv varme og kulde, antal bobler i en S-gærlås.
Det er pt baseret på brug af en Arduino Mega 2560, men jeg har fået klemt det så langt ned i størrelse at det burde kunne køre på en UNO.
Det kræver dog man lige ændrer nogle indstillinger for PIN tilslutningerne, og kontakten til at aktivere/deaktivere relæ styringen er ikke implementeret endnu, men det er ganske få linjer kode der mangler.
Kredsløbet ser sådan ud: (LED'erne vender måske forkert på tegningen)
DataLoggerMega_bb.png
DataLoggerMega_bb.png (470.75 KiB) Vist 14772 gange
Og her er koden: (bemærk at den pt. er sat op til at logføre hvert minut - dette overvejer at ændre til hver time)

Kode: Vælg alt

//biblioteker
#include <DS1307RTC.h>
#include <Time.h>
#include <OneWire.h>
#include <Wire.h>
#include <DallasTemperature.h>
#include <DS1302.h>
#include <SD.h>
#include <LiquidCrystal_I2C.h>
#include <stdlib.h>

//Opstart af boards mm

// Dallas
// Data wire is plugged into port 10 on the Arduino
#define ONE_WIRE_BUS 5
#define TEMPERATURE_PRECISION 9

//SD kort
//CS on Pin 10
const int chipSelect = 53;

// LCD 1602
// set the LCD address to 0x27 for a 16 chars and 2 line display
LiquidCrystal_I2C lcd(0x27,16,2);  

//Definer variabler
tmElements_t tm;
boolean SourceOn, OnAllowed, OffAllowed;
float OldHour, OldMin, BlopCount, LastTemp; 
int i, On, Off;
// the pin that the photogate is attached to
const int  PhotoPin = A0; 
// counter for the number of Blops
int BlopCounter = 0;
// current state of the button
int PhotoState = 0; 
// previous state of the button
int lastPhotoState = 0;     
// Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
OneWire oneWire(ONE_WIRE_BUS);
// Pass our oneWire reference to Dallas Temperature. 
DallasTemperature sensors(&oneWire);
//datafil instans
File dataFile; // Systemet benytter 2 filer: Datalog.txt (temperatur og bobler) og Timelog.txt (Kilder tænd/sluk tidspunkter)

//Parametre
//Her skrives de forskellige parametre styringen skal bruge, grader angives i hele grader resten i minutter.
const float TempMax=35;    //Øvre grænse for temperatur i gærtank. Angives i grader C.
const float TempMin=27;    //Nedre grænse for temperatur i gærtank. Angives i grader C.
const float Hysterese=1;    //Styres af Off og OffAllowed, angiver hvor lang tid en kilde minimum skal være tændt før den må slukkes. Angives i minutter.
const float VentTempSkift=2;  //Styres af On og OnAllowed, angiver hvor lang tid der minimum skal gå fra en kilde slukkes til der må tændes for en kilde. Angives i minutter.
// Relæ og heartbeat udgange.
int Cool = 33;
int Heat = 31;
int Beat = 35;

  
void setup (void)
{
  tmElements_t TimeTest;
  //Reset relæer, og nulstil flag
  SourceOn = false;
  OnAllowed = true;
  OffAllowed = false;
  pinMode(Cool, OUTPUT);
  pinMode(Heat, OUTPUT);
  pinMode(Beat, OUTPUT);
  digitalWrite(Cool, LOW);
  digitalWrite(Heat, LOW);
  digitalWrite(Beat, LOW);
  // initialize the lcd
  lcd.init();                       
  lcd.backlight();  
  // start serial port
  Serial.begin(9600);
  // initialize the Photogate pin as a input:
  pinMode(PhotoPin, INPUT);
  //
  if (RTC.read(TimeTest)) 
  {
    lcd.setCursor(0,0);
    lcd.print("RTC OK");
  }
  else 
  {
    if (RTC.chipPresent()) 
    {
      lcd.clear();
      lcd.print("RTC stoppet");
      delay(2000);
     } 
     else 
     {
      lcd.clear();
      lcd.print("RTC read error!");
      delay(2000);
     }
  }
  lcd.setCursor(7,0);
  // Start up the Dallas library
  sensors.begin();
  lcd.print("Sensor OK");
  lcd.setCursor(0,1);
  // Initialize SD-card
  pinMode(53, OUTPUT);     //  53 on a mega, 4 on a UNO
  if (!SD.begin(chipSelect)) {
    lcd.print("SD-kort fejl!");
    delay(2000);
    // don't do anything more:
    return;
  }
  lcd.print("Card OK");
  delay(2000);
  // Print parametre til lcd
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("Max:");
  lcd.print(TempMax);
  lcd.setCursor(8,0);
  lcd.print("Min:");
  lcd.print(TempMin);
  lcd.setCursor(0,1);
  lcd.print("Hyst:");
  lcd.print(Hysterese);
  lcd.setCursor(8,1);
  lcd.print("Vent:");
  lcd.print(VentTempSkift);
  delay(1500);
  lcd.clear();
  SkrivDisplay();
}
//funktioner
boolean TempStyring() // tænder og slukker for varme og kulde
{
  float CurrTemp;
  if (RTC.read(tm)) // hvis ikke RTC kan læses returneres false
  {
    CurrTemp = sensors.getTempCByIndex(0); // Hent temperatur fra gærspand, 0 er den første sensor på bussen - skal sættes til korrekt index!
    LastTemp = CurrTemp; 
    if (CurrTemp >= TempMax && !SourceOn && OnAllowed) //temp over max og intet er tændt: Tænd kulde
    {
      digitalWrite(Cool, HIGH);
      digitalWrite(Heat, LOW);
      SourceOn = true;
      OffAllowed = false;
      Off = 0;
      On = 0;
      SkrivTid("Cold On;");
    }
    if (CurrTemp <= TempMin && !SourceOn && OnAllowed) // temp under min og intet er tændt: Tænd varme
    {
      digitalWrite(Heat, HIGH);
      digitalWrite(Cool, LOW);
      SourceOn = true;
      OffAllowed = false;
      Off = 0;
      On = 0;
      SkrivTid("Heat On;");
    }
    if (CurrTemp <= TempMax && CurrTemp >= TempMin && OffAllowed) // temp over min og temp under max: Sluk alt!
    {
      digitalWrite(Heat, LOW);
      digitalWrite(Cool, LOW);
      SourceOn = false;
      OnAllowed = false;
      On = 0;
      Off = 0;
      SkrivTid("Source Off;");
    }
  }
  else
  {
    return false;
  }

}

boolean TimeSkift () //undersøger om timetal er ændret
{
    //Set new time variables
    if (RTC.read(tm))
    {
      if ( OldHour != tm.Hour)
      { // hvis Time ændres
        OldHour= tm.Hour;
        // Returner TRUE
        return true;
      }
      else
      { // Hvis dato ikke ændres
        //Returner FALSE
        return false;
      }
    }
}
boolean MinutSkift () //undersøger om Minuttal er ændret
{
    //Set new time variables
    if (RTC.read(tm))
    {
      if ( OldMin != tm.Minute)
      { // hvis Minut ændres
        OldMin= tm.Minute;
        // Returner TRUE
        return true;
      }
      else
      { // Hvis dato ikke ændres
        //Returner FALSE
        return false;
      }
    }
}
boolean SkrivTid(String Tekst)
{
  dataFile = SD.open("tidlog.txt", FILE_WRITE);
  if (dataFile && RTC.read(tm)) {
  dataFile.print(Tekst);
     if (tm.Hour >= 0 && tm.Hour < 10)
   { 
    dataFile.print("0");
    dataFile.print(tm.Hour);
   }
   else
   {
     dataFile.print(tm.Hour);
   }
   dataFile.print(":");
   if (tm.Minute >= 0 && tm.Minute < 10)
   { 
    dataFile.print("0");
    dataFile.print(tm.Minute);
   }
   else
   {
     dataFile.print(tm.Minute);
   }
   dataFile.print(";");
   dataFile.print(tm.Day);
   dataFile.print(':');
   dataFile.println(tm.Month);
   dataFile.close();
  }  
  // if the file isn't open, pop up an error:
  else 
  {
    lcd.clear();
    lcd.print("error tidlog.txt");
    delay(2000);
  }
}
boolean SkrivLog ()
{
  tmElements_t tm;
  RTC.read(tm);
  sensors.requestTemperatures(); // Hent temperaturer fra alle DS18B20
  //lav navn på logfil
  
  float FilData[4];
  sensors.requestTemperatures(); // Send the command to get temperatures
  for (i=0; i<=2; i++)
  {
    FilData[i]= sensors.getTempCByIndex(i);
  }
  //læg blob count i float array FilData på plads 3
  FilData[3] = BlopCounter;
  dataFile = SD.open("datalog.txt", FILE_WRITE);
  // if the file is available, write to it:
  if (dataFile && RTC.read(tm)) {
    for (i=0; i<=3; i++)
  {
    dataFile.print(FilData[i]);
    dataFile.print(";");
  }
   if (tm.Hour >= 0 && tm.Hour < 10)
   { 
    dataFile.print("0");
    dataFile.print(tm.Hour);
   }
   else
   {
     dataFile.print(tm.Hour);
   }
   dataFile.print(":");
   if (tm.Minute >= 0 && tm.Minute < 10)
   { 
    dataFile.print("0");
    dataFile.print(tm.Minute);
   }
   else
   {
     dataFile.print(tm.Minute);
   }
   dataFile.print(";");
   dataFile.print(tm.Day);
   dataFile.print(':');
   dataFile.println(tm.Month);
   dataFile.close();
  }  
  // if the file isn't open, pop up an error:
  else 
  {
    lcd.clear();
    lcd.print("error datalog.txt");
  }
}

boolean SkrivDisplay()
{
  lcd.clear();
  lcd.print("Blops: ");
  lcd.print(BlopCounter);
  lcd.setCursor(11,0);
  lcd.print("On ");
  lcd.print(On);
  lcd.setCursor(10,1);
  lcd.print("Off ");
  lcd.print(Off);
  lcd.setCursor(6,1);
  lcd.print("S ");
  lcd.print(SourceOn);
  lcd.setCursor(0,1);
  lcd.print(LastTemp);
}
//Hovedløkke
void loop()
{
  digitalWrite(Beat, HIGH);

  if (MinutSkift()) // Hvis Minuttal er skiftet skal time undersøges, og temp skal undersøges.
  {
    TempStyring();
    SkrivLog();
    BlopCounter= 0;
    if (SourceOn)
    {
      Off++;
    }
    else
    {
      On++;
    }
    if (TimeSkift()) // hvis timetal skifter skal dato undersøges, temp logføres sammen med antal bobler
    {
      //Serial.println("I Time loekke");
    }
    SkrivDisplay(); //opdater display
  }
  // undersøg om kilder må slukkes eller tændes
      if (Off >=Hysterese && SourceOn) // Hvis det er længere end Hysterese siden der sidst blev tændt for en kilde er det tilladt at slukke en kilde
    {
      OffAllowed = true;
    }
    else
    {
      OffAllowed = false;
    }
    if (On >=VentTempSkift && !SourceOn) // Hvis det er længere end VentTempSkift siden der sidst blev slukket for en kilde er det tilladt at tænde en kilde
    {
      OnAllowed = true;
    }
    else
    {
      OnAllowed = false;
    }
  // Tæl Bobler
  // read the Photogate input pin:
  PhotoState = digitalRead(PhotoPin);
    // compare the Photogate State to its previous state
  if (PhotoState != lastPhotoState) 
  {
    // if the state has changed, increment the counter
    if (PhotoState == HIGH) 
    {
      // if the current state is HIGH then the button went from off to on:
      BlopCounter++;
      SkrivDisplay();
    } 
   }
  // save the current state as the last state, for next time through the loop
  lastPhotoState = PhotoState;
  digitalWrite(Beat, LOW);
  delay(10);
}
Buy a man a beer and he wastes an hour. Teach a man to brew and he wastes a lifetime.
http://bryggeri.landly.dk
http://www.facebook.com/bryggerilandly
http://beersmithrecipes.com/listrecipes/2810/nimbus39
Brugeravatar
MonkeyBrew
Indlæg: 4420
Tilmeldt: 26. okt 2006, 22:13
Geografisk sted: 8670 Låsby

Re: Datalogning af temperatur

Indlæg af MonkeyBrew »

Hold da op hvor et arbejde! Programmering er serberkroatisk for mig. Det har da taget tid at skrive den kode.
Monkeybrew - Abegodt øl!

~ Lars Bang Rasmussen ~

http://www.monkeybrew.dk" onclick="window.open(this.href);return false;

Mæsketemperature for stilarterne:

http://haandbrygforum.dk/viewtopic.php? ... ure#p85351" onclick="window.open(this.href);return false;
Brugeravatar
Nimbus39
Indlæg: 3392
Tilmeldt: 27. jun 2010, 10:52
Geografisk sted: Greve (Mosede Strand)
Kontakt:

Re: Datalogning af temperatur

Indlæg af Nimbus39 »

MonkeyBrew skrev:Hold da op hvor et arbejde! Programmering er serbokroatisk for mig. Det har da taget tid at skrive den kode.
Tjah, som gammel kodenørd (der nu er blevet "forretningskonsulent") er der noget dejligt afslappende ved at kode :-)
Det der har taget længst tid har været at få koden til at opføre sig korrekt, i starten kunne jeg ikke få den til at skrive mere end 1 temp i filen, og så løb jeg tør for RAM på den UNO det lå på, så fandt jeg ud af at det ur jeg brugte vandt vildt meget tid, osv osv... så udfordringerne har været mange men sikke en fed fornemmelse når man får dem løst en efter en.
Jeg er ikke helt færdig med koden endnu, der er lige nogle finpudsninger der skal laves og så tror jeg at jeg vælger at gå tilbage til at bruge en UNO da den er mindre (kan nemmere være i kabinettet)
Endelig skal jeg så have det hele monteret i et kabinet med stik og kabler til de eksterne følere, er også lidt usikker på de små relæer der sidder på mit relæmodul - men jeg har 2 SSR liggende...

Så der er et godt stykke vej endnu, men det er sjovt at lave :-)
Buy a man a beer and he wastes an hour. Teach a man to brew and he wastes a lifetime.
http://bryggeri.landly.dk
http://www.facebook.com/bryggerilandly
http://beersmithrecipes.com/listrecipes/2810/nimbus39
Brugeravatar
MonkeyBrew
Indlæg: 4420
Tilmeldt: 26. okt 2006, 22:13
Geografisk sted: 8670 Låsby

Re: Datalogning af temperatur

Indlæg af MonkeyBrew »

Det er sgu cool. Glæder mig til at se hvordan det skrider frem mod målet. Tillykke med delmålet indtil videre. ;)
En ting er at lave en kode, en anden er at fejlfinde i den. Tror hellere jeg får svorger til at hjælpe mig der, hvis jeg når så langt. :)
Monkeybrew - Abegodt øl!

~ Lars Bang Rasmussen ~

http://www.monkeybrew.dk" onclick="window.open(this.href);return false;

Mæsketemperature for stilarterne:

http://haandbrygforum.dk/viewtopic.php? ... ure#p85351" onclick="window.open(this.href);return false;
Brugeravatar
Nimbus39
Indlæg: 3392
Tilmeldt: 27. jun 2010, 10:52
Geografisk sted: Greve (Mosede Strand)
Kontakt:

Re: Datalogning af temperatur

Indlæg af Nimbus39 »

En lille update på projektet.
Jeg har nu samlet alle stumperne i den indkøbte indbygningskasse.
Det var noget af et puslespil, men alle stumperne er monteret og der er ikke just meget plads:
Moduler uden ledninger i kassen
Moduler uden ledninger i kassen
20140105_182542.jpg (373.64 KiB) Vist 14655 gange
Det har været noget af et arbejde at lodde alle ledningerne på de forskellige komponenter. Jeg valgte at bruge headers til forbindelserne til arduinoen, da den sidder "i låget" og derfor vil det være nemmere at skille den ad når/hvis der skal laves ændringer:
Masser af lodninger, og kun et par der var kolde!
Masser af lodninger, og kun et par der var kolde!
20140106_203819.jpg (378.86 KiB) Vist 14655 gange
Efter at have fejlfundet på den fik jeg den til at virke (der var 2 ledninger der var byttet om)
Første &quot;power up&quot;
Første "power up"
20140106_223605.jpg (390.08 KiB) Vist 14655 gange
Der er 5 dioder og 2 kontakter på fronten.
Den ene kontakt er til at aktivere og deaktivere temp. styringen - denne kontakt aflæses af softwaren.
Den anden kontakt er til at tænde og slukke for lyset i displayet og er loddet direkte på LCD modulet da det var nemmest.
Der er dioder der viser:
"Varme tændt" (rød)
"Kulde tændt" (blå)
"Heartbeat" (grøn)
De 2 dioder på kontakterne er ikke i brug lige nu med den version af softwaren der er lagt i arduinoen, men jeg tror de kommer til at vise om temp. styring er aktiv og temperaturalarm for relæerne.
I displayet udlæser jeg lige pt. Antal bobler siden sidste skrivning til SD kort. Seneste registrerede temperatur i gærspand. Antal minutter siden der sidst blev slukket for en kilde (On) og antal minutter siden der sidst blev tændt for en kilde (Off).
S1 indikerer at temp. styring er aktiv hvis den er slukket står der S0 - det er dette jeg overvejer at flytte til en af dioderne på kontakterne.

Jeg har lavet nogle ændringer ifht. min seneste plan. Jeg har monteret temperatur målere på de 2 relæer for at kunne overvåge om de bliver for varme, dermed måler jeg nu 4 temperaturer: Køle relæ, varme relæ, temperatur udenfor spand og temperatur i spanden. Derudover er dioderne på kontakterne ikke længere "hard wired" til kontakterne men styres af softwaren da det giver flere udviklingsmuligheder.

Desværre gik min skæreklinge til min Fein i stykker så jeg måtte skære hullerne med en stiksav hvilket bestemt ikke er mit foretrukne værktøj til så små huller, men det kom da til at virke omend ikke helt lige...

Nu skal jeg så have finpudset softwaren og da jeg skal brygge i weekenden ser det ud til at den snart får premiere (dog kun logningsdelen da det er en overgæret der skal laves) hvis de sidste stumper når frem, da jeg mangler et printkort til min photogate.
Jeg planlægger at lave en ny software hvor den kan indlæse en gæringsprofil fra SD-kortet så jeg kan gære i køleskabet ved skiftende temperaturer igennem hele gæringsforløbet. f.eks. 5 dage ved 9 grader + 5 dage ved 11 grader efterfulgt af en nedkøling osv.
Buy a man a beer and he wastes an hour. Teach a man to brew and he wastes a lifetime.
http://bryggeri.landly.dk
http://www.facebook.com/bryggerilandly
http://beersmithrecipes.com/listrecipes/2810/nimbus39
Brugeravatar
Nimbus39
Indlæg: 3392
Tilmeldt: 27. jun 2010, 10:52
Geografisk sted: Greve (Mosede Strand)
Kontakt:

Re: Datalogning af temperatur

Indlæg af Nimbus39 »

Så blev min datalogger og styringsenhed færdig nok til en BETA-test (version 0.9)
Jeg fandt på at sætte en lille blæser i den så den kunne køle relæerne:
En MEGET lille blæser
En MEGET lille blæser
20140117_185819.jpg (353.72 KiB) Vist 14612 gange
Da den ikke kunne trækkes direkte fra en udgang på Arduinoen blev jeg nødt til at bruge en transistor der så styrer et direkte flow af 5V til blæseren. Blæseren er monteret ved relæerne og cirkulerer kun luften i kassen, den suger/puster ikke luften ud af kassen da loggeren også skal bruges udendørs og jeg ikke ønsker alt for meget gennemstrømning af evt. fugtig luft i kassen. Kassen er af alu og leder derfor varmen godt, men kan de ikke køles nok ned må jeg nok bore et par huller i kassen og lukke den varme luft ud.

Der er 2 temperaturfølere som skal logge temperaturer under gæringen, en der kan sættes ned i øllet og en der sidder på ledningen som blot måler temperaturen udenfor spanden. Den der sænkes ned i øllet har jeg købt færdiglavet i Kina, men har efterfølgende trukket noget silikoneslange over den da jeg ikke er helt sikker på at det krympflex og ledning den bliver leveret med er "foodgrade"
Den temperaturføler der sidder på ledningen er trukket over med noget (rødt) krympflex, og alle lodninger er overtrukket med krympflex for at undgå kortslutninger.
Sensorerne til temperatur og bobler
Sensorerne til temperatur og bobler
20140117_185937.jpg (364.63 KiB) Vist 14612 gange
Jeg besluttede mig for at købe et færdigt printkort til montering af sensoren der registrerer bobler, da jeg fandt dem til kun 7,- i en dansk butik (Porto kostede mere end de stumper jeg bestilte)
Den monteres på en S-gærlås (vist tidligere: http://haandbrygforum.dk/viewtopic.php? ... =15#p53678" onclick="window.open(this.href);return false;) og registrerer når der sker ændringer i lysstrålen.
Den logfører temperaturen på alle 4 følere så jeg kan følge med i hvor varme relæerne bliver, jeg har 2 SSR med heatsinks som jeg kan bruge i stedet hvis de små relæer bliver for varme.
Som den er sat op nu skriver den data hvert minut, men jeg tror det er for mange målepunkter, så den bliver nok sat op til at logføre data hver time. Det er skrevet ind i koden men den del er kommenteret ud lige nu. Udover de 4 temperaturer tæller den også bobler pr. time og dette tal skrives til loggen sammen med temperaturerne.
Den bruger 2 filer en til temperaturer/bobler og en til tænd/sluk-tidspunkter for varme og kulde.
'Der er 5 parametre man kan justere:
  • Hvor længe en kilde minimum skal være tændt.
  • Hvor længe der går fra en kilde slukkes til en kilde må tændes.
  • Hvor varme relæerne må blive.
  • Max. temperatur på øllet under gæringen.
  • Min. temperatur på øllet under gæringen.
Jeg har en lille krølle på koden som jeg lige skal have løst, idet den ikke kommer ud af "Alarm" løkken når et relæ bliver for varmt. Det er som om den ikke læser temperaturen på relæet og reagerer på den. Men det forventer jeg ikke bliver noget stort problem at fikse.
Her er min kode som den ser ud lige nu:
(EDIT 18/01/14: Ny kode postet der ikke har den omtalte fejl, og samtidig bruger mindre plads i Arduinoen)

Kode: Vælg alt

//biblioteker
#include <DS1307RTC.h>
#include <Time.h>
#include <OneWire.h>
#include <Wire.h>
#include <DallasTemperature.h>
#include <SD.h>
#include <LiquidCrystal_I2C.h>

//Opstart af boards mm

// Dallas
// Data wire is plugged into port 5 Pause the Arduino
#define ONE_WIRE_BUS 5
#define TEMPERATURE_PRECISION 9
//SD kort
//CS on Pin 4
const int chipSelect = 4;

// LCD 1602
// set the LCD address to 0x27 for a 20 chars and 4 line display
LiquidCrystal_I2C lcd(0x27,20,4);  

//Definer variabler
tmElements_t tm;
boolean SourceOn, OnAllowed, OffAllowed, HeatOn, CoolOn, HeatAlarm, CoolAlarm, RelayAlarm, BlowerOn;
boolean ControlState = false;
float OldHour, OldMin, BlopCount, LastTemp; 
int i, Pause, SOT;
// Blæser pin
const int BlowerPin = 1;
// the pin that the photogate is attached to
const int  PhotoPin = A0; 
// counter for the number of Blops
int BlopCounter = 0;
// current state of the buttPause
int PhotoState = 0; 
// previous state of the buttPause
int lastPhotoState = 0;     
// Setup a OneWire  instance to communicate with any OneWire  devices (not just Maxim/Dallas temperature ICs)
OneWire oneWire(ONE_WIRE_BUS);
// Pass our OneWire  reference to Dallas Temperature. 
DallasTemperature sensors(&oneWire);
//datafil instans
File dataFile; // Systemet benytter 2 filer: Datalog.txt (temperatur og bobler) og Timelog.txt (Kilder tænd/sluk tidspunkter)
// Relætemperatur variabler
float CoolRelayTemp, HeatRelayTemp;

//Parametre
//Her skrives de forskellige parametre styringen skal bruge, grader angives i hele grader C resten i minutter.
const float TempMax=35;    //Øvre grænse for temperatur i gærtank. Angives i grader C.
const float TempMin=27;    //Nedre grænse for temperatur i gærtank. Angives i grader C.
const float SourceOnTimeLimit=3;    //Styres af SOT og OffAllowed, angiver hvor lang tid en kilde minimum skal være tændt før den må slukkes. Angives i minutter.
const float VentTempSkift=10;  //Styres af Pause og OnAllowed, angiver hvor lang tid der minimum skal gå fra en kilde slukkes til der må tændes for en kilde. Angives i minutter.
const float RelayAlarmTemp=40;  //Maksimal temperatur et relæ må opnå før alarmen udløses og BEGGE relæer slukkes.
// Relæ og LED udgange.
int Cool = 7;  //Blå diode
int Heat = 6;  //Rød diode
int Beat = 8;  //Grøn diode 
int Styr = 3;  //diode på kPausetakt til relæstyring
int Alarm = 2; //diode på lyskPausetakt til display
char Control = A2;  //bruges til kPausetakt der angiver om relæ styring skal bruges.
  
void setup (void)
{
  tmElements_t TimeTest;
  //Reset relæer, og nulstil flag
  SourceOn = false;
  OnAllowed = true;
  OffAllowed = false;
  CoolOn = false;
  HeatOn = false;
  BlowerOn = false;
  CoolAlarm = false; // Sæt alarm status til false for kølingrelæ
  HeatAlarm = false; // Sæt alarm status til false for varmerelæ
  RelayAlarm = false;
  pinMode(Cool, OUTPUT);
  pinMode(Heat, OUTPUT);
  pinMode(Beat, OUTPUT);
  pinMode(Styr, OUTPUT);
  pinMode(Alarm, OUTPUT);
  pinMode(BlowerPin, OUTPUT);
  pinMode(Control, INPUT);
  digitalWrite(Cool, LOW);
  digitalWrite(Heat, LOW);
  digitalWrite(Beat, LOW);
  digitalWrite(Styr, LOW);
  digitalWrite(Alarm, LOW);
  digitalWrite(BlowerPin, HIGH); // Blæser er slukket når PIN er HIGH
  // initialize the lcd
  lcd.init();                       
  lcd.backlight();  
  // initialize the Photogate pin as a input:
  pinMode(PhotoPin, INPUT);
  //
  if (RTC.read(TimeTest)) 
  {
    lcd.setCursor(0,0);
    lcd.print("RTC OK");
  }
  else 
  {
    if (RTC.chipPresent()) 
    {
      lcd.clear();
      lcd.print("RTC stoppet");
      delay(2000);
     } 
     else 
     {
      lcd.clear();
      lcd.print("RTC read error!");
      delay(2000);
     }
  }
  lcd.setCursor(7,0);
  // Start up the Dallas library
  sensors.begin();
  lcd.print("Sensor OK");
  lcd.setCursor(0,1);
  // Initialize SD-card
  pinMode(4, OUTPUT);     //  53 Pause a mega, 4 Pause a UNO
  if (!SD.begin(chipSelect)) {
    lcd.print("SD-kort fejl!");
    delay(2000);
    // dPause't do anything more:
    return;
  }
  lcd.print("Card OK");
  delay(2000);
  // Print parametre til lcd
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print(TempMin, 0);
  lcd.print(">T<");
  lcd.print(TempMax, 0);
  lcd.setCursor(8,0);
  lcd.print("Alarm:");
  lcd.print(RelayAlarmTemp);
  lcd.setCursor(0,1);
  lcd.print("SOT:");
  lcd.print(SourceOnTimeLimit, 0);
  lcd.setCursor(8,1);
  lcd.print("Vent:");
  lcd.print(VentTempSkift, 0);
  delay(5000);
  lcd.clear();
  SkrivDisplay();
  CoolRelayTemp = sensors.getTempCByIndex(1); // Henter temp på Cool relæ
  HeatRelayTemp = sensors.getTempCByIndex(3); // Henter temp på Heat relæ
}
//funktiPauseer
boolean RelayTemp()  // Overvåger temperaturen på relæerne
{
  CoolRelayTemp = sensors.getTempCByIndex(1); // Henter temp på Cool relæ
  HeatRelayTemp = sensors.getTempCByIndex(3); // Henter temp på Heat relæ
  if (CoolRelayTemp >= RelayAlarmTemp || HeatRelayTemp >= RelayAlarmTemp) // Hvis der er en alarm
  {
    RelayAlarm = true;
    SkrivTid("Relay Alarm;");
    digitalWrite(Cool, LOW);//sluk for køling
    digitalWrite(Heat, LOW);//Sluk for varme
    digitalWrite(Alarm, HIGH); // Tænd alarm diode
    // Sæt globale variabler
    SourceOn = false; 
    OffAllowed = true;
    OnAllowed = false;
    Pause = 0;
    SOT = 0;
    
    if (CoolRelayTemp >= RelayAlarmTemp) // Køle relæ er overophedet 
    {
      CoolAlarm = true; // Sæt global alarm
    }
    
    if (HeatRelayTemp >= RelayAlarmTemp) // Varme relæ er overophedet 
    {
      HeatAlarm = true; // Sæt global alarm
    }
    return false;
  }
 else // Hvis der ikke er en alarm
 {
   CoolAlarm = false; // Sæt alarm status til false for kølingrelæ
   HeatAlarm = false; // Sæt alarm status til false for varmerelæ
   RelayAlarm = false;
   digitalWrite(Alarm, LOW); // Sluk alarmdiode
   SkrivTid("Relay Alarm OK;");
   return true;
 }
}
boolean TempStyring() // tænder og slukker for varme og kulde
{
  float CurrTemp;
  if (RTC.read(tm)) // hvis ikke RTC kan læses returneres false
  {
    CurrTemp = sensors.getTempCByIndex(0); // Hent temperatur fra gærspand, 0 er den første sensor på bussen - skal sættes til korrekt index!
    if (CurrTemp >= TempMax && !SourceOn && OnAllowed) //temp over max og intet er tændt: Tænd kulde
    {
      digitalWrite(Cool, HIGH);
      digitalWrite(Heat, LOW);
      SourceOn = true;
      OffAllowed = false;
      SOT = 0;
      Pause = 0;
      SkrivTid("Cold Pause;");
      CoolOn = true;
    }
    if (CurrTemp <= TempMin && !SourceOn && OnAllowed) // temp under min og intet er tændt: Tænd varme
    {
      digitalWrite(Heat, HIGH);
      digitalWrite(Cool, LOW);
      SourceOn = true;
      OffAllowed = false;
      SOT = 0;
      Pause = 0;
      SkrivTid("Heat Pause;");
      HeatOn = true;
    }
     if (CurrTemp < TempMax && CurrTemp > TempMin && OffAllowed) // temp er over min og under max: Sluk alt!
    {
      digitalWrite(Heat, LOW);
      digitalWrite(Cool, LOW);
      SourceOn = false;
      OnAllowed = false;
      Pause = 0;
      SOT = 0;
      SkrivTid("Source SOT;");
      CoolOn = false;
      HeatOn = false;
    }
  }
  else
  {
    return false;
  }

}

boolean TimeSkift () //undersøger om timetal er ændret
{
    //Set new time variables
    if (RTC.read(tm))
    {
      if ( OldHour != tm.Hour)
      { // hvis Time ændres
        OldHour= tm.Hour;
        // Returner TRUE
        return true;
      }
      else
      { // Hvis time ikke ændres
        //Returner FALSE
        return false;
      }
    }
}
boolean MinutSkift () //undersøger om Minuttal er ændret
{
    //Set new time variables
    if (RTC.read(tm))
    {
      if ( OldMin != tm.Minute)
      { // hvis Minut ændres
        OldMin= tm.Minute;
        // Returner TRUE
        return true;
      }
      else
      { // Hvis dato ikke ændres
        //Returner FALSE
        return false;
      }
    }
}
boolean SkrivTid(String Tekst)
{
  dataFile = SD.open("tidlog.txt", FILE_WRITE);
  if (dataFile && RTC.read(tm)) {
  dataFile.print(Tekst);
  dataFile.print(';');
    // skriv dato og klokkeslæt til fil i formatet yyyy-mm-dd;hh:mm, passer med excel datoformat
  dataFile.print(tmYearToCalendar(tm.Year));
  dataFile.print('-');
  dataFile.print(tm.Month);
  dataFile.print('-');
  dataFile.print(tm.Day);
  dataFile.print(";");
   if (tm.Hour >= 0 && tm.Hour < 10) //skriv klokkeslæt i fil
   { 
    dataFile.print("0");
    dataFile.print(tm.Hour);
   }
   else
   {
     dataFile.print(tm.Hour);
   }
   dataFile.print(":");
   if (tm.Minute >= 0 && tm.Minute < 10)
   { 
    dataFile.print("0");
    dataFile.println(tm.Minute);
   }
   else
   {
     dataFile.println(tm.Minute);
   }
   dataFile.close();
  }  
  // if the file isn't open, pop up an error:
  else 
  {
    lcd.clear();
    lcd.print("error tidlog.txt");
    delay(2000);
  }
}
boolean SkrivLog ()
{
  tmElements_t tm; 
  RTC.read(tm);// hent nyeste tid
  sensors.requestTemperatures(); // Hent temperaturer fra alle DS18B20
  LastTemp = sensors.getTempCByIndex(0);
  float FilData[5];  //array der indeholder de data der skal skrives til datafilen, værdi er antal sensorer plus en ekstra til bobler-værdien.
  sensors.requestTemperatures(); // Send the command to get temperatures
  for (i=0; i<=3; i++) //gennemløb array med data, og læg temperaturer i det. værdi er antal sensorer minus en.
  {
    FilData[i]= sensors.getTempCByIndex(i);
    // Data skrives i denne rækkefølge: Internal, CoolRelay, External, HeatRelay
  }
  //læg blob count i float array FilData på plads 4, skal rettes hvis der er flere/færre end 4 DS18B20
  FilData[4] = BlopCounter; //brug den sidste plads i array til bobler værdien.
  dataFile = SD.open("datalog.txt", FILE_WRITE);
  // if the file is available, write to it:
  if (dataFile && RTC.read(tm)) {
    for (i=0; i<=4; i++) //gennemløb array med data, og skriv data i filen. Værdi er antal DS18B20, sidste værdi der skrives er BlopCounter.
  {
    dataFile.print(FilData[i]);
    dataFile.print(";");
  }
  // skriv dato og klokkeslæt til fil i formatet yyyy-mm-dd;hh:mm, passer med excel datoformat
  dataFile.print(tmYearToCalendar(tm.Year));
  dataFile.print('-');
  dataFile.print(tm.Month);
  dataFile.print('-');
  dataFile.print(tm.Day);
  dataFile.print(";");
  
   if (tm.Hour >= 0 && tm.Hour < 10) //skriv klokkeslæt i fil
   { 
    dataFile.print("0");
    dataFile.print(tm.Hour);
   }
   else
   {
     dataFile.print(tm.Hour);
   }
   dataFile.print(":");
   if (tm.Minute >= 0 && tm.Minute < 10)
   { 
    dataFile.print("0");
    dataFile.println(tm.Minute);
   }
   else
   {
     dataFile.println(tm.Minute);
   }
   dataFile.close();
  }  
  // if the file isn't open, pop up an error:
  else 
  {
    lcd.clear();
    lcd.print("error datalog.txt");
  }
  BlopCounter= 0;  //Nulstil "Blop" tælleren
}

boolean SkrivDisplay()
{
  lcd.clear();
  lcd.print("B:");
  lcd.print(BlopCounter);
  if (BlowerOn)
  {
    lcd.setCursor(15,0);
    lcd.print("*");
  }
  if (ControlState)  //skriver kun hvis TempStyring er aktiveret.
  {
    if (HeatAlarm) // Hvis er er Heatalarm
    {
      lcd.setCursor(0,1);
      lcd.print("Heat-relay ALARM");
    }
    if (CoolAlarm) // Hvis der er en Coolalarm
    {
      lcd.setCursor(0,1);
      lcd.print("Cool-relay ALARM");
    }
    if (!RelayAlarm) // Hvis der ikke er en alarm
    {
      lcd.setCursor(7,1);
      lcd.print("P:");
      lcd.print(Pause);
      lcd.setCursor(12,1);
      lcd.print("A:");
      lcd.print(SOT);
      lcd.setCursor(0,1);
      lcd.print("T:");
      lcd.print(LastTemp, 1);
    }
    if (CoolOn || CoolAlarm)
    {
      lcd.setCursor(7,0);
      lcd.print("CR:");
      lcd.print(CoolRelayTemp, 1);
    }
    if (HeatOn || HeatAlarm)
    {
      lcd.setCursor(7,0);
      lcd.print("HR:");
      lcd.print(HeatRelayTemp, 1);
    }
   }
   else // Hvis styring er deaktiveret skrives temperaturen
   {
     lcd.setCursor(0,1);
     lcd.print("T:");
     lcd.print(LastTemp, 1); 
   }

}
//Hovedløkke
void loop()
{
  digitalWrite(Beat, HIGH);  //tænder grøn diode på frPauset der angiver programmet kører.
  if (analogRead(Control) >=1000)
  {
    ControlState = true;  // TempStyring er aktiv.
    digitalWrite(Styr, HIGH);
  }
  else
  {
    ControlState = false;  //TempStyrng er inaktiv, sluk for evt. kilder der er tændt.
    digitalWrite(Heat, LOW);
    digitalWrite(Cool, LOW);
    digitalWrite(Styr, LOW);
    CoolOn = false;
    HeatOn = false;
    SourceOn = false;
    Pause = VentTempSkift;
  }
  if (MinutSkift()) // Hvis Minuttal er skiftet skal time undersøges, og temp skal undersøges.
  {
    if (!RelayAlarm) // Hvis der ikke er en alarm
    {
      if (SourceOn) // Hvis der er en kilde tændt
      {
        SOT++; // SourceOnTime - tæller tiden en kilde har været tændt 1 op.
        Pause = 0; // Pause nulstilles da der ikke er nogen kilder tændt
      }
      else // Hvis ikke der er en kilde tændt
      {
        Pause++; // Pause - Tæller pausen mellem tændt og slukket 1 op.
        SOT = 0; // SourceOnTimeLimit må ikke tælle op så længe der ikke er tændt for noget.
      }
    }
    if (ControlState) // hvis styring er aktiv
    {
      if (!RelayAlarm) // hvis ikke der er en alarm på relæ temperaturer
      {
        TempStyring();
      }
    }
    if (RelayAlarm || SourceOn && ControlState) //Hvis der er en alarm eller der er tændt for en kilde skal blæser tændes
      {
          digitalWrite(BlowerPin, LOW); // Blæser er tændt når PIN er LOW
          BlowerOn = true;
      }
      else
      {
          digitalWrite(BlowerPin, HIGH); // Blæser er slukket når PIN er HIGH
          BlowerOn = false;
      }
    SkrivLog();  // står dette kald her skriver den log hvert minut

    if (TimeSkift()) // hvis timetal skifter skal temp logføres sammen med antal bobler
    {
      //SkrivLog();  // står dette kald her skriver den log hvert time.
    }
    SkrivDisplay(); //opdater display
  }
  // undersøg om kilder må slukkes eller tændes hvis der ikke er en alarm
  if (!RelayAlarm)
  {
    if (SOT >=SourceOnTimeLimit && SourceOn) // Hvis det er længere end SourceOnTimeLimit siden der sidst blev tændt for en kilde er det tilladt at slukke en kilde
    {
      OffAllowed = true;
    }
    else
    {
      OffAllowed = false;
    }
    if (Pause >=VentTempSkift && !SourceOn) // Hvis det er længere end VentTempSkift siden der sidst blev slukket for en kilde er det tilladt at tænde en kilde
    {
      OnAllowed = true;
    }
    else
    {
      OnAllowed = false;
    }
  }
  else // Hvis der er en alarm
  {
    OffAllowed = true;
    digitalWrite(Cool, LOW);//sluk for køling
    digitalWrite(Heat, LOW);//Sluk for varme
    digitalWrite(Alarm, HIGH); // Tænd alarm diode
  }
  // Tæl Bobler
  // read the Photogate input pin:
  PhotoState = digitalRead(PhotoPin);
    // compare the Photogate State to its previous state
  if (PhotoState != lastPhotoState) 
  {
    // if the state has changed, increment the counter
    if (PhotoState == HIGH) 
    {
      // if the current state is HIGH then the buttPause went from SOT to Pause:
      BlopCounter++;
      SkrivDisplay();
    } 
   }
  // save the current state as the last state, for next time through the loop
  lastPhotoState = PhotoState;
  digitalWrite(Beat, LOW);  //slukker grøn diode på frPauseten der angiver at program kører
  delay(10);
}
Liste over stumper kan laves hvis nogen ønsker det, jeg burde have alle priser osv. men som det ser ud lige nu ligger den omkring 300,- for det hele.
Buy a man a beer and he wastes an hour. Teach a man to brew and he wastes a lifetime.
http://bryggeri.landly.dk
http://www.facebook.com/bryggerilandly
http://beersmithrecipes.com/listrecipes/2810/nimbus39
Besvar

Tilbage til "Microprocessor styring til ølbrygning"