Arduino thermostat och fukt av läsning

PIC, AVR, Arduino, Raspberry Pi, Basic Stamp, PLC mm.
trissan1820
Inlägg: 11
Blev medlem: 1 juni 2013, 15:02:34

Arduino thermostat och fukt av läsning

Inlägg av trissan1820 »

hej jag är nästan helt grön på det här med programmering men har hittat en kod från ett liknande projekt men jag får en felkod när jag ska testa programmet

egg_incubator:258: error: request for member 'year' in 'now', which is of non-class type 'int'

jag misstänker är man kanske behöver nått till lägg för det verkar som att den inte förstår datum och tid

den hårdvara jag har nu är
DTH22 fukt/temp sensor
Arduono uno rv3 "starter kit" så lite motstånd dioder mm


men ingen minneskort display mm som han haft som jag hitta koden hos
men det borde väl gå bra att låta det vara kvar utan att jag har den hårdvaran kanske ska skaffa det sen men börja med att köra med datorn inkopplad.

vore tacksam om jag kunde få lite hjälp jag håller på att försöka lära mig grunderna än.
är kommer koden

Kod: Markera allt

#include "DHT.h"
//#include <LiquidTWI.h>
#include <Wire.h>
#include "Chronodot.h"
#include <SD.h>
#include <Adafruit_RGBLCDShield.h>


/* 
Pins used:
LCD:
Connect via i2c, default address #0 (A0-A2 not jumpered)
The circuit:
* 5V to Arduino 5V pin
* GND to Arduino GND pin
* CLK to Analog #5
* DAT to Analog #4

SDshield
* CS to D8
* MOSI to D11
* MISO to D12
* SCK to D13

RGB Backlight
RED to D3
GREEN to D5
BLUE to D6

Humidity Warning to D2
DHT22 to D4

Heating to D9
*/

Chronodot RTC;
DateTime now = RTC.now();

Adafruit_RGBLCDShield lcd = Adafruit_RGBLCDShield();

File dataFile;
const int chipSelect = 8;     //Sparkfun SD shield pin 8, Adafruit SD shield pin 4.

#define DHTPIN 4              // Pin to read from DHT22 sensor
#define DHTTYPE DHT22         // DHT 22  (AM2302)
                            
int maxT=0, minT=100;         //temperature range
int maxH=0, minH=100;         //Humidity range
DHT dht(DHTPIN, DHTTYPE);

//here's where the temp and hum setpoints are changed
float tempset=23, tempreset=28;
float humset=60, humreset=58;
int tmem=0, hmem=0;

// These #defines make it easy to set the backlight color
#define RED 0x1
#define YELLOW 0x3
#define GREEN 0x2
#define TEAL 0x6
#define BLUE 0x4
#define VIOLET 0x5
#define WHITE 0x7

void setup() {
  Serial.begin(9600); 
  Wire.begin();
  RTC.begin(); 
  SD.begin(chipSelect);
  
  // set up the LCD's number of rows and columns: 
  lcd.begin(16, 2);
  lcd.setBacklight(WHITE);
                                
  pinMode(9, OUTPUT);       //Heating
  pinMode(10, OUTPUT);     //Needed for the SDbreakout board to work.
    
  digitalWrite (9, HIGH);   //This keeps the relay turned off during setup
    
  lcd.begin(16, 2);         //set up the LCD's number of columns and rows:
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Incubator");
  lcd.setCursor(0,1);
  lcd.print("Controler");
  delay(2000);

  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("By George");
  lcd.setCursor(0,1);
  lcd.print("Timmermans");
  delay(2000);
  
  Serial.println("Initializing Chronodot.");
  Serial.println("Date\t\tTime\t\tHumidity\tTemperature\tTempRTC");
  
  dataFile = SD.open("DHT22.txt", FILE_WRITE);   // open the file. note that only one file can be open at a time,
  dataFile.println("Date\t\tTime\t\tHumidity\tTemperature"); 
  dataFile.close();          // so you have to close this one before opening another.

  if (! RTC.isrunning()) {
    Serial.println("RTC is NOT running!");
  }  
  delay(500);
}

void loop() {
  
  // Reading temperature or humidity takes about 250 milliseconds!
  // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
  float h = dht.readHumidity();
  float t = dht.readTemperature();

  // check if returns are valid, if they are NaN (not a number) then something went wrong!
  if (isnan(t) || isnan(h)) {
  
    Serial.println("Failed to read from DHT22");
                                  
    lcd.clear();              //Display error on vfd display.
    lcd.setCursor(0,0);
    lcd.print("Failed to read");
    lcd.setCursor(0,1);
    lcd.print("from DHT22");

    // open the file. note that only one file can be open at a time,
    // so you have to close this one before opening another.
    dataFile = SD.open("DHT22.txt", FILE_WRITE);      
    dataFile.println("Failed to read from DHT22");  //Write error message too MicrSD. 
    dataFile.close();         //Close the file.
    
    lcd.setBacklight(RED);
  } 
  
  else { 
    temperature(h, t);  //Check temerature and humidity and control relays.
    if (now.second() == 0)  {  //Log data every minute(RTC needed)
      debug(h, t, RTC.now());
      Log(h, t, RTC.now());
    }                               
    else  { 
        LCD(h, t, RTC.now());
    }
  }
}

void temperature (float h, float t)  {
  if (tempreset<=t && t<=tempset && tmem==1) {
       digitalWrite (9, HIGH);
  }
  if (t>=tempset) {
       tmem==1,
       lcd.setBacklight(GREEN);
       digitalWrite (9, HIGH);
  }     
  if (t<tempreset)  {
       tmem==0,
       lcd.setBacklight(BLUE);
       digitalWrite (9, LOW);
  }
  if (humreset<=h && h<=humset && hmem==1) {
       digitalWrite (2, LOW);
  }
  if (h>humset) {
       hmem==1,
      digitalWrite (2, LOW);
  }
  if (h<humreset) {
       hmem==0,
       digitalWrite (2, HIGH);
  }
}
  
void Log(float h, float t, DateTime now)  {
    dataFile = SD.open("DHT22.txt", FILE_WRITE);
  if(now.day() < 10) dataFile.print("0");
    dataFile.print(now.day(), DEC);
    dataFile.print('/');
  if(now.month() < 10) dataFile.print("0");
    dataFile.print(now.month(), DEC);
    dataFile.print('/');
    dataFile.print(now.year(), DEC);
    dataFile.print('\t');
  if(now.hour() < 10) dataFile.print("0");
    dataFile.print(now.hour(), DEC);
    dataFile.print(':');
  if(now.minute() < 10) dataFile.print("0");
    dataFile.print(now.minute(), DEC);
    dataFile.print(':');
  if(now.second() < 10) dataFile.print("0");
    dataFile.print(now.second(), DEC);
    dataFile.print("\t");
    dataFile.print(h);
    dataFile.print("\t\t");
    dataFile.println(t);
    dataFile.close();            //Close the file.
  delay(100);
}

void debug(float h, float t, DateTime now)  {
  if(now.day() < 10) Serial.print("0");
    Serial.print(now.day(), DEC);
  if(now.month() < 10) Serial.print("0");
    Serial.print(now.month(), DEC);
    Serial.print('/');
    Serial.print(now.year(), DEC);
    Serial.print('/\t');
  if(now.hour() < 10) Serial.print("0");
    Serial.print(now.hour(), DEC);
    Serial.print(':');
  if(now.minute() < 10) Serial.print("0");
    Serial.print(now.minute(), DEC);
    Serial.print(':');
  if(now.second() < 10) Serial.print("0");
    Serial.print(now.second(), DEC);
    Serial.print("\t");
    Serial.print(h);
    Serial.print("\t\t");
    Serial.print(t);
    Serial.print("\t\t");
    Serial.println(now.tempC());
  delay(100);
}

void LCD(float h, float t, DateTime now)  {
    lcd.clear();          //Display Time, Humidity and Temperature on LCD.
    lcd.setCursor(0,0);
  if(now.hour() < 10) lcd.print("0");
    lcd.print(now.hour(), DEC);
    lcd.setCursor(2,0);
    lcd.print(":");
    lcd.setCursor(3,0);
  if(now.minute() < 10) lcd.print("0");
    lcd.print(now.minute(), DEC);
    lcd.setCursor(5,0);
    lcd.print(":");
    lcd.setCursor(6,0);
  if(now.second() < 10) lcd.print("0");
    lcd.print(now.second(), DEC);
    lcd.setCursor(10,0);
    lcd.print("H");
    lcd.setCursor(11,0);
    lcd.print(h,1);
    lcd.setCursor(15,0);
    lcd.print("%");
        
    lcd.setCursor(0,1);
  if(now.day() < 10) lcd.print("0");
    lcd.print(now.day(), DEC);
    lcd.setCursor(2,1);
    lcd.print('/');
    lcd.setCursor(3,1);
  if(now.month() < 10) lcd.print("0");
    lcd.print(now.month(), DEC);
    lcd.setCursor(5,1);
    lcd.print('/');
    lcd.setCursor(6,1);
    lcd.print(now.year()-2000, DEC);
    lcd.setCursor(10,1);
    lcd.print("T");
    lcd.setCursor(11,1);
    lcd.print(t,1);
    lcd.setCursor(15,1);
    lcd.print((char)223); // degree symbol
}

får inte till en sån där scroll lista någon som vet hur man gör så det blir lättare att läsa så ändrar jag koden
Senast redigerad av trissan1820 1 juni 2013, 17:05:31, redigerad totalt 1 gång.
TobiasEinarsson
Inlägg: 58
Blev medlem: 6 september 2012, 11:15:33
Ort: Göteborg

Re: Arduino thermostat och fukt av läsning

Inlägg av TobiasEinarsson »

Vad är det du vill göra?

Koden du visar handlar till mer än 90% om att styra hårdvara som du inte har (LCD, ChronoDot (realtidsklocka) och SD-kort (för loggning av data)).


Det här är den del i koden som faktiskt pratar med den sensorn som du har:

Kod: Markera allt

float h = dht.readHumidity();
float t = dht.readTemperature();
Detta plus de andra raderna som har med DHT-biblioteket att göra är egentligen det enda du behöver (ja, plus setup och loop då..)

Edit: Använd "code"-taggen för att visa kod.
Senast redigerad av TobiasEinarsson 1 juni 2013, 16:13:56, redigerad totalt 2 gånger.
danei
EF Sponsor
Inlägg: 27428
Blev medlem: 2 juni 2003, 14:21:34
Ort: Östergötland
Kontakt:

Re: Arduino thermostat och fukt av läsning

Inlägg av danei »

När du skriver ditt inlägg finns den en kap som heter [Code] använd den för källkoden.
Se nedan.

[code]
Skriv din kod här.
[/code]

(Jag har slagit av BBCkoder i mitt inlägg annars skulle det bli en ruta.)
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Re: Arduino thermostat och fukt av läsning

Inlägg av sodjan »

Det är väl i princip detta som hela inlägget handlar om:

> ...men det borde väl gå bra att låta det vara kvar...

Varför ska du ha kod kvar för hårdvara som du i alla fall inte har?
Ta bort allt som inte är rellevant för just ditt fall och försök igen.

Resten nedan kan du sannolikt hoppa över om du vill... :-)

> Arduino thermostat och fukt av läsning

Hur uppstår det fukt från läsningen?
Eller menar du kanske "fuktavläsning"?

> ...men jag får en felkod när jag ska testa programmet...

Är det visade felet det *enda* felet som uppstår?

> men ingen minneskort display mm som han haft som jag hitta koden hos men det
> borde väl gå bra att låta det vara kvar utan att jag har den hårdvaran kanske ska
> skaffa det sen men börja med att köra med datorn inkopplad.

Bara ett tips "på vägen", så att säga. :-) Det som jag kopierade ovan från ditt
inlägg är väldigt svårt att få någon rätsida på. Ska det verkligen vara *en* enda
lång mening !?
trissan1820
Inlägg: 11
Blev medlem: 1 juni 2013, 15:02:34

Re: Arduino thermostat och fukt av läsning

Inlägg av trissan1820 »

tack för tipsen får sätta mig i kväll och försöka rensa bort och hoppas jag inte tar bort för mycket kod


den hårdvara jag har nu är
DTH22 fukt/temp sensor
Arduono uno rv3 "starter kit" så lite motstånd dioder mm


men jag inte har som som han som skrev koden använde
Adafruit negative RGB LCD
Adafruit I2C backback
Sparkfun microSD shield
Adafruit chronodot RTC
20 watt heat plate from ebay
4-relay board from ebay

är det tillräckligt tydligt sodjan?

men ett relä och en värmekälla ska jag skaffa.

jag har tänkt att ha datorn ansluten till Arduino ono.
tills jag har fått ordning på den och sedan ha en lcd men någon knapp för att ställa temp

så här vill jag att det ska funka.
en AM2302 samma givare som en DTH22, den ska läsa av luftfuktighet och temp och med tempen vill jag styra ett relä som i sin tur styr en värmekälla som kommer vara mellan 20-100w.

jag ska kunna ställa vilken temp den ska slå på och av.
läsa av vilken luftfuktighet det är.

om det går skulle jag vilja ha så att om man har ett element på 50w och i stället för att det är 100% på eller 0% av.
att det är en dimmer effekt så när den är nära rätt temperatur så sänks effekten så temperaturen blir stabil och mjuk.

äggen jag har ska helst ha en temp på 37,7-37,8 grader.
men olika ägg vill ha olika temp därför bör den vara ställbar

sen ska jag ha en dc fläkt men den tror jag är onödig att styra.
fläkten är mer för att tempen ska vara jämt fördelad i lådan och då är det väl bäst att den går hela tiden eller?
Användarvisningsbild
SeniorLemuren
Inlägg: 8427
Blev medlem: 26 maj 2009, 12:20:37
Ort: Kristinehamn

Re: Arduino thermostat och fukt av läsning

Inlägg av SeniorLemuren »

Vill du bara läsa av luftfuktigheten? D.v.s den skall inte innefattas av någon reglering, utan endast temperaturen skall regleras.

Varför jag frågar är, att om du bara kan läsa av luftfuktigheten utan att kunna reglera den, så förstår jag inte varför du överhuvudtaget vill veta luftfuktigheten. Eller tänker du justera den manuellt? I så fall varför?

Om luftfuktigheten är av vikt och måste justeras manuellt så måste du ju ändå passa processen, även om du kostar på dig att styra temperaturen automatiskt. Vad det ger för vinst förstår jag inte.
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Re: Arduino thermostat och fukt av läsning

Inlägg av sodjan »

> är det tillräckligt tydligt sodjan?

*Vad* är tillräckligt tydligt?

Jag struntar i princip i vad du har för prylar, jag förstog bara inte
varför du försöker bygga kod som förutsätter prylar som du ändå
inte har. Det lär med största sannolikhet misslyckas. Du måste ju
i alla fall någongång fixa koden som du vill ha den, så varför
inte göra det med en gång?

Resten av inlägget var lite för svårläst för att jag ska bry mig.
Man det brukar finnas andra som är mer översende med slarvigt
skrivna inlägg, så det löser sig säkert ändå! :-)

Så mitt tips, vad du nu än försöker göra, tänk över det lite mer
och försök fixa till en kod som gör det som faktiskt behövs. Se t.ex:
http://fritzing.org/projects/arduino-am ... readboard/
Är det inte bättre att utgå från det exemplet?

Kod: Markera allt

/*
  AM2302 Temperature / Humidity Sensor (DHT22)
  
  Current Code
  Created by Derek Erb 30/01/2013
  Modified 30/01/2013
  
  Requirement : Arduino + AM2302 sensor connected to pin 2
  
  DHT Library from:
  https://github.com/adafruit/DHT-sensor-library

  v0.03 Delays and formatting
  v0.02 Delay 3 seconds between readings
*/

#include "DHT.h"          // DHT & AM2302 library

// Version number
const float fVerNum = 0.03;

// Data pin connected to AM2302
#define DHTPIN 2

#define DHTTYPE DHT22       // DHT 22  (AM2302)

DHT dht(DHTPIN, DHTTYPE);   // LED pins

//////////////////////////////////////////////////////
//
// SETUP
//
void setup() {
  // Setup serial monitor
  Serial.begin(9600);
  
  // Wait 3 seconds
  delay(3000);
  
  Serial.println(F("\nAM2302 Sensor"));
  Serial.print(F("Version : "));
  Serial.println(fVerNum);
  Serial.println(F("Arduino - Derek Erb\n"));
  delay(5000);
  
  dht.begin();
}
  

void loop() {
  
  // Reading temperature or humidity takes about 250 milliseconds!
  // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
  float h = dht.readHumidity();
  float t = dht.readTemperature();

  // check if returns are valid, if they are NaN (not a number) then something went wrong!
  if (isnan(t) || isnan(h)) {
    Serial.println(F("Failed to read from DHT"));
  }
  else {
    Serial.print(F("Humidity: ")); 
    Serial.print(h);
    Serial.print(F(" %\t"));
    Serial.print(F("Temperature: ")); 
    Serial.print(t);
    Serial.println(F(" C"));
  }
  
  // Wait 3 seconds
  delay(3000);
}
trissan1820
Inlägg: 11
Blev medlem: 1 juni 2013, 15:02:34

Re: Arduino thermostat och fukt av läsning

Inlägg av trissan1820 »

tack sodjan jag uppfatta det som att du inte förstod vad jag menade men det är nog en bättre kod att börja från.

SeniorLemuren jag vet inte hur man ska justera luftfuktigheten på nått bra vis.
kanske ventilera om den är för hög.
normalt sätt räcker det med en skål med vatten som står i lådan.
lyftfuktigheten ska vara ca 40-50% vissa arter vill ha högre men jag vill ha ca 40%
och de 2-3 sista dagarna innan kläckning höjer man till 60-80% då sprayar man väggarna med en blomspruta så det är inte så mycket manuellt arbete men har du ett enkelt och billigt förslag på hur man löser det med automatik så lyssnar jag

jag kan till lägga att vaktel äggen kläcks på ca 18 dagar så en skål vatten kanske man får fylla på en gång kanske 2 gånger och det tycker jag att det är ett okej arbete
så en av läsning tror jag skulle räcka på luftfuktigheten och om luft fuktigheten är högre eller lägre någon dag tror jag inte det påverkar äggen så mycket tempen är viktigare.
trissan1820
Inlägg: 11
Blev medlem: 1 juni 2013, 15:02:34

Re: Arduino thermostat och fukt av läsning

Inlägg av trissan1820 »

fick inte sodjans kod att funka men har hittat en annan som funkar

det jag egentligen saknar på den här koden är en pinout helst en dimmer funktion till ett element
eller en on off pinout som slåt på och av på ställd temp.

men det är lite för svårt för mig att programmera så jag ska sätta mig och studera programmering nu i stället om ingen hjälper mig att skriva in det som saknas.
men jag ska försöka lite själv också.

Kod: Markera allt

/*
 * Arduino sketch code for reading RHT03 (also known as DHT22, RHT22, and
 * AM2302) temperature/humidity sensor. This sensor implements its own funky
 * 1-wire bus (totally unrelated to the Dallas/Maxim 1-wire bus) for
 * signalling.
 *
 * See: http://blog.ringerc.id.au/2012/01/using-rht03-aliases-rht-22.html
 *
 * This was my first non-trivial adventure into C programming on the Arduino,
 * before I understood the basics of how to read pins directly via registers
 * and write reasonably fast code. It's fat, slow and stupid, plus it wastes
 * a precious interrupt line. It was a great learning experience, but should
 * probably be left at that.
 * 
 * Don't use this code for anything you care about, there's a decently
 * written library for the sensor here:
 *
 *  https://github.com/nethoncho/Arduino-DHT22
 *
 * ... which I've patched for Arduino 1.0 support and a few other tweaks and
 * pushed to here:
 *
 *  https://github.com/ringerc/Arduino-DHT22
 *
 * Use that instead of this code.
 *
 * If you want to use this code in the Arduino IDE, rename the file to the
 * extension ".ino".
 */

#include <stdio.h>
#include <util/delay_basic.h>

const int sensorReadTimeoutMillis = 1000;
const int serialBaudRate = 9600;
const int sensorReadIntervalMs = 5000;
int millisSinceLastRead = 0;
int sensorPin = 2;

// Microseconds since last state transition. Used to check timing, which is required
// to read bits and helpful for error checking in other states.
volatile long lastTransitionMicros = 0;

// This counter tracks how many signal line changes have happened in this
// sensor run, so we can record each pulse length in the right part of the timings
// array. We also use this for sanity checking; if we didn't get 86 pulses, something
// went wrong.
volatile int signalLineChanges;

// The timings array stores intervals between pulse changes so we can decode them
// once the sensor finishes sending the pulse sequence.
int timings[88];

// If an interrupt needs to report an error, we store the message
// here and print it once the interrupt has ended.
char errorMsgBuf[256];

// and a flag to store error state during sensor read/processing
boolean errorFlag = false;

//
// Capture sensor data, returning true on success and false on failure.
//
// On false return the arguments are **NOT** modified.
//
// Temperature is returned in decidegrees centigrade, ie degrees C times ten.
// Divide by ten to get the real temperature. Eg a return of 325 means a
// temperature of 32.4 degrees C. Negative temperatures may be returned,
// so make sure to use the absolute of the remainder when extracting the
// fractional part, eg:
//
//  int wholePart = temperature/10;
//  int fractionalPart = abs(temperature%10);
//
// Humidity is returned in percentage relative humidity times ten. Divide by ten
// to get the real relative humidity. Eg a return of 631 means 63.1% humidity.
//
boolean readSensor(int * temperature_decidegrees_c, int * rel_humidity_decipercent) {
  initState();
  // Install the state transition interrupts so we see our own request pulses
  // and all the sensor replies,
  attachInterrupt(sensorPin - 2, sensorLineChange, CHANGE);
  // Send a sensor read request pulse (7000ms LOW) and check that the sensor replies with 80ms low
  if (!requestSensorRead()) {
    flagError();
  } else {
    // collect the sensor line pulses then stop capturing interrupts on the line
    // once we either time out or get all the sensor pulses we expect.
    const long startMillis = millis();
    do {
      delay(100);
    } while ( signalLineChanges < 86 && ( (millis() - startMillis) < sensorReadTimeoutMillis));
    detachInterrupt(sensorPin - 2);
    if (signalLineChanges != 86) {
      sprintf(errorMsgBuf, "*** MISSED INTERRUPTS ***: Expected 86 line changes, saw %i", signalLineChanges);
      flagError();
    } else {
      //debugPrintTimings();  // XXX DEBUG
      // TODO: memory barrier to ensure visibility of timings array
      // Feed the collected pulse sequence through the state machine to analyze it.
      analyseTimings(temperature_decidegrees_c, rel_humidity_decipercent);
    }
  }
  return !errorFlag;
}
  
// Interrupt service routine to capture timing between signal pulses and record
// them. The pulse sequence will be analysed once it's all been captured so we don't
// have to worry so much about execution time.
void sensorLineChange() {
  const long pulseMicros = micros() - lastTransitionMicros;
  lastTransitionMicros = micros();
  timings[signalLineChanges] = pulseMicros;
  signalLineChanges++;
}

// Clear all the sensor reader state before we start reading
void initState() {
  detachInterrupt(sensorPin - 2);
  for (int i = 0; i < 86; i++) { timings[i] = 0; }
  errorFlag = false;
  lastTransitionMicros = micros();
  signalLineChanges = 0;
  // TODO: memory barrier to guarantee visibility of timings array
}

// DEBUG routine: dump timings array to serial
void debugPrintTimings() { // XXX DEBUG
  for (int i = 0; i < 86; i++) { // XXX DEBUG
    if (i%10==0) { Serial.print("\n\t"); }
    char buf[24];
    sprintf(buf, i%2==0 ? "H[%02i]: %-3i  " : "L[%02i]: %-3i  ", i, timings[i]);
    Serial.print(buf);
  } // XXX DEBUG
  Serial.print("\n"); // XXX DEBUG
}

void analyseTimings(int * temperature_decidegrees_c, int * rel_humidity_decipercent) {
  // The pulse sequence is:
  // (Processed by requestSensorRead()):
  //   LOW (1000 - 10000us) - our sensor request
  //   HIGH (20-40us) - our pull high after sensor request
  //   LOW (80us) - Sensor pulls down to ACK request
  //   HIGH (80us) - Sensor pulls up to ACK request
  // (Processed as results here):
  //   16 bits of humidity data, 8 bits integral and 8 bits fractional part
  //   16 bits of temperature data, 8 bits integral and 8 bits fractional part
  //   8 bits of checksum
  // each bit of which is sent as:
  //   LOW (50us): Expect bit pulse
  //   -- THEN EITHER --
  //   HIGH(18-30us): 0 bit
  //   -- OR --
  //   HIGH(55-85us): 1 bi
  // Start at the 6th entry of the timings array, the first pre-bit low pulse
  int timingsIdx = 5;
  int humid16 = readnbits(&timingsIdx, 16);
  if (errorFlag) {
    Serial.println("Failed to capture humidity data");
    return;
  }
  int temp16 = readnbits(&timingsIdx, 16);
  if (errorFlag) {
    Serial.println("Failed to capture temperature data");
    return;
  }
  int checksum8 = readnbits(&timingsIdx, 8);
  if (errorFlag) {
    Serial.println("Failed to capture checksum");
    return;
  }
  // Verify the checksum. "Checksum" is too good a word to describe this
  // but it'll probably help catch the odd bit error.
  byte cs = (byte)(humid16>>8) + (byte)(humid16&0xFF) + (byte)(temp16>>8) + (byte)(temp16&0xFF);
  if (cs != checksum8) {
    sprintf(errorMsgBuf, "Checksum mismatch, bad sensor read");
    flagError();
  }
  // If bit 16 is set in the temperature, temperature is negative.
  if ( temp16 & (1<<15) ) {
    temp16 = -(temp16 & (~(1<<15)));
  }
  if (!errorFlag) {
    *temperature_decidegrees_c = temp16;
    *rel_humidity_decipercent = humid16;
  }
}

int readnbits(int * timingsIdx, int nbits) {
  const int * t = timings + *timingsIdx;
  const int * tStop = t + nbits*2;
  int result = 0;
  char buf[12];
  while (t != tStop) {
    checkPreBitLowPulse( *(t++), (*timingsIdx)++ );
    result = shiftNextBit( result, *(t++), (*timingsIdx)++ );
  }
  return result;
}


int shiftNextBit(int oldValue, int pulseMicros, int timingIndex) {
  // The datasheet says 0 pulses are 22-26us and 1 pulses are 70us. The datasheet is a lie, there's
  // lots more variation than that. I've observed 0s from 12 <= x <= 40  for example.  
  if (pulseMicros > 10 && pulseMicros < 40) {
    return (oldValue<<1) | 0;
  } else if (pulseMicros > 60 && pulseMicros < 85) {
    return (oldValue<<1) | 1;
  } else {
    sprintf(errorMsgBuf, "Bad bit pulse length: %i us at timing idx %i", pulseMicros, timingIndex);
    flagError();
    return 0xFFFFFFFF;
  }
}

// Ensure the passed pulse length is within an acceptable range for a pre-bit-transmission
// low pulse. It should be 45-55 us, but the datasheet is full of lies and we seem to need a tolerance
// around 35-75us to get it to actually work.
void checkPreBitLowPulse(int pulseMicros, int timingIndex) {
  if (pulseMicros <= 35 || pulseMicros >= 75) {
    sprintf(errorMsgBuf, "Low pulse before bit transmit (%i us) outside 45-70us tolerance at timing idx %i", pulseMicros, timingIndex);
    flagError();
  }
}

// Signal the sensor to request data.
// At entry the line should be pulled high, and it'll be pulled high
// on return.
boolean requestSensorRead() {
  // Make sure we're pulled HIGH to start with
  if (digitalRead(sensorPin) != HIGH) {
    sprintf(errorMsgBuf, "Line not HIGH at entry to requestSensorRead()");
    flagError();
    return false;
  }
  // Pulse the line low for 1-10ms (we use 7ms)
  // to request that the sensor take a reading
  digitalWrite(sensorPin, LOW);
  pinMode(sensorPin, OUTPUT);
  delayMicroseconds(7000);
  
  // Push the pin explicitly HIGH. This shouldn't really be necessary, but appears to
  // produce a more clean and definite response, plus the datasheet says we should push
  // it high for 20-40us. Without this the sensor readings tend to be unreliable.
  digitalWrite(sensorPin, HIGH);
  delayMicroseconds(30);
  
  // Go back to input mode and restore the pull-up so we can receive the sensor's
  // acknowledgement LOW pulse. The pin will remain HIGH because of the 20k pull-up
  // resistor activated by the Arduino when an OUTPUT pin is set HIGH.
  pinMode(sensorPin, INPUT);
  
  // Then wait for the sensor to pull it low. The sensor will respond
  // after between 20 and 100 microseconds by pulling the line low.  
  // If it hasn't done so within 200 microseconds assume it didn't see our
  // pulse and enter error state.
  int pulseLength = pulseIn(sensorPin, LOW, 200);
  if (pulseLength == 0) {
    sprintf(errorMsgBuf, "Sensor read failed: Sensor never pulled line LOW after initial request");
    flagError();
    return false;
  }
  // The sensor has pulled the line low. Wait for it to return to HIGH.
  delayMicroseconds(5);
  pulseLength = pulseIn(sensorPin, HIGH, 200);
  if (pulseLength == 0) {
    sprintf(errorMsgBuf, "Sensor read failed: Sensor didn't go back HIGH after LOW response to read request");
    flagError();
    return false;
  }
  return true;
}

void flagError() {
  // On error restore the sensor pin to pulled up with high impedance
  pinMode(sensorPin, INPUT);
  digitalWrite(sensorPin, HIGH);
  // Flag error state
  errorFlag = true;
  // then write the error msg
  Serial.println(errorMsgBuf);
}

void setup() {
  // INPUT mode is the default, but being explicit never hurts
  pinMode(sensorPin, INPUT); 
  // Pull the sensor pin high using the Arduino's built-in 20k 
  // pull-up resistor. The sensor expects it to be pulled high
  // for the first 2s and kept high as its default state.
  digitalWrite(sensorPin, HIGH);
  // The sensor expects no communication for the first 2s, so delay
  // entry to the polling loop to give it tons of time to warm up.
  delay(5000);
  // Now ensure the serial port is ready
  Serial.begin(serialBaudRate);
  Serial.println("Sensor initialized, Ready for first reading");
}

//
// Read the sensor and write results like:
//
// Reading: 32.2 degrees C at 53.4 relative humidity
//
// ... to the serial output.
//
void loop() {
  Serial.println("Reading sensor...");
  int temperature;
  int humidity;
  boolean success = readSensor(&temperature, &humidity);
  if (success) {
    char buf[128];
    sprintf(buf, "Reading: %i.%i degrees C at %i.%i relative humidity", temperature/10, abs(temperature%10), humidity/10, humidity%10);
    Serial.println(buf);
  }
  delay(sensorReadIntervalMs);
}
Användarvisningsbild
SeniorLemuren
Inlägg: 8427
Blev medlem: 26 maj 2009, 12:20:37
Ort: Kristinehamn

Re: Arduino thermostat och fukt av läsning

Inlägg av SeniorLemuren »

Jaa, om du höjer luftfuktigheten bara genom att spraya med en blomspruta så kan du väl lika gärna låta µC ta hand om sprayningen också, när du ändå har luftfuktigheten som input. Använd bara en liten vindrutespolmotor som startas och gör samma jobb som blomsprutan när luftfuktigheten den blir för låg.
Användarvisningsbild
Icecap
Inlägg: 26650
Blev medlem: 10 januari 2005, 14:52:15
Ort: Starup (Haderslev), Danmark

Re: Arduino thermostat och fukt av läsning

Inlägg av Icecap »

Att styra temperaturen vid att styra det med PWM är helt rätt väg att gå. Normalt använder man en PI-reglering och om temperaturen ska ändras ibland kan man ha en PID-reglering på bör-värdet inför PI-regleringen - men det är ganska säkert överkurs i detta projekt.

Samma sak kan göras med fukten bara det kan skapas ett sätt som tillför fukt. Ta man t.ex. en pump som ser till att spruta in vatten kan man styra den med korta pulser. Den får gärna ge relativ låg mängd men högre tryck, det är lättare att dosera med lågt flöde och lättare att sprida med högre tryck.

Men jag håller med om att man bara ska ha de delar av programmet som används, SD-kort osv. finns det ingen anledning att ha med och att tro att du kan släppa enklare undan vid att inte veta vad du gör men bara kopiera ett befintligt projekt kommer i alla lägen inte att fungera.
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Re: Arduino thermostat och fukt av läsning

Inlägg av sodjan »

> fick inte sodjans kod...

Det var inte *min* kod. :-)

Ja, den koden som jag länkade till visade ju i princip bara
avläsningen av sensorn, vad man sedan gör med värderna
är ju en lite annan sak och det är ju väldig specifikt för varje
unik applikation (allså svårt att hitta något exempel för det).

Det man får göra är att söka andra exempel där man t.ex
hanterar värmestyrning. "Arduino pwm heater control" ger
en hel del träffar.

Sedan är det upp till en själv att "sy ihop" det hela. D.v.s anpassa
värderna som kommer från avläsningen av temp-givaren till de
värden som används som input i "heater" rutinerna. Sannolikt får
man skala värderna eller liknande för att få det att passa ihop.

En annan sak, är det någon speciell anledning till att inte helt
enkelt använda en kommersiell termostat som man kan köpa?
trissan1820
Inlägg: 11
Blev medlem: 1 juni 2013, 15:02:34

Re: Arduino thermostat och fukt av läsning

Inlägg av trissan1820 »

okej tack för hjälpen om jag får ordning på det här så kan en spolar pump va ett bra alternativ.

ok sodjan då förstår jag.
jag får försöka plugga på och klistra och klippa så gott det går.

jag ville inte köpa en termostat för de var så pass dyra de jag hitta men nu när jag redan har köpt mitt kitt så hitta jag en termostat för någon hundring bara. men jag har alltid varit fascinerad av mickroproceccorer så jag tänkte jag kunde lära mig lite men det är ganska svårt
trissan1820
Inlägg: 11
Blev medlem: 1 juni 2013, 15:02:34

Re: Arduino thermostat och fukt av läsning

Inlägg av trissan1820 »

hej skulle behöva lite hjälp med hur jag ska göra för att läsa av värdena till en pinout

det jag har lyckats med är att få pin13 led att lysa då givaren läser in data och så har jag en pinout Heatpin 6

som jag har tänkt ha som on off till en värmekälla jag börjar med onoff tänkte jag innan jag germig in på pwm styrning.

om jag för står det rätt så ska jag skriva så här
if (sensorPin2put < 345) //det är värdet här jag inte vet vad det ska vara kan det vara så att 345 är 34.5 grader
{
digitalWrite (6, HIGH); // för att slå på värmekällan
}
if (sensorPin2put < 355)
{
digitalWrite (6, LOW); // slår av värmekällan när det är 35.5 grader
}

är det så man ska göra?
Användarvisningsbild
Icecap
Inlägg: 26650
Blev medlem: 10 januari 2005, 14:52:15
Ort: Starup (Haderslev), Danmark

Re: Arduino thermostat och fukt av läsning

Inlägg av Icecap »

Hur man "ska" göra beror helt på vad man vill uppnå!

Vill du ha temperaturen till att vara inom snäva intervall vill det bästa sätt vara att ha en PI-reglering. Och vad är då en PI-reglering? Det är det samma som en PID-reglering där D-faktorn är ställd till noll och google kan sannolikt hjälpa till med PID-reglering om det inte står något i wiki'n.

Fungerar det bra men konstanta svängningar runt 1°C fungerar ditt regleringssätt också men vill du ha det inom t.ex. 0,2°C är PI-regleringen vägen fram.

En ren integrerande reglering kan fungera alldeles utmärkt också men gemensamt för dessa regleringar är att det bör finnas en stabil tidbas att utgå ifrån, översatt betyder det att det bör startas en timer-interrupt och om man har väldigt dåligt koll på programmeringen kan bet bli besvärligt att få det hela till att fungera som det ska.

Men i grunden är det såhär:
* En timer ger interrupt var 0,1 sekund (eller någon annan hastighet i det grannlag).
* En variabel ("Percentage") innehåller det önskade värmevärde, t.ex. i %. Alltså hur mycket elementet ska vara på.
* Allt larv med "digitalwrite" osv. skiter man i och definierar pinnarna korrekt direkt.
Sedan kör man en programsnudd som i essens ser ut såhär:

Kod: Markera allt

#define Heater_Element PORTx.y // Vad det nu är...

void Timer_ISR(void)
  {
  static unsigned char Counter;
  if(Counter < Percentage) Heater_Element = true;
  else Heater_Element = false;
  if(++Counter >= 100) Counter = 0; // Makes count 0-99
  }
Då kan main-loop bara ställa rätt värde i "Percentage" och elementet slås på till den effekt. Är det ett 50W element och man väljer 1% får man ut 0,5W, så enkelt är det.

Om man samtidig har en långsammare timer på kanske 30 sekunders intervall (man kan använda samma timer-interrupt men skala ner det bara) kan man kolla då om temperaturen är korrekt. Är den det är allt OK och inget ändras, är den för låg stegar man upp "Percentage" ett snäpp och är den för hög stegar man ner den ett snäpp. Tiden mellan regleringarna ska såklart anpassas till den regleringstid det finns, går det snabbt att ändra temperaturen måste regleringen reglera snabbat osv.
Skriv svar