├── LICENSE ├── README.md ├── examples ├── Example1-SerialVisualizer │ └── Example1-SerialVisualizer.ino ├── Example2-UsingInterrupts │ └── Example2-UsingInterrupts.ino ├── Example3-DeviceTemperature │ └── Example3-DeviceTemperature.ino ├── Example4-ProcessingHeatCam │ ├── Example4-ProcessingHeatCam.ino │ └── HeatCam │ │ └── HeatCam.pde └── Example5-HotPixel │ └── Example5-HotPixel.ino ├── keywords.txt ├── library.properties └── src ├── SparkFun_GridEYE_Arduino_Library.cpp └── SparkFun_GridEYE_Arduino_Library.h /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 SparkFun Electronics 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | SparkFun_GridEYE_Arduino_Library 2 | ======================================== 3 | 4 | ![SparkFun Grid-EYE Infrared Array Breakout - AMG8833 (Qwiic)](https://cdn.sparkfun.com//assets/parts/1/2/7/7/5/14607-SparkFun_GridEYE_Infrared_Array_-_AMG8833__Qwiic_-01.jpg) 5 | 6 | [*SparkFun Grid-EYE Infrared Array Breakout - AMG8833 (Qwiic) (SEN-14607)*](https://www.sparkfun.com/products/14607) 7 | 8 | This is a library written for the Panasonic Grid-EYE AMG88 9 | SparkFun sells these at its website: www.sparkfun.com 10 | 11 | Do you like this library? Help support SparkFun. Buy a board! 12 | * [SEN-14607](https://www.sparkfun.com/products/14607) 13 | * [SPX-14568](https://www.sparkfun.com/products/14568) 14 | 15 | Written by Nick Poole @ SparkFun Electronics, January 11th, 2018 16 | 17 | The GridEYE from Panasonic is an 8 by 8 thermopile array capable 18 | of detecting temperature remotely at 64 discrete points. 19 | 20 | This library handles communication with the GridEYE and provides 21 | methods for manipulating temperature registers in Celsius, 22 | Fahrenheit and raw values. 23 | 24 | Repository Contents 25 | ------------------- 26 | 27 | * **/examples** - Example sketches for the library (.ino). Run these from the Arduino IDE. 28 | * **/src** - Source files for the library (.cpp, .h). 29 | * **keywords.txt** - Keywords from this library that will be highlighted in the Arduino IDE. 30 | * **library.properties** - General library properties for the Arduino package manager. 31 | 32 | Documentation 33 | -------------- 34 | 35 | * **[Installing an Arduino Library Guide](https://learn.sparkfun.com/tutorials/installing-an-arduino-library)** - Basic information on how to install an Arduino library. 36 | * **[Product Repository](https://github.com/sparkfun/Qwiic_GRIDEye)** - Main repository (including hardware files) for the GridEye. 37 | * **[Hookup Guide](https://learn.sparkfun.com/tutorials/qwiic-grid-eye-infrared-array-amg88xx-hookup-guide)** - Basic hookup guide for the Qwiic GRID-Eye Infrared Array. 38 | 39 | Products that use this Library 40 | --------------------------------- 41 | 42 | * [SEN-14607](https://www.sparkfun.com/products/14607) - SparkFun breakout board for Grid-EYE AMG8833 43 | * [SPX-14568](https://www.sparkfun.com/products/14568) - SparkX breakout board for Grid-EYE AMG8833 44 | 45 | License Information 46 | ------------------- 47 | 48 | This product is _**open source**_! 49 | 50 | Please review the LICENSE.md file for license information. 51 | 52 | If you have any questions or concerns on licensing, please contact techsupport@sparkfun.com. 53 | 54 | Distributed as-is; no warranty is given. 55 | 56 | - Your friends at SparkFun. 57 | -------------------------------------------------------------------------------- /examples/Example1-SerialVisualizer/Example1-SerialVisualizer.ino: -------------------------------------------------------------------------------- 1 | /* 2 | Using the Panasonic Grid-EYE Sensor 3 | By: Nick Poole 4 | SparkFun Electronics 5 | Date: January 12th, 2018 6 | 7 | MIT License: Permission is hereby granted, free of charge, to any person obtaining a copy of this 8 | software and associated documentation files (the "Software"), to deal in the Software without 9 | restriction, including without limitation the rights to use, copy, modify, merge, publish, 10 | distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the 11 | Software is furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all copies or 14 | substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING 17 | BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 19 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | 22 | Feel like supporting our work? Buy a board from SparkFun! 23 | https://www.sparkfun.com/products/14568 24 | 25 | This example implements a rudimentary heat camera in the serial terminal, using a matrix of ascii 26 | characters to represent the temperature of each pixel in the device. Start your terminal at 115200 27 | and make the window as small as possible for best effect. 28 | 29 | Hardware Connections: 30 | Attach the Qwiic Shield to your Arduino/Photon/ESP32 or other 31 | Plug the sensor onto the shield 32 | */ 33 | 34 | #include 35 | #include 36 | 37 | // Use these values (in degrees C) to adjust the contrast 38 | #define HOT 40 39 | #define COLD 20 40 | 41 | // This table can be of type int because we map the pixel 42 | // temperature to 0-3. Temperatures are reported by the 43 | // library as floats 44 | int pixelTable[64]; 45 | 46 | GridEYE grideye; 47 | 48 | void setup() { 49 | 50 | // Start your preferred I2C object 51 | Wire.begin(); 52 | // Library assumes "Wire" for I2C but you can pass something else with begin() if you like 53 | grideye.begin(); 54 | // Pour a bowl of serial 55 | Serial.begin(115200); 56 | 57 | } 58 | 59 | void loop() { 60 | 61 | // loop through all 64 pixels on the device and map each float value to a number 62 | // between 0 and 3 using the HOT and COLD values we set at the top of the sketch 63 | for(unsigned char i = 0; i < 64; i++){ 64 | pixelTable[i] = map(grideye.getPixelTemperature(i), COLD, HOT, 0, 3); 65 | } 66 | 67 | 68 | // loop through the table of mapped values and print a character corresponding to each 69 | // pixel's temperature. Add a space between each. Start a new line every 8 in order to 70 | // create an 8x8 grid 71 | for(unsigned char i = 0; i < 64; i++){ 72 | if(pixelTable[i]==0){Serial.print(".");} 73 | else if(pixelTable[i]==1){Serial.print("o");} 74 | else if(pixelTable[i]==2){Serial.print("0");} 75 | else if(pixelTable[i]==3){Serial.print("O");} 76 | Serial.print(" "); 77 | if((i+1)%8==0){ 78 | Serial.println(); 79 | } 80 | } 81 | 82 | // in between updates, throw a few linefeeds to visually separate the grids. If you're using 83 | // a serial terminal outside the Arduino IDE, you can replace these linefeeds with a clearscreen 84 | // command 85 | Serial.println(); 86 | Serial.println(); 87 | 88 | 89 | // toss in a delay because we don't need to run all out 90 | delay(100); 91 | 92 | } 93 | -------------------------------------------------------------------------------- /examples/Example2-UsingInterrupts/Example2-UsingInterrupts.ino: -------------------------------------------------------------------------------- 1 | /* 2 | Using Interrupts on the Panasonic Grid-EYE Sensor 3 | By: Nick Poole 4 | SparkFun Electronics 5 | Date: January 12th, 2018 6 | 7 | MIT License: Permission is hereby granted, free of charge, to any person obtaining a copy of this 8 | software and associated documentation files (the "Software"), to deal in the Software without 9 | restriction, including without limitation the rights to use, copy, modify, merge, publish, 10 | distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the 11 | Software is furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all copies or 14 | substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING 17 | BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 19 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | 22 | Feel like supporting our work? Buy a board from SparkFun! 23 | https://www.sparkfun.com/products/14568 24 | 25 | This example demonstrates the use of the GridEYE's interrupt registers. Open a serial terminal 26 | and you should find the device is waiting for an interrupt to fire. Once an object enters the 27 | sensor's range with a temperature above the UPPER_LIMIT or below the LOWER_LIMIT, the example 28 | code will display a table of all pixels and their respective interrupt states. The HYSTERESIS 29 | parameter may be used to stabilize sensor behavior close to the limits. I recommend running 30 | this example code using the default parameters at room temperature and waving a hot soldering 31 | iron in front of the sensor to fire the interrupt. 32 | 33 | Hardware Connections: 34 | Attach the Qwiic Shield to your Arduino/Photon/ESP32 or other 35 | Plug the sensor onto the shield 36 | */ 37 | 38 | #include 39 | #include 40 | 41 | // Use these values (in degrees C) to adjust the interrupt parameters 42 | #define UPPER_LIMIT 50 43 | #define LOWER_LIMIT 0 44 | #define HYSTERESIS 5 45 | 46 | // This table will be used to hold the contents of the interrupt table register 47 | bool interruptTable[64]; 48 | 49 | GridEYE grideye; 50 | 51 | void setup() { 52 | 53 | // Start your preferred I2C object 54 | Wire.begin(); 55 | // Library assumes "Wire" for I2C but you can pass something else with begin() if you like 56 | grideye.begin(); 57 | // Pour a bowl of serial 58 | Serial.begin(115200); 59 | 60 | // Set interrupt parameters 61 | grideye.setInterruptModeAbsolute(); 62 | grideye.setUpperInterruptValue(UPPER_LIMIT); 63 | grideye.setLowerInterruptValue(LOWER_LIMIT); 64 | grideye.setInterruptHysteresis(HYSTERESIS); 65 | 66 | } 67 | 68 | void loop() { 69 | 70 | // check every 500ms to see if the interrupt flag is set 71 | while(!grideye.interruptFlagSet()){ 72 | Serial.println("waiting for interrupt flag..."); 73 | delay(500); 74 | } 75 | 76 | // tell the user that an interrupt was fired 77 | Serial.println("interrupt caught!"); 78 | 79 | // populate the interrupt flag table 80 | for(int i = 0; i < 64; i++){ 81 | interruptTable[i] = grideye.pixelInterruptSet(i); 82 | } 83 | 84 | // display the interrupt flag table 85 | for(unsigned char i = 0; i < 64; i++){ 86 | Serial.print(interruptTable[i]); 87 | Serial.print(" "); 88 | if((i+1)%8==0){ 89 | Serial.println(); 90 | } 91 | } 92 | 93 | // clear the interrupt flag bit in the device register 94 | grideye.clearInterruptFlag(); 95 | 96 | } 97 | -------------------------------------------------------------------------------- /examples/Example3-DeviceTemperature/Example3-DeviceTemperature.ino: -------------------------------------------------------------------------------- 1 | /* 2 | Using Interrupts on the Panasonic Grid-EYE Sensor 3 | By: Nick Poole 4 | SparkFun Electronics 5 | Date: January 12th, 2018 6 | 7 | MIT License: Permission is hereby granted, free of charge, to any person obtaining a copy of this 8 | software and associated documentation files (the "Software"), to deal in the Software without 9 | restriction, including without limitation the rights to use, copy, modify, merge, publish, 10 | distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the 11 | Software is furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all copies or 14 | substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING 17 | BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 19 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | 22 | Feel like supporting our work? Buy a board from SparkFun! 23 | https://www.sparkfun.com/products/14568 24 | 25 | This example demonstrates the use of the GridEYE's thermistor register for reading the internal 26 | temperature of the device. This information can be used to compensate for thermal conditions that 27 | might make measurements difficult to make. The example code prints the readings of the thermistor 28 | in degrees C, degrees F and also the bitwise value of the registor. Touching the device with your 29 | hand should raise the tmperature of the device so you can observe the deflection. 30 | 31 | Hardware Connections: 32 | Attach the Qwiic Shield to your Arduino/Photon/ESP32 or other 33 | Plug the sensor onto the shield 34 | */ 35 | 36 | #include 37 | #include 38 | 39 | GridEYE grideye; 40 | 41 | void setup() { 42 | 43 | // Start your preferred I2C object 44 | Wire.begin(); 45 | // Library assumes "Wire" for I2C but you can pass something else with begin() if you like 46 | grideye.begin(); 47 | // Pour a bowl of serial 48 | Serial.begin(115200); 49 | 50 | } 51 | 52 | void loop() { 53 | 54 | Serial.print("Thermistor Temperature in Celsius: "); 55 | Serial.println(grideye.getDeviceTemperature()); 56 | Serial.print("Thermistor Temperature in Fahrenheit: "); 57 | Serial.println(grideye.getDeviceTemperatureFahrenheit()); 58 | Serial.print("Thermistor Temperature register contents: "); 59 | Serial.println(grideye.getDeviceTemperatureRaw(), BIN); 60 | 61 | Serial.println(); 62 | Serial.println(); 63 | 64 | delay(1000); 65 | 66 | } 67 | -------------------------------------------------------------------------------- /examples/Example4-ProcessingHeatCam/Example4-ProcessingHeatCam.ino: -------------------------------------------------------------------------------- 1 | /* 2 | Visualizing the Panasonic Grid-EYE Sensor Data using Processing 3 | By: Nick Poole 4 | SparkFun Electronics 5 | Date: January 12th, 2018 6 | 7 | MIT License: Permission is hereby granted, free of charge, to any person obtaining a copy of this 8 | software and associated documentation files (the "Software"), to deal in the Software without 9 | restriction, including without limitation the rights to use, copy, modify, merge, publish, 10 | distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the 11 | Software is furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all copies or 14 | substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING 17 | BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 19 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | 22 | Feel like supporting our work? Buy a board from SparkFun! 23 | https://www.sparkfun.com/products/14568 24 | 25 | This example is intended as a companion sketch to the Processing sketch found in the same folder. 26 | Once this code is running on your hardware, open the accompanying Processing sketch and run it 27 | as well. The Processing sketch will receive the comma separated values generated by this code and 28 | use them to generate a thermal image. If you don't have Processing, you can download it here: 29 | https://processing.org/ 30 | 31 | Hardware Connections: 32 | Attach the Qwiic Shield to your Arduino/Photon/ESP32 or other 33 | Plug the sensor onto the shield 34 | */ 35 | 36 | #include 37 | #include 38 | 39 | GridEYE grideye; 40 | 41 | void setup() { 42 | 43 | // Start your preferred I2C object 44 | Wire.begin(); 45 | // Library assumes "Wire" for I2C but you can pass something else with begin() if you like 46 | grideye.begin(); 47 | // Pour a bowl of serial 48 | Serial.begin(115200); 49 | 50 | } 51 | 52 | void loop() { 53 | 54 | // Print the temperature value of each pixel in floating point degrees Celsius 55 | // separated by commas 56 | for(unsigned char i = 0; i < 64; i++){ 57 | Serial.print(grideye.getPixelTemperature(i)); 58 | Serial.print(","); 59 | } 60 | 61 | // End each frame with a linefeed 62 | Serial.println(); 63 | 64 | // Give Processing time to chew 65 | delay(100); 66 | 67 | } 68 | 69 | -------------------------------------------------------------------------------- /examples/Example4-ProcessingHeatCam/HeatCam/HeatCam.pde: -------------------------------------------------------------------------------- 1 | /* 2 | Visualizing the Panasonic Grid-EYE Sensor Data using Processing 3 | By: Nick Poole 4 | SparkFun Electronics 5 | Date: January 12th, 2018 6 | 7 | MIT License: Permission is hereby granted, free of charge, to any person obtaining a copy of this 8 | software and associated documentation files (the "Software"), to deal in the Software without 9 | restriction, including without limitation the rights to use, copy, modify, merge, publish, 10 | distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the 11 | Software is furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all copies or 14 | substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING 17 | BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 19 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | 22 | Feel like supporting our work? Buy a board from SparkFun! 23 | https://www.sparkfun.com/products/14568 24 | 25 | This example is intended as a companion sketch to the Arduino sketch found in the same folder. 26 | Once the accompanying code is running on your hardware, run this Processing sketch. 27 | This Processing sketch will receive the comma separated values generated by the Arduino code and 28 | use them to generate a thermal image. 29 | 30 | Hardware Connections: 31 | Attach the Qwiic Shield to your Arduino/Photon/ESP32 or other 32 | Plug the sensor onto the shield 33 | */ 34 | 35 | import processing.serial.*; 36 | 37 | String myString = null; 38 | Serial myPort; // The serial port 39 | 40 | float[] temps = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; 41 | 42 | // The statements in the setup() function 43 | // execute once when the program begins 44 | void setup() { 45 | size(400, 400); // Size must be the first statement 46 | noStroke(); 47 | frameRate(30); 48 | 49 | // Print a list of connected serial devices in the console 50 | printArray(Serial.list()); 51 | // Depending on where your GridEYE falls on this list, you 52 | // may need to change Serial.list()[0] to a different number 53 | myPort = new Serial(this, Serial.list()[0], 115200); 54 | myPort.clear(); 55 | // Throw out the first chunk in case we caught it in the 56 | // middle of a frame 57 | myString = myPort.readStringUntil(13); 58 | myString = null; 59 | // change to HSB color mode, this will make it easier to color 60 | // code the temperature data 61 | colorMode(HSB, 360, 100, 100); 62 | } 63 | 64 | // The statements in draw() are executed until the 65 | // program is stopped. Each statement is executed in 66 | // sequence and after the last line is read, the first 67 | // line is executed again. 68 | void draw() { 69 | 70 | // When there is a sizeable amount of data on the serial port 71 | // read everything up to the first linefeed 72 | if(myPort.available() > 64){ 73 | myString = myPort.readStringUntil(13); 74 | 75 | // readStringUntil is a non-blocking function and will return null if it can't find the linefeed 76 | if(myString == null){ 77 | return; 78 | } 79 | 80 | // generate an array of strings that contains each of the comma 81 | // separated values 82 | String splitString[] = splitTokens(myString, ","); 83 | 84 | // for each of the 64 values, map the temperatures between 20C and 40C 85 | // to the blue through red portion of the color space 86 | for(int q = 0; q < 64; q++){ 87 | 88 | temps[q] = map(float(splitString[q]), 20, 40, 240, 360); 89 | 90 | } 91 | } 92 | 93 | 94 | // Prepare variables needed to draw our heatmap 95 | int x = 0; 96 | int y = 0; 97 | int i = 0; 98 | background(0); // Clear the screen with a black background 99 | 100 | 101 | // each GridEYE pixel will be represented by a 50px square: 102 | // because 50 x 8 = 400, we draw squares until our y location 103 | // is 400 104 | while(y < 400){ 105 | 106 | 107 | // for each increment in the y direction, draw 8 boxes in the 108 | // x direction, creating a 64 pixel matrix 109 | while(x < 400){ 110 | // before drawing each pixel, set our paintcan color to the 111 | // appropriate mapped color value 112 | fill(temps[i], 100, 100); 113 | rect(x,y,50,50); 114 | x = x + 50; 115 | i++; 116 | } 117 | 118 | y = y + 50; 119 | x = 0; 120 | } 121 | 122 | // Add a gaussian blur to the canvas in order to create a rough 123 | // visual interpolation between pixels. 124 | filter(BLUR,10); 125 | } 126 | -------------------------------------------------------------------------------- /examples/Example5-HotPixel/Example5-HotPixel.ino: -------------------------------------------------------------------------------- 1 | /* 2 | Finding Hot Spots with the Panasonic Grid-EYE Sensor 3 | By: Nick Poole 4 | SparkFun Electronics 5 | Date: January 12th, 2018 6 | 7 | MIT License: Permission is hereby granted, free of charge, to any person obtaining a copy of this 8 | software and associated documentation files (the "Software"), to deal in the Software without 9 | restriction, including without limitation the rights to use, copy, modify, merge, publish, 10 | distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the 11 | Software is furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all copies or 14 | substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING 17 | BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 19 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | 22 | Feel like supporting our work? Buy a board from SparkFun! 23 | https://www.sparkfun.com/products/14568 24 | 25 | This example reports the index and temperature of the hottest pixel in frame every 500ms 26 | 27 | Hardware Connections: 28 | Attach the Qwiic Shield to your Arduino/Photon/ESP32 or other 29 | Plug the sensor onto the shield 30 | */ 31 | 32 | #include 33 | #include 34 | 35 | GridEYE grideye; 36 | 37 | void setup() { 38 | 39 | // Start your preferred I2C object 40 | Wire.begin(); 41 | // Library assumes "Wire" for I2C but you can pass something else with begin() if you like 42 | grideye.begin(); 43 | // Pour a bowl of serial 44 | Serial.begin(115200); 45 | 46 | } 47 | 48 | void loop() { 49 | 50 | // variables to store temperature values 51 | float testPixelValue = 0; 52 | float hotPixelValue = 0; 53 | int hotPixelIndex = 0; 54 | 55 | // for each of the 64 pixels, record the temperature and compare it to the 56 | // hottest pixel that we've tested. If it's hotter, that becomes the new 57 | // king of the hill and its index is recorded. At the end of the loop, we 58 | // should have the index and temperature of the hottest pixel in the frame 59 | for(unsigned char i = 0; i < 64; i++){ 60 | testPixelValue = grideye.getPixelTemperature(i); 61 | if(testPixelValue > hotPixelValue){ 62 | hotPixelValue = testPixelValue; 63 | hotPixelIndex = i; 64 | } 65 | } 66 | 67 | // Print the result in human readable format 68 | Serial.print("The hottest pixel is #"); 69 | Serial.print(hotPixelIndex); 70 | Serial.print(" at "); 71 | Serial.print(hotPixelValue); 72 | Serial.println("C"); 73 | 74 | // toss in a delay because we don't need to run all out 75 | delay(500); 76 | 77 | } 78 | -------------------------------------------------------------------------------- /keywords.txt: -------------------------------------------------------------------------------- 1 | ####################################### 2 | # Syntax Coloring Map 3 | ####################################### 4 | 5 | ####################################### 6 | # Datatypes (KEYWORD1) 7 | ####################################### 8 | 9 | GridEYE KEYWORD1 10 | 11 | ####################################### 12 | # Methods and Functions (KEYWORD2) 13 | ####################################### 14 | 15 | begin KEYWORD2 16 | 17 | getPixelTemperature KEYWORD2 18 | getPixelTemperatureRaw KEYWORD2 19 | getPixelTemperatureSigned KEYWORD2 20 | getPixelTemperatureFahrenheit KEYWORD2 21 | 22 | getDeviceTemperature KEYWORD2 23 | getDeviceTemperatureRaw KEYWORD2 24 | getDeviceTemperatureSigned KEYWORD2 25 | getDeviceTemperatureFahrenheit KEYWORD2 26 | 27 | setFramerate1FPS KEYWORD2 28 | setFramerate10FPS KEYWORD2 29 | isFramerate10FPS KEYWORD2 30 | getFramerate KEYWORD2 31 | 32 | wake KEYWORD2 33 | sleep KEYWORD2 34 | standby60seconds KEYWORD2 35 | standby10seconds KEYWORD2 36 | 37 | interruptPinEnable KEYWORD2 38 | interruptPinDisable KEYWORD2 39 | setInterruptModeAbsolute KEYWORD2 40 | setInterruptModeDifference KEYWORD2 41 | interruptPinEnabled KEYWORD2 42 | 43 | interruptFlagSet KEYWORD2 44 | pixelTemperatureOutputOK KEYWORD2 45 | deviceTemperatureOutputOK KEYWORD2 46 | clearInterruptFlag KEYWORD2 47 | clearPixelTemperatureOverflow KEYWORD2 48 | clearDeviceTemperatureOverflow KEYWORD2 49 | clearAllOverflow KEYWORD2 50 | clearAllStatusFlags KEYWORD2 51 | 52 | pixelInterruptSet KEYWORD2 53 | 54 | movingAverageEnable KEYWORD2 55 | movingAverageDisable KEYWORD2 56 | movingAverageEnabled KEYWORD2 57 | 58 | setUpperInterruptValue KEYWORD2 59 | setUpperInterruptValueRaw KEYWORD2 60 | setUpperInterruptValueFahrenheit KEYWORD2 61 | 62 | setLowerInterruptValue KEYWORD2 63 | setLowerInterruptValueRaw KEYWORD2 64 | setLowerInterruptValueFahrenheit KEYWORD2 65 | 66 | setInterruptHysteresis KEYWORD2 67 | setInterruptHysteresisRaw KEYWORD2 68 | setInterruptHysteresisFahrenheit KEYWORD2 69 | 70 | getUpperInterruptValue KEYWORD2 71 | getUpperInterruptValueRaw KEYWORD2 72 | getUpperInterruptValueSigned KEYWORD2 73 | getUpperInterruptValueFahrenheit KEYWORD2 74 | 75 | getLowerInterruptValue KEYWORD2 76 | getLowerInterruptValueRaw KEYWORD2 77 | getLowerInterruptValueSigned KEYWORD2 78 | getLowerInterruptValueFahrenheit KEYWORD2 79 | 80 | getInterruptHysteresis KEYWORD2 81 | getInterruptHysteresisRaw KEYWORD2 82 | getInterruptHysteresisSigned KEYWORD2 83 | getInterruptHysteresisFahrenheit KEYWORD2 84 | 85 | setRegister KEYWORD2 86 | getRegister KEYWORD2 87 | getRegister8 KEYWORD2 88 | getRegister16 KEYWORD2 89 | 90 | convertUnsignedSigned16 KEYWORD2 91 | convertSignedUnsigned16 KEYWORD2 92 | convertSigned12ToFloat KEYWORD2 93 | convertFloatToSigned12 KEYWORD2 94 | 95 | setI2CAddress KEYWORD2 96 | 97 | ####################################### 98 | # Constants (LITERAL1) 99 | ####################################### 100 | -------------------------------------------------------------------------------- /library.properties: -------------------------------------------------------------------------------- 1 | name=SparkFun GridEYE AMG88 Library 2 | version=1.0.2 3 | author=SparkFun Electronics 4 | maintainer=SparkFun Electronics 5 | sentence=Library for the Panasonic GridEYE Thermopile Array - AMG88 6 | paragraph=An Arduino Library for the GridEYE Thermopile Array. Remotely detects temperature on an 8x8 array and reports in Celsius, Fahrenheit and raw register values. 7 | category=Sensors 8 | url=https://github.com/sparkfun/SparkFun_GridEYE_Arduino_Library 9 | architectures=* 10 | -------------------------------------------------------------------------------- /src/SparkFun_GridEYE_Arduino_Library.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | This is a library written for the Panasonic Grid-EYE AMG88 3 | SparkFun sells these at its website: www.sparkfun.com 4 | Do you like this library? Help support SparkFun. Buy a board! 5 | https://www.sparkfun.com/products/14568 6 | 7 | Written by Nick Poole @ SparkFun Electronics, January 11th, 2018 8 | 9 | The GridEYE from Panasonic is an 8 by 8 thermopile array capable 10 | of detecting temperature remotely at 64 discrete points. 11 | 12 | This library handles communication with the GridEYE and provides 13 | methods for manipulating temperature registers in Celsius, 14 | Fahrenheit and raw values. 15 | 16 | https://github.com/sparkfun/SparkFun_GridEYE_Arduino_Library 17 | 18 | Development environment specifics: 19 | Arduino IDE 1.8.3 20 | 21 | This program is distributed in the hope that it will be useful, 22 | but WITHOUT ANY WARRANTY; without even the implied warranty of 23 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 24 | GNU General Public License for more details. 25 | 26 | You should have received a copy of the GNU General Public License 27 | along with this program. If not, see . 28 | */ 29 | 30 | #include "SparkFun_GridEYE_Arduino_Library.h" 31 | 32 | // Attempt communication with the device 33 | // Return true if we got a 'Polo' back from Marco 34 | void GridEYE::begin(uint8_t deviceAddress, TwoWire &wirePort) 35 | { 36 | _deviceAddress = deviceAddress; 37 | _i2cPort = &wirePort; 38 | } 39 | 40 | // Change the address we read and write to 41 | void GridEYE::setI2CAddress(uint8_t addr) 42 | { 43 | _deviceAddress = addr; 44 | } 45 | 46 | /******************************************************** 47 | * Functions for retreiving the temperature of 48 | * a single pixel. 49 | ******************************************************** 50 | * 51 | * getPixelTemperature() - returns float Celsius 52 | * 53 | * getPixelTemperatureFahrenheit() - returns float Fahrenheit 54 | * 55 | * getPixelTemperatureRaw() - returns int16_t contents of 56 | * both pixel temperature registers concatinated 57 | * 58 | ********************************************************/ 59 | 60 | float GridEYE::getPixelTemperature(unsigned char pixelAddr) 61 | { 62 | // Temperature registers are numbered 128-255 63 | // Each pixel has a lower and higher register 64 | unsigned char pixelLowRegister = TEMPERATURE_REGISTER_START + (2 * pixelAddr); 65 | uint16_t temperature = 0; 66 | 67 | if (!getRegister16(pixelLowRegister, &temperature)) 68 | return -99.0; // Indicate a read error 69 | 70 | return (convertSigned12ToFloat(temperature) * 0.25); // Convert to Degrees C. LSB resolution is 0.25C. 71 | } 72 | 73 | float GridEYE::getPixelTemperatureFahrenheit(unsigned char pixelAddr) 74 | { 75 | float DegreesC = getPixelTemperature(pixelAddr); 76 | if (DegreesC == -99.0) 77 | return DegreesC; 78 | return (DegreesC * 1.8 + 32); // Convert to Fahrenheit 79 | } 80 | 81 | int16_t GridEYE::getPixelTemperatureRaw(unsigned char pixelAddr) 82 | { 83 | // Temperature registers are numbered 128-255 84 | // Each pixel has a lower and higher register 85 | unsigned char pixelLowRegister = TEMPERATURE_REGISTER_START + (2 * pixelAddr); 86 | uint16_t temperature = 0; 87 | getRegister16(pixelLowRegister, &temperature); 88 | 89 | return convertUnsignedSigned16(temperature); // Somewhat ambiguous... 90 | } 91 | 92 | int16_t GridEYE::getPixelTemperatureSigned(unsigned char pixelAddr) 93 | { 94 | // Temperature registers are numbered 128-255 95 | // Each pixel has a lower and higher register 96 | unsigned char pixelLowRegister = TEMPERATURE_REGISTER_START + (2 * pixelAddr); 97 | uint16_t temperature = 0; 98 | if (!getRegister16(pixelLowRegister, &temperature)) 99 | return -99; // Indicate a read error 100 | 101 | // temperature is 12-bit twos complement 102 | // check if temperature is negative 103 | if (temperature & (1 << 11)) 104 | temperature |= 0xF000; // Set the other MS bits to 1 to preserve the two's complement 105 | else 106 | temperature &= 0x07FF; // Clear the unused bits - just in case 107 | 108 | return convertUnsignedSigned16(temperature); // Convert to int16_t without ambiguity 109 | } 110 | 111 | /******************************************************** 112 | * Functions for retreiving the temperature of 113 | * the device according to the embedded thermistor. 114 | ******************************************************** 115 | * 116 | * getDeviceTemperature() - returns float Celsius 117 | * 118 | * getDeviceTemperatureFahrenheit() - returns float Fahrenheit 119 | * 120 | * getDeviceTemperatureRaw() - returns int16_t contents of 121 | * both thermistor temperature registers concatinated 122 | * 123 | ********************************************************/ 124 | 125 | float GridEYE::getDeviceTemperature() 126 | { 127 | 128 | uint16_t temperature = 0; 129 | 130 | if (!getRegister16(THERMISTOR_REGISTER_LSB, &temperature)) 131 | return -99.0; // Indicate a read error 132 | 133 | return (convertSigned12ToFloat(temperature) * 0.0625); 134 | } 135 | 136 | float GridEYE::getDeviceTemperatureFahrenheit() 137 | { 138 | float DegreesC = getDeviceTemperature(); 139 | if (DegreesC == -99.0) 140 | return DegreesC; 141 | return (DegreesC * 1.8 + 32); 142 | } 143 | 144 | int16_t GridEYE::getDeviceTemperatureRaw() 145 | { 146 | uint16_t temperature = 0; 147 | 148 | getRegister16(THERMISTOR_REGISTER_LSB, &temperature); 149 | 150 | return convertUnsignedSigned16(temperature); // Somewhat ambiguous... 151 | } 152 | 153 | int16_t GridEYE::getDeviceTemperatureSigned() 154 | { 155 | uint16_t temperature = 0; 156 | if (!getRegister16(THERMISTOR_REGISTER_LSB, &temperature)) 157 | return -99; // Indicate a read error 158 | 159 | // temperature is 12-bit twos complement 160 | // check if temperature is negative 161 | if (temperature & (1 << 11)) 162 | temperature |= 0xF000; // Set the other MS bits to 1 to preserve the two's complement 163 | else 164 | temperature &= 0x07FF; // Clear the unused bits - just in case 165 | 166 | return convertUnsignedSigned16(temperature); // Convert to int16_t without ambiguity 167 | } 168 | 169 | /******************************************************** 170 | * Functions for manipulating Framerate 171 | ******************************************************** 172 | * 173 | * Internal framerate of the device is always 10fps 174 | * When operating in 1FPS mode, each frame is an average 175 | * of 10 readings. 176 | * 177 | * setFramerate1FPS() - sets framerate to 1 Frame per Second 178 | * 179 | * setFramerate10FPS() - sets framerate to 10 Frames per Second 180 | * 181 | * isFramerate10FPS() - returns true if framerate is currently 182 | * set to 10 Frames per Second (device default) 183 | * 184 | ********************************************************/ 185 | 186 | void GridEYE::setFramerate1FPS() 187 | { 188 | setRegister(FRAMERATE_REGISTER, 1); 189 | } 190 | 191 | void GridEYE::setFramerate10FPS() 192 | { 193 | setRegister(FRAMERATE_REGISTER, 0); 194 | } 195 | 196 | bool GridEYE::getFramerate(bool *is10FPS) 197 | { 198 | uint8_t val = 0; 199 | 200 | bool result = getRegister8(FRAMERATE_REGISTER, &val); 201 | 202 | if (result) 203 | *is10FPS = val == 0; // If val is zero, frame rate it 10FPS 204 | 205 | return result; 206 | } 207 | 208 | bool GridEYE::isFramerate10FPS() 209 | { 210 | bool is10FPS = false; 211 | 212 | getFramerate(&is10FPS); 213 | 214 | return is10FPS; 215 | } 216 | 217 | /******************************************************** 218 | * Functions for manipulating Operating Mode 219 | ******************************************************** 220 | * 221 | * Device defaults to normal mode on reset. 222 | * When the device is in standby mode, the temperature 223 | * register is only updated intermittently. 224 | * 225 | * wake() - returns device to normal mode from any 226 | * other state. 227 | * 228 | * sleep() - puts device into sleep mode, temperature 229 | * register is not updated 230 | * 231 | * standby60seconds() - puts device into standby mode 232 | * with 60 second update frequency 233 | * 234 | * standby10seconds() - puts device into standby mode 235 | * with 10 second update frequency 236 | * 237 | ********************************************************/ 238 | 239 | void GridEYE::wake() 240 | { 241 | 242 | setRegister(POWER_CONTROL_REGISTER, 0x00); 243 | } 244 | 245 | void GridEYE::sleep() 246 | { 247 | 248 | setRegister(POWER_CONTROL_REGISTER, 0x10); 249 | } 250 | 251 | void GridEYE::standby60seconds() 252 | { 253 | 254 | setRegister(POWER_CONTROL_REGISTER, 0x20); 255 | } 256 | 257 | void GridEYE::standby10seconds() 258 | { 259 | 260 | setRegister(POWER_CONTROL_REGISTER, 0x21); 261 | } 262 | 263 | /******************************************************** 264 | * Functions for manipulating Interrupt Control Register 265 | ******************************************************** 266 | * 267 | * interruptPinEnable() - Enable INT pin to pull low on 268 | * interrupt flag 269 | * 270 | * interruptPinDisable() - Put INT pin into Hi-Z state 271 | * 272 | * setInterruptModeAbsolute() - Set interrupt mode to 273 | * "Absolute Value" mode 274 | * 275 | * setInterruptModeDifference() - Set interrupt mode to 276 | * "Difference" mode 277 | * 278 | * interruptPinEnabled() - returns true if the INT pin 279 | * is enabled. Returns false if INT pin is in Hi-Z 280 | * 281 | ********************************************************/ 282 | 283 | void GridEYE::interruptPinEnable() 284 | { 285 | uint8_t ICRValue = 0; 286 | 287 | if (getRegister8(INT_CONTROL_REGISTER, &ICRValue)) 288 | { 289 | ICRValue |= (1 << 0); 290 | 291 | setRegister(INT_CONTROL_REGISTER, ICRValue); 292 | } 293 | } 294 | 295 | void GridEYE::interruptPinDisable() 296 | { 297 | uint8_t ICRValue = 0; 298 | 299 | if (getRegister8(INT_CONTROL_REGISTER, &ICRValue)) 300 | { 301 | ICRValue &= ~(1 << 0); 302 | 303 | setRegister(INT_CONTROL_REGISTER, ICRValue); 304 | } 305 | } 306 | 307 | void GridEYE::setInterruptModeAbsolute() 308 | { 309 | uint8_t ICRValue = 0; 310 | 311 | if (getRegister8(INT_CONTROL_REGISTER, &ICRValue)) 312 | { 313 | ICRValue |= (1 << 1); 314 | 315 | setRegister(INT_CONTROL_REGISTER, ICRValue); 316 | } 317 | } 318 | 319 | void GridEYE::setInterruptModeDifference() 320 | { 321 | uint8_t ICRValue = 0; 322 | 323 | if (getRegister8(INT_CONTROL_REGISTER, &ICRValue)) 324 | { 325 | ICRValue &= ~(1 << 1); 326 | 327 | setRegister(INT_CONTROL_REGISTER, ICRValue); 328 | } 329 | } 330 | 331 | bool GridEYE::interruptPinEnabled() 332 | { 333 | uint8_t ICRValue = 0; 334 | 335 | if (!getRegister8(INT_CONTROL_REGISTER, &ICRValue)) 336 | return false; // Somewhat ambiguous... 337 | 338 | return (ICRValue & (1 << 0)); 339 | } 340 | 341 | /******************************************************** 342 | * Functions for manipulating Status/Clear Registers 343 | ******************************************************** 344 | * 345 | * interruptFlagSet() - returns true if there is an 346 | * interrupt flag in the status register 347 | * 348 | * pixelTemperatureOutputOK() - returns false if temperature 349 | * output overflow flag is present in status register 350 | * 351 | * deviceTemperatureOutputOK() - returns false if thermistor 352 | * output overflow flag is present in status register 353 | * 354 | * clearInterruptFlag() - clears interrupt flag in the 355 | * status register 356 | * 357 | * clearPixelTemperatureOverflow() - clears temperature 358 | * output overflow flag in status register 359 | * 360 | * clearDeviceTemperatureOverflow() - clears thermistor 361 | * output overflow flag in status register 362 | * 363 | * clearAllOverflow() - clears both thermistor and 364 | * temperature overflow flags in status register but 365 | * leaves interrupt flag untouched 366 | * 367 | * clearAllStatusFlags() - clears all flags in status 368 | * register 369 | * 370 | ********************************************************/ 371 | 372 | bool GridEYE::interruptFlagSet() 373 | { 374 | uint8_t StatRegValue = 0; 375 | 376 | if (!getRegister8(STATUS_REGISTER, &StatRegValue)) 377 | return false; // Somewhat ambiguous... 378 | 379 | return (StatRegValue & (1 << 1)); 380 | } 381 | 382 | bool GridEYE::pixelTemperatureOutputOK() 383 | { 384 | uint8_t StatRegValue = 0; 385 | 386 | if (!getRegister8(STATUS_REGISTER, &StatRegValue)) 387 | return false; // Somewhat ambiguous... 388 | 389 | return (StatRegValue & (1 << 2)); 390 | } 391 | 392 | bool GridEYE::deviceTemperatureOutputOK() 393 | { 394 | uint8_t StatRegValue = 0; 395 | 396 | if (!getRegister8(STATUS_REGISTER, &StatRegValue)) 397 | return false; // Somewhat ambiguous... 398 | 399 | return (StatRegValue & (1 << 3)); 400 | } 401 | 402 | void GridEYE::clearInterruptFlag() 403 | { 404 | 405 | setRegister(STATUS_CLEAR_REGISTER, 0x02); 406 | } 407 | 408 | void GridEYE::clearPixelTemperatureOverflow() 409 | { 410 | 411 | setRegister(STATUS_CLEAR_REGISTER, 0x04); 412 | } 413 | 414 | void GridEYE::clearDeviceTemperatureOverflow() 415 | { 416 | 417 | setRegister(STATUS_CLEAR_REGISTER, 0x08); 418 | } 419 | 420 | void GridEYE::clearAllOverflow() 421 | { 422 | 423 | setRegister(STATUS_CLEAR_REGISTER, 0x0C); 424 | } 425 | 426 | void GridEYE::clearAllStatusFlags() 427 | { 428 | 429 | setRegister(STATUS_CLEAR_REGISTER, 0x0E); 430 | } 431 | 432 | /******************************************************** 433 | * Function for reading Interrupt Table Register 434 | ******************************************************** 435 | * 436 | * pixelInterruptSet() - Returns true if interrupt flag 437 | * is set for the specified pixel 438 | * 439 | ********************************************************/ 440 | 441 | bool GridEYE::pixelInterruptSet(uint8_t pixelAddr) 442 | { 443 | unsigned char interruptTableRegister = INT_TABLE_REGISTER_INT0 + (pixelAddr / 8); 444 | uint8_t pixelPosition = (pixelAddr % 8); 445 | 446 | uint8_t interruptTableRow = 0; 447 | 448 | if (!getRegister8(interruptTableRegister, &interruptTableRow)) 449 | return false; // Somewhat ambiguous... 450 | 451 | return (interruptTableRow & (1 << pixelPosition)); 452 | } 453 | 454 | /******************************************************** 455 | * Functions for manipulating Average Register 456 | ******************************************************** 457 | * 458 | * Moving Average Mode enable and disable are only 459 | * referenced in some of the documentation for this 460 | * device but not in all documentation. Requires writing 461 | * in sequence to a reserved register. I'm not sure it 462 | * does anything. 463 | * 464 | * movingAverageEnable() - enable "Twice Moving Average" 465 | * 466 | * movingAverageDisable() - disable "Twice Moving Average" 467 | * 468 | * movingAverageEnabled() - returns true if enabled 469 | * 470 | ********************************************************/ 471 | 472 | void GridEYE::movingAverageEnable() 473 | { 474 | 475 | setRegister(RESERVED_AVERAGE_REGISTER, 0x50); 476 | setRegister(RESERVED_AVERAGE_REGISTER, 0x45); 477 | setRegister(RESERVED_AVERAGE_REGISTER, 0x57); 478 | setRegister(AVERAGE_REGISTER, 0x20); 479 | setRegister(RESERVED_AVERAGE_REGISTER, 0x00); 480 | } 481 | 482 | void GridEYE::movingAverageDisable() 483 | { 484 | 485 | setRegister(RESERVED_AVERAGE_REGISTER, 0x50); 486 | setRegister(RESERVED_AVERAGE_REGISTER, 0x45); 487 | setRegister(RESERVED_AVERAGE_REGISTER, 0x57); 488 | setRegister(AVERAGE_REGISTER, 0x00); 489 | setRegister(RESERVED_AVERAGE_REGISTER, 0x00); 490 | } 491 | 492 | bool GridEYE::movingAverageEnabled() 493 | { 494 | uint8_t AVGRegValue = 0; 495 | 496 | if (!getRegister8(AVERAGE_REGISTER, &AVGRegValue)) 497 | return false; // Somewhat ambiguous... 498 | 499 | return (AVGRegValue & (1 << 5)); 500 | } 501 | 502 | /******************************************************** 503 | * Functions for manipulating Interrupt Level Register 504 | ******************************************************** 505 | * 506 | * setUpperInterruptValue() - accepts float Celsius 507 | * 508 | * setUpperInterruptValueRaw() - accepts int16_t register 509 | * configuration 510 | * 511 | * setUpperInterruptValueFahrenheit() - accepts float 512 | * Fahrenheit 513 | * 514 | * setLowerInterruptValue() - accepts float Celsius 515 | * 516 | * setLowerInterruptValueRaw() - accepts int16_t register 517 | * configuration 518 | * 519 | * setLowerInterruptValueFahrenheit() - accepts float 520 | * Fahrenheit 521 | * 522 | * setInterruptHysteresis() - accepts float Celsius 523 | * 524 | * setInterruptHysteresisRaw() - accepts int16_t register 525 | * configuration 526 | * 527 | * setInterruptHysteresisFahrenheit() - accepts float 528 | * Fahrenheit 529 | * 530 | * getUpperInterruptValue() - returns float Celsius 531 | * 532 | * getUpperInterruptValueRaw() - returns int16_t register 533 | * contents 534 | * 535 | * getUpperInterruptValueFahrenheit() - returns float 536 | * Fahrenheit 537 | * 538 | * getLowerInterruptValue() - returns float Celsius 539 | * 540 | * getLowerInterruptValueRaw() - returns int16_t register 541 | * contents 542 | * 543 | * getLowerInterruptValueFahrenheit() - returns float 544 | * Fahrenheit 545 | * 546 | * getInterruptHysteresis() - returns float Celsius 547 | * 548 | * getInterruptHysteresisRaw() - returns int16_t register 549 | * contents 550 | * 551 | * getInterruptHysteresisFahrenheit() - returns float 552 | * Fahrenheit 553 | * 554 | ********************************************************/ 555 | 556 | void GridEYE::setUpperInterruptValue(float DegreesC) 557 | { 558 | uint16_t temperature12 = convertFloatToSigned12(DegreesC * 4); // Convert to 12-bit signed with 0.25C LSB resolution 559 | 560 | setRegister(INT_LEVEL_REGISTER_UPPER_LSB, temperature12 & 0xFF); 561 | setRegister(INT_LEVEL_REGISTER_UPPER_MSB, temperature12 >> 8); 562 | } 563 | 564 | void GridEYE::setUpperInterruptValueRaw(int16_t regValue) 565 | { 566 | setRegister(INT_LEVEL_REGISTER_UPPER_LSB, regValue & 0xFF); 567 | setRegister(INT_LEVEL_REGISTER_UPPER_MSB, regValue >> 8); 568 | } 569 | 570 | void GridEYE::setUpperInterruptValueFahrenheit(float DegreesF) 571 | { 572 | uint16_t temperature12 = convertFloatToSigned12((DegreesF - 32) * 4 / 1.8); // Convert to 12-bit signed 573 | 574 | setRegister(INT_LEVEL_REGISTER_UPPER_LSB, temperature12 & 0xFF); 575 | setRegister(INT_LEVEL_REGISTER_UPPER_MSB, temperature12 >> 8); 576 | } 577 | 578 | void GridEYE::setLowerInterruptValue(float DegreesC) 579 | { 580 | uint16_t temperature12 = convertFloatToSigned12(DegreesC * 4); // Convert to 12-bit signed with 0.25C LSB resolution 581 | 582 | setRegister(INT_LEVEL_REGISTER_LOWER_LSB, temperature12 & 0xFF); 583 | setRegister(INT_LEVEL_REGISTER_LOWER_MSB, temperature12 >> 8); 584 | } 585 | 586 | void GridEYE::setLowerInterruptValueRaw(int16_t regValue) 587 | { 588 | setRegister(INT_LEVEL_REGISTER_LOWER_LSB, regValue & 0xFF); 589 | setRegister(INT_LEVEL_REGISTER_LOWER_MSB, regValue >> 8); 590 | } 591 | 592 | void GridEYE::setLowerInterruptValueFahrenheit(float DegreesF) 593 | { 594 | uint16_t temperature12 = convertFloatToSigned12((DegreesF - 32) * 4 / 1.8); // Convert to 12-bit signed 595 | 596 | setRegister(INT_LEVEL_REGISTER_LOWER_LSB, temperature12 & 0xFF); 597 | setRegister(INT_LEVEL_REGISTER_LOWER_MSB, temperature12 >> 8); 598 | } 599 | 600 | void GridEYE::setInterruptHysteresis(float DegreesC) 601 | { 602 | uint16_t temperature12 = convertFloatToSigned12(DegreesC * 4); // Convert to 12-bit signed with 0.25C LSB resolution 603 | 604 | setRegister(INT_LEVEL_REGISTER_HYST_LSB, temperature12 & 0xFF); 605 | setRegister(INT_LEVEL_REGISTER_HYST_MSB, temperature12 >> 8); 606 | } 607 | 608 | void GridEYE::setInterruptHysteresisRaw(int16_t regValue) 609 | { 610 | setRegister(INT_LEVEL_REGISTER_HYST_LSB, regValue & 0xFF); 611 | setRegister(INT_LEVEL_REGISTER_HYST_MSB, regValue >> 8); 612 | } 613 | 614 | void GridEYE::setInterruptHysteresisFahrenheit(float DegreesF) 615 | { 616 | uint16_t temperature12 = convertFloatToSigned12((DegreesF - 32) * 4 / 1.8); // Convert to 12-bit signed 617 | 618 | setRegister(INT_LEVEL_REGISTER_HYST_LSB, temperature12 & 0xFF); 619 | setRegister(INT_LEVEL_REGISTER_HYST_MSB, temperature12 >> 8); 620 | } 621 | 622 | float GridEYE::getUpperInterruptValue() 623 | { 624 | uint16_t temperature = 0; 625 | 626 | if (!getRegister16(INT_LEVEL_REGISTER_UPPER_LSB, &temperature)) 627 | return -99.0; // Indicate a read error 628 | 629 | return ((convertSigned12ToFloat(temperature)) * 0.25); // Convert to Degrees C. LSB resolution is 0.25C. 630 | } 631 | 632 | float GridEYE::getUpperInterruptValueFahrenheit() 633 | { 634 | uint16_t temperature = 0; 635 | 636 | if (!getRegister16(INT_LEVEL_REGISTER_UPPER_LSB, &temperature)) 637 | return -99.0; // Indicate a read error 638 | 639 | return (((convertSigned12ToFloat(temperature)) * 0.25 * 1.8) + 32); // Convert to Degrees F 640 | } 641 | 642 | int16_t GridEYE::getUpperInterruptValueRaw() 643 | { 644 | uint16_t val = 0; 645 | getRegister16(INT_LEVEL_REGISTER_UPPER_LSB, &val); 646 | return convertUnsignedSigned16(val); 647 | } 648 | 649 | int16_t GridEYE::getUpperInterruptValueSigned() 650 | { 651 | uint16_t temperature = 0; 652 | if (!getRegister16(INT_LEVEL_REGISTER_UPPER_LSB, &temperature)) 653 | return -99; // Indicate a read error 654 | 655 | // temperature is 12-bit twos complement 656 | // check if temperature is negative 657 | if (temperature & (1 << 11)) 658 | temperature |= 0xF000; // Set the other MS bits to 1 to preserve the two's complement 659 | else 660 | temperature &= 0x07FF; // Clear the unused bits - just in case 661 | 662 | return convertUnsignedSigned16(temperature); // Convert to int16_t without ambiguity 663 | } 664 | 665 | float GridEYE::getLowerInterruptValue() 666 | { 667 | uint16_t temperature = 0; 668 | 669 | if (!getRegister16(INT_LEVEL_REGISTER_LOWER_LSB, &temperature)) 670 | return -99.0; // Indicate a read error 671 | 672 | return ((convertSigned12ToFloat(temperature)) * 0.25); // Convert to Degrees C. LSB resolution is 0.25C. 673 | } 674 | 675 | float GridEYE::getLowerInterruptValueFahrenheit() 676 | { 677 | uint16_t temperature = 0; 678 | 679 | if (!getRegister16(INT_LEVEL_REGISTER_LOWER_LSB, &temperature)) 680 | return -99.0; // Indicate a read error 681 | 682 | return (((convertSigned12ToFloat(temperature)) * 0.25 * 1.8) + 32); // Convert to Degrees F 683 | } 684 | 685 | int16_t GridEYE::getLowerInterruptValueRaw() 686 | { 687 | uint16_t val = 0; 688 | getRegister16(INT_LEVEL_REGISTER_LOWER_LSB, &val); 689 | return convertUnsignedSigned16(val); 690 | } 691 | 692 | int16_t GridEYE::getLowerInterruptValueSigned() 693 | { 694 | uint16_t temperature = 0; 695 | if (!getRegister16(INT_LEVEL_REGISTER_LOWER_LSB, &temperature)) 696 | return -99; // Indicate a read error 697 | 698 | // temperature is 12-bit twos complement 699 | // check if temperature is negative 700 | if (temperature & (1 << 11)) 701 | temperature |= 0xF000; // Set the other MS bits to 1 to preserve the two's complement 702 | else 703 | temperature &= 0x07FF; // Clear the unused bits - just in case 704 | 705 | return convertUnsignedSigned16(temperature); // Convert to int16_t without ambiguity 706 | } 707 | 708 | float GridEYE::getInterruptHysteresis() 709 | { 710 | uint16_t temperature = 0; 711 | 712 | if (!getRegister16(INT_LEVEL_REGISTER_HYST_LSB, &temperature)) 713 | return -99.0; // Indicate a read error 714 | 715 | return ((convertSigned12ToFloat(temperature)) * 0.25); // Convert to Degrees C. LSB resolution is 0.25C. 716 | } 717 | 718 | float GridEYE::getInterruptHysteresisFahrenheit() 719 | { 720 | uint16_t temperature = 0; 721 | 722 | if (!getRegister16(INT_LEVEL_REGISTER_HYST_LSB, &temperature)) 723 | return -99.0; // Indicate a read error 724 | 725 | return (((convertSigned12ToFloat(temperature)) * 0.25 * 1.8) + 32); // Convert to Degrees F 726 | } 727 | 728 | int16_t GridEYE::getInterruptHysteresisRaw() 729 | { 730 | uint16_t val = 0; 731 | getRegister16(INT_LEVEL_REGISTER_HYST_LSB, &val); 732 | return convertUnsignedSigned16(val); 733 | } 734 | 735 | int16_t GridEYE::getInterruptHysteresisSigned() 736 | { 737 | uint16_t temperature = 0; 738 | if (!getRegister16(INT_LEVEL_REGISTER_HYST_LSB, &temperature)) 739 | return -99; // Indicate a read error 740 | 741 | // temperature is 12-bit twos complement 742 | // check if temperature is negative 743 | if (temperature & (1 << 11)) 744 | temperature |= 0xF000; // Set the other MS bits to 1 to preserve the two's complement 745 | else 746 | temperature &= 0x07FF; // Clear the unused bits - just in case 747 | 748 | return convertUnsignedSigned16(temperature); // Convert to int16_t without ambiguity 749 | } 750 | 751 | /******************************************************** 752 | * Functions for setting and getting registers over I2C 753 | ******************************************************** 754 | * 755 | * setRegister() - set unsigned char value at unsigned char register 756 | * 757 | * getRegister8() - get unsigned char value from unsigned char register 758 | * 759 | * getRegister16() - get uint16_t value from unsigned char register 760 | * 761 | * getRegister() - get up to INT16 value from unsigned char register 762 | * 763 | ********************************************************/ 764 | 765 | bool GridEYE::setRegister(unsigned char reg, unsigned char val) 766 | { 767 | 768 | _i2cPort->beginTransmission(_deviceAddress); 769 | _i2cPort->write(reg); 770 | _i2cPort->write(val); 771 | return (_i2cPort->endTransmission() == 0); 772 | } 773 | 774 | bool GridEYE::getRegister8(unsigned char reg, uint8_t *val) 775 | { 776 | 777 | _i2cPort->beginTransmission(_deviceAddress); 778 | _i2cPort->write(reg); 779 | if (_i2cPort->endTransmission(false) != 0) // 'false' for a repeated start 780 | return false; 781 | 782 | bool result = _i2cPort->requestFrom(_deviceAddress, (uint8_t)1) == 1; // Request 1 byte 783 | 784 | if (result) 785 | *val = _i2cPort->read(); 786 | 787 | return result; 788 | } 789 | 790 | bool GridEYE::getRegister16(unsigned char reg, uint16_t *val) 791 | { 792 | 793 | _i2cPort->beginTransmission(_deviceAddress); 794 | _i2cPort->write(reg); 795 | if (_i2cPort->endTransmission(false) != 0) // 'false' for a repeated start 796 | return false; 797 | 798 | bool result = _i2cPort->requestFrom(_deviceAddress, (uint8_t)2) == 2; // Request 2 bytes 799 | 800 | if (result) 801 | { 802 | // Get bytes from sensor. Little endian (LSB first) 803 | uint8_t lsb = _i2cPort->read(); 804 | uint8_t msb = _i2cPort->read(); 805 | 806 | // concat bytes into uint16_t 807 | *val = (((uint16_t)msb) << 8) | lsb; 808 | } 809 | 810 | return result; 811 | } 812 | 813 | // Provided for backward compatibility only. Not recommended... 814 | int16_t GridEYE::getRegister(unsigned char reg, int8_t len) 815 | { 816 | if (len == 2) 817 | { 818 | uint16_t result = 0; 819 | getRegister16(reg, &result); 820 | return convertUnsignedSigned16(result); 821 | } 822 | else 823 | { 824 | uint8_t result = 0; 825 | getRegister8(reg, &result); 826 | return convertUnsignedSigned16((uint16_t)result); 827 | } 828 | } 829 | 830 | // Avoid any ambiguity when casting uint16_t to int16_t 831 | int16_t GridEYE::convertUnsignedSigned16(uint16_t val) 832 | { 833 | union 834 | { 835 | int16_t signed16; 836 | uint16_t unsigned16; 837 | } signedUnsigned16; 838 | 839 | signedUnsigned16.unsigned16 = val; 840 | 841 | return signedUnsigned16.signed16; 842 | } 843 | 844 | // Avoid any ambiguity when casting int16_t to uint16_t 845 | uint16_t GridEYE::convertSignedUnsigned16(int16_t val) 846 | { 847 | union 848 | { 849 | int16_t signed16; 850 | uint16_t unsigned16; 851 | } signedUnsigned16; 852 | 853 | signedUnsigned16.signed16 = val; 854 | 855 | return signedUnsigned16.unsigned16; 856 | } 857 | 858 | float GridEYE::convertSigned12ToFloat(uint16_t val) 859 | { 860 | // val is 12-bit twos complement 861 | // check if val is negative 862 | if (val & (1 << 11)) 863 | val |= 0xF000; // Set the other MS bits to 1 to preserve the two's complement 864 | else 865 | val &= 0x07FF; // Clear the unused bits - just in case 866 | 867 | return ((float)convertUnsignedSigned16(val)); // Convert to int16_t without ambiguity. Cast to float. 868 | } 869 | 870 | uint16_t GridEYE::convertFloatToSigned12(float val) 871 | { 872 | int16_t signedVal = round(val); 873 | uint16_t unsignedVal = convertSignedUnsigned16(signedVal); // Convert without ambiguity 874 | 875 | if (unsignedVal | (1 << 15)) // If the two's complement value is negative 876 | return ((unsignedVal & 0x0FFF) | (1 << 11)); // Limit to 12-bits 877 | else 878 | return(unsignedVal & 0x07FF); 879 | } 880 | 881 | -------------------------------------------------------------------------------- /src/SparkFun_GridEYE_Arduino_Library.h: -------------------------------------------------------------------------------- 1 | /* 2 | This is a library written for the Panasonic Grid-EYE AMG88 3 | SparkFun sells these at its website: www.sparkfun.com 4 | Do you like this library? Help support SparkFun. Buy a board! 5 | https://www.sparkfun.com/products/14568 6 | 7 | Written by Nick Poole @ SparkFun Electronics, January 11th, 2018 8 | 9 | The GridEYE from Panasonic is an 8 by 8 thermopile array capable 10 | of detecting temperature remotely at 64 discrete points. 11 | 12 | This library handles communication with the GridEYE and provides 13 | methods for manipulating temperature registers in Celsius, 14 | Fahrenheit and raw values. 15 | 16 | https://github.com/sparkfun/SparkFun_GridEYE_Arduino_Library 17 | 18 | Development environment specifics: 19 | Arduino IDE 1.8.3 20 | 21 | This program is distributed in the hope that it will be useful, 22 | but WITHOUT ANY WARRANTY; without even the implied warranty of 23 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 24 | GNU General Public License for more details. 25 | 26 | You should have received a copy of the GNU General Public License 27 | along with this program. If not, see . 28 | */ 29 | 30 | #pragma once 31 | 32 | #if (ARDUINO >= 100) 33 | #include "Arduino.h" 34 | #else 35 | #include "WProgram.h" 36 | #endif 37 | 38 | #include 39 | 40 | // The default I2C address for the THING on the SparkX breakout is 0x69. 0x68 is also possible. 41 | #define DEFAULT_ADDRESS 0x69 42 | 43 | // Platform specific configurations 44 | 45 | // Define the size of the I2C buffer based on the platform the user has 46 | //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 47 | #if defined(__AVR_ATmega328P__) || defined(__AVR_ATmega168__) 48 | 49 | // I2C_BUFFER_LENGTH is defined in Wire.H 50 | #define I2C_BUFFER_LENGTH BUFFER_LENGTH 51 | 52 | #elif defined(__SAMD21G18A__) 53 | 54 | // SAMD21 uses RingBuffer.h 55 | #define I2C_BUFFER_LENGTH SERIAL_BUFFER_SIZE 56 | 57 | #elif __MK20DX256__ 58 | // Teensy 59 | 60 | #elif ARDUINO_ARCH_ESP32 61 | // ESP32 based platforms 62 | 63 | #else 64 | 65 | // The catch-all default is 32 66 | #define I2C_BUFFER_LENGTH 32 67 | 68 | #endif 69 | //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 70 | 71 | // Registers 72 | #define POWER_CONTROL_REGISTER 0x00 73 | #define RESET_REGISTER 0x01 74 | #define FRAMERATE_REGISTER 0x02 75 | #define INT_CONTROL_REGISTER 0x03 76 | #define STATUS_REGISTER 0x04 77 | #define STATUS_CLEAR_REGISTER 0x05 78 | #define AVERAGE_REGISTER 0x07 79 | #define INT_LEVEL_REGISTER_UPPER_LSB 0x08 80 | #define INT_LEVEL_REGISTER_UPPER_MSB 0x09 81 | #define INT_LEVEL_REGISTER_LOWER_LSB 0x0A 82 | #define INT_LEVEL_REGISTER_LOWER_MSB 0x0B 83 | #define INT_LEVEL_REGISTER_HYST_LSB 0x0C 84 | #define INT_LEVEL_REGISTER_HYST_MSB 0x0D 85 | #define THERMISTOR_REGISTER_LSB 0x0E 86 | #define THERMISTOR_REGISTER_MSB 0x0F 87 | #define INT_TABLE_REGISTER_INT0 0x10 88 | #define RESERVED_AVERAGE_REGISTER 0x1F 89 | #define TEMPERATURE_REGISTER_START 0x80 90 | 91 | class GridEYE 92 | { 93 | public: 94 | // Return values 95 | 96 | // By default use the default I2C addres, and use Wire port 97 | void begin(uint8_t deviceAddress = DEFAULT_ADDRESS, TwoWire &wirePort = Wire); 98 | 99 | float getPixelTemperature(unsigned char pixelAddr); 100 | int16_t getPixelTemperatureRaw(unsigned char pixelAddr); // The return value is somewhat ambiguous. Use getPixelTemperatureSigned for a better experience... 101 | int16_t getPixelTemperatureSigned(unsigned char pixelAddr); 102 | float getPixelTemperatureFahrenheit(unsigned char pixelAddr); 103 | 104 | float getDeviceTemperature(); 105 | int16_t getDeviceTemperatureRaw(); // The return value is somewhat ambiguous. Use getDeviceTemperatureSigned for a better experience... 106 | int16_t getDeviceTemperatureSigned(); 107 | float getDeviceTemperatureFahrenheit(); 108 | 109 | void setFramerate1FPS(); 110 | void setFramerate10FPS(); 111 | bool isFramerate10FPS(); 112 | bool getFramerate(bool *is10FPS); 113 | 114 | void wake(); 115 | void sleep(); 116 | void standby60seconds(); 117 | void standby10seconds(); 118 | 119 | void interruptPinEnable(); 120 | void interruptPinDisable(); 121 | void setInterruptModeAbsolute(); 122 | void setInterruptModeDifference(); 123 | bool interruptPinEnabled(); 124 | 125 | bool interruptFlagSet(); 126 | bool pixelTemperatureOutputOK(); 127 | bool deviceTemperatureOutputOK(); 128 | void clearInterruptFlag(); 129 | void clearPixelTemperatureOverflow(); 130 | void clearDeviceTemperatureOverflow(); 131 | void clearAllOverflow(); 132 | void clearAllStatusFlags(); 133 | 134 | bool pixelInterruptSet(uint8_t pixelAddr); 135 | 136 | void movingAverageEnable(); 137 | void movingAverageDisable(); 138 | bool movingAverageEnabled(); 139 | 140 | void setUpperInterruptValue(float DegreesC); 141 | void setUpperInterruptValueRaw(int16_t regValue); 142 | void setUpperInterruptValueFahrenheit(float DegreesF); 143 | 144 | void setLowerInterruptValue(float DegreesC); 145 | void setLowerInterruptValueRaw(int16_t regValue); 146 | void setLowerInterruptValueFahrenheit(float DegreesF); 147 | 148 | void setInterruptHysteresis(float DegreesC); 149 | void setInterruptHysteresisRaw(int16_t regValue); 150 | void setInterruptHysteresisFahrenheit(float DegreesF); 151 | 152 | float getUpperInterruptValue(); 153 | int16_t getUpperInterruptValueRaw(); // The return value is somewhat ambiguous. Use getUpperInterruptValueSigned for a better experience... 154 | int16_t getUpperInterruptValueSigned(); 155 | float getUpperInterruptValueFahrenheit(); 156 | 157 | float getLowerInterruptValue(); 158 | int16_t getLowerInterruptValueRaw(); // The return value is somewhat ambiguous. Use getLowerInterruptValueSigned for a better experience... 159 | int16_t getLowerInterruptValueSigned(); 160 | float getLowerInterruptValueFahrenheit(); 161 | 162 | float getInterruptHysteresis(); 163 | int16_t getInterruptHysteresisRaw(); // The return value is somewhat ambiguous. Use getInterruptHysteresisSigned for a better experience... 164 | int16_t getInterruptHysteresisSigned(); 165 | float getInterruptHysteresisFahrenheit(); 166 | 167 | bool setRegister(unsigned char reg, unsigned char val); 168 | int16_t getRegister(unsigned char reg, int8_t len); // Provided for backward compatibility only. Not recommended... 169 | bool getRegister8(unsigned char reg, uint8_t *val); 170 | bool getRegister16(unsigned char reg, uint16_t *val); // Note: this returns an unsigned val. Use convertUnsignedSigned to convert to int16_t 171 | int16_t convertUnsignedSigned16(uint16_t val); 172 | uint16_t convertSignedUnsigned16(int16_t val); 173 | float convertSigned12ToFloat(uint16_t val); 174 | uint16_t convertFloatToSigned12(float val); 175 | 176 | void setI2CAddress(uint8_t addr); // Set the I2C address we read and write to 177 | 178 | private: 179 | TwoWire *_i2cPort; // The generic connection to user's chosen I2C hardware 180 | uint8_t _deviceAddress; // Keeps track of I2C address. setI2CAddress changes this. 181 | }; 182 | --------------------------------------------------------------------------------