-
Notifications
You must be signed in to change notification settings - Fork 7
/
Arduino-Weather-Station.ino
603 lines (534 loc) · 18.8 KB
/
Arduino-Weather-Station.ino
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
/* Name: lacrosse.ino
* Version: 1.2
* Author: Kelsey Jordahl
* Copyright: Kelsey Jordahl 2010-2018
(portions copyright Marc Alexander, Jonathan Oxer 2009;
Interactive Matter 2009 [licensed under GPL with permission])
* License: GPLv3
* Time-stamp: <Sat Jul 11 13:54:28 PDT 2020>
Receive La Crosse TX4 weather sensor data with Arduino and send to
serial (USB) port. Also records indoor pressure and temperature from
two on-board I2C sensors, a BMP085 and a DS1631. Assumes the 433 MHz
data pin is connected to Digital Pin 8 (PB0). Analog pins 4 and 5 are
used for I2C communication with pressure and temperature sensors.
Based on idea, and some code, from Practical Arduino
http://www.practicalarduino.com/projects/weather-station-receiver
http://github.com/practicalarduino/WeatherStationReceiver
Also useful was the detailed data protocol description at
http://www.f6fbb.org/domo/sensors/tx3_th.php
433.92 MHz RF receiver:
http://www.sparkfun.com/commerce/product_info.php?products_id=8950
BMP085 pressure sensor:
Breakout board and datasheet available from SparkFun:
http://www.sparkfun.com/commerce/product_info.php?products_id=9694
functions to communicate with BMP085 via I2C from:
http://interactive-matter.org/2009/12/arduino-barometric-pressure-sensor-bmp085
see also:
http://news.jeelabs.org/2009/02/19/hooking-up-a-bmp085-sensor
DS1631 temperature sensor:
Maxim digital temperature sensor with I2C interface in DIP-8 package
http://www.maxim-ic.com/datasheet/index.mvp/id/3241
see also:
http://kennethfinnegan.blogspot.com/2009/10/arduino-temperature-logger.html
Thermistor (no longer used):
Vishay 10 kOhm NTC thermistor
part no: NTCLE100E3103GB0
<http://www.vishay.com/thermistors/list/product-29049>
LM61 (no longer used):
National Semiconductor TO-92 Temperature Sensor
10 mV/degree with 600 mV offset, temperature range -30 deg C to 100 deg C
part no: LM61BIZ
<http://www.national.com/mpf/LM/LM61.html>
see: http://www.arduino.cc/playground/ComponentLib/Thermistor2
and: http://www.ladyada.net/learn/sensors/tmp36.html
This program is free software: you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version. A copy of the GPL
version 3 license can be found in the file COPYING or at
<http://www.gnu.org/licenses/>.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
*/
#include <math.h>
#include <Wire.h>
#include <ArduinoJson.h>
// Comment out for a normal build
// Uncomment for a debug build
//#define DEBUG
#define INPUT_CAPTURE_IS_RISING_EDGE() ((TCCR1B & _BV(ICES1)) != 0)
#define INPUT_CAPTURE_IS_FALLING_EDGE() ((TCCR1B & _BV(ICES1)) == 0)
#define SET_INPUT_CAPTURE_RISING_EDGE() (TCCR1B |= _BV(ICES1))
#define SET_INPUT_CAPTURE_FALLING_EDGE() (TCCR1B &= ~_BV(ICES1))
#define GREEN_TESTLED_ON() ((PORTD &= ~(1<<PORTD6)))
#define GREEN_TESTLED_OFF() ((PORTD |= (1<<PORTD6)))
// I reversed the red - did I flip the LED from the schematic?
#define RED_TESTLED_OFF() ((PORTD &= ~(1<<PORTD7)))
#define RED_TESTLED_ON() ((PORTD |= (1<<PORTD7)))
#define BMP085_ADDRESS 0x77 /* I2C address of BMP085 pressure sensor */
#define DS1631_ADDRESS 0x48 /* I2C address of DS1631 temp sensor */
#define MAXTICK 6009 /* about 60 s interval for pressure sampling */
// DS1631 command codes
#define STARTTEMP 0x51
#define READTEMP 0xAA
#define PRECISION_11BIT 0x08
#define PRECISION_12BIT 0x0C
/* serial port communication (via USB) */
#define BAUD_RATE 9600
#define PACKET_SIZE 9 /* number of nibbles in packet (after inital byte) */
#define PACKET_START 0x0A /* byte to match for start of packet */
// 0.5 ms high is a one
#define MIN_ONE 135 // minimum length of '1'
#define MAX_ONE 155 // maximum length of '1'
// 1.3 ms high is a zero
#define MIN_ZERO 335 // minimum length of '0'
#define MAX_ZERO 370 // maximum length of '0'
// 1 ms between bits
#define MIN_WAIT 225 // minimum interval since end of last bit
#define MAX_WAIT 275 // maximum interval since end of last bit
/* constants for extended Steinhart-Hart equation from thermistor datasheet
#define A 3.354016E-03
#define B 2.569850E-04
#define C 2.620131E-06
#define D 6.383091E-08
*/
/* ADC depends on reference voltage. Could tie this to internal 1.05 V? */
/* Linux machine voltage */
//#define VCC 4.85 /* supply voltage on USB */
/* MacBook voltage */
//#define VCC 5.05 /* supply voltage on USB */
//#define LM61PIN 0 /* analog pin for LM61 sensor */
//#define THERMPIN 1 /* analog pin for thermistor */
const unsigned char oversampling_setting = 3; //oversampling for measurement
const unsigned char pressure_waittime[4] = { 5, 8, 14, 26 };
/* calibration constants 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;
unsigned int CapturedTime;
unsigned int PreviousCapturedTime;
unsigned int CapturedPeriod;
unsigned int PreviousCapturedPeriod;
unsigned int SinceLastBit;
unsigned int LastBitTime;
unsigned int BitCount;
byte j;
float tempC; /* temperature in deg C */
float tempF; /* temperature in deg F */
float dp; /* dewpoint (deg C) */
byte h; /* relative humidity */
byte DataPacket[PACKET_SIZE]; /* actively loading packet */
byte FinishedPacket[PACKET_SIZE]; /* fully read packet */
byte PacketBitCounter;
boolean ReadingPacket;
boolean PacketDone;
byte CapturedPeriodWasHigh;
byte PreviousCapturedPeriodWasHigh;
byte mask; /* temporary mask byte */
byte CompByte; /* byte containing the last 8 bits read */
volatile unsigned int tick = 0; /* count ticks of the clock */
int temperature = 0; /* BMP085 temp (0.1 deg) */
long pressure = 0; /* BMP085 pressure (Pa) */
unsigned int starttime;
unsigned int interval;
boolean timerflag = false; /* flag to set when timer goes off */
// pressure sample interval timer
ISR(TIMER2_COMPA_vect) {
if (tick++ > MAXTICK) {
timerflag = true;
tick=0;
}
}
// does nothing now
ISR( TIMER1_OVF_vect )
{
//increment the 32 bit timestamp counter (see overflow notes above)
//overflow is allowed as this timestamp is most likely to be used as a delta from the previous timestamp,
//so if it's used externally in the same 32 bit unsigned type it will come out ok.
GREEN_TESTLED_OFF();
}
ISR( TIMER1_CAPT_vect )
{
// Immediately grab the current capture time in case it triggers again and
// overwrites ICR1 with an unexpected new value
CapturedTime = ICR1;
// GREEN test led on (flicker for debug)
GREEN_TESTLED_ON();
if( INPUT_CAPTURE_IS_RISING_EDGE() )
{
SET_INPUT_CAPTURE_FALLING_EDGE(); //previous period was low and just transitioned high
CapturedPeriodWasHigh = false; //uiICP_CapturedPeriod about to be stored will be a low period
} else {
SET_INPUT_CAPTURE_RISING_EDGE(); //previous period was high and transitioned low
CapturedPeriodWasHigh = true; //uiICP_CapturedPeriod about to be stored will be a high period
}
CapturedPeriod = (CapturedTime - PreviousCapturedTime);
if ((CapturedPeriod > MIN_ONE) && (CapturedPeriodWasHigh == true)) { // possible bit
/* time from end of last bit to beginning of this one */
SinceLastBit = (PreviousCapturedTime - LastBitTime);
if ((CapturedPeriod < MAX_ONE) && (SinceLastBit > MIN_WAIT)) {
if (SinceLastBit > MAX_WAIT) { // too long since last bit read
if ((SinceLastBit > (2*MIN_WAIT+MIN_ONE)) && (SinceLastBit < (2*MAX_WAIT+MAX_ONE))) { /* missed a one */
#ifdef DEBUG
Serial.println("missed one");
#endif
} else {
if ((SinceLastBit > (2*MIN_WAIT+MIN_ZERO)) && (SinceLastBit < (2*MAX_WAIT+MAX_ZERO))) { /* missed a zero */
#ifdef DEBUG
Serial.println("missed zero");
#endif
}
}
RED_TESTLED_OFF();
if (ReadingPacket) {
#ifdef DEBUG
Serial.print("dropped packet. bits read: ");
Serial.println(PacketBitCounter,DEC);
#endif
ReadingPacket=0;
PacketBitCounter=0;
}
CompByte=0xFF; /* reset comparison byte */
} else { /* call it a one */
if (ReadingPacket) { /* record the bit as a one */
// Serial.print("1");
mask = (1 << (3 - (PacketBitCounter & 0x03)));
DataPacket[(PacketBitCounter >> 2)] |= mask;
PacketBitCounter++;
} else { /* still looking for valid packet data */
if (CompByte != 0xFF) { /* don't bother recording if no zeros recently */
CompByte = ((CompByte << 1) | 0x01); /* push one on the end */
}
}
LastBitTime = CapturedTime;
}
} else { /* Check whether it's a zero */
if ((CapturedPeriod > MIN_ZERO) && (CapturedPeriod < MAX_ZERO)) {
if (ReadingPacket) { /* record the bit as a zero */
// Serial.print("0");
mask = (1 << (3 - (PacketBitCounter & 0x03)));
DataPacket[(PacketBitCounter >> 2)] &= ~mask;
PacketBitCounter++;
} else { /* still looking for valid packet data */
CompByte = (CompByte << 1); /* push zero on the end */
/* if ((CompByte & 0xF0) != 0xf0) { */
/* Serial.println(CompByte,HEX); */
/* } */
}
LastBitTime = CapturedTime;
}
}
}
if (ReadingPacket) {
if (PacketBitCounter == (4*PACKET_SIZE)) { /* done reading packet */
memcpy(&FinishedPacket,&DataPacket,PACKET_SIZE);
RED_TESTLED_OFF();
PacketDone = 1;
ReadingPacket = 0;
PacketBitCounter = 0;
}
} else {
/* Check whether we have the start of a data packet */
if (CompByte == PACKET_START) {
// Serial.println("Got packet start!");
CompByte=0xFF; /* reset comparison byte */
RED_TESTLED_ON();
/* set a flag and start recording data */
ReadingPacket = 1;
}
}
//save the current capture data as previous so it can be used for period calculation again next time around
PreviousCapturedTime = CapturedTime;
PreviousCapturedPeriod = CapturedPeriod;
PreviousCapturedPeriodWasHigh = CapturedPeriodWasHigh;
//GREEN test led off (flicker for debug)
GREEN_TESTLED_OFF();
}
float dewpoint(float T, float h) {
float td;
// Simplified dewpoint formula from Lawrence (2005), doi:10.1175/BAMS-86-2-225
td = T - (100-h)*pow(((T+273.15)/300),2)/5 - 0.00135*pow(h-84,2) + 0.35;
return td;
}
void setup() {
Serial.begin( BAUD_RATE ); //using the USB serial port for debugging and logging
// Serial.println( "La Crosse weather station capture begin" );
StaticJsonBuffer<100> jsonBuffer;
JsonObject& json = jsonBuffer.createObject();
json["message"] = "start";
json.printTo(Serial);
Serial.println();
Wire.begin();
bmp085_get_cal_data();
// initialize the DS1631 temperature sensor
Wire.beginTransmission(DS1631_ADDRESS);
Wire.write(0xAC);
Wire.write(PRECISION_12BIT);
Wire.endTransmission();
delay(10);
Wire.beginTransmission(DS1631_ADDRESS);
Wire.write(STARTTEMP);
Wire.endTransmission();
cli();
DDRB = 0x2F; // B00101111
DDRB &= ~(1<<DDB0); //PBO(ICP1) input
PORTB &= ~(1<<PORTB0); //ensure pullup resistor is also disabled
//PORTD6 and PORTD7, GREEN and RED test LED setup
DDRD |= B11000000; //(1<<PORTD6); //DDRD |= (1<<PORTD7); (example of B prefix)
GREEN_TESTLED_OFF(); //GREEN test led off
// Set up timer1 for RF signal detection
TCCR1A = B00000000; //Normal mode of operation, TOP = 0xFFFF, TOV1 Flag Set on MAX
TCCR1B = ( _BV(ICNC1) | _BV(CS11) | _BV(CS10) );
SET_INPUT_CAPTURE_RISING_EDGE();
//Timer1 Input Capture Interrupt Enable, Overflow Interrupt Enable
TIMSK1 = ( _BV(ICIE1) | _BV(TOIE1) );
// Set up timer2 for countdown timer
TCCR2A = (1<<WGM21); /* CTC mode */
TCCR2B = ((1<<CS22) | (1<<CS21) | (1<<CS20)); /* clock/1024 prescaler */
TIMSK2 = (1<<OCIE2A); /* enable interupts */
ASSR &= ~(1<<AS2); /* make sure we're running on internal clock */
OCR2A = 155; /* interrupt f=100.16 Hz, just under 10 ms period */
sei();
interrupts(); // Enable interrupts (NOTE: is this necessary? Should be enabled by default)
}
// in the main loop, just hang around waiting to see whether the interrupt routine has gathered a full packet yet
void loop() {
delay(2); // wait for a short time
if (PacketDone) { // have a bit string that's ended
ParsePacket(FinishedPacket);
PacketDone=0;
}
if (timerflag) { // time to take a pressure sample
timerflag = false;
interval=millis() - starttime; /* measure time since last sample */
starttime = millis();
PrintIndoor(); /* get DS1631 temp */
bmp085_read_temperature_and_pressure(&temperature,&pressure);
StaticJsonBuffer<100> jsonBuffer;
JsonObject& json = jsonBuffer.createObject();
json["bmp085_temperature"] = temperature * 0.1;
json["pressure"] = pressure;
json.printTo(Serial);
Serial.println();
}
}
// parse a raw data string
void ParsePacket(byte *Packet) {
byte chksum;
StaticJsonBuffer<100> jsonBuffer;
#ifdef DEBUG
Serial.print("RAW: ");
for (j=0; j<PACKET_SIZE; j++) {
Serial.print(Packet[j], HEX);
}
Serial.println("");
#endif
chksum = 0x0A;
for (j=0; j<(PACKET_SIZE-1); j++) {
chksum += Packet[j];
}
if ((chksum & 0x0F) == Packet[PACKET_SIZE-1]) { /* checksum pass */
/* check for bad digits and make sure that most significant digits repeat */
if ((Packet[3]==Packet[6]) && (Packet[4]==Packet[7]) && (Packet[3]<10) && (Packet[4]<10) && (Packet[5]<10)) {
if (Packet[0]==0) { /* temperature packet */
tempC=(Packet[3]*10-50 + Packet[4] + ( (float) Packet[5])/10);
tempF=tempC*9/5 + 32;
JsonObject& json = jsonBuffer.createObject();
json["outdoor_temperature"] = tempC;
json.printTo(Serial);
Serial.println();
/* PrintIndoor(); // moved to time interval sampling with pressure */
dp=dewpoint(tempC,h);
} else {
if (Packet[0]==0x0E) { /* humidity packet */
h=(Packet[3]*10 + Packet[4]);
JsonObject& json = jsonBuffer.createObject();
json["humidity"] = h;
json.printTo(Serial);
Serial.println();
} else {
if (Packet[0]==0x0B) { /* custom packet */
Serial.print("CUSTOM: T= ");
tempC=(Packet[3]*10-50 + Packet[4] + ( (float) Packet[5])/10);
tempF=tempC*9/5 + 32;
Serial.print(tempC,1); /* print to 0.1 deg precision */
Serial.print(" degC, ");
Serial.print(tempF,1); /* print to 0.1 deg precision */
Serial.println(" degF");
}
}
}
} else {
#ifdef DEBUG
Serial.println("Fail secondary data check.");
#endif
}
} else { /* checksum fail */
#ifdef DEBUG
Serial.print("chksum = 0x");
Serial.print(chksum,HEX);
Serial.print(" data chksum = 0x");
Serial.println(Packet[PACKET_SIZE-1],HEX);
#endif
}
}
// send indoor temperature to serial port
void PrintIndoor() {
byte temp[2];
StaticJsonBuffer<100> jsonBuffer;
JsonObject& json = jsonBuffer.createObject();
Wire.beginTransmission(DS1631_ADDRESS);
Wire.write(READTEMP);
Wire.endTransmission();
Wire.requestFrom(DS1631_ADDRESS, 2);
temp[0] = Wire.read(); // MSB
temp[1] = Wire.read(); // LSB
tempC = temp[0] + temp[1] / 256.0;
json["indoor_temperature"] = tempC;
json["ds1631_msb"] = temp[0];
json["ds1631_lsb"] = temp[1];
json.printTo(Serial);
Serial.println();
}
void bmp085_read_temperature_and_pressure(int* temperature, long* pressure) {
long 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)<<oversampling_setting + 2) >> 2;
b3 = (((int32_t) ac1 * 4 + x3)<<oversampling_setting) >> 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() {
#ifdef DEBUG
Serial.println("Reading BMP085 calibration data");
#endif
ac1 = read_int_register(0xAA);
ac2 = read_int_register(0xAC);
ac3 = read_int_register(0xAE);
ac4 = read_int_register(0xB0);
ac5 = read_int_register(0xB2);
ac6 = read_int_register(0xB4);
b1 = read_int_register(0xB6);
b2 = read_int_register(0xB8);
mb = read_int_register(0xBA);
mc = read_int_register(0xBC);
md = read_int_register(0xBE);
#ifdef DEBUG
Serial.print("AC1: ");
Serial.println(ac1,DEC);
Serial.print("AC2: ");
Serial.println(ac2,DEC);
Serial.print("AC3: ");
Serial.println(ac3,DEC);
Serial.print("AC4: ");
Serial.println(ac4,DEC);
Serial.print("AC5: ");
Serial.println(ac5,DEC);
Serial.print("AC6: ");
Serial.println(ac6,DEC);
Serial.print("B1: ");
Serial.println(b1,DEC);
Serial.print("B2: ");
Serial.println(b1,DEC);
Serial.print("MB: ");
Serial.println(mb,DEC);
Serial.print("MC: ");
Serial.println(mc,DEC);
Serial.print("MD: ");
Serial.println(md,DEC);
#endif
}
long bmp085_read_up() {
write_register(0xf4,0x34+(oversampling_setting<<6));
delay(pressure_waittime[oversampling_setting]);
unsigned char msb, lsb, xlsb;
Wire.beginTransmission(BMP085_ADDRESS);
Wire.write(0xf6); // register to read
Wire.endTransmission();
Wire.requestFrom(BMP085_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(BMP085_ADDRESS);
Wire.write(r);
Wire.write(v);
Wire.endTransmission();
}
char read_register(unsigned char r)
{
unsigned char v;
Wire.beginTransmission(BMP085_ADDRESS);
Wire.write(r); // register to read
Wire.endTransmission();
Wire.requestFrom(BMP085_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(BMP085_ADDRESS);
Wire.write(r); // register to read
Wire.endTransmission();
Wire.requestFrom(BMP085_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));
}