From 8e04a74abc338167d5c509f48e907f5311edda79 Mon Sep 17 00:00:00 2001 From: Johannes Krug Date: Fri, 21 Jun 2019 11:27:24 +0200 Subject: [PATCH] =?UTF-8?q?Code=20ver=C3=A4ndert,=20l=C3=A4uft=20noch=20ni?= =?UTF-8?q?cht?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Arduino_ESP32_MLX90640.ino | 2 +- .../MLX90640_I2C_Driver.zip | Bin 2322 -> 0 bytes .../Arduino_ESP32_MLX90640_aktuell.ino | 313 ++++++++++++++++++ .../MLX90640_API.zip | Bin .../MLX90640_I2C_Driver1.cpp | 125 +++++++ .../MLX90640_I2C_Driver1.h | 51 +++ .../Example1_BasicReadings.ino | 8 +- .../wärmebildkamera/MLX90640_I2C_Driver.cpp | 31 +- 8 files changed, 521 insertions(+), 9 deletions(-) rename arduino/{Arduino_ESP32_MLX90640 => Arduino_ESP32_MLX90640_alt}/Arduino_ESP32_MLX90640.ino (99%) delete mode 100644 arduino/wärmebildkamera/Arduino_ESP32_MLX90640/MLX90640_I2C_Driver.zip create mode 100644 arduino/wärmebildkamera/Arduino_ESP32_MLX90640_aktuell/Arduino_ESP32_MLX90640_aktuell.ino rename arduino/wärmebildkamera/{Arduino_ESP32_MLX90640 => Arduino_ESP32_MLX90640_aktuell}/MLX90640_API.zip (100%) create mode 100644 arduino/wärmebildkamera/Arduino_ESP32_MLX90640_aktuell/MLX90640_I2C_Driver1.cpp create mode 100644 arduino/wärmebildkamera/Arduino_ESP32_MLX90640_aktuell/MLX90640_I2C_Driver1.h diff --git a/arduino/Arduino_ESP32_MLX90640/Arduino_ESP32_MLX90640.ino b/arduino/Arduino_ESP32_MLX90640_alt/Arduino_ESP32_MLX90640.ino similarity index 99% rename from arduino/Arduino_ESP32_MLX90640/Arduino_ESP32_MLX90640.ino rename to arduino/Arduino_ESP32_MLX90640_alt/Arduino_ESP32_MLX90640.ino index 9fd2210..e5d7775 100644 --- a/arduino/Arduino_ESP32_MLX90640/Arduino_ESP32_MLX90640.ino +++ b/arduino/Arduino_ESP32_MLX90640_alt/Arduino_ESP32_MLX90640.ino @@ -30,7 +30,7 @@ float T_max, T_min; // maximale bzw. minimale gemesse float T_center; // Temperatur in der Bildschirmmitte - +boolean isConnected(); // *************************************** // **************** SETUP **************** diff --git a/arduino/wärmebildkamera/Arduino_ESP32_MLX90640/MLX90640_I2C_Driver.zip b/arduino/wärmebildkamera/Arduino_ESP32_MLX90640/MLX90640_I2C_Driver.zip deleted file mode 100644 index d5c281a809e07897f090595334f4157d71944435..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2322 zcmZ{mcTf|E62?ObLJ&fUBmxRZfQw)VfujWsf;5SdUIY&!O^Og96ahtP9wiK2klv1? z7?c_g=>h32(u*KX3`V3#QRKKcZ{GOkJ$GmJo88%&-(TO(8XK{(LjV8(Cm`Nq1n=(2 z8L`9;01R*g0ML`^b)2;tN?8eIZ-~~hzv|=W@9cwgBofJ%9^P~m@)g8_>HS{sd} zxG!}Ha{o5*HXu>KR`;>luaW5A=&r{M^{&HGJxIT|P-VO|Xv!bOR$w&RCORPz_L znpea>Orv*PsgiB=BY(-D7<^rnSUtKa{)E8qW8LAeUn;75@=^ zS1P_eMHJF?A%C1JPwdUY1DW@y{GRwsi9OUf)`;jE?9_EdZRD~OAF|ACx7`b!#ELE0 zg4M&lH%qaq6gFsJR9A$wu%mcEm_To#TrkU;lz?PvBAN@_X%GR+7A^7YCscS*(_j#| z-B3jSsBjTXEz7z;!Z~fcEWaUV%58M}Wdb2fPjsF{N&%G$Cl~IH8R3ZcOa1*1cP$tP z)#DbSEx~>jz|lK6cXt26tL%)`X2|%q*ya7}rz@Qv2~FwpoAjWACT^}j0TW%L zd9pW(sfSy=?G`j|l*j?W50}L6811L`HAa67E+37&lFtI29^&_u(SF#c%JOUg8S5B_ zByeB?FO8QltfQWpNsiLho1^w+Gu7(9?*tJJdf5n8uM@ct{prMAteqqf^CI+x(?~rZ z!fV-#`=zOwXAHt$0MGN(^2MZt*Q@}aVgaH@=|3Yp}K#6g$Q_D;&yQDe+vKas!%bP@+`cL{9a>QHy4-7Nc&$x4A^h9$6^xm_L>$;HuSn-^_BzPL8(lMXSLM@@-f1(w?Tf zO#QK%gPD8f@tjRv)@GTonU0q`X*x^Zrw5dsLdp4Tw^eX7cz@0(R-`){e)iRcZ?^6t zs;!??Y!NC1F>+%gZ*hbUd70MkmuD8|{B*_Nb-#IING#A)2#yE?d(XG_y=vZL?pHTE zTP&s?kNO4dIWz=5J)-u_DX;l|BHCu@p1qb`8ysklA8t|A#@u4BT;b%%K&|#NT*zg- zniY4my*k%l+t)Nx5}kCgm2>X3Az9aqdN&}Fb_uAOA>xqf`|=so?jV+~T^2hD76FEZ zM`rg&{_d*Q>G;=6P)QC{R_%)s9{ANrSmlK;FcMw0;*oD+F%mHI{l>0a9=DmzSXCgC zp8S;q4!$QP#JrzdVSZFrVEP&E<6KnM6lRQbwMY*MBw42!e-Lpano9CFghpjEOZo+f zGqd9;5& zy;DF}Pkv=VIUI%$jN)!!H5Dg?3(J-zZXB)c9|4X3a~FdMBlwVI@P$QI006=P0G#>B zUA*($e8%*h7T<#*E7CgmO_(^dYNJ-!Co#pYjx&a76mIZuB58JPP(GJF zjTKx3rz{1UvOV0YEUID~?@2jZta!0|9fHNP|6#bbT0N|OY+nA{QZ_Ty=Oa$KmX!Rb zJ6q-4xq~^uB)c@b7)UB>bPEXCvk}50H-yL@Fm&m)OfYnazS>T5VXuTw*ugD~Z7QsA z1^Lm`(WD{nrp$>P4aye*bd|(H>u%dNc%gq+v&G%OWxfX6oYmf+jhh{L!#G6cXa#G0 z2sHE7C@=%hj_}w87UIt&m~k5>_e-gv&)qk=A>WH-Y+20BI}@U<;pD?Db6Az-&B~CtQf*?GzG&9MGJg&+!})Jo|1A&W*Xt9RR+<;fmB9;@k-JXzvMieJ zU)b>j@qgaGBu}sMQas0D5=vyz&(x3s6iQE6+ve`uBQ?6{C{*fmIEc zV?3mP?HpLz2g6-5;!+3_k66jlpGEa?)vnJ5-UGuc{cSTUZq>IGi42x7gLa~}O{{Qk zxMPGXW(;d=#KMXN{OntRpZMaR5dT;G>F)sg_W}z51_)@r*?kNjV}UgMxBdwFU;F(C pf&u?O=+2LrU$$%@yC<05#~y+|s<9F9#LoZ#>q!ous2t}%-QRaN9vc7v diff --git a/arduino/wärmebildkamera/Arduino_ESP32_MLX90640_aktuell/Arduino_ESP32_MLX90640_aktuell.ino b/arduino/wärmebildkamera/Arduino_ESP32_MLX90640_aktuell/Arduino_ESP32_MLX90640_aktuell.ino new file mode 100644 index 0000000..37f6a1a --- /dev/null +++ b/arduino/wärmebildkamera/Arduino_ESP32_MLX90640_aktuell/Arduino_ESP32_MLX90640_aktuell.ino @@ -0,0 +1,313 @@ +#include +#include "MLX90640_API.h" +#include "MLX90640_I2C_Driver1.h" +#include "SPI.h" +//#include "Adafruit_GFX.h" +//#include "Adafruit_ILI9341.h" + +// For the ESP-WROVER_KIT, these are the default. +/*#define TFT_CS 15 +#define TFT_DC 2 +#define TFT_MOSI 13 +#define TFT_CLK 14 +#define TFT_RST 26 +#define TFT_MISO 12 +#define TFT_LED 27*/ + +/*Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_MOSI, TFT_CLK, TFT_RST, TFT_MISO);*/ + +const byte MLX90640_address = 0x33; //Default 7-bit unshifted address of the MLX90640 + +#define TA_SHIFT 8 //Default shift for MLX90640 in open air + +static float mlx90640To[768]; +paramsMLX90640 mlx90640; + +int xPos, yPos; // Abtastposition +int R_colour, G_colour, B_colour; // RGB-Farbwert +int i, j; // Zählvariable +float T_max, T_min; // maximale bzw. minimale gemessene Temperatur +float T_center; // Temperatur in der Bildschirmmitte + + + + +// *************************************** +// **************** SETUP **************** +// *************************************** + +void setup() + { + Serial.begin(115200); + + Wire.begin(); + Wire.setClock(400000); //Increase I2C clock speed to 400kHz + + while (!Serial); //Wait for user to open terminal + + Serial.println("MLX90640 IR Array Example"); + + if (isConnected() == false) + { + Serial.println("MLX90640 not detected at default I2C address. Please check wiring. Freezing."); + while (1); + } + + Serial.println("MLX90640 online!"); + + //Get device parameters - We only have to do this once + int status; + uint16_t eeMLX90640[832]; + + status = MLX90640_DumpEE(MLX90640_address, eeMLX90640); + + if (status != 0) + Serial.println("Failed to load system parameters"); + if (status == 0) + Serial.println("dumpee_okay"); + + status = MLX90640_ExtractParameters(eeMLX90640, &mlx90640); + + if (status != 0) + { + Serial.println("Parameter extraction failed"); + Serial.print(" status = "); + Serial.println(status); + } + + //Once params are extracted, we can release eeMLX90640 array + + MLX90640_I2CWrite(0x33, 0x800D, 6401); // writes the value 1901 (HEX) = 6401 (DEC) in the register at position 0x800D to enable reading out the temperatures!!! + // =============================================================================================================================================================== + + //MLX90640_SetRefreshRate(MLX90640_address, 0x00); //Set rate to 0.25Hz effective - Works + //MLX90640_SetRefreshRate(MLX90640_address, 0x01); //Set rate to 0.5Hz effective - Works + //MLX90640_SetRefreshRate(MLX90640_address, 0x02); //Set rate to 1Hz effective - Works + //MLX90640_SetRefreshRate(MLX90640_address, 0x03); //Set rate to 2Hz effective - Works + MLX90640_SetRefreshRate(MLX90640_address, 0x04); //Set rate to 4Hz effective - Works + //MLX90640_SetRefreshRate(MLX90640_address, 0x05); //Set rate to 8Hz effective - Works at 800kHz + //MLX90640_SetRefreshRate(MLX90640_address, 0x06); //Set rate to 16Hz effective - Works at 800kHz + //MLX90640_SetRefreshRate(MLX90640_address, 0x07); //Set rate to 32Hz effective - fails + + + //pinMode(TFT_LED, OUTPUT); + //digitalWrite(TFT_LED, HIGH); + + /*tft.begin(); + + tft.setRotation(1); + + tft.fillScreen(ILI9341_BLACK); + tft.fillRect(0, 0, 319, 13, tft.color565(255, 0, 10)); + tft.setCursor(100, 3); + tft.setTextSize(1); + tft.setTextColor(ILI9341_YELLOW, tft.color565(255, 0, 10)); + tft.print("Thermographie - stoppi"); + + tft.drawLine(250, 210 - 0, 258, 210 - 0, tft.color565(255, 255, 255)); + tft.drawLine(250, 210 - 30, 258, 210 - 30, tft.color565(255, 255, 255)); + tft.drawLine(250, 210 - 60, 258, 210 - 60, tft.color565(255, 255, 255)); + tft.drawLine(250, 210 - 90, 258, 210 - 90, tft.color565(255, 255, 255)); + tft.drawLine(250, 210 - 120, 258, 210 - 120, tft.color565(255, 255, 255)); + tft.drawLine(250, 210 - 150, 258, 210 - 150, tft.color565(255, 255, 255)); + tft.drawLine(250, 210 - 180, 258, 210 - 180, tft.color565(255, 255, 255)); + + tft.setCursor(80, 220); + tft.setTextColor(ILI9341_WHITE, tft.color565(0, 0, 0)); + tft.print("T+ = "); + + + // drawing the colour-scale + // ======================== + + for (i = 0; i < 181; i++) + { + //value = random(180); + + getColour(i); + tft.drawLine(240, 210 - i, 250, 210 - i, tft.color565(R_colour, G_colour, B_colour)); + } + + + +*/ + } +// ********************************** +// ************** LOOP ************** +// ********************************** + +void loop(){ + for (byte x = 0 ; x < 2 ; x++) //Read both subpages + { + uint16_t mlx90640Frame[834]; + int status = MLX90640_GetFrameData(MLX90640_address, mlx90640Frame); + + if (status < 0) + { + Serial.print("GetFrame Error: "); + Serial.println(status); + } + + float vdd = MLX90640_GetVdd(mlx90640Frame, &mlx90640); + float Ta = MLX90640_GetTa(mlx90640Frame, &mlx90640); + + float tr = Ta - TA_SHIFT; //Reflected temperature based on the sensor ambient temperature + float emissivity = 0.95; + + MLX90640_CalculateTo(mlx90640Frame, &mlx90640, emissivity, tr, mlx90640To); + } + + + // determine T_min and T_max and eliminate error pixels + // ==================================================== + + mlx90640To[1*32 + 21] = 0.5 * (mlx90640To[1*32 + 20] + mlx90640To[1*32 + 22]); // eliminate the error-pixels + mlx90640To[4*32 + 30] = 0.5 * (mlx90640To[4*32 + 29] + mlx90640To[4*32 + 31]); // eliminate the error-pixels + + T_min = mlx90640To[0]; + T_max = mlx90640To[0]; + + for (i = 1; i < 768; i++) + { + if((mlx90640To[i] > -41) && (mlx90640To[i] < 301)) + { + if(mlx90640To[i] < T_min) + { + T_min = mlx90640To[i]; + } + + if(mlx90640To[i] > T_max) + { + T_max = mlx90640To[i]; + } + } + else if(i > 0) // temperature out of range + { + mlx90640To[i] = mlx90640To[i-1]; + } + else + { + mlx90640To[i] = mlx90640To[i+1]; + } + } + + + // determine T_center + // ================== + + T_center = mlx90640To[11* 32 + 15]; + + // drawing the picture + // =================== + + for (i = 0 ; i < 24 ; i++) + { + for (j = 0; j < 32; j++) + { + mlx90640To[i*32 + j] = 180.0 * (mlx90640To[i*32 + j] - T_min) / (T_max - T_min); + + getColour(mlx90640To[i*32 + j]); + + // tft.fillRect(217 - j * 7, 35 + i * 7, 7, 7, tft.color565(R_colour, G_colour, B_colour)); + } + } + /* + 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)); + 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)); + + tft.fillRect(260, 25, 37, 10, tft.color565(0, 0, 0)); + tft.fillRect(260, 205, 37, 10, tft.color565(0, 0, 0)); + tft.fillRect(115, 220, 37, 10, tft.color565(0, 0, 0)); + + tft.setTextColor(ILI9341_WHITE, tft.color565(0, 0, 0)); + tft.setCursor(265, 25); + tft.print(T_max, 1); + tft.setCursor(265, 205); + tft.print(T_min, 1); + tft.setCursor(120, 220); + tft.print(T_center, 1); + + tft.setCursor(300, 25); + tft.print("C"); + tft.setCursor(300, 205); + tft.print("C"); + tft.setCursor(155, 220); + tft.print("C"); + */ + delay(20); + } + + + +// =============================== +// ===== determine the colour ==== +// =============================== + +void getColour(int j) + { + if (j >= 0 && j < 30) + { + R_colour = 0; + G_colour = 0; + B_colour = 20 + (120.0/30.0) * j; + } + + if (j >= 30 && j < 60) + { + R_colour = (120.0 / 30) * (j - 30.0); + G_colour = 0; + B_colour = 140 - (60.0/30.0) * (j - 30.0); + } + + if (j >= 60 && j < 90) + { + R_colour = 120 + (135.0/30.0) * (j - 60.0); + G_colour = 0; + B_colour = 80 - (70.0/30.0) * (j - 60.0); + } + + if (j >= 90 && j < 120) + { + R_colour = 255; + G_colour = 0 + (60.0/30.0) * (j - 90.0); + B_colour = 10 - (10.0/30.0) * (j - 90.0); + } + + if (j >= 120 && j < 150) + { + R_colour = 255; + G_colour = 60 + (175.0/30.0) * (j - 120.0); + B_colour = 0; + } + + if (j >= 150 && j <= 180) + { + R_colour = 255; + G_colour = 235 + (20.0/30.0) * (j - 150.0); + B_colour = 0 + 255.0/30.0 * (j - 150.0); + } + + } + + +//Returns true if the MLX90640 is detected on the I2C bus +boolean isConnected() + { + Wire.beginTransmission((uint8_t)MLX90640_address); + + if (Wire.endTransmission() != 0) + return (false); //Sensor did not ACK + + return (true); + } + + + + + + + + + + + diff --git a/arduino/wärmebildkamera/Arduino_ESP32_MLX90640/MLX90640_API.zip b/arduino/wärmebildkamera/Arduino_ESP32_MLX90640_aktuell/MLX90640_API.zip similarity index 100% rename from arduino/wärmebildkamera/Arduino_ESP32_MLX90640/MLX90640_API.zip rename to arduino/wärmebildkamera/Arduino_ESP32_MLX90640_aktuell/MLX90640_API.zip diff --git a/arduino/wärmebildkamera/Arduino_ESP32_MLX90640_aktuell/MLX90640_I2C_Driver1.cpp b/arduino/wärmebildkamera/Arduino_ESP32_MLX90640_aktuell/MLX90640_I2C_Driver1.cpp new file mode 100644 index 0000000..2dcf231 --- /dev/null +++ b/arduino/wärmebildkamera/Arduino_ESP32_MLX90640_aktuell/MLX90640_I2C_Driver1.cpp @@ -0,0 +1,125 @@ +/** + @copyright (C) 2017 Melexis N.V. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +*/ + +#include +#include +#include "MLX90640_I2C_Driver.h" + +void MLX90640_I2CInit() +{ + +} +int MLX90640_I2CRead(uint8_t _deviceAddress, unsigned int startAddress, unsigned int nWordsRead, uint16_t *data) +{ + // nWordsRead must be <= 32767 + Wire.beginTransmission(_deviceAddress); + Wire.write(startAddress >> 8); //MSB + Wire.write(startAddress & 0xFF); //LSB + Wire.endTransmission(false); + i2c_err_t error = Wire.readTransmission(_deviceAddress, (uint8_t*) data, nWordsRead*2); + if(error != 0){//problems + Serial.printf("Block read from sensor(0x%02X) at address=%d of %d uint16_t's failed=%d(%s)\n", + _deviceAddress,startAddress,nWordsRead,error,Wire.getErrorText(error)); + } + else { // reverse byte order, sensor Big Endian, ESP32 Little Endian + for(auto a = 0; a>8)&0xff); + } + } + return 0; +} +/* +//Read a number of words from startAddress. Store into Data array. +//Returns 0 if successful, -1 if error +int MLX90640_I2CRead(uint8_t _deviceAddress, unsigned int startAddress, unsigned int nWordsRead, uint16_t *data) +{ + + //Caller passes number of 'unsigned ints to read', increase this to 'bytes to read' + uint16_t bytesRemaining = nWordsRead * 2; + + //It doesn't look like sequential read works. Do we need to re-issue the address command each time? + + uint16_t dataSpot = 0; //Start at beginning of array + + //Setup a series of chunked I2C_BUFFER_LENGTH byte reads + while (bytesRemaining > 0) + { + Wire.beginTransmission(_deviceAddress); + Wire.write(startAddress >> 8); //MSB + Wire.write(startAddress & 0xFF); //LSB + if(Wire.endTransmission(false) != 7){ + Serial.println("Error: Sensor did not ack"); + return (0);//Sensor did not ACK + + } + uint16_t numberOfBytesToRead = bytesRemaining; + if (numberOfBytesToRead > I2C_BUFFER_LENGTH) numberOfBytesToRead = I2C_BUFFER_LENGTH; + + Wire.requestFrom((uint8_t)_deviceAddress, numberOfBytesToRead); + if (Wire.available()) + { + for (uint16_t x = 0 ; x < numberOfBytesToRead / 2; x++) + { + //Store data into array + data[dataSpot] = Wire.read() << 8; //MSB + data[dataSpot] |= Wire.read(); //LSB + + dataSpot++; + } + } + + bytesRemaining -= numberOfBytesToRead; + + startAddress += numberOfBytesToRead / 2; + } + + return (0); //Success +} +*/ +//Set I2C Freq, in kHz +//MLX90640_I2CFreqSet(1000) sets frequency to 1MHz +void MLX90640_I2CFreqSet(int freq) +{ + //i2c.frequency(1000 * freq); + Wire.setClock((long)1000 * freq); +} + +//Write two bytes to a two byte address +int MLX90640_I2CWrite(uint8_t _deviceAddress, unsigned int writeAddress, uint16_t data) +{ + Wire.beginTransmission((uint8_t)_deviceAddress); + Wire.write(writeAddress >> 8); //MSB + Wire.write(writeAddress & 0xFF); //LSB + Wire.write(data >> 8); //MSB + Wire.write(data & 0xFF); //LSB + if (Wire.endTransmission() != 0) + { + //Sensor did not ACK + Serial.println("Error: Sensor did not ack"); + return (0);//Sensor did not ACK + } + + uint16_t dataCheck; + MLX90640_I2CRead(_deviceAddress, writeAddress, 1, &dataCheck); + if (dataCheck != data) + { + //Serial.println("The write request didn't stick"); + return -2; + } + + return (0); //Success +} diff --git a/arduino/wärmebildkamera/Arduino_ESP32_MLX90640_aktuell/MLX90640_I2C_Driver1.h b/arduino/wärmebildkamera/Arduino_ESP32_MLX90640_aktuell/MLX90640_I2C_Driver1.h new file mode 100644 index 0000000..4de44d0 --- /dev/null +++ b/arduino/wärmebildkamera/Arduino_ESP32_MLX90640_aktuell/MLX90640_I2C_Driver1.h @@ -0,0 +1,51 @@ +/** + @copyright (C) 2017 Melexis N.V. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +*/ +#ifndef _MLX90640_I2C_Driver_H_ +#define _MLX90640_I2C_Driver_H_ + +#include + +//Define the size of the I2C buffer based on the platform the user has +//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +#if defined(__AVR_ATmega328P__) || defined(__AVR_ATmega168__) + +//I2C_BUFFER_LENGTH is defined in Wire.H +#define I2C_BUFFER_LENGTH BUFFER_LENGTH + +#elif defined(__SAMD21G18A__) + +//SAMD21 uses RingBuffer.h +#define I2C_BUFFER_LENGTH SERIAL_BUFFER_SIZE + +#elif __MK20DX256__ +//Teensy 3.2 +#define I2C_BUFFER_LENGTH 32 + +#else + +//The catch-all default is 32 +#define I2C_BUFFER_LENGTH 32 + +#endif +//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + + +void MLX90640_I2CInit(void); +int MLX90640_I2CRead(uint8_t slaveAddr, unsigned int startAddress, unsigned int nWordsRead, uint16_t *data); +int MLX90640_I2CWrite(uint8_t slaveAddr, unsigned int writeAddress, uint16_t data); +void MLX90640_I2CFreqSet(int freq); +#endif diff --git a/arduino/wärmebildkamera/Example1_BasicReadings/Example1_BasicReadings.ino b/arduino/wärmebildkamera/Example1_BasicReadings/Example1_BasicReadings.ino index f1ce9f2..b211b94 100644 --- a/arduino/wärmebildkamera/Example1_BasicReadings/Example1_BasicReadings.ino +++ b/arduino/wärmebildkamera/Example1_BasicReadings/Example1_BasicReadings.ino @@ -28,7 +28,6 @@ */ #include - #include "MLX90640_API.h" #include "MLX90640_I2C_Driver.h" @@ -86,10 +85,10 @@ void loop() float tr = Ta - TA_SHIFT; //Reflected temperature based on the sensor ambient temperature float emissivity = 0.95; - + Serial.print("loop-schleife"); MLX90640_CalculateTo(mlx90640Frame, &mlx90640, emissivity, tr, mlx90640To); } - + Serial.print("loop-schleife2"); for (int x = 0 ; x < 10 ; x++) { Serial.print("Pixel "); @@ -110,4 +109,5 @@ boolean isConnected() if (Wire.endTransmission() != 0) return (false); //Sensor did not ACK return (true); -} + Serial.print("verbunden"); + } diff --git a/arduino/wärmebildkamera/MLX90640_I2C_Driver.cpp b/arduino/wärmebildkamera/MLX90640_I2C_Driver.cpp index 0689a49..2dcf231 100644 --- a/arduino/wärmebildkamera/MLX90640_I2C_Driver.cpp +++ b/arduino/wärmebildkamera/MLX90640_I2C_Driver.cpp @@ -23,7 +23,26 @@ void MLX90640_I2CInit() { } - +int MLX90640_I2CRead(uint8_t _deviceAddress, unsigned int startAddress, unsigned int nWordsRead, uint16_t *data) +{ + // nWordsRead must be <= 32767 + Wire.beginTransmission(_deviceAddress); + Wire.write(startAddress >> 8); //MSB + Wire.write(startAddress & 0xFF); //LSB + Wire.endTransmission(false); + i2c_err_t error = Wire.readTransmission(_deviceAddress, (uint8_t*) data, nWordsRead*2); + if(error != 0){//problems + Serial.printf("Block read from sensor(0x%02X) at address=%d of %d uint16_t's failed=%d(%s)\n", + _deviceAddress,startAddress,nWordsRead,error,Wire.getErrorText(error)); + } + else { // reverse byte order, sensor Big Endian, ESP32 Little Endian + for(auto a = 0; a>8)&0xff); + } + } + return 0; +} +/* //Read a number of words from startAddress. Store into Data array. //Returns 0 if successful, -1 if error int MLX90640_I2CRead(uint8_t _deviceAddress, unsigned int startAddress, unsigned int nWordsRead, uint16_t *data) @@ -42,7 +61,11 @@ int MLX90640_I2CRead(uint8_t _deviceAddress, unsigned int startAddress, unsigned Wire.beginTransmission(_deviceAddress); Wire.write(startAddress >> 8); //MSB Wire.write(startAddress & 0xFF); //LSB - Wire.endTransmission(false) + if(Wire.endTransmission(false) != 7){ + Serial.println("Error: Sensor did not ack"); + return (0);//Sensor did not ACK + + } uint16_t numberOfBytesToRead = bytesRemaining; if (numberOfBytesToRead > I2C_BUFFER_LENGTH) numberOfBytesToRead = I2C_BUFFER_LENGTH; @@ -66,7 +89,7 @@ int MLX90640_I2CRead(uint8_t _deviceAddress, unsigned int startAddress, unsigned return (0); //Success } - +*/ //Set I2C Freq, in kHz //MLX90640_I2CFreqSet(1000) sets frequency to 1MHz void MLX90640_I2CFreqSet(int freq) @@ -87,7 +110,7 @@ int MLX90640_I2CWrite(uint8_t _deviceAddress, unsigned int writeAddress, uint16_ { //Sensor did not ACK Serial.println("Error: Sensor did not ack"); - return (-1); + return (0);//Sensor did not ACK } uint16_t dataCheck;