Repo for ESP32 Weather Station Development
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

224 lignes
6.6KB

  1. #include "bme280.h"
  2. #include "bme280_defs.h"
  3. #include "driver/i2c.h"
  4. #include <u8g2.h>
  5. #include "u8g2_esp32_hal.h"
  6. #include <esp_log.h>
  7. void i2c_setup()
  8. {
  9. printf("Setting up I²C driver... ");
  10. //i2c_driver_install(0, I2C_MODE_MASTER, 0, 0, 0);
  11. i2c_config_t config;
  12. config.mode = I2C_MODE_MASTER;
  13. config.sda_io_num = 18;
  14. config.sda_pullup_en = GPIO_PULLUP_ENABLE;
  15. config.scl_io_num = 19;
  16. config.scl_pullup_en = GPIO_PULLUP_ENABLE;
  17. config.master.clk_speed = 100000;
  18. i2c_param_config(I2C_NUM_0, &config);
  19. printf("Set driver parameters... ");
  20. esp_err_t err = i2c_driver_install(I2C_NUM_0, I2C_MODE_MASTER, 0, 0, 0);
  21. if (err == ESP_OK)
  22. printf("Driver installed!\n");
  23. else if (err == ESP_ERR_INVALID_ARG)
  24. printf("Driver install failed, invalid arguments!\n");
  25. else
  26. printf("Driver install failed!\n");
  27. }
  28. void i2c_detect()
  29. {
  30. printf("Scanning I²C bus:\n");
  31. uint8_t address;
  32. printf(" 0 1 2 3 4 5 6 7 8 9 a b c d e f\r\n");
  33. for (int i = 0; i < 128; i += 16) {
  34. printf("%02x: ", i);
  35. for (int j = 0; j < 16; j++) {
  36. fflush(stdout);
  37. address = i + j;
  38. i2c_cmd_handle_t cmd = i2c_cmd_link_create();
  39. i2c_master_start(cmd);
  40. i2c_master_write_byte(cmd, (address << 1) | I2C_MASTER_WRITE, 0x1);
  41. i2c_master_stop(cmd);
  42. esp_err_t ret = i2c_master_cmd_begin(I2C_NUM_0, cmd, 50 / portTICK_RATE_MS);
  43. i2c_cmd_link_delete(cmd);
  44. if (ret == ESP_OK) {
  45. printf("%02x ", address);
  46. } else if (ret == ESP_ERR_TIMEOUT) {
  47. printf("UU ");
  48. } else {
  49. printf("-- ");
  50. }
  51. }
  52. printf("\r\n");
  53. }
  54. }
  55. int8_t i2c_read(uint8_t dev_id, uint8_t reg_addr, uint8_t *data, uint16_t len) {
  56. i2c_cmd_handle_t cmd = i2c_cmd_link_create();
  57. i2c_master_start(cmd);
  58. i2c_master_write_byte(cmd, dev_id << 1 | I2C_MASTER_WRITE, 1);
  59. i2c_master_write_byte(cmd, reg_addr, 1);
  60. i2c_master_start(cmd);
  61. i2c_master_write_byte(cmd, dev_id << 1 | I2C_MASTER_READ, 1);
  62. if (len > 1) {
  63. i2c_master_read(cmd, data, len - 1, I2C_MASTER_ACK);
  64. }
  65. i2c_master_read_byte(cmd, data + len - 1, I2C_MASTER_NACK);
  66. i2c_master_stop(cmd);
  67. i2c_master_cmd_begin(I2C_NUM_0, cmd, 500 / portTICK_RATE_MS);
  68. i2c_cmd_link_delete(cmd);
  69. return 0;
  70. }
  71. int8_t i2c_write(uint8_t dev_id, uint8_t reg_addr, uint8_t *data, uint16_t len) {
  72. //printf("Writing to bus: dev_id=%x, reg_addr=%x, data=%p, length=%u\n", dev_id, reg_addr, data, len);
  73. i2c_cmd_handle_t cmd = i2c_cmd_link_create();
  74. i2c_master_start(cmd);
  75. i2c_master_write_byte(cmd, (dev_id << 1) | I2C_MASTER_WRITE, 1);
  76. i2c_master_write_byte(cmd, reg_addr, 1);
  77. i2c_master_write(cmd, data, len, 1);
  78. i2c_master_stop(cmd);
  79. i2c_master_cmd_begin(I2C_NUM_0, cmd, 500 / portTICK_RATE_MS);
  80. i2c_cmd_link_delete(cmd);
  81. return 0;
  82. }
  83. void i2c_delay(uint32_t period) {
  84. vTaskDelay(period / portTICK_PERIOD_MS);
  85. }
  86. void i2c_shutdown()
  87. {
  88. printf("Shutting down I²C bus... ");
  89. esp_err_t err = i2c_driver_delete(I2C_NUM_0);
  90. if (err == ESP_ERR_INVALID_ARG)
  91. printf("Failed, invalid arguments!\n");
  92. else
  93. printf("Success!\n");
  94. }
  95. void read_sensor(struct bme280_dev* dev, int32_t* temp, uint32_t* pressure, uint32_t* humidity) {
  96. uint8_t settings_sel;
  97. uint32_t req_delay;
  98. struct bme280_data comp_data;
  99. /* Recommended mode of operation: Indoor navigation */
  100. dev->settings.osr_h = BME280_OVERSAMPLING_1X;
  101. dev->settings.osr_p = BME280_OVERSAMPLING_16X;
  102. dev->settings.osr_t = BME280_OVERSAMPLING_16X;
  103. dev->settings.filter = BME280_FILTER_COEFF_16;
  104. settings_sel = BME280_OSR_PRESS_SEL | BME280_OSR_TEMP_SEL | BME280_OSR_HUM_SEL | BME280_FILTER_SEL;
  105. bme280_set_sensor_settings(settings_sel, dev);
  106. /*Calculate the minimum delay required between consecutive measurement based upon the sensor enabled
  107. * and the oversampling configuration. */
  108. req_delay = 12*bme280_cal_meas_delay(&(dev->settings));
  109. printf("req_delay=%i\r\n", req_delay);
  110. /* Continuously stream sensor data */
  111. bme280_set_sensor_mode(BME280_FORCED_MODE, dev);
  112. /* Wait for the measurement to complete and print data @25Hz */
  113. dev->delay_ms(req_delay / portTICK_PERIOD_MS);
  114. bme280_get_sensor_data(BME280_ALL, &comp_data, dev);
  115. *temp = comp_data.temperature;
  116. *pressure = comp_data.pressure;
  117. *humidity = comp_data.humidity;
  118. }
  119. void print_data(u8g2_t* u8g2, int32_t temp, uint32_t pressure, uint32_t humidity) {
  120. int32_t temp1 = temp / 100;
  121. int32_t temp2 = (abs(temp) % 100) / 10;
  122. uint32_t press1 = pressure / 100;
  123. uint32_t humid1 = humidity / 1024;
  124. uint32_t humid2 = (humidity - humid1*1024) * 10 / 1024;
  125. //temp1 = 12;
  126. //temp2 = 3;
  127. int32_t temp3 = -1*temp1;
  128. int32_t temp4 = temp2;
  129. //press1 = 9999;
  130. //humid1 = 13;
  131. //humid2 = 4;
  132. char temp1str[31];
  133. char temp1str2[32];
  134. sprintf(temp1str, "%d,%d", temp1, temp2);
  135. if (temp1 < 10) {
  136. sprintf(temp1str2, " %s", temp1str);
  137. } else {
  138. sprintf(temp1str2, "%s", temp1str);
  139. }
  140. char temp2str[31];
  141. char temp2str2[33];
  142. sprintf(temp2str, "%d,%d", temp3, temp4);
  143. uint8_t spaces = 0;
  144. if (temp3 > 0)
  145. spaces++;
  146. if (abs(temp3) < 10)
  147. spaces++;
  148. if (spaces == 2)
  149. sprintf(temp2str2, " %s", temp2str);
  150. else if (spaces == 1)
  151. sprintf(temp2str2, " %s", temp2str);
  152. else {
  153. sprintf(temp2str2, "%s", temp2str);
  154. }
  155. char tempstr[70];
  156. sprintf(tempstr, "%s %s °C", temp1str2, temp2str2);
  157. u8g2_ClearBuffer(u8g2);
  158. char pressstr[27];
  159. char humidstr[27];
  160. sprintf(pressstr, "%d %d hPa", press1, press1);
  161. sprintf(humidstr, "%d,%d %d,%d %%", humid1, humid2, humid1, humid2);
  162. u8g2_SetFont(u8g2, u8g2_font_profont17_mf);
  163. int8_t fontheight = u8g2_GetAscent(u8g2);
  164. int8_t fontmargin = abs(u8g2_GetDescent(u8g2))+2;
  165. u8g2_DrawStr(u8g2, 0, fontheight, " IN OUT ");
  166. u8g2_DrawStr(u8g2, 0, 2*fontheight + fontmargin, tempstr);
  167. u8g2_DrawStr(u8g2, 0, 3*fontheight + 2*fontmargin, humidstr);
  168. u8g2_DrawStr(u8g2, 0, 4*fontheight + 3*fontmargin, pressstr);
  169. u8g2_SendBuffer(u8g2);
  170. }
  171. void app_main(void)
  172. {
  173. int32_t temp = 0;
  174. uint32_t pressure = 0;
  175. uint32_t humidity = 0;
  176. // INIT SENSOR
  177. i2c_setup();
  178. struct bme280_dev dev;
  179. dev.dev_id = 0x76;
  180. dev.intf = BME280_I2C_INTF;
  181. dev.read = i2c_read;
  182. dev.write = i2c_write;
  183. dev.delay_ms = i2c_delay;
  184. bme280_init(&dev);
  185. // INIT DISPLAY
  186. u8g2_esp32_hal_t u8g2_esp32_hal = U8G2_ESP32_HAL_DEFAULT;
  187. u8g2_esp32_hal.sda = 18;
  188. u8g2_esp32_hal.scl = 19;
  189. u8g2_esp32_hal_init(u8g2_esp32_hal);
  190. u8g2_t u8g2;
  191. u8g2_Setup_ssd1306_i2c_128x64_vcomh0_f(&u8g2, U8G2_R0, u8g2_esp32_i2c_byte_cb,
  192. u8g2_esp32_gpio_and_delay_cb);
  193. u8x8_SetI2CAddress(&u8g2.u8x8,0x3C << 1);
  194. u8g2_InitDisplay(&u8g2); // send init sequence to the display, display is in sleep mode after this,
  195. u8g2_SetPowerSave(&u8g2, 0); // wake up display
  196. while (1) {
  197. read_sensor(&dev, &temp, &pressure, &humidity);
  198. printf("%i °c, %i hPa, %i %%\r\n", temp, pressure, humidity);
  199. print_data(&u8g2, temp, pressure, humidity);
  200. vTaskDelay(250 / portTICK_PERIOD_MS);
  201. }
  202. }