-------------------------------------------------------------------------------- -- -- Estación Metereologica Emisor. -- -- En el emisor se realizara, la captura datos sensores. -- -- Hardware -- PIC 18F4550 con cristal externo 20Mhz. -- LCD 2x16 A BUS 4 BITS -- RTC DS3232 PROTOCOLO I2C -- SENSOR HUMEDAD/TEMPERATURA DHT22 PROTOCOLO 1_WIRE -- SENSOR PRESIÓN ATMOSFERICA BMP085 PROTOCOLO I2C -- -- LCD PIC -- ---------------------------- -- PUERTO DATOS --> [D7..D4] -- E --> D3 -- RS --> D2 -- -- DTH22 PIC -- ---------------------------- -- DATOS --> D1 -- -- BMP085 PIC -- ---------------------------- -- BMP_SDA --> B0 -- BMP_SDL --> B1 -- -------------------------------------------------------------------------------- include 18f4550 pragma target clock 48_000_000 -- fuses pragma target PLLDIV P5 -- divide by 5 - 20MHZ_INPUT pragma target CPUDIV P1 -- [primary oscillator src: /1][96 mhz pll src: /2] pragma target USBPLL F48MHZ -- CLOCK_SRC_FROM_96MHZ_PLL_2 pragma target OSC HS_PLL pragma target FCMEN DISABLED pragma target IESO DISABLED pragma target PWRTE DISABLED -- power up timer pragma target VREGEN DISABLED -- USB voltage regulator pragma target VOLTAGE MINIMUM -- brown out voltage pragma target BROWNOUT DISABLED -- no brownout detection pragma target WDTPS P32K -- watch dog saler setting pragma target WDT DISABLED -- no watchdog pragma target CCP2MUX ENABLED -- CCP2 pin C1 pragma target PBADEN DIGITAL -- digital input port<0..4> pragma target LPT1OSC LOW_POWER -- low power timer 1 pragma target MCLR EXTERNAL -- master reset on RE3 pragma target STVR DISABLED -- reset on stack over/under flow pragma target LVP DISABLED -- no low-voltage programming pragma target XINST ENABLED -- extended instruction set pragma target DEBUG DISABLED -- background debugging pragma target CP0 DISABLED -- code block 0 not protected pragma target CP1 DISABLED -- code block 1 not protected pragma target CP2 DISABLED -- code block 2 not protected pragma target CP3 DISABLED -- code block 3 not protected pragma target CPB DISABLED -- bootblock code not write protected pragma target CPD DISABLED -- eeprom code not write protected pragma target WRT0 DISABLED -- table writeblock 0 not protected pragma target WRT1 DISABLED -- table write block 1 not protected pragma target WRT2 DISABLED -- table write block 2 not protected pragma target WRT3 DISABLED -- table write block 3 not protected pragma target WRTB DISABLED -- bootblock not write protected pragma target WRTD DISABLED -- eeprom not write protected pragma target WRTC DISABLED -- config not write protected pragma target EBTR0 DISABLED -- table read block 0 not protected pragma target EBTR1 DISABLED -- table read block 1 not protected pragma target EBTR2 DISABLED -- table read block 2 not protected pragma target EBTR3 DISABLED -- table read block 3 not protected pragma target EBTRB DISABLED -- boot block not protected enable_digital_io() include delay include print include format -------------------------------------------------------------------------------- -- I2C -------------------------------------------------------------------------------- alias i2c_scl is pin_B1 alias i2c_scl_direction is pin_B1_direction alias i2c_sda is pin_B0 alias i2c_sda_direction is pin_B0_direction const word _i2c_bus_speed = 1 -- 100kHz const bit _i2c_level = true include i2c_hardware -------------------------------------------------------------------------------- -- BMP085 -------------------------------------------------------------------------------- const byte BMP085_ADDRESS = 0xEE var bit r var sword ac1 var sword ac2 var sword ac3 var word ac4 var word ac5 var word ac6 var sword b1 var sword b2 var sword mb var sword mc var sword md var word ut var dword up var sdword b5 var sdword temp_bmp085 var sdword pres_bmp085 -------------------------------------------------------------------------------- -- LCD 2x16 modo 4 bits -------------------------------------------------------------------------------- alias lcd_rs is pin_D2 -- LCD command/data select. alias lcd_rs_direction is pin_D2_direction alias lcd_en is pin_D3 -- LCD data trigger alias lcd_en_direction is pin_D3_direction alias lcd_dataport is portD_high -- LCD puerto datos alias lcd_dataport_direction is portD_high_direction lcd_rs_direction = output lcd_en_direction = output lcd_dataport_direction = output const byte LCD_ROWS = 2 -- 2 lineas const byte LCD_CHARS = 16 -- 16 caracteres por linea include lcd_hd44780_4 -- LCD libreria de 4 lineas de datos -------------------------------------------------------------------------------- -- DTH 22 -------------------------------------------------------------------------------- alias pin_dht11 is pin_D1 -- Pin señal dht22 alias pin_dht11_direction is pin_D1_direction const bit USE_DHT22 = true -- Se indica uso dht22 include temperature_humidity_dht11 -- Libreria dht11-dht22 -------------------------------------------------------------------------------- -- Escribir 8 bits en bmp085 procedure bmp085WriteByte(byte in address, byte in dato) is i2c_start() r = i2c_transmit_byte(BMP085_ADDRESS) r = r + i2c_transmit_byte(address) r = r + i2c_transmit_byte(dato) i2c_stop() end procedure -------------------------------------------------------------------------------- -- Leer 16 bits bmp085 function bmp085ReadWord(byte in address) return word is var byte msb var byte lsb var word temp = 0 i2c_start() r = i2c_transmit_byte(BMP085_ADDRESS) r = r + i2c_transmit_byte(address) i2c_start() r = i2c_transmit_byte(BMP085_ADDRESS |0x01) msb = i2c_receive_byte(1) lsb = i2c_receive_byte(0) i2c_stop() temp = word (msb) temp = temp << 8 temp = temp + lsb return temp end function -------------------------------------------------------------------------------- -- Leer 8 bits bmp085 function bmp085ReadByte(byte in address) return byte is var byte dato i2c_start() r = i2c_transmit_byte(BMP085_ADDRESS) r = r + i2c_transmit_byte(address) i2c_start() r = i2c_transmit_byte(BMP085_ADDRESS |0x01) dato = i2c_receive_byte(0) i2c_stop() end function -------------------------------------------------------------------------------- -- Leer presion bmp085 sin compensar function bmp085ReadUP() return dword is var byte msb var byte lsb var byte xlsb var dword temp = 0 var dword x1 var dword x2 var dword x3 bmp085WriteByte(0xF4, 0xF4) delay_1ms(26) i2c_restart() r = i2c_transmit_byte(BMP085_ADDRESS) r = r + i2c_transmit_byte(0xF6) i2c_start() r = i2c_transmit_byte(BMP085_ADDRESS |0x01) msb = i2c_receive_byte(1) lsb = i2c_receive_byte(1) xlsb = i2c_receive_byte(0) i2c_stop() x1 = dword (msb) * 65536 x2 = dword (lsb) * 256 x3 = dword (xlsb) temp = x1 + x2 + x3 temp = temp / 32 return temp end function -------------------------------------------------------------------------------- -- Leer temperatura bmp085 sin compensar function bmp085ReadUT() return word is var word ut bmp085WriteByte(0xF4, 0x2E) delay_1ms(5) ut = bmp085ReadWord(0xF6) return ut end function -------------------------------------------------------------------------------- -- Leer valores de calibracion bmp085 procedure bmp085Calibration() is --Leer factores calibracion ac1 = sword (bmp085ReadWord(0xAA)) ac2 = sword (bmp085ReadWord(0xAC)) ac3 = sword (bmp085ReadWord(0xAE)) ac4 = word (bmp085ReadWord(0xB0)) ac5 = word (bmp085ReadWord(0xB2)) ac6 = word (bmp085ReadWord(0xB4)) b1 = sword (bmp085ReadWord(0xB6)) b2 = sword (bmp085ReadWord(0xB8)) mb = sword (bmp085ReadWord(0xBA)) mc = sword (bmp085ReadWord(0xBC)) md = sword (bmp085ReadWord(0xBE)) ac1 = sword (bmp085ReadWord(0xAA)) end procedure -------------------------------------------------------------------------------- -- Calcular temperatura real bmp085 en 0.1ºC function bmp085_calc_temperatura() return sdword is var sdword x1 var sdword x2 var sdword t -- Formulas datasheet x1 = sdword (ut - ac6) -- X1 = (UT - AC6) * AC5 / 2^15 x1 = x1 * ac5 / 32768 x2 = mc x2 = x2 * 2048 x2 = x2 / (x1 + md) -- X2 = MC * 2^11 / (X1 + MD) b5 = x1 + x2 -- B5 = X1 + X2 t = (b5 + 8)/16 -- T = (B5 + 8) / 2^4 return t end function -------------------------------------------------------------------------------- -- Calcula presion real a nivel del mar en Pa function bmp085_calc_presion() return sdword is var sdword b3 var sdword b6 var sdword x1 var sdword x2 var sdword x3 var dword x4 var sdword p var dword b4 var dword b7 var dword p2 -- Formulas datasheet (OSS = 3) b6 = sdword (b5) - 4000 -- B6 = B5 - 4000 x3 = sdword (b6 * b6) / 4096 -- X1 = (B2 * (B6 * B6) / 2^12)) / 2^11 x2 = sdword (b2) * x3 x1 = x2 / 2048 x2 = (sdword (ac2) * b6) / 2048 -- X2 = AC2 * B6 / 2^11 x3 = x1 + x2 -- X3 = X1 + X2 x1 = sdword (ac1) * 4 -- B3 = ((AC1 * 4 + X3) << OSS + 2) / 4 x1 = x1 + x3 x1 = sdword(x1 * 8) + 2 b3 = sdword (x1) / 4 x1 = sdword(ac3) * b6 / 8192 -- X1 = AC3 * B6 / 2*13 x3 = sdword (b6 * b6) / 4096 -- X2 = (B1 * (B6 * B6) / 2^12)) / 2^16 x3 = sdword (b1) * sdword (x3) x2 = sdword (x3) / 65536 x3 = sdword (x1 + x2 + 2) / 4 -- X3 = (X1 + X2) + 2 / 2^2 p2 = dword (x3 + 32768) -- B4 = AC4 * (unsigned long)(x3 + 32768) / 2^15 p2 = dword (p2) * dword (ac4) b4 = dword (p2) / 32768 b7 = dword (up) - dword (b3) -- B7 = ((unsigned long) UP -B3) * (50000 >> OSS) b7 = dword (b7) * 6250 p2 = sdword((b7 / b4) * 2) -- P = (B7 / B4) * 2 p = sdword(p2) x1 = (p2 >> 8) * (p2 >> 8) -- X1 = (P /2^8) * (P / 2^8) x4 = dword (x1 * 3038) / 65536 -- X1 = (X1 * 3038) / 2^16 x2 = (0xFFFFE343 * p) / 65536 -- X2 = (-7357 * P) / 2^16 x1 = sdword (x4) + sdword(x2) p = p + ((x1 + 3791) / 16) -- P = P + (X1 + X2 + 3791)/2^4 return p end function -------------------------------------------------------------------------------- -- PROGRAMA PRINCIPAL -------------------------------------------------------------------------------- delay_100ms(2) -- Estabiliza tensiones lcd_init() -- Inicia lcd -- Mensaje de Bienvenida lcd_cursor_position(0,0) print_string(lcd, "Est. Met. Emisor") lcd_cursor_position(1,0) print_string(lcd, "----------------") delay_1s(3) lcd_clear_screen() -- Ini i2c i2c_initialize() delay_100ms(1) bmp085Calibration() forever loop ut = bmp085ReadUT() delay_100ms(1) up = bmp085ReadUP() delay_100ms(1) -- Leer sensor de presion temp_bmp085 = bmp085_calc_temperatura() pres_bmp085 = bmp085_calc_presion() --Leer sensor humedad-temperatura y presentar if (dht11_read() == 0) then -- Si lectura dht22 correcta lcd_cursor_position(0,0) print_string(lcd,"T = ") format_word_dec(lcd, dht11_temperature,3,1) lcd_cursor_position(1,0) print_string(lcd,"H = ") format_word_dec(lcd, dht11_humidity,3,1) end if delay_1s(5) lcd_clear_screen() -- Presentar valores bmp085 lcd_cursor_position(0,0) print_string(lcd,"T = ") format_sdword_dec(lcd,temp_bmp085 ,4,1) lcd_cursor_position(1,0) print_string(lcd,"P = ") format_sdword_dec(lcd, pres_bmp085,6,2) delay_1s(5) lcd_clear_screen() end loop