commit ede7fc88f1f57e45e8f9a35da8382f56e1d8b099 Author: Israel Herrera Date: Tue Jun 3 19:26:39 2025 +0000 Code diff --git a/BMP180 b/BMP180 new file mode 100755 index 0000000..f3f6e74 Binary files /dev/null and b/BMP180 differ diff --git a/HTU21D b/HTU21D new file mode 100755 index 0000000..4438f90 Binary files /dev/null and b/HTU21D differ diff --git a/bmp180-library/bmp180.c b/bmp180-library/bmp180.c new file mode 100644 index 0000000..a8ee589 --- /dev/null +++ b/bmp180-library/bmp180.c @@ -0,0 +1,116 @@ +#include "bmp180.h" +#include +#include +#include +#include +#include + +#define BMP180_ADDR 0x77 + +// Lectura de 16 bits de un registro (dos bytes) +static int read16(int fd, uint8_t reg, int16_t *value) { + uint8_t buf[2]; + if (write(fd, ®, 1) != 1) return -1; + if (read(fd, buf, 2) != 2) return -1; + *value = (buf[0] << 8) | buf[1]; + return 0; +} + +// Escritura de 8 bits a un registro +static int write8(int fd, uint8_t reg, uint8_t value) { + uint8_t buf[2] = {reg, value}; + if (write(fd, buf, 2) != 2) return -1; + return 0; +} + +// Leer calibración desde el sensor +int bmp180_init(int fd, bmp180_calib_data_t *calib) { + if (read16(fd, 0xAA, &calib->AC1) < 0) return -1; + if (read16(fd, 0xAC, &calib->AC2) < 0) return -1; + if (read16(fd, 0xAE, &calib->AC3) < 0) return -1; + if (read16(fd, 0xB0, (int16_t*)&calib->AC4) < 0) return -1; + if (read16(fd, 0xB2, (int16_t*)&calib->AC5) < 0) return -1; + if (read16(fd, 0xB4, (int16_t*)&calib->AC6) < 0) return -1; + if (read16(fd, 0xB6, &calib->B1) < 0) return -1; + if (read16(fd, 0xB8, &calib->B2) < 0) return -1; + if (read16(fd, 0xBA, &calib->MB) < 0) return -1; + if (read16(fd, 0xBC, &calib->MC) < 0) return -1; + if (read16(fd, 0xBE, &calib->MD) < 0) return -1; + return 0; +} + +// Leer temperatura sin procesar (raw temp) +static int bmp180_read_raw_temperature(int fd, int32_t *raw_temp) { + if (write8(fd, 0xF4, 0x2E) < 0) return -1; // start temp measurement + usleep(4500); // esperar 4.5 ms + int16_t value; + if (read16(fd, 0xF6, &value) < 0) return -1; + *raw_temp = value; + return 0; +} + +// Leer presión sin procesar (raw pressure) +static int bmp180_read_raw_pressure(int fd, int32_t *raw_press, int oss) { + if (write8(fd, 0xF4, 0x34 + (oss << 6)) < 0) return -1; // start pressure measurement + usleep(25000); // esperar 25 ms para oss=0 (simple oversampling) + uint8_t buf[3]; + uint8_t reg = 0xF6; + if (write(fd, ®, 1) != 1) return -1; + if (read(fd, buf, 3) != 3) return -1; + *raw_press = ((buf[0] << 16) | (buf[1] << 8) | buf[2]) >> (8 - oss); + return 0; +} + +int bmp180_read_temperature(int fd, bmp180_calib_data_t *calib, double *temperature) { + int32_t UT; + if (bmp180_read_raw_temperature(fd, &UT) < 0) return -1; + + int32_t X1 = ((UT - calib->AC6) * calib->AC5) >> 15; + int32_t X2 = (calib->MC << 11) / (X1 + calib->MD); + int32_t B5 = X1 + X2; + *temperature = ((B5 + 8) >> 4) / 10.0; + return 0; +} + +int bmp180_read_pressure(int fd, bmp180_calib_data_t *calib, double *pressure) { + int oss = 0; // oversampling setting 0..3 + int32_t UP; + if (bmp180_read_raw_pressure(fd, &UP, oss) < 0) return -1; + + // Recalcular B5 para temperatura, necesario para presión + int32_t UT; + if (bmp180_read_raw_temperature(fd, &UT) < 0) return -1; + + int32_t X1 = ((UT - calib->AC6) * calib->AC5) >> 15; + int32_t X2 = (calib->MC << 11) / (X1 + calib->MD); + int32_t B5 = X1 + X2; + + int32_t B6 = B5 - 4000; + X1 = (calib->B2 * ((B6 * B6) >> 12)) >> 11; + X2 = (calib->AC2 * B6) >> 11; + int32_t X3 = X1 + X2; + int32_t B3 = (((calib->AC1 * 4 + X3) << oss) + 2) >> 2; + + X1 = (calib->AC3 * B6) >> 13; + X2 = (calib->B1 * ((B6 * B6) >> 12)) >> 16; + X3 = ((X1 + X2) + 2) >> 2; + + uint32_t B4 = (calib->AC4 * (uint32_t)(X3 + 32768)) >> 15; + uint32_t B7 = ((uint32_t)UP - B3) * (50000 >> oss); + + int32_t p; + 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 = p + ((X1 + X2 + 3791) >> 4); + + *pressure = p / 100.0; // Pa a hPa (mbar) + return 0; +} diff --git a/bmp180-library/bmp180.h b/bmp180-library/bmp180.h new file mode 100644 index 0000000..d8a7157 --- /dev/null +++ b/bmp180-library/bmp180.h @@ -0,0 +1,17 @@ +#ifndef BMP180_H +#define BMP180_H + +#include + +typedef struct { + int16_t AC1, AC2, AC3; + uint16_t AC4, AC5, AC6; + int16_t B1, B2; + int16_t MB, MC, MD; +} bmp180_calib_data_t; + +int bmp180_init(int fd, bmp180_calib_data_t *calib); +int bmp180_read_temperature(int fd, bmp180_calib_data_t *calib, double *temperature); +int bmp180_read_pressure(int fd, bmp180_calib_data_t *calib, double *pressure); + +#endif diff --git a/bmp180-library/main.c b/bmp180-library/main.c new file mode 100644 index 0000000..62b16dd --- /dev/null +++ b/bmp180-library/main.c @@ -0,0 +1,49 @@ +#include +#include +#include +#include +#include +#include "bmp180.h" + +#define I2C_BUS "/dev/i2c-2" +#define BMP180_ADDR 0x77 + +int main() { + int fd = open(I2C_BUS, O_RDWR); + if (fd < 0) { + perror("Error abriendo el bus I2C"); + return 1; + } + + if (ioctl(fd, I2C_SLAVE, BMP180_ADDR) < 0) { + perror("Error configurando la dirección I2C"); + close(fd); + return 1; + } + + bmp180_calib_data_t calib; + if (bmp180_init(fd, &calib) < 0) { + fprintf(stderr, "Error leyendo datos de calibración BMP180\n"); + close(fd); + return 1; + } + + double temperature, pressure; + + if (bmp180_read_temperature(fd, &calib, &temperature) < 0) { + fprintf(stderr, "Error leyendo temperatura BMP180\n"); + close(fd); + return 1; + } + + if (bmp180_read_pressure(fd, &calib, &pressure) < 0) { + fprintf(stderr, "Error leyendo presión BMP180\n"); + close(fd); + return 1; + } + + printf("{\"temperature\": %.2f, \"pressure\": %.2f}\n", temperature, pressure); + + close(fd); + return 0; +} diff --git a/data/BMP180.json b/data/BMP180.json new file mode 100644 index 0000000..d3af33e --- /dev/null +++ b/data/BMP180.json @@ -0,0 +1 @@ +{ "temperature": 28.70, "pressure": 813.51} \ No newline at end of file diff --git a/data/HTU21D.json b/data/HTU21D.json new file mode 100644 index 0000000..ca9eba0 --- /dev/null +++ b/data/HTU21D.json @@ -0,0 +1 @@ +{ "temperature": 24.60, "humidity": 52.50 } diff --git a/data/test.json b/data/test.json new file mode 100644 index 0000000..e69de29 diff --git a/htu21d-library/.gitignore b/htu21d-library/.gitignore new file mode 100644 index 0000000..1377554 --- /dev/null +++ b/htu21d-library/.gitignore @@ -0,0 +1 @@ +*.swp diff --git a/htu21d-library/HTU21D.c b/htu21d-library/HTU21D.c new file mode 100644 index 0000000..a29b4b6 --- /dev/null +++ b/htu21d-library/HTU21D.c @@ -0,0 +1,45 @@ +#include //Send and recive I2C commands +#include //setup i2c devices +#include //Definitions and structures +#include //smbus commands +#include //To print error + +#include "htu21d.h" + +//Temperature +int getTemp(int fd, double *temp){ + getReset(fd); + char buffer[3]; + __s32 res = i2c_smbus_read_i2c_block_data(fd,HTU21D_TEMP, 3, buffer); + if(res<0){ + perror("ERROR-1: Failed to read Temperature"); + return -1; + } + *temp = -46.85+175.72*(buffer[0]*256+buffer[1])/65536.0; + return 0; +} + +//Humidity +int getHum(int fd, double *hum){ + getReset(fd); + char buffer[3]; + __s32 res = i2c_smbus_read_i2c_block_data(fd,HTU21D_HUM, 3, buffer); + if(res<0){ + perror("ERROR -3: Failed to read Humidity"); + return -1; + } + *hum = -6+125*(buffer[0]*256+buffer[1])/65536.0; + return 0; +} + + +//reset function: +int getReset(int fd){ + if(0>ioctl(fd, I2C_SLAVE, HTU21D_ADDR)){ + perror("ERROR -2: Failed in reset"); + return -2; + } + i2c_smbus_write_byte(fd, HTU21D_RESET); + return 0; + +} diff --git a/htu21d-library/htu21d.h b/htu21d-library/htu21d.h new file mode 100644 index 0000000..83499c9 --- /dev/null +++ b/htu21d-library/htu21d.h @@ -0,0 +1,20 @@ +#ifndef HTU21D_H +#define HTU21D_H + +// HTU21D i2c address +#define HTU21D_ADDR 0x40 + +//commands for readings +#define HTU21D_TEMP 0xE3 +#define HTU21D_HUM 0xE5 +#define HTU21D_RESET 0xFE + +//funtion declarations + +//Temp: +int getTemp(int fd, double *temp); +//HUM +int getHum(int fd, double *hum); +//RESET +int getReset(int fd); +#endif diff --git a/htu21d-library/main.c b/htu21d-library/main.c new file mode 100644 index 0000000..aeabac4 --- /dev/null +++ b/htu21d-library/main.c @@ -0,0 +1,43 @@ +/* Example code of using htu21d.h + Israel Herrera + 20/03/2025 +*/ + +#include +#include +#include +//Aditional librarys +#include +#include +#include "htu21d.h" + +#define I2C_PATH "/dev/i2c-%d" +#define I2C_PORT 2 +int main(){ + char filePath[20]; + snprintf(filePath, sizeof(filePath), I2C_PATH, I2C_PORT ); + int fd = open(filePath, O_RDWR); + + if(fd<0){ + fprintf(stderr, "Error: Unable to access HTU21D sensor: %s",strerror(errno)); + exit(-1); + } + //measurements + double temperature=0; + double humidity=0; + if((getTemp(fd, &temperature)<0)||(getHum(fd, &humidity)<0)){ + fprintf(stderr,"Error -404: Measurments not read"); + exit(-1); + } + + + //printf("HTU21D Module \n"); + //printf("%5.2fC \n", temperature); + //printf("%5.2fC \n", humidity); + printf("{"); + printf("\"temperature\": %5.2f,", temperature); + printf("\"humidity\": %5.2f", humidity); + printf("}"); + return 0; + +} diff --git a/ui/BMP180.json b/ui/BMP180.json new file mode 100644 index 0000000..e69de29 diff --git a/ui/HTU21D.json b/ui/HTU21D.json new file mode 100644 index 0000000..e69de29 diff --git a/ui/index.html b/ui/index.html new file mode 100644 index 0000000..5de0824 --- /dev/null +++ b/ui/index.html @@ -0,0 +1,35 @@ + + + + + + Sensor Dashboard + + + +
+
+

Sensor Dashboard

+ +
+ Temperature & Pressure Icon +

BMP180

+
+ Temperature: -- °C + Pressure: -- hPa +
+
+ +
+ Humidity Icon +

HTU21D

+
+ Humidity: -- % + Temperature: -- °C +
+
+
+ + + + diff --git a/ui/index.js b/ui/index.js new file mode 100644 index 0000000..5654753 --- /dev/null +++ b/ui/index.js @@ -0,0 +1,28 @@ +function updateBMP180() { + fetch('BMP180.json') + .then(res => res.json()) + .then(data => { + document.getElementById('temperature').textContent = `Temperature: ${data.temperature.toFixed(2)} °C`; + document.getElementById('pressure').textContent = `Pressure: ${data.pressure.toFixed(2)} hPa`; + }) + .catch(err => console.error("Error BMP180:", err)); +} + +function updateHTU21D() { + fetch('HTU21D.json') + .then(res => res.json()) + .then(data => { + document.getElementById('humidity').textContent = `Humidity: ${data.humidity.toFixed(1)} %`; + document.getElementById('tempHTU').textContent = `Temperature: ${data.temperature.toFixed(1)} °C`; + }) + .catch(err => console.error("Error HTU21D:", err)); +} + +setInterval(() => { + updateBMP180(); + updateHTU21D(); +}, 3000); + +// Carga inicial +updateBMP180(); +updateHTU21D(); diff --git a/ui/style.css b/ui/style.css new file mode 100644 index 0000000..ca37440 --- /dev/null +++ b/ui/style.css @@ -0,0 +1,85 @@ +* { + margin: 0; + padding: 0; + box-sizing: border-box; + font-family: "Segoe UI", sans-serif; +} + +body, html { + height: 100%; + background-color: #0d1117; + color: #ffffff; + position: relative; + overflow: hidden; +} + +.background { + background-image: url('https://wallpapers.com/images/hd/blue-circuit-board-traces-zn0xezd4t8axj9r6.webp'); + background-size: cover; + background-position: center; + opacity: 0.1; + filter: blur(3px); + position: absolute; + top: 0; left: 0; + width: 100%; + height: 100%; + z-index: -1; +} + +.container { + max-width: 800px; + margin: 40px auto; + background-color: #161b22; + padding: 30px; + border-radius: 20px; + box-shadow: 0 0 30px rgba(0, 255, 255, 0.2); + animation: fadeIn 1s ease-in; +} + +h1 { + text-align: center; + margin-bottom: 30px; + font-size: 2.5rem; + color: #58a6ff; +} + +.sensor-card { + background-color: #1f2937; + padding: 20px; + border-radius: 15px; + margin-bottom: 20px; + box-shadow: 0 0 20px rgba(100, 255, 255, 0.1); + animation: slideIn 1s ease; + display: flex; + flex-direction: column; + align-items: center; + text-align: center; +} + +.sensor-card img { + width: 64px; + height: 64px; + margin-bottom: 10px; +} + +.sensor-card h2 { + margin-bottom: 10px; + color: #90cdf4; +} + +.data span { + display: block; + margin: 5px 0; + font-size: 1.2rem; + color: #ffffff; +} + +@keyframes fadeIn { + from { opacity: 0; transform: translateY(-20px); } + to { opacity: 1; transform: translateY(0); } +} + +@keyframes slideIn { + from { opacity: 0; transform: scale(0.9); } + to { opacity: 1; transform: scale(1); } +}