Om oss

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

onsdag 5. november 2014

DIY: Enkel arduino temperatursensor med LCD

I anledning den nye meskeboksen må der også temperaturavlesning til. Fremfor å åpne/lukke boksen hver gang man vil sjekke mesketemperaturen, kan det være greit å ha en probe i selve mesken og kunne lese av temperaturen på utsiden av boksen. Enter Arduino + LCD shield + DS18B20.

Handleliste
1 stk Arduino (eller tilsvarende) - 41,20 kr
1 stk LCD shield - 24,44 kr
1 stk DS18B20 sensor (preferert vanntett utgave, ferdig kablet) - 11,44 kr
1 stk koblingsboks (art.nr. 32-6183) - 59 kr
Wagoklemmer
Kabler
Elektrikertape
Evt. strømforsyning - 26,91 kr


The wire-up
Klem på LCD-shieldet til Arduinoen, koble signal fra temperatursensoren til digital 3, jord til jord og power til 5V. Dernest en 4,7 kOhm motstand mellom signal og 5V. Voila! Jeg benyttet wagoklemmer til kobling av motstand for å gjøre det enkelt.
Koblingsskjema

The code

/*
The circuit:
 * LCD RS pin to digital pin 8
 * LCD Enable pin to digital pin 9
 * LCD D4 pin to digital pin 4
 * LCD D5 pin to digital pin 5
 * LCD D6 pin to digital pin 6
 * LCD D7 pin to digital pin 7
 * LCD R/W pin to ground
 */

#include <LiquidCrystal.h>
#include <OneWire.h>
#include <DallasTemperature.h>

LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
int lcd_key     = 0;
int brightness = 50;
int adc_key_in  = 0;
double temp;
double mintemp = 100;
double maxtemp;
double lasttemp;

String infotext = " Rogue Brewing  ";
#define btnRIGHT  0
#define btnUP     1
#define btnDOWN   2
#define btnLEFT   3
#define btnSELECT 4
#define btnNONE   5
#define ONE_WIRE_BUS 3                              // Data wire is plugged into digital pin 3 on the Arduino
#define NumberOfDevices 2                           // 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.

void setup() {
  lcd.begin(16,2);
  Serial.begin(9600);
  sensors.begin();
  analogWrite(10,brightness);

  totalDevices = discoverOneWireDevices();         // get addresses of our one wire devices into allAddress array 
  for (byte i=0; i < totalDevices; i++) {
    sensors.setResolution(allAddress[i], 10);      // and set the a to d conversion resolution of each.
  }
}

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 || tempC == 85.00) {
    double diff = tempC - lasttemp;
    if(diff > 2 || diff < -2)
    {
      return lasttemp;
    }
  }
  
  lasttemp = tempC;
  if(tempC != 0.00){
  if (tempC > maxtemp){
    maxtemp = tempC;
  }
  else if(tempC < mintemp){
    mintemp = tempC;
  }
  else{}
  }
  return tempC;                                 // and print its value.

}

void adjust_brightness(String mode)
{
  if(mode == "add")
  {
    if(brightness < 150)
    {
       brightness += 10;
       analogWrite(10,brightness);
       Serial.println("test");
    }
  }
  else
  {
    if(brightness > 0)
    {
       brightness -= 10;
       analogWrite(10,brightness);
    }
  }
}
int read_LCD_buttons()
{
  adc_key_in = analogRead(0);
  if (adc_key_in > 1000) return btnNONE;
  if (adc_key_in < 50)   return btnRIGHT;  
  if (adc_key_in < 250)  return btnUP; 
  if (adc_key_in < 450)  return btnDOWN; 
  if (adc_key_in < 650)  return btnLEFT; 
  if (adc_key_in < 850)  return btnSELECT;  

  return btnNONE;
}

void loop() {

  sensors.requestTemperatures();                // Initiate  temperature request to all devices
  for (byte i=0; i < totalDevices; i++) {
    if(printAddress(allAddress[i]) == "28b914fb0500003c") {
      temp = printTemperature(allAddress[i]);
    }
  }

  String tempstring = "Temp: " +String(temp) +" C  ";

  lcd.setCursor(0, 0);
  lcd.print(tempstring);

  lcd.setCursor(0,1);
  lcd.print(infotext);
  delay(50);

  lcd_key = read_LCD_buttons();

  switch (lcd_key)
  {
    case btnRIGHT:
    {
      lcd.setCursor(0,1);
      infotext = "MAX: " +String(maxtemp) +"      ";
      break;
    }
    case btnLEFT:
    {
      lcd.setCursor(0,1);
      infotext = "MIN: " +String(mintemp) +"      ";
      break;
    }
    case btnUP:
    {
      adjust_brightness("add");
      break;
    }
    case btnDOWN:
    {
      adjust_brightness("subtract");
      break;
    }
    case btnSELECT:
    {
      lcd.setCursor(0,1);
      infotext = " Rogue Brewing  ";
      break;
    }
    case btnNONE:
    {
      break;
    }
  }
 }

Kommentarer til koden:
- Knappene på LCD-shield gjør følgende:
  • SELECT: Nullstiller teksten på linje 2 i displayet
  • LEFT: Viser minste registrerte temperatur
  • RIGHT: Viser høyeste registrerte temperatur
  • UP/DOWN: Justerer brightness i displayet
  • RESET: Reset
- Av og til kommer syke temperaturavlesninger som f.eks. -127 og 85. Derfor er det lagt inn meget enkelt feilhåndtering som ikke registrerer slike feilregistreringer

The setup

Stripp koblingsboksen for alt unødvendig støpt plast og kutt til litt spor slik at Arduinoen fits like a glove. Skjær ut hull i lokket til LCD-skjerm og knapper. Før gjennom USB/strømkabel og sensor, og legg wagoklemmene fin nedi boksen. Sett på lokket. Eventuelt gå amok med elektrikertape og litt papp for å dekke til litt blemmer og andre åpninger i boksen ;)


Minste registrerte temperatur

Høyeste registrerte temperatur - høyeste lysstyrke

Høyste registrerte temperatur - laveste lysstyrke

Lokk ferdig utskjært. Sort of...

Let's tape this motha up!



Se så! Da var det bare å klaske på borrelåstape på baksida og klemme den fast på meskeboksen, evt en vegg i nærheten og slippe sensoren nedi mesken.

Ingen kommentarer:

Legg inn en kommentar