Thermiek melder

Projecten die niet passen in bovenstaande onderwerpen
Berichten: 7
Geregistreerd: 23 Sep 2012, 20:04

Thermiek melder

Berichtdoor cordan » 25 Sep 2012, 18:13

Hoi allemaal,
Ik ben daniel en ben een fervente modelbouwer(vliegtuigen) en al een jaartje of zo spookt er een probleempje door mijn hoofd.
Als ik aan het vliegen ben met mijn zwevers is het de bedoeling om zo lang mogelijk in de lucht te blijven,dus zoeken wij thermiek bellen zodat we gebruik
kunnen maken van de opwaartse lucht om terug hoogte te winnen.
Het probleem is dat als je in een bel zit dat je dat niet ziet en eer je door hebt dat je aan het stijgen bent moet je vliegtuig toch al enkele tientallen meters
omhoog gegaan zijn.Er bestaat wel een soort zendertje dat je kan inbouwen en via een oortje kan je dan luisteren of je stijgt of daald maar dat spreekt mij niet aan en is vrij prijzig.
Nu heb ik sinds enkele weken voor het eerst in mijn leven van Arduino gehoord,en na wat googelen dacht ik "dat is het"!
Dus heb ik mij een arduino nano V3 gekocht en een sensor van BOSCH(BMP085) om de luchtdruk te meten en na wat zoeken een sketch gevonden om dat allemaal aan de gang te krijgen wat trouwens perfect werkt.In tussen natuurlijk wat zitten te oefenen met blink en zo want C is compleet nieuw voor mij!
Nu zou ik het programma wat willen aanpassen zodat als de luchtdruk daalt (dan gaat mijn vliegtuig omhoog) er op pin 13 een led gaat knipperen.
Na herhaaldelijke pogingen moet ik zeggen dat dit toch iets te moeilijk wordt voor mij! Ik krijg steeds foutmeldingen als ik ook maar een regeltje wil toevoegen in het programma vandaar dat ik hulp vraag.
Eigenlijk zou het programma gewoon moeten kijken of de luchtdruk is gedaald ten opzichte van een seconde of 2 geleden en zo ja dan moet er een led 3 X gaan knipperen zo dat ik later een powerled verder kan gaan aansturen.
Heeft er iemand zin om eens naar dat programma te kijken waar ik het best wat kan invoegen en mij wat vooruit te helpen ?
Alvast bedank :oops:





// Connect VCC to VCC and GND to GND, SCL goes to analogue pin 5, SDA to analogue pin4.
// Notice! Sparkfun breakoutboard contains already 4.7K pull ups,
// If not using pre-built pull-ups:
// --> Add some pull up resistors (1K to 20K, most often something like 4.7K) between SDA, SCL and VCC finishes the setup.

// References: http://interactive-matter.org/2009/12/a ... or-bmp085/ and http://news.jeelabs.org/2009/02/19/hook ... 85-sensor/
// Specification: http://www.bosch-sensortec.com/content/ ... 000-05.pdf
// SparkFun breakout board: http://www.sparkfun.com/commerce/produc ... ts_id=9694

#include "Wire.h"

#define I2C_ADDRESS 0x77

const unsigned char oversampling_setting = 3; //oversamplig for measurement
const unsigned char pressure_waittime[4] = { 5, 8, 14, 26 };

//just taken from the BMP085 datasheet
int ac1;
int ac2;
int ac3;
unsigned int ac4;
unsigned int ac5;
unsigned int ac6;
int b1;
int b2;
int mb;
int mc;
int md;

void setup()
{
Serial.begin(9600); // start serial for output
Serial.println("Setting up BMP085");
Wire.begin();
bmp085_get_cal_data();
}
void bmp085_read_temperature_and_pressure(int& temperature, long& pressure);
void loop()
{
int temperature = 0;
long pressure = 0;


bmp085_read_temperature_and_pressure(&temperature,&pressure);
Serial.print(temperature,DEC);
Serial.print(" ");
Serial.print(pressure/10,DEC);
Serial.println();
delay(100);
}

void bmp085_read_temperature_and_pressure(int* temperature, long* pressure) {
int ut= bmp085_read_ut();
long up = bmp085_read_up();
long x1, x2, x3, b3, b5, b6, p;
unsigned long b4, b7;

//calculate the temperature
x1 = ((long)ut - ac6) * ac5 >> 15;
x2 = ((long) mc << 11) / (x1 + md);
b5 = x1 + x2;
*temperature = (b5 + 8) >> 4;

//calculate the pressure
b6 = b5 - 4000;
x1 = (b2 * (b6 * b6 >> 12)) >> 11;
x2 = ac2 * b6 >> 11;
x3 = x1 + x2;

//b3 = (((int32_t) ac1 * 4 + x3)<> 2;

if (oversampling_setting == 3) b3 = ((int32_t) ac1 * 4 + x3 + 2) << 1;
if (oversampling_setting == 2) b3 = ((int32_t) ac1 * 4 + x3 + 2);
if (oversampling_setting == 1) b3 = ((int32_t) ac1 * 4 + x3 + 2) >> 1;
if (oversampling_setting == 0) b3 = ((int32_t) ac1 * 4 + x3 + 2) >> 2;

x1 = ac3 * b6 >> 13;
x2 = (b1 * (b6 * b6 >> 12)) >> 16;
x3 = ((x1 + x2) + 2) >> 2;
b4 = (ac4 * (uint32_t) (x3 + 32768)) >> 15;
b7 = ((uint32_t) up - b3) * (50000 >> oversampling_setting);
p = b7 < 0x80000000 ? (b7 * 2) / b4 : (b7 / b4) * 2;

x1 = (p >> 8) * (p >> 8);
x1 = (x1 * 3038) >> 16;
x2 = (-7357 * p) >> 16;
*pressure = p + ((x1 + x2 + 3791) >> 4);

}

unsigned int bmp085_read_ut() {
write_register(0xf4,0x2e);
delay(5); //longer than 4.5 ms
return read_int_register(0xf6);
}

void bmp085_get_cal_data() {
Serial.println("Reading Calibration Data");
ac1 = read_int_register(0xAA);
Serial.print("AC1: ");
Serial.println(ac1,DEC);
ac2 = read_int_register(0xAC);
Serial.print("AC2: ");
Serial.println(ac2,DEC);
ac3 = read_int_register(0xAE);
Serial.print("AC3: ");
Serial.println(ac3,DEC);
ac4 = read_int_register(0xB0);
Serial.print("AC4: ");
Serial.println(ac4,DEC);
ac5 = read_int_register(0xB2);
Serial.print("AC5: ");
Serial.println(ac5,DEC);
ac6 = read_int_register(0xB4);
Serial.print("AC6: ");
Serial.println(ac6,DEC);
b1 = read_int_register(0xB6);
Serial.print("B1: ");
Serial.println(b1,DEC);
b2 = read_int_register(0xB8);
Serial.print("B2: ");
Serial.println(b1,DEC);
mb = read_int_register(0xBA);
Serial.print("MB: ");
Serial.println(mb,DEC);
mc = read_int_register(0xBC);
Serial.print("MC: ");
Serial.println(mc,DEC);
md = read_int_register(0xBE);
Serial.print("MD: ");
Serial.println(md,DEC);
}

long bmp085_read_up() {
write_register(0xf4,0x34+(oversampling_setting<<6));
delay(pressure_waittime[oversampling_setting]);

unsigned char msb, lsb, xlsb;
Wire.beginTransmission(I2C_ADDRESS);
Wire.write(0xf6); // register to read
Wire.endTransmission();

Wire.requestFrom(I2C_ADDRESS, 3); // read a byte
while(!Wire.available()) {
// waiting
}
msb = Wire.read();
while(!Wire.available()) {
// waiting
}
lsb |= Wire.read();
while(!Wire.available()) {
// waiting
}
xlsb |= Wire.read();
return (((long)msb<<16) | ((long)lsb<<8) | ((long)xlsb)) >>(8-oversampling_setting);
}

void write_register(unsigned char r, unsigned char v)
{
Wire.beginTransmission(I2C_ADDRESS);
Wire.write(r);
Wire.write(v);
Wire.endTransmission();
}

char read_register(unsigned char r)
{
unsigned char v;
Wire.beginTransmission(I2C_ADDRESS);
Wire.write(r); // register to read
Wire.endTransmission();

Wire.requestFrom(I2C_ADDRESS, 1); // read a byte
while(!Wire.available()) {
// waiting
}
v = Wire.read();
return v;
}

int read_int_register(unsigned char r)
{
unsigned char msb, lsb;
Wire.beginTransmission(I2C_ADDRESS);
Wire.write(r); // register to read
Wire.endTransmission();

Wire.requestFrom(I2C_ADDRESS, 2); // read a byte
while(!Wire.available()) {
// waiting
}
msb = Wire.read();
while(!Wire.available()) {
// waiting
}
lsb = Wire.read();
return (((int)msb<<8) | ((int)lsb));
}

Advertisement

Gebruikers-avatar
Berichten: 700
Geregistreerd: 05 Mrt 2012, 21:56
Woonplaats: Appingedam

Re: Thermiek melder

Berichtdoor pjh » 25 Sep 2012, 19:28

Bij de code hieronder gaat er een led branden bij stijgen en uit bij dalen. Eigenlijk heel simpel in de loop gezet. Laat maar weten als je vragen hebt.

In de code zeg ik gewoon: als druk lager dan seconde eerder dan led aan, anders uit.
Je kunt ook het verschil gebruiken om een frequentie aan te geven. Dus hoe sneller het vliegtuig stijgt, hoe sneller hij knippert. Met een andere kleur led kun je dan dalen aangeven.

Verder vroeg ik me af hoe je de read-out van je sensor in het vliegtuig, op de grond krijgt. Heb je een twee-weg zender? of is daar nog een aparte modaliteit voor nodig? In het laatste geval vraag ik me af wat de afstand tussen jou en je vliegtuig maximaal is. Ofwel: met welke golflengte kun je het beste deze communicatielijn openzetten?

Wat je denk ik wel vrij eenvoudig zou kunnen doen, is data-loggen in het vliegtuig zelf. Op eBay heb je voor een paar euro een GYRO enzo. Maar dat weet je vast al. Kun je data wegschrijven naar een SD-kaartje en later uitlezen. Dat was een van mijn eerste projectjes. Maar ik zette mijn duino niet in de lucht, maar in de vriezer (link: http://youtu.be/Uh4YoAdY-M0.



Code: Alles selecteren
/* BMP085 Extended Example Code
  by: Jim Lindblom
  SparkFun Electronics
  date: 1/18/11
  license: CC BY-SA v3.0 - http://creativecommons.org/licenses/by-sa/3.0/
 
  Get pressure and temperature from the BMP085 and calculate altitude.
  Serial.print it out at 9600 baud to serial monitor.

  Update (7/19/11): I've heard folks may be encountering issues
  with this code, who're running an Arduino at 8MHz. If you're
  using an Arduino Pro 3.3V/8MHz, or the like, you may need to
  increase some of the delays in the bmp085ReadUP and
  bmp085ReadUT functions.
*/

#include <Wire.h>

#define BMP085_ADDRESS 0x77  // I2C address of BMP085

const unsigned char OSS = 0;  // Oversampling Setting

// Calibration values
int ac1;
int ac2;
int ac3;
unsigned int ac4;
unsigned int ac5;
unsigned int ac6;
int b1;
int b2;
int mb;
int mc;
int md;
int ledPin = 13;
// b5 is calculated in bmp085GetTemperature(...), this variable is also used in bmp085GetPressure(...)
// so ...Temperature(...) must be called before ...Pressure(...).
long b5;

short temperature;
long pressure;
long pressureOud;

void setup()
{
  Serial.begin(9600);
  Wire.begin();
  bmp085Calibration();
  pinMode(13, OUTPUT);
}

void loop()
{
  temperature = bmp085GetTemperature(bmp085ReadUT());
  pressure = bmp085GetPressure(bmp085ReadUP());
  if (pressure > pressureOud){
    digitalWrite(13,HIGH);
  }
  else{
    digitalWrite(13,LOW);
  }
  pressureOud = pressure;
  /*
  Serial.print("Temperature: ");
  Serial.print(temperature, DEC);
  Serial.println(" *0.1 deg C");
  Serial.print("Pressure: ");
  Serial.print(pressure, DEC);
  Serial.println(" Pa");
  Serial.println();
  */
  delay(1000);
}

// Stores all of the bmp085's calibration values into global variables
// Calibration values are required to calculate temp and pressure
// This function should be called at the beginning of the program
void bmp085Calibration()
{
  ac1 = bmp085ReadInt(0xAA);
  ac2 = bmp085ReadInt(0xAC);
  ac3 = bmp085ReadInt(0xAE);
  ac4 = bmp085ReadInt(0xB0);
  ac5 = bmp085ReadInt(0xB2);
  ac6 = bmp085ReadInt(0xB4);
  b1 = bmp085ReadInt(0xB6);
  b2 = bmp085ReadInt(0xB8);
  mb = bmp085ReadInt(0xBA);
  mc = bmp085ReadInt(0xBC);
  md = bmp085ReadInt(0xBE);
}

// Calculate temperature given ut.
// Value returned will be in units of 0.1 deg C
short bmp085GetTemperature(unsigned int ut)
{
  long x1, x2;
 
  x1 = (((long)ut - (long)ac6)*(long)ac5) >> 15;
  x2 = ((long)mc << 11)/(x1 + md);
  b5 = x1 + x2;

  return ((b5 + 8)>>4); 
}

// Calculate pressure given up
// calibration values must be known
// b5 is also required so bmp085GetTemperature(...) must be called first.
// Value returned will be pressure in units of Pa.
long bmp085GetPressure(unsigned long up)
{
  long x1, x2, x3, b3, b6, p;
  unsigned long b4, b7;
 
  b6 = b5 - 4000;
  // Calculate B3
  x1 = (b2 * (b6 * b6)>>12)>>11;
  x2 = (ac2 * b6)>>11;
  x3 = x1 + x2;
  b3 = (((((long)ac1)*4 + x3)<<OSS) + 2)>>2;
 
  // Calculate B4
  x1 = (ac3 * b6)>>13;
  x2 = (b1 * ((b6 * b6)>>12))>>16;
  x3 = ((x1 + x2) + 2)>>2;
  b4 = (ac4 * (unsigned long)(x3 + 32768))>>15;
 
  b7 = ((unsigned long)(up - b3) * (50000>>OSS));
  if (b7 < 0x80000000)
    p = (b7<<1)/b4;
  else
    p = (b7/b4)<<1;
   
  x1 = (p>>8) * (p>>8);
  x1 = (x1 * 3038)>>16;
  x2 = (-7357 * p)>>16;
  p += (x1 + x2 + 3791)>>4;
 
  return p;
}

// Read 1 byte from the BMP085 at 'address'
char bmp085Read(unsigned char address)
{
  unsigned char data;
 
  Wire.beginTransmission(BMP085_ADDRESS);
  Wire.write(address);
  Wire.endTransmission();
 
  Wire.requestFrom(BMP085_ADDRESS, 1);
  while(!Wire.available())
    ;
   
  return Wire.read();
}

// Read 2 bytes from the BMP085
// First byte will be from 'address'
// Second byte will be from 'address'+1
int bmp085ReadInt(unsigned char address)
{
  unsigned char msb, lsb;
 
  Wire.beginTransmission(BMP085_ADDRESS);
  Wire.write(address);
  Wire.endTransmission();
 
  Wire.requestFrom(BMP085_ADDRESS, 2);
  while(Wire.available()<2)
    ;
  msb = Wire.read();
  lsb = Wire.read();
 
  return (int) msb<<8 | lsb;
}

// Read the uncompensated temperature value
unsigned int bmp085ReadUT()
{
  unsigned int ut;
 
  // Write 0x2E into Register 0xF4
  // This requests a temperature reading
  Wire.beginTransmission(BMP085_ADDRESS);
  Wire.write(0xF4);
  Wire.write(0x2E);
  Wire.endTransmission();
 
  // Wait at least 4.5ms
  delay(5);
 
  // Read two bytes from registers 0xF6 and 0xF7
  ut = bmp085ReadInt(0xF6);
  return ut;
}

// Read the uncompensated pressure value
unsigned long bmp085ReadUP()
{
  unsigned char msb, lsb, xlsb;
  unsigned long up = 0;
 
  // Write 0x34+(OSS<<6) into register 0xF4
  // Request a pressure reading w/ oversampling setting
  Wire.beginTransmission(BMP085_ADDRESS);
  Wire.write(0xF4);
  Wire.write(0x34 + (OSS<<6));
  Wire.endTransmission();
 
  // Wait for conversion, delay time dependent on OSS
  delay(2 + (3<<OSS));
 
  // Read register 0xF6 (MSB), 0xF7 (LSB), and 0xF8 (XLSB)
  Wire.beginTransmission(BMP085_ADDRESS);
  Wire.write(0xF6);
  Wire.endTransmission();
  Wire.requestFrom(BMP085_ADDRESS, 3);
 
  // Wait for data to become available
  while(Wire.available() < 3)
    ;
  msb = Wire.read();
  lsb = Wire.read();
  xlsb = Wire.read();
 
  up = (((unsigned long) msb << 16) | ((unsigned long) lsb << 8) | (unsigned long) xlsb) >> (8-OSS);
 
  return up;
}


Berichten: 7
Geregistreerd: 23 Sep 2012, 20:04

Re: Thermiek melder

Berichtdoor cordan » 26 Sep 2012, 18:36

Bedankt PJH ;)
Dat was inderdaad de oplossing!
Alleen was hij een beetje te gevoelig en bleef maar constant knipperen.
Oorzaak is dat de luchtdruk constant varieert met een paar Pa maar dat heb ik opgelost door de uitlezing van de druk door 10 te delen en zo is hij wat minder gevoelig voor schommelingen van de lucht druk.
Beter was misschien om de luchtdruk om te tellen naar de werkelijke hoogte waar het toestel zich bevind en dan de vergelijking te doen,ik ben dat ergens tegen gekomen op het net maar dat zal ik wel eens op een ander tijdstip eens proberen,dan zou ik misschien ook een melding kunnen inbouwen als ik de wettelijke vlieghoogte bereikt heb en dat is in Belgie 120 m .
Wat betreft hoe ik de data omlaag ga halen hoeft niet,de arduino gaat gewoon met het toestel mee omhoog en er zal ergens aan de onderkant een 3W powerled gemonteerd worden zodat ik vanaf de grond zie of hij stijgt!
Natuurlijk zal ik er nog een beetje hardware tussen moeten zetten om de led aan te sturen maar dat is geen probleem voor mij.
Alvast hartelijk bedankt voor de hulp en tot nog eens op het forum ;)
Intussen ga ik wat c studeren want ik denk dat die aruino's heel wat mogelijkheden hebben op het gebied van A tot Z !!!!

Gebruikers-avatar
Berichten: 700
Geregistreerd: 05 Mrt 2012, 21:56
Woonplaats: Appingedam

Re: Thermiek melder

Berichtdoor pjh » 27 Sep 2012, 01:20

Op dezesite http://bildr.org/2011/06/bmp085-arduino/ vond ik goede code voor een hoogte meter.
Deze code heb ik weer aangepast om met een led signaal de hoogte weer te geven.

Een knipperende led kan op verschillende manieren de hoogte doorgeven.
'Een' manier zou zo kunnen zijn:
1. led LANG aan om start info aan te geven
2. led knippert 0-4 keer om het aantal 100-meters aan te geven
3. led LANG aan
4. led knippert 0-3 keer om het aantal 25-meters aan te geven
5. led LANG aan
6. led knippert 0-4 keer om het aantal 5-meters aan te geven
7. led LANG uit.

Hier een plaatje ter verduidelijking: http://huinink.info/wp-content/uploads/2012/09/code-hoogte.jpg

Verderop staat de complete code, maar hier eerst het stukje dat ik heb toegevoegd:

Code: Alles selecteren
void lichtSignaal(int hoogte){
  int duurLang = 800;
  int duurKort = 400;
  int duurPauze = 200;
  int duurLangePauze = 1000;
 
  unsigned int h[3];
  h[0] = hoogte/100;
  h[1] = (hoogte - 100 * h[0]) / 25;
  h[2] = (hoogte - 100 * h[0] - h[1] * 25) / 5;
 
  for (int j = 0; j < 3; j++){
    digitalWrite(ledPin, HIGH);
    delay(duurLang);
    digitalWrite(ledPin, LOW);
    delay(duurPauze);

    for (int i = 0; i < h[j]; i++){
      digitalWrite(ledPin, HIGH);
      delay(duurKort);
      digitalWrite(ledPin, LOW);
      delay(duurPauze);
    }
    delay(300 * (4-h[j]));
    Serial.println(h[j]);
  }
  delay(duurLangePauze);
}


Dit is de seriele output:
Afbeelding

Dit is het LEDJE (http://youtu.be/vBnUd8ihbx4): het knippert zoals hierboven staat:
1. led LANG aan
2. led knippert 1 x kort = 1 x 100
3. led LANG aan
4. led knippert 0 keer kort = 0 x 25 meters
5. led LANG aan
6. led knippert 3 keer kort = 3 x 5 meters
7. led LANG uit
hoogte ==> 1 x 100 + 0x 25 + 3 x 5 = 115 meter


Sketch:

Code: Alles selecteren
//Arduino 1.0+ Only
//Arduino 1.0+ Only

/*Based largely on code by  Jim Lindblom

 Get pressure, altitude, and temperature from the BMP085.
 Serial.print it out at 9600 baud to serial monitor.
 */

#include <Wire.h>

#define BMP085_ADDRESS 0x77  // I2C address of BMP085

const unsigned char OSS = 0;  // Oversampling Setting

// Calibration values
int ac1;
int ac2;
int ac3;
unsigned int ac4;
unsigned int ac5;
unsigned int ac6;
int b1;
int b2;
int mb;
int mc;
int md;

  float temperature;
  float pressure;
  float atm;
  float altitude;
 
// b5 is calculated in bmp085GetTemperature(...), this variable is also used in bmp085GetPressure(...)
// so ...Temperature(...) must be called before ...Pressure(...).
long b5;

int ledPin = 13;

void setup(){
  pinMode(ledPin, OUTPUT);
  Serial.begin(9600);
  Wire.begin();

  bmp085Calibration();
}

void loop()
{
  temperature = bmp085GetTemperature(bmp085ReadUT()); //MUST be called first
  pressure = bmp085GetPressure(bmp085ReadUP());
  atm = pressure / 101325; // "standard atmosphere"
  altitude = calcAltitude(pressure); //Uncompensated caculation - in Meters
delay(10);
  lichtSignaal(altitude);

  Serial.print("Temperature: ");
  Serial.print(temperature, 2); //display 2 decimal places
  Serial.println("deg C");

  Serial.print("Pressure: ");
  Serial.print(pressure, 0); //whole number only.
  Serial.println(" Pa");

  Serial.print("Standard Atmosphere: ");
  Serial.println(atm, 4); //display 4 decimal places

  Serial.print("Altitude: ");
  Serial.print(altitude, 2); //display 2 decimal places
  Serial.println(" M");

  Serial.println();//line break

  delay(1000); //wait a second and get values again.
}

// Stores all of the bmp085's calibration values into global variables
// Calibration values are required to calculate temp and pressure
// This function should be called at the beginning of the program
void bmp085Calibration()
{
  ac1 = bmp085ReadInt(0xAA);
  ac2 = bmp085ReadInt(0xAC);
  ac3 = bmp085ReadInt(0xAE);
  ac4 = bmp085ReadInt(0xB0);
  ac5 = bmp085ReadInt(0xB2);
  ac6 = bmp085ReadInt(0xB4);
  b1 = bmp085ReadInt(0xB6);
  b2 = bmp085ReadInt(0xB8);
  mb = bmp085ReadInt(0xBA);
  mc = bmp085ReadInt(0xBC);
  md = bmp085ReadInt(0xBE);
}

// Calculate temperature in deg C
float bmp085GetTemperature(unsigned int ut){
  long x1, x2;

  x1 = (((long)ut - (long)ac6)*(long)ac5) >> 15;
  x2 = ((long)mc << 11)/(x1 + md);
  b5 = x1 + x2;

  float temp = ((b5 + 8)>>4);
  temp = temp /10;

  return temp;
}

// Calculate pressure given up
// calibration values must be known
// b5 is also required so bmp085GetTemperature(...) must be called first.
// Value returned will be pressure in units of Pa.
long bmp085GetPressure(unsigned long up){
  long x1, x2, x3, b3, b6, p;
  unsigned long b4, b7;

  b6 = b5 - 4000;
  // Calculate B3
  x1 = (b2 * (b6 * b6)>>12)>>11;
  x2 = (ac2 * b6)>>11;
  x3 = x1 + x2;
  b3 = (((((long)ac1)*4 + x3)<<OSS) + 2)>>2;

  // Calculate B4
  x1 = (ac3 * b6)>>13;
  x2 = (b1 * ((b6 * b6)>>12))>>16;
  x3 = ((x1 + x2) + 2)>>2;
  b4 = (ac4 * (unsigned long)(x3 + 32768))>>15;

  b7 = ((unsigned long)(up - b3) * (50000>>OSS));
  if (b7 < 0x80000000)
    p = (b7<<1)/b4;
  else
    p = (b7/b4)<<1;

  x1 = (p>>8) * (p>>8);
  x1 = (x1 * 3038)>>16;
  x2 = (-7357 * p)>>16;
  p += (x1 + x2 + 3791)>>4;

  long temp = p;
  return temp;
}

// Read 1 byte from the BMP085 at 'address'
char bmp085Read(unsigned char address)
{
  unsigned char data;

  Wire.beginTransmission(BMP085_ADDRESS);
  Wire.write(address);
  Wire.endTransmission();

  Wire.requestFrom(BMP085_ADDRESS, 1);
  while(!Wire.available())
    ;

  return Wire.read();
}

// Read 2 bytes from the BMP085
// First byte will be from 'address'
// Second byte will be from 'address'+1
int bmp085ReadInt(unsigned char address)
{
  unsigned char msb, lsb;

  Wire.beginTransmission(BMP085_ADDRESS);
  Wire.write(address);
  Wire.endTransmission();

  Wire.requestFrom(BMP085_ADDRESS, 2);
  while(Wire.available()<2)
    ;
  msb = Wire.read();
  lsb = Wire.read();

  return (int) msb<<8 | lsb;
}

// Read the uncompensated temperature value
unsigned int bmp085ReadUT(){
  unsigned int ut;

  // Write 0x2E into Register 0xF4
  // This requests a temperature reading
  Wire.beginTransmission(BMP085_ADDRESS);
  Wire.write(0xF4);
  Wire.write(0x2E);
  Wire.endTransmission();

  // Wait at least 4.5ms
  delay(5);

  // Read two bytes from registers 0xF6 and 0xF7
  ut = bmp085ReadInt(0xF6);
  return ut;
}

// Read the uncompensated pressure value
unsigned long bmp085ReadUP(){

  unsigned char msb, lsb, xlsb;
  unsigned long up = 0;

  // Write 0x34+(OSS<<6) into register 0xF4
  // Request a pressure reading w/ oversampling setting
  Wire.beginTransmission(BMP085_ADDRESS);
  Wire.write(0xF4);
  Wire.write(0x34 + (OSS<<6));
  Wire.endTransmission();

  // Wait for conversion, delay time dependent on OSS
  delay(2 + (3<<OSS));

  // Read register 0xF6 (MSB), 0xF7 (LSB), and 0xF8 (XLSB)
  msb = bmp085Read(0xF6);
  lsb = bmp085Read(0xF7);
  xlsb = bmp085Read(0xF8);

  up = (((unsigned long) msb << 16) | ((unsigned long) lsb << 8) | (unsigned long) xlsb) >> (8-OSS);

  return up;
}

void writeRegister(int deviceAddress, byte address, byte val) {
  Wire.beginTransmission(deviceAddress); // start transmission to device
  Wire.write(address);     // send register address
  Wire.write(val);         // send value to write
  Wire.endTransmission();  // end transmission
}

int readRegister(int deviceAddress, byte address){

  int v;
  Wire.beginTransmission(deviceAddress);
  Wire.write(address); // register to read
  Wire.endTransmission();

  Wire.requestFrom(deviceAddress, 1); // read a byte

  while(!Wire.available()) {
    // waiting
  }

  v = Wire.read();
  return v;
}

float calcAltitude(float pressure){

  float A = pressure/101325;
  float B = 1/5.25588;
  float C = pow(A,B);
  C = 1 - C;
  C = C /0.0000225577;

  return C;
}

void lichtSignaal(int hoogte){
  int duurLang = 800;
  int duurKort = 400;
  int duurPauze = 200;
  int duurLangePauze = 1000;
 
  unsigned int h[3];
  h[0] = hoogte/100;
  h[1] = (hoogte - 100 * h[0]) / 25;
  h[2] = (hoogte - 100 * h[0] - h[1] * 25) / 5;
 
  for (int j = 0; j < 3; j++){
    digitalWrite(ledPin, HIGH);
    delay(duurLang);
    digitalWrite(ledPin, LOW);
    delay(duurPauze);

    for (int i = 0; i < h[j]; i++){
      digitalWrite(ledPin, HIGH);
      delay(duurKort);
      digitalWrite(ledPin, LOW);
      delay(duurPauze);
    }
    delay(300 * (4-h[j]));
    Serial.println(h[j]);
  }
  delay(duurLangePauze);
}

Berichten: 7
Geregistreerd: 23 Sep 2012, 20:04

Re: Thermiek melder

Berichtdoor cordan » 28 Sep 2012, 18:02

Alweer bedankt voor de moeite pjh.
Ik denk dat ik heb wat ik wil hebben,zo als ik al zei dat ik veel verschil in de uitlezing had bij elke meting ,heb ik eens een andere sensor gebruikt.
Nu is de uilezing veel stabieler,en ik heb de indruk als ik de arduino loskoppel van de PC en overschakel naar baterijen dat het nog beter is.
Volgende stap is eens alles aan elkaar solderen want slecht contact kan ook de oorzaak zijn!
Ook denk ik dat er een foutje in uw programa geslopen was.

if (pressure > pressureOud) dat moest zijn if (pressure < pressureOud) want de druk daald al je omhoog gaat.

Nu heb ik dat nog een beetje aangepast met if (pressure < pressureOud -5)
Op deze manier heb ik de schommelingen er wat uitgehaald zodat de led niet de hele tijd aan gaat als hij op de zelfde hoogte is.
Ik heb alles nu eens getest op de trap (1 verdiep) en dan krijg ik 4 x melding als ik omhoog ga,als ik omlaag ga krijg ik geen melding.
Dat is een gemiddelde van om de 60 cm hoogte verschil, een melding (om de 3 sec gemeten),als ik om de 10 sec ga meten dan zal de gevoeligheid groter worden!

Wat betreft die andere programmas ,dat werkte niet. de led bleef de hele tijd flikkeren.
Ik zal in de week alles eens filmen en op youtube zetten,
Bedankt voor alles en tot in de week.

Gebruikers-avatar
Berichten: 700
Geregistreerd: 05 Mrt 2012, 21:56
Woonplaats: Appingedam

Re: Thermiek melder

Berichtdoor pjh » 28 Sep 2012, 19:47

Ja, dat met hoger en lager heb ik gewoon zonder nadenken erin gezet. Is maar voorbeeldcode moet je maar denken.
Je (pressure < pressureOud - 5) zal wel werken, maar je koppelt hier wel twee grootheden (pascal en tijd) aan elkaar. Immers: die 5 pascal zal het verschil niet maken, maar die 5 geldt voor het tijdsverschil tussen twee metingen. Ga je langzamer meten, dus met grotere intervallen, dan zal je marge van 5 relatief minder effect hebben. Je zou bijvoorbeeld het aantal miliseconden tussen pressure en pressureOud meting kunnen bijhouden en daarmee de werkelijke stijging of daling in meters per seconden kunnen berekenen. Dan doe je alleen maar het lampje aan bij een bepaalde stijging of daling.
- je komt maar niet van me af hè? - 

Berichten: 7
Geregistreerd: 23 Sep 2012, 20:04

Re: Thermiek melder

Berichtdoor cordan » 01 Okt 2012, 11:59

Niet erg hoor!
Ik heb dit weekend een gaatje gevonden om alles eens te gaan testen in de lucht,het systeem werkt goed allen een probleempje met de 3W powerled.
Ik had echt gedacht dat ik hem nog zou zien op 150m hoogte maar dat viel tegen.
Tot 50 a 60 m hoogte en dan was het op,dan zag je het niet meer.
Ik heb wel de led los gebruikt zonder lens met de gedachte dat ik hem dan zijdelings ook nog zag maar niet dus !
Ik zal nu iets anders moeten gaan verzinnen,misschien toch maar eens een acril lens er op zetten!
Ik kan natuurlijk ook gewoon naar meer wats gaan maar of dat verschil gaat maken weet ik niet.
Wat betreft met die 2 grootheden,Als ik op mijn serieele monitor kijk werkt dat,gaat de controller dan niet gewoon 5 eenheden van pascal verwerken?
Als dit tijd is dan moet dit 5 milli seconden zijn en zal dat wel niet veel efect hebben op de meting.
Als ik op de serieele monitor kijk dan zie ik de drukverschillen met een paar pascal ,gemiddeld tussen de 5 en 10 en soms tot 15 pascal per meting.
Nu zit ik binnen in het huis en de wind zal wel voor overdruk en onderdruk zorgen in het huis maar al bij al het project werkt!
in de loop van volgende weken zal ik nog wat moeten expirimenteren met de soft en hardware maar dat komt wel goed.

Groetjes,ik hou je nog wel op de hoogte van het verloop!

Gebruikers-avatar
Berichten: 116
Geregistreerd: 23 Dec 2011, 00:11
Woonplaats: Enschede

Re: Thermiek melder

Berichtdoor bigred » 01 Okt 2012, 17:29

cordan schreef:,ik hou je nog wel op de hoogte


Leuke woordspeling :-)

Gebruikers-avatar
Berichten: 700
Geregistreerd: 05 Mrt 2012, 21:56
Woonplaats: Appingedam

Re: Thermiek melder

Berichtdoor pjh » 01 Okt 2012, 19:00

Het zal allemaal wel niet zo veel uitmaken, maar dat met die 5 pascal klopt niet.

Neem nu alleen al het feit dat je zegt: druk < drukoud -5. Dat betekend dat je alleen schommelingen in één richting opvangt. Het zal wel een verbetering zijn en laat het maar gewoon zoals het is, maar je kunt bijvoorbeeld ook zeggen: if (abs(druk-drukOud)) > 5)
op deze manier kijk je naar het verschil ongeacht het min of plus teken.

Terug naar Overige projecten

Wie is er online?

Gebruikers in dit forum: Geen geregistreerde gebruikers en 9 gasten