Om oss

Denne siden omhandler bryggerlauget Svarstad Ølbryggerlaug, SØL for short. Her vil vi publisere litt info om bryggingen, bilder og video.

Arduino temperaturlogger - del 1


Etter inspirasjon fra en tråd i Norbryggs forum bestemte jeg meg for å forsøke å lage en Arduino-basert temperaturlogger.  En takk til Erlend H. på Norbrygg-forumet for php-kilder og selve ideen.

Da jeg ikke hadde noen av «ingrediensene» for å lage en slik logger, ei heller noen kunnskap om lodding, måtte en del deler og utstyr kjøpes inn. Jeg har laget en liste over det jeg har brukt, hvor det kan kjøpes og hva det koster. En del kan sikkert kjøpes billigere dersom man leter litt, men dette er nå i hvert fall hva jeg endte opp med (dollarpriser er ganget opp med 6):

Deler
1 x Arduino UNO m/USB-kabel ($15.20 = 91,2 kr)
1 x Ethernet shield ($13.99 = 83,94 kr)
1 x Breadboard 170 tie points ($1.25 = 7,5 kr)
1 x Breadboard jumpers ($2.2 = 13,2 kr)
Diverse motstander ($4.70 = 28,2 kr)
3 x DS18B20 temperatursensor ($1.40 = 8,4 kr)
3 x 3.5mm male stereo jack (19 kr)
3 x 3.5mm male to dual female plug ($0.99 = 5,94 kr)
2 x LED ($0.99 = 5,94 kr)
1 x Ethernet kabel ($0.99 = 5,94 kr)
Krympestrømper (39,9 kr)
Elektrikertape (19 kr)

Sum deler: 419,84 

Utstyr
Loddestasjon (599 kr)
Loddetinn 0.6 mm (129 kr)
Varmluftspistol (129 kr)
Div. tenger (99 kr)
Avisoleringstang (39,90 kr)
Loddelisse (22,90 kr)
Loddestativ (46,90 kr)

Sum utstyr: 1065,70

Sum total: 1438,6

Oppkobling Arduino

Jeg går ikke igjennom installasjon av Arduino og hvordan denne fungerer, se heller http://www.arduino.cc/ for dette. Koble opp Arduino, breadboard, LEDs, prober osv. som forklart her:


En 1 kOhm motstand er koblet mellom signal (digital pin 8) og anoden til rød LED. Katoden er koblet til GROUND. Videre er hvit LED koblet til digital pin 13 og GROUND. Til slutt er det female jack connectoren som er koblet til GROUND, digital pin 3 og 5V, der 5V og signal er koblet sammen over en 4,7 kOhm motstand.

Når det gjelder female jack connector (og male jack connector på probene), koblet jeg slik:

3.5 mm female jack connector

3.5 mm male jack connector

Når alt er tilkoblet slik det skal, må du finne ut MAC-adressen på probene du bruker. Det kan være greit å bruke denne sketchen som utgangspunkt, og deretter endre til korrekte verdien i sketchen jeg har laget. I tillegg må serverinfo og sti til PHP-script korrigeres. 

Last opp PHP-scriptet post.php på serveren din (krever en database med 5 felt: id (int, primær, autoincrement), Dato (datetime), Beer (double), Skap (double), Ute (double)):

<?
//  Denne PHP-fila forventer en forespørsel som dette:
//  domene.net/beer/post.php?beer=8.5&skap=9.2&ute=21.5
//  Siden responderer med OK hvis skrivingen gikk greit, alt annet returnerer siste linje i databasen med klokkeslett og øltemperatur

//login endres etter behov
$server = "<server>";
$username = "<username>";
$password = "<password>";
$database = "<db navn>";
$table = "<tabellnavn>";

$connection = mysql_connect($server, $username, $password) or die(mysql_error()); 
mysql_select_db($database) or die(mysql_error()); 

// gjør data klar til skriving
$date = date("Y-m-d H:i:s"); // lagrer web-serverens tid/dato til en lokal variabel
$beer = $_GET['beer'];
$skap = $_GET['skap'];
$ute = $_GET['ute'];

// Her skal det inn kode som sjekker at verdiene som er kommet er 'gyldige' tall

 if($beer && $skap && $ute ) // skriv kun til datatbase hvis alle temperaturene er her
{
mysql_query('INSERT into '.$table.' (Dato, Beer, Skap, Ute) 
VALUES ("'.$date.'", "'.$beer.'", "'.$skap.'", "'.$ute.'")') 
or die(mysql_error());
echo "OK"; // Dette er alt vi returnerer på en vellykket skriveoperasjon
else { // hvis ikke alle verdiene er der, les siste linje og skriv den ut.
$result = mysql_query('SELECT Dato, Beer from '.$table.' ORDER by id DESC LIMIT 1');
$data = mysql_fetch_assoc($result);
print "Temp: ". $data['Beer'] ." - Date: ". $data['Dato'] . "\n";
print"<br>";
//print $result.date;
}
mysql_close($connection);
?>



Last deretter opp denne sketchen til Arduinoen:



#include <SPI.h>
#include <Ethernet.h>
#include <OneWire.h>
#include <DallasTemperature.h>

int ledWhite = 13;
int ledRed = 8;

#define ONE_WIRE_BUS 3                              // Data wire is plugged into digital pin 3 on the Arduino
#define NumberOfDevices 5                           // Set maximum number of devices in order to dimension array holding all Device Address arrays.

OneWire oneWire(ONE_WIRE_BUS);                      // Setup a oneWire instance to communicate with any OneWire devices

DallasTemperature sensors(&oneWire);                // Pass our oneWire reference to Dallas Temperature. 

byte allAddress [NumberOfDevices][8];               // Device Addresses are 8-element byte arrays. We need one for each of our DS18B20 sensors.
byte totalDevices;                                  // Declare variable to store number of One Wire devices that are actually discovered.

byte mac[] = { 0x00, 0xAA, 0xBB, 0xCC, 0xDE, 0x02 };

char server[] = "domene.net";                    // Server we want to connect to
EthernetClient client;

void setup() {
  pinMode(ledWhite, OUTPUT);
  pinMode(ledRed, OUTPUT);
    
  Serial.begin(9600);
  sensors.begin();

  totalDevices = discoverOneWireDevices();         // get addresses of our one wire devices into allAddress array 
  Serial.print("Number of probes discovered:");
  Serial.println(totalDevices);
  for (byte i=0; i < totalDevices; i++) 
    sensors.setResolution(allAddress[i], 10);      // and set the a to d conversion resolution of each.

  // start the Ethernet connection:
  if (Ethernet.begin(mac) == 0) {
    Serial.println("Failed to configure Ethernet using DHCP");
    // no point in carrying on, so do nothing forevermore:
    for(;;)
      ;
  }
  // give the Ethernet shield a second to initialize:
  delay(1000);
  Serial.println("Initializing..");
}

void HttpRequest(double t1, double t2, double t3)  //t1 = ute, t2 = øl,t3 = skap
{
  if (client.connect(server, 80)) {
    Serial.println("Connected to server, updating temperatures..");
    client.print("GET /beer/post.php?beer=");
    client.print(t2);
    client.print("&skap=");
    client.print(t3);
    client.print("&ute=");
    client.print(t1);
    client.println(" HTTP/1.0");
    client.println("Host: www.server.com"); // For shared hosting this is important!
    client.println();

    digitalWrite(ledWhite, HIGH);  } 
  else {
    digitalWrite(ledRed, LOW);
    digitalWrite(ledRed, HIGH);
    digitalWrite(ledRed, LOW);
    digitalWrite(ledRed, HIGH);
    digitalWrite(ledRed, LOW);
    digitalWrite(ledRed, HIGH);
    digitalWrite(ledRed, LOW);
    Serial.println("Connection to server failed");
  }
}

byte discoverOneWireDevices() {
  byte j=0;                                         // search for OneWire devices and copy to device address arrays.
  while ((j < NumberOfDevices) && (oneWire.search(allAddress[j]))) {        
    j++;
  }
  return j;                                         // return total number of devices found.
}

String printAddress(DeviceAddress addr) {
  byte i;
  String ad = "";
  for( i=0; i < 8; i++) {                         // prefix the printout with 0x
      if (addr[i] < 16) {
        ad = ad + "0";                            // add a leading '0' if required.
      }
      ad = ad + String(addr[i], HEX);             // print the actual value in HEX
      if (i < 7) {
      }
    }
    return ad;
}

double printTemperature(DeviceAddress addr) {
  float tempC = sensors.getTempC(addr);           // read the device at addr.
  if (tempC == -127.00) {
    return -100;
  } else {
    return tempC;                                 // and print its value.
  }
}

void loop()
{
  digitalWrite(ledWhite, LOW);
  digitalWrite(ledRed, LOW);

  double tempute = 0;
  double tempbeer = 0;
  double tempskap = 0;
  boolean tUte = false;
  boolean tBeer = false;
  boolean tSkap = false;
  
  sensors.requestTemperatures();                // Initiate  temperature request to all devices
  for (byte i=0; i < totalDevices; i++) {
    if(printAddress(allAddress[i]) == "<mac til probe 1>") {
      tempute = printTemperature(allAddress[i]);
      tUte = true;
    }
    if(printAddress(allAddress[i]) == "<mac til probe 2>") {
      tempbeer = printTemperature(allAddress[i]);
      tBeer = true;
    }
    if(printAddress(allAddress[i]) == "<mac til probe 3>") {
      tempskap = printTemperature(allAddress[i]);
      tSkap = true;
    }
  }

  if(tUte != false && tBeer !=false && tSkap !=false) {
    digitalWrite(ledRed, LOW);
    HttpRequest(tempute, tempbeer, tempskap);
  }
  else {
    digitalWrite(ledRed, HIGH);
    Serial.println("Missing one or more temperatures from probe");
    Serial.print("Beer probe reading: ");
    Serial.println(tempbeer);
    Serial.print("Outside probe reading: ");
    Serial.println(tempute);
    Serial.print("Fridge probe reading: ");
    Serial.println(tempskap);
  }

  while (client.connected()) {
    while (client.available()) {
      char c = client.read();
      Serial.print(c);
    }
  }
  Serial.println();
  Serial.println("Disconnecting from server");
  client.stop();

  delay(120000);                            // set update interval of 120.000 ms = 120 seconds = 2 minutes
}



Sketchen gjør (noe forenklet) følgende:
  • Detekterer tilkoblede prober og skriver ut dette til seriellkoblingen
  • Konfigurerer Ethernet-tilkobling via DHCP
  • Sjekker temperaturen på tilkoblede prober
  • Sender temperaturinformasjon til et PHP-script (hvit LED vil lyse når informasjon overføres hit)
  • Dersom det ikke oppnås kontakt med PHP-scriptet vil den røde LED’en blinke
  • Dersom en eller flere definerte prober ikke kan finnes skrives en feilmelding til serielltilkoblingen, og rød LED vil lyse konstant
  • Tidsintervall for hver sjekk er satt til 2 minutter
Sjekk at alt spiller som det skal ved å hente opp Serial Monitoren. Du er ute etter et slikt skjermbilde:



OK, 3 prober er oppdaget og posting til PHP-script fungerte slik det skal.

Ikke OK, her finner ikke Arduinoen noen prober tilkoblet, og vil derfor heller ikke poste til PHP-script.

Dersom alt funker er det på tide å gå i gang med loddingen.

Lodding

Jeg startet med lodding av 3.5 mm jacktilkobling på den ene proben. Testet så at denne virket (hvilket den ikke gjorde grunnet dårlige loddekunnskaper, så måtte korrigere litt). Deretter loddet jeg 3.5 mm female jack og testet at dette virket. Til slutt loddet jeg de siste probene. 

Rekkefølgen her er jo likegyldig, poenget er å hele tiden teste for å verifisere, og eliminere feil.


Hvordan man lodder skal ikke jeg uttale meg om, da dette var mitt første loddeprosjekt noensinne. Det gjenspeilet seg i en del prøv-og-feil-situasjoner, men det gikk da i orden til slutt :)

Loddetips #1: Husk å tinne loddetuppen godt!
Loddetips #2: Husk å tre på krympeslange og "kroppen" til jackpluggen FØR du lodder kontakten...
Loddetips #3: TEST mellom hver loddeoperasjon


Lodding av 3.5 mm jack til temperatursensor. Blå wire = signal, sort wire = jord, rød wire = live


Lodding ferdig, testet, feilet, rettet på med elektrikerteip, testet ok! :)


Første probe ferdig med krympeslange

Lodding av 3.5 mm female jack. Brukte breadboard jumpere, kuttet av pluggen i den ene enden og strippet wirene. La deretter et lag loddetinn på og startet loddingen.



Signal og 5V ferdig loddet


Makrobilder er no' dritt med et tilårskomment Casio Exilim...

Probe nr 2 in the making


Arduino-oppkobling (uten rød LED)



Arduino-oppkobling komplett med rød LED




Neste steg..

..er å få dette bygget inn i et "hus". Samt å tune PHP-script slik at man kan gå fra Proof Of Concept til ferdig "produkt". :)

Mer om dette i et senere innlegg, må tenke litt og kjøpe inn litt mer stæsj. :D

Les del 2 HER
Led del 3 HER

Ingen kommentarer:

Legg inn en kommentar