Smart-Home am Beispiel der Präsenzerkennung im Raum Projektarbeit Lennart Heimbs, Johannes Krug, Sebastian Dohle und Kevin Holzschuh bei Prof. Oliver Hofmann SS2019
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

Arduino_ESP32_MLX90640.ino 9.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312
  1. #include <Wire.h>
  2. #include "MLX90640_API.h"
  3. #include "MLX90640_I2C_Driver.h"
  4. //#include "SPI.h"
  5. //#include "Adafruit_GFX.h"
  6. //#include "Adafruit_ILI9341.h"
  7. // For the ESP-WROVER_KIT, these are the default.
  8. /*#define TFT_CS 15
  9. #define TFT_DC 2
  10. #define TFT_MOSI 13
  11. #define TFT_CLK 14
  12. #define TFT_RST 26
  13. #define TFT_MISO 12
  14. #define TFT_LED 27*/
  15. /*Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_MOSI, TFT_CLK, TFT_RST, TFT_MISO);*/
  16. const byte MLX90640_address = 0x33; //Default 7-bit unshifted address of the MLX90640
  17. #define TA_SHIFT 8 //Default shift for MLX90640 in open air
  18. static float mlx90640To[768];
  19. paramsMLX90640 mlx90640;
  20. int xPos, yPos; // Abtastposition
  21. int R_colour, G_colour, B_colour; // RGB-Farbwert
  22. int i, j; // Zählvariable
  23. float T_max, T_min; // maximale bzw. minimale gemessene Temperatur
  24. float T_center; // Temperatur in der Bildschirmmitte
  25. boolean isConnected();
  26. // ***************************************
  27. // **************** SETUP ****************
  28. // ***************************************
  29. void setup()
  30. {
  31. Serial.begin(115200);
  32. Wire.begin();
  33. Wire.setClock(400000); //Increase I2C clock speed to 400kHz
  34. while (!Serial); //Wait for user to open terminal
  35. Serial.println("MLX90640 IR Array Example");
  36. if (isConnected() == false)
  37. {
  38. Serial.println("MLX90640 not detected at default I2C address. Please check wiring. Freezing.");
  39. while (1);
  40. }
  41. Serial.println("MLX90640 online!");
  42. //Get device parameters - We only have to do this once
  43. int status;
  44. uint16_t eeMLX90640[832];
  45. status = MLX90640_DumpEE(MLX90640_address, eeMLX90640);
  46. if (status != 0)
  47. Serial.println("Failed to load system parameters");
  48. status = MLX90640_ExtractParameters(eeMLX90640, &mlx90640);
  49. if (status != 0)
  50. {
  51. Serial.println("Parameter extraction failed");
  52. Serial.print(" status = ");
  53. Serial.println(status);
  54. }
  55. //Once params are extracted, we can release eeMLX90640 array
  56. MLX90640_I2CWrite(0x33, 0x800D, 6401); // writes the value 1901 (HEX) = 6401 (DEC) in the register at position 0x800D to enable reading out the temperatures!!!
  57. // ===============================================================================================================================================================
  58. //MLX90640_SetRefreshRate(MLX90640_address, 0x00); //Set rate to 0.25Hz effective - Works
  59. //MLX90640_SetRefreshRate(MLX90640_address, 0x01); //Set rate to 0.5Hz effective - Works
  60. //MLX90640_SetRefreshRate(MLX90640_address, 0x02); //Set rate to 1Hz effective - Works
  61. //MLX90640_SetRefreshRate(MLX90640_address, 0x03); //Set rate to 2Hz effective - Works
  62. MLX90640_SetRefreshRate(MLX90640_address, 0x04); //Set rate to 4Hz effective - Works
  63. //MLX90640_SetRefreshRate(MLX90640_address, 0x05); //Set rate to 8Hz effective - Works at 800kHz
  64. //MLX90640_SetRefreshRate(MLX90640_address, 0x06); //Set rate to 16Hz effective - Works at 800kHz
  65. //MLX90640_SetRefreshRate(MLX90640_address, 0x07); //Set rate to 32Hz effective - fails
  66. //pinMode(TFT_LED, OUTPUT);
  67. //digitalWrite(TFT_LED, HIGH);
  68. /*tft.begin();
  69. tft.setRotation(1);
  70. tft.fillScreen(ILI9341_BLACK);
  71. tft.fillRect(0, 0, 319, 13, tft.color565(255, 0, 10));
  72. tft.setCursor(100, 3);
  73. tft.setTextSize(1);
  74. tft.setTextColor(ILI9341_YELLOW, tft.color565(255, 0, 10));
  75. tft.print("Thermographie - stoppi");
  76. tft.drawLine(250, 210 - 0, 258, 210 - 0, tft.color565(255, 255, 255));
  77. tft.drawLine(250, 210 - 30, 258, 210 - 30, tft.color565(255, 255, 255));
  78. tft.drawLine(250, 210 - 60, 258, 210 - 60, tft.color565(255, 255, 255));
  79. tft.drawLine(250, 210 - 90, 258, 210 - 90, tft.color565(255, 255, 255));
  80. tft.drawLine(250, 210 - 120, 258, 210 - 120, tft.color565(255, 255, 255));
  81. tft.drawLine(250, 210 - 150, 258, 210 - 150, tft.color565(255, 255, 255));
  82. tft.drawLine(250, 210 - 180, 258, 210 - 180, tft.color565(255, 255, 255));
  83. tft.setCursor(80, 220);
  84. tft.setTextColor(ILI9341_WHITE, tft.color565(0, 0, 0));
  85. tft.print("T+ = ");
  86. // drawing the colour-scale
  87. // ========================
  88. for (i = 0; i < 181; i++)
  89. {
  90. //value = random(180);
  91. getColour(i);
  92. tft.drawLine(240, 210 - i, 250, 210 - i, tft.color565(R_colour, G_colour, B_colour));
  93. }
  94. }
  95. */
  96. // **********************************
  97. // ************** LOOP **************
  98. // **********************************
  99. void loop()
  100. {
  101. for (byte x = 0 ; x < 2 ; x++) //Read both subpages
  102. {
  103. uint16_t mlx90640Frame[834];
  104. int status = MLX90640_GetFrameData(MLX90640_address, mlx90640Frame);
  105. if (status < 0)
  106. {
  107. Serial.print("GetFrame Error: ");
  108. Serial.println(status);
  109. }
  110. float vdd = MLX90640_GetVdd(mlx90640Frame, &mlx90640);
  111. float Ta = MLX90640_GetTa(mlx90640Frame, &mlx90640);
  112. float tr = Ta - TA_SHIFT; //Reflected temperature based on the sensor ambient temperature
  113. float emissivity = 0.95;
  114. MLX90640_CalculateTo(mlx90640Frame, &mlx90640, emissivity, tr, mlx90640To);
  115. }
  116. // determine T_min and T_max and eliminate error pixels
  117. // ====================================================
  118. mlx90640To[1*32 + 21] = 0.5 * (mlx90640To[1*32 + 20] + mlx90640To[1*32 + 22]); // eliminate the error-pixels
  119. mlx90640To[4*32 + 30] = 0.5 * (mlx90640To[4*32 + 29] + mlx90640To[4*32 + 31]); // eliminate the error-pixels
  120. T_min = mlx90640To[0];
  121. T_max = mlx90640To[0];
  122. for (i = 1; i < 768; i++)
  123. {
  124. if((mlx90640To[i] > -41) && (mlx90640To[i] < 301))
  125. {
  126. if(mlx90640To[i] < T_min)
  127. {
  128. T_min = mlx90640To[i];
  129. }
  130. if(mlx90640To[i] > T_max)
  131. {
  132. T_max = mlx90640To[i];
  133. }
  134. }
  135. else if(i > 0) // temperature out of range
  136. {
  137. mlx90640To[i] = mlx90640To[i-1];
  138. }
  139. else
  140. {
  141. mlx90640To[i] = mlx90640To[i+1];
  142. }
  143. }
  144. // determine T_center
  145. // ==================
  146. T_center = mlx90640To[11* 32 + 15];
  147. // drawing the picture
  148. // ===================
  149. for (i = 0 ; i < 24 ; i++)
  150. {
  151. for (j = 0; j < 32; j++)
  152. {
  153. mlx90640To[i*32 + j] = 180.0 * (mlx90640To[i*32 + j] - T_min) / (T_max - T_min);
  154. getColour(mlx90640To[i*32 + j]);
  155. // tft.fillRect(217 - j * 7, 35 + i * 7, 7, 7, tft.color565(R_colour, G_colour, B_colour));
  156. }
  157. }
  158. /*
  159. tft.drawLine(217 - 15*7 + 3.5 - 5, 11*7 + 35 + 3.5, 217 - 15*7 + 3.5 + 5, 11*7 + 35 + 3.5, tft.color565(255, 255, 255));
  160. tft.drawLine(217 - 15*7 + 3.5, 11*7 + 35 + 3.5 - 5, 217 - 15*7 + 3.5, 11*7 + 35 + 3.5 + 5, tft.color565(255, 255, 255));
  161. tft.fillRect(260, 25, 37, 10, tft.color565(0, 0, 0));
  162. tft.fillRect(260, 205, 37, 10, tft.color565(0, 0, 0));
  163. tft.fillRect(115, 220, 37, 10, tft.color565(0, 0, 0));
  164. tft.setTextColor(ILI9341_WHITE, tft.color565(0, 0, 0));
  165. tft.setCursor(265, 25);
  166. tft.print(T_max, 1);
  167. tft.setCursor(265, 205);
  168. tft.print(T_min, 1);
  169. tft.setCursor(120, 220);
  170. tft.print(T_center, 1);
  171. tft.setCursor(300, 25);
  172. tft.print("C");
  173. tft.setCursor(300, 205);
  174. tft.print("C");
  175. tft.setCursor(155, 220);
  176. tft.print("C");
  177. */
  178. delay(20);
  179. }
  180. // ===============================
  181. // ===== determine the colour ====
  182. // ===============================
  183. void getColour(int j)
  184. {
  185. if (j >= 0 && j < 30)
  186. {
  187. R_colour = 0;
  188. G_colour = 0;
  189. B_colour = 20 + (120.0/30.0) * j;
  190. }
  191. if (j >= 30 && j < 60)
  192. {
  193. R_colour = (120.0 / 30) * (j - 30.0);
  194. G_colour = 0;
  195. B_colour = 140 - (60.0/30.0) * (j - 30.0);
  196. }
  197. if (j >= 60 && j < 90)
  198. {
  199. R_colour = 120 + (135.0/30.0) * (j - 60.0);
  200. G_colour = 0;
  201. B_colour = 80 - (70.0/30.0) * (j - 60.0);
  202. }
  203. if (j >= 90 && j < 120)
  204. {
  205. R_colour = 255;
  206. G_colour = 0 + (60.0/30.0) * (j - 90.0);
  207. B_colour = 10 - (10.0/30.0) * (j - 90.0);
  208. }
  209. if (j >= 120 && j < 150)
  210. {
  211. R_colour = 255;
  212. G_colour = 60 + (175.0/30.0) * (j - 120.0);
  213. B_colour = 0;
  214. }
  215. if (j >= 150 && j <= 180)
  216. {
  217. R_colour = 255;
  218. G_colour = 235 + (20.0/30.0) * (j - 150.0);
  219. B_colour = 0 + 255.0/30.0 * (j - 150.0);
  220. }
  221. }
  222. //Returns true if the MLX90640 is detected on the I2C bus
  223. boolean isConnected()
  224. {
  225. Wire.beginTransmission((uint8_t)MLX90640_address);
  226. if (Wire.endTransmission() != 0)
  227. return (false); //Sensor did not ACK
  228. return (true);
  229. }