Added ENS160 (Air quality) and ENS210 (Temperature & Humidity) sensor

This commit is contained in:
chrfriese123 2021-01-17 15:26:10 +00:00
parent fa0e8867af
commit dc73b67a61
18 changed files with 2854 additions and 0 deletions

View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2020 Sciosense
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@ -0,0 +1,151 @@
# ScioSense ENS160
Arduino library for the ENS160 digital four channel MOX gas sensor with I2C interface from ScioSense
## Introduction
This project is an Arduino *library*. It implements a driver with examples for the ENS160.
The ENS160 chip is a digital gas sensor for TVOC and eCO2 with an I2C interface.
The driver in this Arduino library is based on the code supplied by *Sciosense*, the manufacturer of the chip.
Note that the ENS160 requires a supply voltage of 1.71V .. 1.98V.
The ENS160 also requires a IO voltage of 1.71V .. 3.6V.
## Links
The ENS160 is made by [Sciosense](http://www.sciosense.com).
- The datasheet of the ENS160 is not yet released but can be provided on request
## Prerequisites
It is assumed that
- The Arduino IDE has been installed.
If not, refer to "Install the Arduino Desktop IDE" on the
[Arduino site](https://www.arduino.cc/en/Guide/HomePage).
- The library directory is at its default location.
For me, that is `C:\Users\sciosense\Documents\Arduino\libraries`.
## Installation
- Visit the project page for the Arduino CCS811 library.
- Click the green button Clone or download on the right side.
- From the pop-up choose Download ZIP.
- In Arduino IDE, select Sketch > Include Library > Manage Libraries ... and browse to the just downloaded ZIP file.
- When the IDE is ready this README.md should be located at e.g. `C:\Users\sciosense\Documents\Arduino\libraries\sciosense_ens160\README.md`.
## Build an example
To build an example sketch
- (Re)start Arduino.
- Open File > Example > Examples from Custom Libraries > ENS160 > ENS160basic_normal
- Make sure Tools > Board lists the correct board.
- Select Sketch > Verify/Compile.
## Functions
> bool begin(bool debug=false, bool bootloader=false)
Required to initialize the sensor during startup. The function takes up to two arguments:
First one enables a debug mode to provide further output during sensor operation. Default setting is false (deactivated)
Second one enables bootloader mode, which is only required to flash a new firmware. Default setting is false (deactivated)
Returns true in case of success and false in case of any issues.
> bool available()
Provides true/false feedback whether the sensor is available or not. The information will be created during initialization.
> bool setMode(uint8_t mode)
This function is used to set the sensor operation mode. Currently two modes are implemented and can be set by the following commands:
*ENS160_OPMODE_STD*: operates the sensor with a predefined heater scheme and provides prediction for eCO2 and TVOC
*ENS160_OPMODE_CUSTOM*: operates the sensor with a custom defined heaterand measurement scheme, only raw resistance values will be
reported (see also initCustomMode / addCustomStep)
Returns true in case of success and false in case of any issues.
> bool initCustomMode(uint16_t stepNum)
To be able ot use the custom mode, first it has to be initialized. The number of steps is required as input parameter. Each step has to be configured individually by calling *addCustomStep*.
Returns true in case of success and false in case of any issues.
> bool addCustomStep(uint16_t time, bool measureHP0, bool measureHP1, bool measureHP2, bool measureHP3, uint16_t tempHP0, uint16_t tempHP1, uint16_t tempHP2, uint16_t tempHP3)
For each of the steps defined in *initCustomMode* all releavant parameters have to be defined. These are
*time* defines the duration of the step
*measureHP<x>* defines if the resistance value for a specific hotplate should be measured
*tempHP<x>* sets the temperatuer for the specific hotplate
Returns true in case of success and false in case of any issues.
> bool measure(bool waitForNew = True)
Performs the sensor measurement, which means that values from the ASIC internal registers will be stored as result in internal variables.
If the variable *waitForNew* is set (default), the function will only terminate once new data is stored in the ASIC internal registers. Due to the measurement frequency this can take up to 1sec.
If the variable *waitForNew* is not set, the function might terminate with pervious non-updates results stored in the internal variables.
Returns true in case of success and false in case of any issues.
> bool set_envdata210(uint16_t t, uint16_t h)
In case temperature and humidity compensation is reuqired for sensor operation, this function allowe the storage of t and h (in ENS210 format) to ENV_DATA register.
Returns true in case of success and false in case of any issues.
> uint8_t getMajorRev()
Function returns the major number of the firmware release.
> uint8_t getMinorRev()
Function returns the minor number of the firmware release.
> uint8_t getBuild()
Function returns the build number of the firmware release.
> uint16_t getTVOC()
Function returns the TVOC value stored in the internal variable.
> uint16_t geteCO2()
Function returns the equivalent CO2 value stored in the internal variable.
> uint32_t getHP0()
Function returns the raw resistance value of hotplate 0 stored in the internal variable.
> uint32_t getHP1()
Function returns the raw resistance value of hotplate 1 stored in the internal variable.
> uint32_t getHP2()
Function returns the raw resistance value of hotplate 2 stored in the internal variable.
> uint32_t getHP3()
Function returns the raw resistance value of hotplate 3 stored in the internal variable.
> uint32_t getHP0BL()
Function returns the stored baseline of hotplate 0 (resistance).
> uint32_t getHP1BL()
Function returns the stored baseline of hotplate 1 (resistance).
> uint32_t getHP2BL()
Function returns the stored baseline of hotplate 2 (resistance).
> uint32_t getHP3BL()
Function returns the stored baseline of hotplate 3 (resistance).
### ScioSense is a Joint Venture of ams AG

View File

@ -0,0 +1,80 @@
/***************************************************************************
This is a example for ENS160 basic reading
Written by Christoph Friese for Sciosense / 29-April-2020
***************************************************************************/
#include <Wire.h>
int ArduinoLED = 13;
//-------------------------------------------------------------
//ENS160 related items
//-------------------------------------------------------------
#include "ScioSense_ENS160.h" // ENS160 library
ScioSense_ENS160 ens160(ENS160_I2CADDR_0);
//ScioSense_ENS160 ens160(ENS160_I2CADDR_1);
/*--------------------------------------------------------------------------
SETUP function
initiate sensor
--------------------------------------------------------------------------*/
void setup() {
bool ok;
//-------------------------------------------------------------
// General setup steps
//-------------------------------------------------------------
Serial.begin(9600);
while (!Serial) {}
//Switch on LED for init
pinMode(ArduinoLED, OUTPUT);
digitalWrite(ArduinoLED, LOW);
Serial.println("ENS160 example");
delay(1000);
//-------------------------------------------------------------
//ENS160 related items
//-------------------------------------------------------------
Serial.print("ENS160...");
ok = ens160.begin();
Serial.println(ens160.available() ? "done." : "failed!");
if (ens160.available()) {
// Print ENS160 versions
Serial.print("Rev: "); Serial.print(ens160.getMajorRev());
Serial.print("."); Serial.print(ens160.getMinorRev());
Serial.print("."); Serial.println(ens160.getBuild());
Serial.print("setup: ENS160 custom mode ");
ens160.initCustomMode(3); // Create custom sequence with three steps
ens160.addCustomStep(50, 0, 0, 0, 0, 80, 80, 80, 80); // Step 1: 50ms, no measurments, all hotplates at low temperatures
ens160.addCustomStep(350, 1, 1, 1, 1, 160, 215, 215, 200); // Step 2: 350ms, no measurments, all hotplates at medium temperatures
ens160.addCustomStep(600, 1, 1, 1, 1, 250, 350, 350, 325); // Step 3: 600ms, measurments done, all hotplates at high temperatures
if (!ens160.setMode(ENS160_OPMODE_CUSTOM) ) {
Serial.println("FAILED");
} else {
Serial.println("successful");
}
}
}
/*--------------------------------------------------------------------------
MAIN LOOP FUNCTION
Cylce every 1000ms and perform action
--------------------------------------------------------------------------*/
void loop() {
if (ens160.available()) {
ens160.measure();
Serial.print("R HP0: ");Serial.print(ens160.getHP0());Serial.print("Ohm\t");
Serial.print("R HP1: ");Serial.print(ens160.getHP1());Serial.print("Ohm\t");
Serial.print("R HP2: ");Serial.print(ens160.getHP2());Serial.print("Ohm\t");
Serial.print("R HP3: ");Serial.print(ens160.getHP3());Serial.println("Ohm");
}
delay(1000);
}

View File

@ -0,0 +1,78 @@
/***************************************************************************
This is a example for ENS160 basic reading
Written by Christoph Friese for Sciosense / 8-April-2020
***************************************************************************/
#include <Wire.h>
int ArduinoLED = 13;
//-------------------------------------------------------------
//ENS160 related items
//-------------------------------------------------------------
#include "ScioSense_ENS160.h" // ENS160 library
ScioSense_ENS160 ens160(ENS160_I2CADDR_0);
//sciosense_ENS160 ens160(ENS160_I2CADDR_1);
/*--------------------------------------------------------------------------
SETUP function
initiate sensor
--------------------------------------------------------------------------*/
void setup() {
bool ok;
//-------------------------------------------------------------
// General setup steps
//-------------------------------------------------------------
Serial.begin(9600);
while (!Serial) {}
//Switch on LED for init
pinMode(ArduinoLED, OUTPUT);
digitalWrite(ArduinoLED, LOW);
Serial.println("ENS160 example");
delay(1000);
//-------------------------------------------------------------
//ENS160 related items
//-------------------------------------------------------------
Serial.print("ENS160...");
ok = ens160.begin();
Serial.println(ens160.available() ? "done." : "failed!");
if (ens160.available()) {
// Print ENS160 versions
Serial.print("Rev: "); Serial.print(ens160.getMajorRev());
Serial.print("."); Serial.print(ens160.getMinorRev());
Serial.print("."); Serial.println(ens160.getBuild());
Serial.print("setup: ENS160 standard mode ");
if (!ens160.setMode(ENS160_OPMODE_STD) ) {
Serial.println("FAILED");
} else {
Serial.println("successful");
}
}
}
/*--------------------------------------------------------------------------
MAIN LOOP FUNCTION
Cylce every 1000ms and perform action
--------------------------------------------------------------------------*/
void loop() {
if (ens160.available()) {
ens160.measure();
Serial.print("TVOC (0x22): ");Serial.print(ens160.getTVOC());Serial.print("ppb\t");
Serial.print("eCO2 (0x24): ");Serial.print(ens160.geteCO2());Serial.print("ppm\t");
Serial.print("R HP0: ");Serial.print(ens160.getHP0());Serial.print("Ohm\t");
Serial.print("R HP1: ");Serial.print(ens160.getHP1());Serial.print("Ohm\t");
Serial.print("R HP2: ");Serial.print(ens160.getHP2());Serial.print("Ohm\t");
Serial.print("R HP3: ");Serial.print(ens160.getHP3());Serial.println("Ohm");
}
delay(1000);
}

View File

@ -0,0 +1,107 @@
/***************************************************************************
This is a example for ENS160 basic reading
Written by Christoph Friese for Sciosense / 8-April-2020
***************************************************************************/
#include <Wire.h>
int ArduinoLED = 13;
//-------------------------------------------------------------
//ENS160 related items
//-------------------------------------------------------------
#include "ScioSense_ENS160.h" // ENS160 library
ScioSense_ENS160 ens160(ENS160_I2CADDR_0);
//sciosense_ENS160 ens160(ENS160_I2CADDR_1);
//-------------------------------------------------------------
//ENS210 related items
//-------------------------------------------------------------
#include "ScioSense_ENS210.h"
ScioSense_ENS210 ens210;
/*--------------------------------------------------------------------------
SETUP function
initiate sensor
--------------------------------------------------------------------------*/
void setup() {
bool ok;
//-------------------------------------------------------------
// General setup steps
//-------------------------------------------------------------
Serial.begin(9600);
while (!Serial) {}
//Switch on LED for init
pinMode(ArduinoLED, OUTPUT);
digitalWrite(ArduinoLED, LOW);
Serial.println("ENS160 example with RH & T compensation");
delay(1000);
//-------------------------------------------------------------
//ENS160 related items
//-------------------------------------------------------------
Serial.print("ENS160...");
ok = ens160.begin();
Serial.println(ens160.available() ? "done." : "failed!");
if (ens160.available()) {
// Print ENS160 versions
Serial.print("Rev: "); Serial.print(ens160.getMajorRev());
Serial.print("."); Serial.print(ens160.getMinorRev());
Serial.print("."); Serial.println(ens160.getBuild());
Serial.print("setup: ENS160 standard mode ");
if (!ens160.setMode(ENS160_OPMODE_STD) ) {
Serial.println("FAILED");
} else {
Serial.println("successful");
}
}
//-------------------------------------------------------------
//ENS210 related items
//-------------------------------------------------------------
Serial.print("ENS210...");
ok = ens210.begin();
Serial.println(ens210.available() ? "done." : "failed!");
ens210.setSingleMode(false);
//blink LED
digitalWrite(ArduinoLED, HIGH);
delay(100);
digitalWrite(ArduinoLED, LOW);
}
/*--------------------------------------------------------------------------
MAIN LOOP FUNCTION
Cylce every 1000ms and perform action
--------------------------------------------------------------------------*/
void loop() {
if (ens160.available()) {
if (ens210.available()) {
ens210.measure();
ens160.set_envdata210(ens210.getDataT(),ens210.getDataH());
}
ens160.measure();
}
Serial.print("TVOC (0x22): ");Serial.print(ens160.getTVOC());Serial.print("ppb\t");
Serial.print("eCO2 (0x24): ");Serial.print(ens160.getEtOH());Serial.print("ppm\t");
Serial.print("R HP0: ");Serial.print(ens160.getHP0());Serial.print("Ohm\t");
Serial.print("R HP1: ");Serial.print(ens160.getHP1());Serial.print("Ohm\t");
Serial.print("R HP2: ");Serial.print(ens160.getHP2());Serial.print("Ohm\t");
Serial.print("R HP3: ");Serial.print(ens160.getHP3());Serial.print("Ohm\t");
Serial.print("Temperature: ");Serial.print(ens210.getTempCelsius());Serial.print("°C\t");
Serial.print("Humidity: "); Serial.print(ens210.getHumidityPercent());Serial.println("%");
delay(1000);
}

View File

@ -0,0 +1,774 @@
// Hex dump of 'c:\Users\cfri\Desktop\clare_fw_app_production_v2.3.1\clare_fw_app_production_v2.3.1.bin' created at 2019-12-21 18:31:29.368520
#include <stdint.h>
const uint8_t image_data[] PROGMEM = {
0x50, 0x07, 0x00, 0x20, 0x69, 0x08, 0x00, 0x10, 0x71, 0x08, 0x00, 0x10, 0x73, 0x08, 0x00, 0x10,
0x75, 0x08, 0x00, 0x10, 0x77, 0x08, 0x00, 0x10, 0x79, 0x08, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b, 0x08, 0x00, 0x10,
0x7d, 0x08, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x08, 0x00, 0x10, 0x65, 0x17, 0x00, 0x10,
0x85, 0x0b, 0x00, 0x10, 0x6d, 0x0c, 0x00, 0x10, 0x99, 0x0c, 0x00, 0x10, 0xc9, 0x0c, 0x00, 0x10,
0xfd, 0x0c, 0x00, 0x10, 0x03, 0x48, 0x85, 0x46, 0x00, 0xf0, 0x40, 0xf9, 0x00, 0x48, 0x00, 0x47,
0x09, 0x21, 0x00, 0x10, 0x50, 0x07, 0x00, 0x20, 0x08, 0x48, 0x80, 0x47, 0x08, 0x48, 0x00, 0x47,
0xfe, 0xe7, 0xfe, 0xe7, 0xfe, 0xe7, 0xfe, 0xe7, 0xfe, 0xe7, 0xfe, 0xe7, 0xfe, 0xe7, 0xfe, 0xe7,
0xfe, 0xe7, 0xfe, 0xe7, 0xfe, 0xe7, 0xfe, 0xe7, 0xfe, 0xe7, 0xfe, 0xe7, 0x05, 0x21, 0x00, 0x10,
0x55, 0x08, 0x00, 0x10, 0xf8, 0xb5, 0x02, 0x46, 0x4a, 0x40, 0xd4, 0x0f, 0x42, 0x00, 0x4b, 0x00,
0x52, 0x08, 0x5b, 0x08, 0x9a, 0x42, 0x02, 0xd2, 0x02, 0x46, 0x08, 0x46, 0x11, 0x46, 0x4a, 0x00,
0x23, 0xd0, 0xc3, 0x0d, 0x4a, 0x00, 0xdd, 0xb2, 0x12, 0x0e, 0xad, 0x1a, 0x20, 0x2d, 0x35, 0xda,
0x49, 0x02, 0x01, 0x26, 0x49, 0x0a, 0xf6, 0x05, 0x8a, 0x19, 0x00, 0x2c, 0x00, 0xd0, 0x52, 0x42,
0x20, 0x21, 0x4f, 0x1b, 0x11, 0x46, 0xb9, 0x40, 0x2a, 0x41, 0x10, 0x18, 0xc2, 0x0d, 0x9a, 0x42,
0x21, 0xd0, 0x00, 0x2c, 0x17, 0xd0, 0x01, 0x2d, 0x08, 0xdc, 0xda, 0x05, 0x80, 0x1a, 0xd2, 0x0f,
0x80, 0x19, 0xd2, 0x07, 0xdb, 0xb2, 0x00, 0xf0, 0x0b, 0xf9, 0xf8, 0xbd, 0xda, 0x05, 0x80, 0x1a,
0x01, 0x23, 0x40, 0x00, 0x1b, 0x06, 0xc0, 0x18, 0x80, 0x18, 0x5a, 0x42, 0x80, 0x18, 0xca, 0x0f,
0x10, 0x43, 0x49, 0x00, 0x07, 0xe0, 0x49, 0x08, 0xc2, 0x07, 0x11, 0x43, 0xda, 0x05, 0x80, 0x1a,
0x80, 0x19, 0x40, 0x08, 0x80, 0x18, 0x00, 0xf0, 0xeb, 0xf8, 0xf8, 0xbd, 0x61, 0x00, 0x01, 0x22,
0x51, 0x1a, 0x00, 0x1b, 0xf7, 0xe7, 0x01, 0x22, 0xd2, 0x07, 0x51, 0x40, 0xaa, 0xe7, 0x01, 0x22,
0xd2, 0x07, 0x50, 0x40, 0xa6, 0xe7, 0x02, 0x46, 0x70, 0xb5, 0x4a, 0x40, 0xd3, 0x0f, 0xdb, 0x07,
0x40, 0x00, 0x2d, 0xd0, 0x4a, 0x00, 0x2a, 0xd0, 0x01, 0x0e, 0x14, 0x0e, 0x00, 0x02, 0x12, 0x02,
0x09, 0x19, 0x40, 0x0a, 0x52, 0x0a, 0x84, 0x18, 0xe5, 0x01, 0x04, 0x46, 0x54, 0x43, 0x00, 0x0a,
0x12, 0x0a, 0x2e, 0x04, 0x50, 0x43, 0xa4, 0x19, 0x42, 0x19, 0x20, 0x0c, 0xc5, 0x43, 0xaa, 0x18,
0x12, 0x0c, 0x01, 0x25, 0xad, 0x03, 0x52, 0x1c, 0x52, 0x19, 0x12, 0x04, 0x7f, 0x39, 0x24, 0x04,
0x00, 0xd0, 0x52, 0x1c, 0x10, 0x43, 0x01, 0xd4, 0x40, 0x00, 0x49, 0x1e, 0xc2, 0xb2, 0x0c, 0x06,
0xc0, 0x09, 0x20, 0x18, 0x40, 0x1c, 0x40, 0x08, 0x80, 0x2a, 0x02, 0xd0, 0x03, 0xe0, 0x00, 0x20,
0x70, 0xbd, 0x40, 0x08, 0x40, 0x00, 0x00, 0x29, 0x00, 0xda, 0x00, 0x20, 0x18, 0x43, 0x70, 0xbd,
0x70, 0xb5, 0x02, 0x46, 0x4a, 0x40, 0xd5, 0x0f, 0x40, 0x00, 0x4a, 0x00, 0xed, 0x07, 0x40, 0x08,
0x52, 0x08, 0x00, 0x28, 0x14, 0xd0, 0x00, 0x2a, 0x12, 0xd0, 0xc4, 0x0d, 0xd3, 0x0d, 0x41, 0x02,
0x01, 0x20, 0xc0, 0x05, 0x52, 0x02, 0x49, 0x0a, 0x52, 0x0a, 0xe4, 0x1a, 0x09, 0x18, 0x12, 0x18,
0x7d, 0x34, 0x91, 0x42, 0x01, 0xd3, 0x64, 0x1c, 0x00, 0xe0, 0x49, 0x00, 0x00, 0x2c, 0x01, 0xda,
0x00, 0x20, 0x70, 0xbd, 0x00, 0x23, 0x91, 0x42, 0x01, 0xd3, 0x89, 0x1a, 0x03, 0x43, 0x40, 0x08,
0x49, 0x00, 0x00, 0x28, 0xf7, 0xd1, 0x00, 0x29, 0x0a, 0xd0, 0x91, 0x42, 0x02, 0xd1, 0x01, 0x21,
0xc9, 0x07, 0x05, 0xe0, 0x91, 0x42, 0x01, 0xd2, 0x01, 0x21, 0x01, 0xe0, 0x01, 0x21, 0xc9, 0x43,
0xe0, 0x05, 0xc0, 0x18, 0x40, 0x19, 0x00, 0xf0, 0x63, 0xf8, 0x70, 0xbd, 0x42, 0x00, 0x05, 0xd0,
0x42, 0x00, 0x12, 0x0e, 0x52, 0x42, 0x8a, 0x42, 0x01, 0xdb, 0x00, 0x20, 0x70, 0x47, 0xc9, 0x05,
0x08, 0x18, 0x70, 0x47, 0x10, 0xb5, 0x41, 0x00, 0x0d, 0xd0, 0x41, 0x00, 0x09, 0x0e, 0x96, 0x29,
0x09, 0xdc, 0x7e, 0x29, 0x0a, 0xdc, 0x07, 0xdb, 0x41, 0x02, 0x05, 0xd0, 0xc0, 0x0f, 0x7f, 0x21,
0xc0, 0x07, 0xc9, 0x05, 0x40, 0x18, 0x10, 0xbd, 0x00, 0x20, 0x10, 0xbd, 0x96, 0x22, 0x54, 0x1a,
0x20, 0x21, 0x0a, 0x1b, 0x01, 0x46, 0x91, 0x40, 0xe0, 0x40, 0x00, 0xf0, 0x39, 0xf8, 0xa0, 0x40,
0x10, 0xbd, 0xc2, 0x17, 0xc1, 0x0f, 0x50, 0x40, 0x10, 0xb5, 0x40, 0x18, 0xca, 0x07, 0x96, 0x23,
0x00, 0x21, 0x00, 0xf0, 0x35, 0xf8, 0x10, 0xbd, 0xc2, 0x0f, 0x41, 0x00, 0x40, 0x02, 0x01, 0x23,
0x40, 0x0a, 0xdb, 0x05, 0xd2, 0x07, 0x09, 0x0e, 0xc0, 0x18, 0x7f, 0x29, 0x01, 0xda, 0x00, 0x20,
0x70, 0x47, 0x96, 0x29, 0x03, 0xdc, 0x96, 0x23, 0x59, 0x1a, 0xc8, 0x40, 0x01, 0xe0, 0x96, 0x39,
0x88, 0x40, 0x00, 0x2a, 0xf4, 0xd0, 0x40, 0x42, 0x70, 0x47, 0x00, 0x00, 0x06, 0x4c, 0x01, 0x25,
0x06, 0x4e, 0x05, 0xe0, 0xe3, 0x68, 0x07, 0xcc, 0x2b, 0x43, 0x0c, 0x3c, 0x98, 0x47, 0x10, 0x34,
0xb4, 0x42, 0xf7, 0xd3, 0xff, 0xf7, 0xb2, 0xfe, 0xc4, 0x2e, 0x00, 0x10, 0xe4, 0x2e, 0x00, 0x10,
0x00, 0x29, 0x04, 0xda, 0x40, 0x1c, 0x49, 0x00, 0x01, 0xd1, 0x40, 0x08, 0x40, 0x00, 0x70, 0x47,
0x70, 0xb4, 0x00, 0x24, 0x05, 0x0c, 0x05, 0xd1, 0x10, 0x24, 0x00, 0x04, 0x02, 0xd1, 0x00, 0x29,
0x21, 0xd0, 0x11, 0x24, 0x05, 0x0e, 0x01, 0xd1, 0x00, 0x02, 0x08, 0x34, 0x05, 0x0f, 0x01, 0xd1,
0x00, 0x01, 0x24, 0x1d, 0x85, 0x0f, 0x01, 0xd1, 0x80, 0x00, 0xa4, 0x1c, 0x00, 0x28, 0x01, 0xdb,
0x40, 0x00, 0x64, 0x1c, 0x00, 0x29, 0x08, 0xd0, 0x20, 0x25, 0x2e, 0x1b, 0x0d, 0x46, 0xf5, 0x40,
0xa1, 0x40, 0x00, 0xd0, 0x01, 0x21, 0x29, 0x43, 0x08, 0x43, 0x01, 0x06, 0x1b, 0x1b, 0x00, 0x0a,
0xdb, 0x1d, 0x02, 0xd5, 0x00, 0x20, 0x70, 0xbc, 0x70, 0x47, 0xdb, 0x05, 0x18, 0x18, 0x80, 0x18,
0x00, 0x29, 0xf8, 0xda, 0x40, 0x1c, 0x49, 0x00, 0xf5, 0xd1, 0x70, 0xbc, 0x40, 0x08, 0x40, 0x00,
0x70, 0x47, 0x00, 0x00, 0x70, 0xb5, 0x31, 0x48, 0x41, 0x68, 0x49, 0x1c, 0x41, 0x60, 0x30, 0x4e,
0x71, 0x6a, 0x30, 0x4a, 0x0a, 0x40, 0x30, 0x4c, 0x22, 0x81, 0x4a, 0x0b, 0x01, 0x25, 0x2a, 0x40,
0x22, 0x73, 0x89, 0x0b, 0x03, 0x22, 0x0a, 0x40, 0xe2, 0x71, 0x21, 0x79, 0x0c, 0x22, 0x4a, 0x43,
0x80, 0x69, 0x81, 0x18, 0x08, 0x22, 0x89, 0x56, 0x00, 0x29, 0x31, 0xdb, 0x31, 0x68, 0x40, 0x88,
0x89, 0x0d, 0x81, 0x42, 0x06, 0xd2, 0x30, 0x68, 0x80, 0x0d, 0x03, 0xd0, 0x23, 0x48, 0x71, 0x6b,
0x01, 0x40, 0x21, 0x61, 0x0f, 0x20, 0x00, 0x02, 0x31, 0x68, 0x01, 0x42, 0x20, 0xd0, 0x00, 0xbf,
0x00, 0xbf, 0x00, 0xf0, 0x39, 0xfe, 0xe1, 0x79, 0x1d, 0x48, 0x00, 0x29, 0x04, 0xd1, 0x61, 0x89,
0x01, 0x40, 0x89, 0xb2, 0x71, 0x61, 0xe1, 0x79, 0x01, 0x29, 0x04, 0xd1, 0x61, 0x89, 0x01, 0x40,
0x89, 0xb2, 0xb1, 0x61, 0xe1, 0x79, 0x02, 0x29, 0x04, 0xd1, 0x61, 0x89, 0x01, 0x40, 0x89, 0xb2,
0xf1, 0x61, 0xe1, 0x79, 0x03, 0x29, 0x03, 0xd1, 0x61, 0x89, 0x01, 0x40, 0x88, 0xb2, 0x30, 0x62,
0x20, 0x7b, 0x00, 0x28, 0x08, 0xd0, 0xe5, 0x70, 0xa2, 0x79, 0x23, 0x79, 0x59, 0x1c, 0x00, 0x20,
0x9a, 0x42, 0x00, 0xd0, 0x08, 0x46, 0x60, 0x71, 0x0a, 0x48, 0x05, 0x60, 0x0a, 0x48, 0x01, 0x78,
0x20, 0x22, 0x0a, 0x43, 0x02, 0x70, 0x00, 0xbf, 0x00, 0xbf, 0x70, 0xbd, 0x70, 0x01, 0x00, 0x20,
0x08, 0x00, 0x00, 0x40, 0xff, 0x03, 0x00, 0x00, 0xf0, 0x01, 0x00, 0x20, 0xff, 0xff, 0x3f, 0x00,
0xff, 0x3f, 0x00, 0x00, 0x80, 0xe2, 0x00, 0xe0, 0x00, 0x0c, 0x00, 0x40, 0x80, 0xb5, 0x07, 0x48,
0x01, 0x68, 0x49, 0x1c, 0x01, 0x60, 0x00, 0xf0, 0x4b, 0xfd, 0x05, 0x48, 0x02, 0x21, 0x01, 0x60,
0x04, 0x48, 0x01, 0x78, 0x40, 0x22, 0x0a, 0x43, 0x02, 0x70, 0x80, 0xbd, 0x70, 0x00, 0x00, 0x20,
0x80, 0xe2, 0x00, 0xe0, 0x00, 0x0c, 0x00, 0x40, 0x07, 0x48, 0x01, 0x21, 0x81, 0x70, 0x07, 0x48,
0x81, 0x68, 0x49, 0x1c, 0x81, 0x60, 0x06, 0x48, 0x04, 0x21, 0x01, 0x60, 0x05, 0x48, 0x01, 0x78,
0x80, 0x22, 0x0a, 0x43, 0x02, 0x70, 0x70, 0x47, 0xf0, 0x01, 0x00, 0x20, 0x70, 0x01, 0x00, 0x20,
0x80, 0xe2, 0x00, 0xe0, 0x00, 0x0c, 0x00, 0x40, 0x10, 0xb5, 0x09, 0x4c, 0x20, 0x69, 0x00, 0x28,
0x01, 0xd0, 0x00, 0xf0, 0xef, 0xf8, 0x07, 0x48, 0x08, 0x21, 0x01, 0x60, 0x06, 0x48, 0x01, 0x78,
0x01, 0x70, 0xe0, 0x68, 0x40, 0x1c, 0xe0, 0x60, 0x00, 0xbf, 0x00, 0xbf, 0x10, 0xbd, 0xc0, 0x46,
0x70, 0x01, 0x00, 0x20, 0x80, 0xe2, 0x00, 0xe0, 0x00, 0x0c, 0x00, 0x40, 0x05, 0x48, 0x01, 0x68,
0x49, 0x1c, 0x01, 0x60, 0x04, 0x48, 0x10, 0x21, 0x01, 0x60, 0x04, 0x48, 0x01, 0x78, 0x01, 0x70,
0x70, 0x47, 0xc0, 0x46, 0x74, 0x00, 0x00, 0x20, 0x80, 0xe2, 0x00, 0xe0, 0x00, 0x0c, 0x00, 0x40,
0x10, 0xb5, 0x00, 0xf0, 0x13, 0xf8, 0x06, 0x4c, 0xf0, 0x21, 0x20, 0x46, 0x01, 0xf0, 0x96, 0xfd,
0x20, 0x20, 0x04, 0x49, 0x00, 0x22, 0x0a, 0x54, 0x03, 0x48, 0x84, 0x61, 0x10, 0xbd, 0xc0, 0x46,
0x78, 0x00, 0x00, 0x20, 0xf0, 0x01, 0x00, 0x20, 0x70, 0x01, 0x00, 0x20, 0x10, 0xb5, 0x01, 0x20,
0x81, 0x07, 0x0b, 0x68, 0x03, 0x22, 0x93, 0x43, 0x02, 0x22, 0x13, 0x43, 0x0b, 0x60, 0x00, 0x23,
0x01, 0xe0, 0x00, 0xbf, 0x5b, 0x1c, 0xdc, 0xb2, 0x07, 0x2c, 0xfa, 0xd9, 0x0b, 0x68, 0x93, 0x43,
0x0b, 0x60, 0x98, 0x22, 0x8b, 0x58, 0x80, 0x24, 0xa3, 0x43, 0x8b, 0x50, 0x08, 0x49, 0x08, 0x60,
0x04, 0x20, 0x08, 0x60, 0x21, 0x20, 0x07, 0x4c, 0x00, 0x21, 0x21, 0x54, 0x60, 0x1c, 0x06, 0x21,
0x01, 0xf0, 0x64, 0xfd, 0x04, 0x48, 0x20, 0x61, 0x00, 0xf0, 0x3e, 0xfd, 0x10, 0xbd, 0xc0, 0x46,
0x80, 0xe2, 0x00, 0xe0, 0xf0, 0x01, 0x00, 0x20, 0x9a, 0x19, 0x12, 0x00, 0xb0, 0xb5, 0x81, 0x1e,
0x02, 0x29, 0x10, 0xd3, 0x01, 0x46, 0xd0, 0x39, 0x02, 0x29, 0x0c, 0xd3, 0xc0, 0x28, 0x19, 0xd0,
0xb1, 0x28, 0x21, 0xd1, 0x14, 0x48, 0x18, 0x49, 0x81, 0x61, 0x15, 0x48, 0x00, 0x21, 0x81, 0x71,
0x01, 0x21, 0xc1, 0x70, 0xb0, 0xbd, 0xd0, 0x38, 0x41, 0x1e, 0x88, 0x41, 0x21, 0x21, 0x10, 0x4c,
0x60, 0x54, 0x0d, 0x49, 0x0f, 0x4a, 0x8a, 0x61, 0x01, 0x25, 0xa5, 0x71, 0x00, 0xf0, 0x1e, 0xf8,
0xe5, 0x70, 0xb0, 0xbd, 0x08, 0x48, 0x09, 0x49, 0x81, 0x61, 0x09, 0x48, 0x01, 0x21, 0xc1, 0x70,
0x20, 0x21, 0x41, 0x5c, 0x81, 0x71, 0xb0, 0xbd, 0x03, 0x48, 0x04, 0x49, 0x81, 0x61, 0x20, 0x20,
0x03, 0x49, 0x08, 0x5c, 0x88, 0x71, 0xb0, 0xbd, 0x70, 0x01, 0x00, 0x20, 0x78, 0x00, 0x00, 0x20,
0xf0, 0x01, 0x00, 0x20, 0xac, 0x2e, 0x00, 0x10, 0xa0, 0x2e, 0x00, 0x10, 0xf0, 0xb5, 0x87, 0xb0,
0x07, 0x46, 0x02, 0xa9, 0x01, 0x91, 0x01, 0xf0, 0x01, 0xf9, 0x06, 0x46, 0x18, 0x4d, 0x2c, 0x1d,
0x40, 0x21, 0x20, 0x46, 0x01, 0xf0, 0x0a, 0xfd, 0x01, 0x20, 0x00, 0x2e, 0x39, 0x46, 0x00, 0xd0,
0x01, 0x46, 0x00, 0x2f, 0x00, 0xd0, 0x39, 0x46, 0x34, 0x22, 0xa9, 0x54, 0x11, 0x49, 0x12, 0x4a,
0x12, 0x4b, 0x00, 0x27, 0x8f, 0x63, 0xca, 0x63, 0x11, 0x49, 0x29, 0x60, 0x6b, 0x61, 0xab, 0x61,
0xe8, 0x63, 0x00, 0x2e, 0x0f, 0xd1, 0x01, 0x98, 0x00, 0x78, 0x01, 0x28, 0x0b, 0xd1, 0x02, 0xa8,
0x00, 0x1d, 0x4e, 0xc8, 0x4e, 0xc4, 0x35, 0x20, 0x04, 0x21, 0x29, 0x54, 0xff, 0x20, 0x2e, 0x30,
0x00, 0x21, 0xa8, 0x63, 0xe9, 0x63, 0x00, 0xbf, 0x00, 0xbf, 0x07, 0xb0, 0xf0, 0xbd, 0xc0, 0x46,
0x90, 0x02, 0x00, 0x20, 0x50, 0x02, 0x00, 0x20, 0x89, 0x4a, 0x00, 0x64, 0x00, 0xff, 0x7f, 0x47,
0x01, 0x53, 0x4d, 0x41, 0xfe, 0xb5, 0x2e, 0x48, 0x01, 0x78, 0x20, 0x25, 0x29, 0x40, 0x49, 0x09,
0x02, 0x78, 0x10, 0x23, 0x13, 0x40, 0xda, 0x08, 0x0a, 0x43, 0x03, 0x78, 0x08, 0x21, 0x0b, 0x40,
0x5b, 0x08, 0x13, 0x43, 0x02, 0x78, 0x52, 0x00, 0x0a, 0x40, 0x1a, 0x43, 0x03, 0x78, 0x5b, 0x01,
0x40, 0x24, 0x1c, 0x40, 0x14, 0x43, 0x02, 0x78, 0x52, 0x01, 0x2a, 0x40, 0x22, 0x43, 0x21, 0x4b,
0x01, 0x95, 0x5b, 0x5d, 0x0c, 0x24, 0x5c, 0x43, 0x1f, 0x4b, 0x1a, 0x55, 0x1b, 0x19, 0x02, 0x78,
0x92, 0x09, 0x04, 0x79, 0xa4, 0x00, 0x14, 0x43, 0x5c, 0x80, 0x02, 0x7a, 0x1a, 0x71, 0x04, 0x7b,
0x5c, 0x71, 0x05, 0x7c, 0x9d, 0x71, 0x06, 0x7d, 0xde, 0x71, 0x07, 0x7e, 0x02, 0x97, 0x5f, 0x72,
0x01, 0x27, 0x00, 0x2a, 0x00, 0xd1, 0x17, 0x46, 0x02, 0x22, 0x3a, 0x43, 0x00, 0x2c, 0x00, 0xd0,
0x17, 0x46, 0x04, 0x22, 0x3a, 0x43, 0x00, 0x2d, 0x00, 0xd0, 0x17, 0x46, 0x39, 0x43, 0x00, 0x2e,
0x00, 0xd0, 0x0f, 0x46, 0x00, 0x7f, 0x1f, 0x72, 0xc0, 0x09, 0x98, 0x72, 0x04, 0xd0, 0x01, 0x20,
0x02, 0x99, 0x00, 0xf0, 0x13, 0xf8, 0xfe, 0xbd, 0x00, 0x20, 0x02, 0x99, 0x00, 0xf0, 0x0e, 0xf8,
0x01, 0x99, 0x04, 0x48, 0x02, 0x46, 0x50, 0x5c, 0x40, 0x1c, 0x50, 0x54, 0xfe, 0xbd, 0xc0, 0x46,
0xd0, 0x00, 0x00, 0x40, 0xf0, 0x01, 0x00, 0x20, 0x78, 0x00, 0x00, 0x20, 0x10, 0xb5, 0x03, 0x46,
0x3f, 0x24, 0x0c, 0x40, 0x01, 0x22, 0x05, 0x48, 0x00, 0x2b, 0x01, 0xd0, 0xc0, 0x21, 0x00, 0xe0,
0x80, 0x21, 0x0c, 0x43, 0xe1, 0xb2, 0x00, 0xf0, 0x23, 0xfc, 0x10, 0xbd, 0x0c, 0x01, 0x00, 0x40,
0xf0, 0xb5, 0x95, 0xb0, 0x01, 0x24, 0xa6, 0x07, 0x5c, 0x4b, 0x98, 0x78, 0x00, 0x28, 0x07, 0x96,
0x00, 0xd1, 0x9f, 0xe0, 0x00, 0x20, 0x98, 0x70, 0x59, 0x48, 0x18, 0x80, 0x02, 0x94, 0x18, 0x79,
0x0c, 0x25, 0x68, 0x43, 0x57, 0x4f, 0xb9, 0x69, 0x08, 0x5c, 0xc0, 0x07, 0x56, 0x4c, 0x12, 0xd0,
0x30, 0x6b, 0x20, 0x40, 0x19, 0x46, 0x18, 0x31, 0x00, 0xf0, 0x96, 0xfc, 0x4f, 0x4b, 0x38, 0x21,
0x52, 0x48, 0x41, 0x5c, 0x06, 0x29, 0x06, 0xd8, 0x1a, 0x8b, 0x4b, 0x00, 0xc2, 0x52, 0x4b, 0x4b,
0x49, 0x1c, 0x38, 0x22, 0x81, 0x54, 0x18, 0x79, 0x68, 0x43, 0xb9, 0x69, 0x08, 0x5c, 0x80, 0x07,
0x13, 0xd5, 0x39, 0x20, 0x49, 0x4e, 0x37, 0x5c, 0x07, 0x98, 0x40, 0x6b, 0x20, 0x40, 0x19, 0x46,
0x1a, 0x31, 0x00, 0xf0, 0x79, 0xfc, 0x41, 0x4b, 0x06, 0x2f, 0x06, 0xd8, 0x78, 0x00, 0x30, 0x18,
0x59, 0x8b, 0xc1, 0x81, 0x78, 0x1c, 0x39, 0x21, 0x70, 0x54, 0x18, 0x79, 0x68, 0x43, 0x3d, 0x49,
0x89, 0x69, 0x08, 0x5c, 0x40, 0x07, 0x13, 0xd5, 0x3a, 0x20, 0x3c, 0x4e, 0x37, 0x5c, 0x07, 0x98,
0x80, 0x6b, 0x20, 0x40, 0x19, 0x46, 0x1c, 0x31, 0x00, 0xf0, 0x5e, 0xfc, 0x33, 0x4b, 0x06, 0x2f,
0x06, 0xd8, 0x78, 0x00, 0x30, 0x18, 0x99, 0x8b, 0x81, 0x83, 0x78, 0x1c, 0x3a, 0x21, 0x70, 0x54,
0x18, 0x79, 0x68, 0x43, 0x2f, 0x49, 0x89, 0x69, 0x08, 0x5c, 0x00, 0x07, 0x13, 0xd5, 0x3b, 0x20,
0x2e, 0x4e, 0x37, 0x5c, 0x07, 0x98, 0xc0, 0x6b, 0x20, 0x40, 0x19, 0x46, 0x1e, 0x31, 0x00, 0xf0,
0x43, 0xfc, 0x26, 0x4b, 0x06, 0x2f, 0x06, 0xd8, 0x78, 0x00, 0x30, 0x18, 0xd9, 0x8b, 0x41, 0x85,
0x78, 0x1c, 0x3b, 0x21, 0x70, 0x54, 0x19, 0x79, 0x28, 0x46, 0x48, 0x43, 0x21, 0x4f, 0xba, 0x69,
0x10, 0x5c, 0x2f, 0x22, 0x02, 0x40, 0x20, 0x2a, 0x07, 0x9e, 0x02, 0xd1, 0x72, 0x6b, 0x22, 0x40,
0x5a, 0x61, 0x4f, 0x22, 0x02, 0x40, 0x40, 0x2a, 0x02, 0xd1, 0xf2, 0x6b, 0x22, 0x40, 0x1a, 0x61,
0x40, 0x06, 0x00, 0xd1, 0x44, 0xe1, 0x38, 0x78, 0x01, 0x24, 0xc0, 0x28, 0x01, 0xd0, 0xb1, 0x28,
0x06, 0xd1, 0x30, 0x46, 0x9c, 0x30, 0x22, 0x46, 0x00, 0xf0, 0x82, 0xfb, 0x0f, 0x4b, 0x38, 0x78,
0x01, 0x46, 0xc0, 0x39, 0x11, 0x29, 0x2c, 0xd9, 0x81, 0x1e, 0x02, 0x29, 0x2e, 0xd3, 0xb1, 0x28,
0x2c, 0xd0, 0x9f, 0xe0, 0x58, 0x78, 0x18, 0x70, 0x09, 0x28, 0x00, 0xd9, 0x2d, 0xe1, 0x40, 0x00,
0x78, 0x44, 0x80, 0x88, 0x40, 0x00, 0x87, 0x44, 0x14, 0x00, 0x2a, 0x01, 0x2e, 0x01, 0xea, 0x02,
0x28, 0x01, 0x28, 0x01, 0x13, 0x00, 0x28, 0x01, 0xa5, 0x00, 0x23, 0x01, 0xf0, 0x01, 0x00, 0x20,
0x06, 0x06, 0x00, 0x00, 0x70, 0x01, 0x00, 0x20, 0xff, 0xff, 0x3f, 0x00, 0x50, 0x02, 0x00, 0x20,
0x44, 0xe7, 0x58, 0x1c, 0xd9, 0x78, 0x00, 0x29, 0x00, 0xd1, 0x0c, 0xe1, 0x5c, 0x70, 0xd8, 0x1c,
0x09, 0xe1, 0x22, 0x46, 0x8a, 0x40, 0xfa, 0x49, 0x0a, 0x42, 0xcd, 0xd0, 0x0c, 0x94, 0x18, 0x79,
0x45, 0x43, 0xb8, 0x69, 0x40, 0x5d, 0x40, 0x06, 0x80, 0x0f, 0xfa, 0x4d, 0x32, 0xd0, 0x19, 0x7c,
0x30, 0x46, 0xf0, 0x30, 0x37, 0x46, 0x00, 0x26, 0x32, 0x46, 0x1c, 0x46, 0xf6, 0x4b, 0x98, 0x47,
0x61, 0x7c, 0x38, 0x46, 0xf4, 0x30, 0x32, 0x46, 0xf3, 0x4b, 0x98, 0x47, 0x61, 0x8a, 0x3f, 0x20,
0x0b, 0x90, 0x01, 0x40, 0x38, 0x46, 0xf8, 0x30, 0x32, 0x46, 0xef, 0x4b, 0x98, 0x47, 0xfc, 0x37,
0x38, 0x46, 0x31, 0x46, 0x32, 0x46, 0xec, 0x4f, 0xb8, 0x47, 0x21, 0x7d, 0x28, 0x46, 0x32, 0x46,
0xb8, 0x47, 0x61, 0x7d, 0x28, 0x1d, 0x32, 0x46, 0xb8, 0x47, 0xe1, 0x8a, 0x0b, 0x98, 0x01, 0x40,
0x28, 0x46, 0x08, 0x30, 0x32, 0x46, 0xb8, 0x47, 0x0c, 0x35, 0x28, 0x46, 0x31, 0x46, 0x0c, 0x9a,
0xb8, 0x47, 0x2d, 0xe0, 0x19, 0x7e, 0x30, 0x46, 0xf0, 0x30, 0x34, 0x46, 0x00, 0x26, 0x32, 0x46,
0x1f, 0x46, 0xdd, 0x4b, 0x98, 0x47, 0x79, 0x7e, 0x20, 0x46, 0xf4, 0x30, 0x32, 0x46, 0xda, 0x4b,
0x98, 0x47, 0xb9, 0x7e, 0x20, 0x46, 0xf8, 0x30, 0x32, 0x46, 0xd7, 0x4b, 0x98, 0x47, 0xf9, 0x7e,
0xfc, 0x34, 0x20, 0x46, 0x32, 0x46, 0xd4, 0x4c, 0xa0, 0x47, 0x39, 0x7f, 0x28, 0x46, 0x32, 0x46,
0xa0, 0x47, 0x79, 0x7f, 0x28, 0x1d, 0x32, 0x46, 0xa0, 0x47, 0xb9, 0x7f, 0x28, 0x46, 0x08, 0x30,
0x32, 0x46, 0xa0, 0x47, 0x23, 0x46, 0xf9, 0x7f, 0x0c, 0x35, 0x28, 0x46, 0x0c, 0x9a, 0x98, 0x47,
0xca, 0x48, 0x01, 0x46, 0x48, 0x69, 0x40, 0x1c, 0x48, 0x61, 0x00, 0xbf, 0x00, 0xbf, 0x08, 0x78,
0xc7, 0x4b, 0x07, 0x9e, 0x01, 0x46, 0xd0, 0x39, 0x02, 0x29, 0x03, 0xd3, 0x80, 0x1e, 0x01, 0x28,
0x00, 0xd9, 0x85, 0xe0, 0x98, 0x79, 0x59, 0x79, 0x81, 0x42, 0x00, 0xd0, 0x80, 0xe0, 0x08, 0x20,
0x58, 0x70, 0x02, 0x9c, 0x05, 0x20, 0x90, 0x21, 0x72, 0x58, 0x00, 0x2a, 0x02, 0xda, 0x40, 0x1e,
0xf9, 0xd1, 0x0d, 0xe0, 0x70, 0x58, 0x05, 0x21, 0x94, 0x22, 0xb2, 0x58, 0x00, 0x2a, 0x02, 0xda,
0x49, 0x1e, 0xf9, 0xd1, 0x04, 0xe0, 0x94, 0x21, 0x71, 0x58, 0xb6, 0x4a, 0xd1, 0x87, 0x90, 0x87,
0x12, 0xa8, 0x00, 0xf0, 0xb1, 0xfc, 0x38, 0x22, 0xb2, 0x49, 0x02, 0xe0, 0x00, 0x23, 0x8b, 0x54,
0x52, 0x1c, 0x3c, 0x2a, 0xfa, 0xd1, 0x09, 0x22, 0xad, 0x4b, 0x5a, 0x70, 0x00, 0x28, 0x57, 0xd1,
0x02, 0x94, 0x62, 0x02, 0x0c, 0x92, 0xac, 0x4b, 0x18, 0x68, 0x90, 0x43, 0x18, 0x60, 0x12, 0xaf,
0x38, 0x78, 0x9c, 0x22, 0xb0, 0x50, 0xb8, 0x88, 0xa0, 0x22, 0xb0, 0x50, 0x78, 0x88, 0xa4, 0x22,
0xb0, 0x50, 0xf8, 0x88, 0xa8, 0x22, 0xb0, 0x50, 0x88, 0x8f, 0xbc, 0x22, 0xb0, 0x50, 0xc8, 0x8f,
0xc0, 0x21, 0x70, 0x50, 0x45, 0x20, 0x04, 0x06, 0xa0, 0x4d, 0x68, 0x68, 0x21, 0x46, 0xff, 0xf7,
0x32, 0xfb, 0x01, 0xf0, 0x05, 0xfb, 0xac, 0x21, 0x70, 0x50, 0xa8, 0x68, 0x21, 0x46, 0xff, 0xf7,
0x2a, 0xfb, 0x01, 0xf0, 0xfd, 0xfa, 0xb0, 0x21, 0x70, 0x50, 0xe8, 0x68, 0x21, 0x46, 0xff, 0xf7,
0x22, 0xfb, 0x01, 0xf0, 0xf5, 0xfa, 0xb4, 0x21, 0x70, 0x50, 0x28, 0x69, 0x21, 0x46, 0xff, 0xf7,
0x1a, 0xfb, 0x01, 0xf0, 0xed, 0xfa, 0xb8, 0x21, 0x70, 0x50, 0xf7, 0x4a, 0x10, 0x68, 0x0c, 0x99,
0x08, 0x43, 0x10, 0x60, 0x38, 0x7a, 0x80, 0x07, 0x0f, 0xd5, 0x28, 0x68, 0xf3, 0x49, 0x88, 0x42,
0x0b, 0xd1, 0x02, 0x98, 0x0d, 0x90, 0x28, 0x1d, 0x0d, 0xa9, 0x0a, 0x1d, 0x78, 0xc8, 0x78, 0xc2,
0x21, 0x20, 0xeb, 0x4a, 0x10, 0x5c, 0x00, 0xf0, 0x9d, 0xfe, 0x00, 0xbf, 0x00, 0xbf, 0xe8, 0x4b,
0x58, 0x79, 0x18, 0x71, 0x58, 0x1c, 0x00, 0x21, 0x01, 0x70, 0x15, 0xb0, 0xf0, 0xbd, 0x02, 0x20,
0x58, 0x70, 0x00, 0x20, 0x18, 0x73, 0x02, 0x94, 0x58, 0x79, 0x0c, 0x21, 0x09, 0x91, 0x48, 0x43,
0xe0, 0x4f, 0xb9, 0x69, 0x0a, 0x18, 0x53, 0x88, 0x9b, 0x05, 0x12, 0x7a, 0x0f, 0x24, 0x0a, 0x94,
0x22, 0x40, 0x12, 0x02, 0x1a, 0x43, 0x08, 0x5c, 0x6f, 0x21, 0x01, 0x40, 0x11, 0x43, 0x10, 0x20,
0x08, 0x43, 0x70, 0x60, 0xd6, 0x48, 0x00, 0x69, 0xff, 0xf7, 0x7b, 0xfb, 0x01, 0x46, 0x25, 0x20,
0x40, 0x06, 0xff, 0xf7, 0xc8, 0xfa, 0x21, 0x21, 0x49, 0x06, 0xff, 0xf7, 0xcc, 0xfa, 0x35, 0x21,
0x09, 0x06, 0xff, 0xf7, 0xc8, 0xfa, 0xd2, 0x49, 0x08, 0x60, 0x3d, 0x6b, 0x09, 0x68, 0x28, 0x46,
0xff, 0xf7, 0x68, 0xfa, 0x01, 0x46, 0x28, 0x46, 0xff, 0xf7, 0xfa, 0xfa, 0x01, 0x46, 0x7c, 0x6b,
0x20, 0x46, 0xff, 0xf7, 0xb8, 0xfa, 0xb9, 0x6b, 0xff, 0xf7, 0xad, 0xfa, 0xf9, 0x6b, 0x06, 0x91,
0xff, 0xf7, 0xa9, 0xfa, 0xc6, 0x4e, 0x70, 0x60, 0x20, 0x46, 0x29, 0x46, 0xff, 0xf7, 0xab, 0xfa,
0x04, 0x46, 0x0c, 0x94, 0x3f, 0x6c, 0x31, 0x68, 0x38, 0x46, 0xff, 0xf7, 0x9c, 0xfa, 0x01, 0x46,
0x20, 0x46, 0xff, 0xf7, 0xa0, 0xfa, 0x06, 0x46, 0x28, 0x46, 0x39, 0x46, 0xff, 0xf7, 0x42, 0xfa,
0x07, 0x46, 0xbb, 0x4c, 0x21, 0x68, 0x28, 0x46, 0xff, 0xf7, 0x3c, 0xfa, 0x01, 0x46, 0x38, 0x46,
0x27, 0x46, 0xff, 0xf7, 0x90, 0xfa, 0x01, 0x46, 0x30, 0x46, 0xff, 0xf7, 0xc9, 0xfa, 0xb8, 0x60,
0xb0, 0x48, 0x46, 0x6c, 0x39, 0x68, 0x30, 0x46, 0xff, 0xf7, 0x7d, 0xfa, 0x01, 0x46, 0x0c, 0x98,
0xff, 0xf7, 0x81, 0xfa, 0x04, 0x46, 0x28, 0x46, 0x31, 0x46, 0xff, 0xf7, 0x23, 0xfa, 0x06, 0x46,
0x39, 0x68, 0x28, 0x46, 0xff, 0xf7, 0x1e, 0xfa, 0x01, 0x46, 0x30, 0x46, 0xff, 0xf7, 0x73, 0xfa,
0x01, 0x46, 0x20, 0x46, 0xff, 0xf7, 0xac, 0xfa, 0xf8, 0x60, 0x89, 0x20, 0xc1, 0x05, 0xa1, 0x4c,
0x60, 0x6f, 0xff, 0xf7, 0x68, 0xfa, 0x0b, 0x90, 0x6b, 0x20, 0xc5, 0x05, 0xa0, 0x6e, 0x26, 0x46,
0x29, 0x46, 0xff, 0xf7, 0x60, 0xfa, 0xf9, 0x68, 0xff, 0xf7, 0x5d, 0xfa, 0x7f, 0x21, 0xc9, 0x05,
0x0c, 0x91, 0xff, 0xf7, 0xff, 0xf9, 0x04, 0x46, 0xf0, 0x6e, 0x29, 0x46, 0xff, 0xf7, 0x53, 0xfa,
0x06, 0x46, 0xf8, 0x68, 0xf9, 0x68, 0xff, 0xf7, 0x4e, 0xfa, 0x01, 0x46, 0x30, 0x46, 0xff, 0xf7,
0x4a, 0xfa, 0x01, 0x46, 0x20, 0x46, 0xff, 0xf7, 0xed, 0xf9, 0x01, 0x46, 0x0b, 0x98, 0xff, 0xf7,
0x42, 0xfa, 0xb8, 0x61, 0x8b, 0x4e, 0xf0, 0x69, 0x01, 0xf0, 0x0b, 0xfa, 0x73, 0x21, 0xcc, 0x05,
0x21, 0x46, 0xff, 0xf7, 0x38, 0xfa, 0x75, 0x21, 0xc9, 0x05, 0x01, 0x91, 0xff, 0xf7, 0x33, 0xfa,
0x05, 0x90, 0x30, 0x6a, 0x01, 0xf0, 0xfd, 0xf9, 0x21, 0x46, 0xff, 0xf7, 0x2c, 0xfa, 0x00, 0x95,
0x29, 0x46, 0xff, 0xf7, 0x28, 0xfa, 0x7e, 0x49, 0x0a, 0x46, 0x0b, 0x90, 0x50, 0x79, 0x09, 0x9b,
0x58, 0x43, 0xb1, 0x69, 0x08, 0x18, 0x04, 0x1d, 0x10, 0x79, 0x58, 0x43, 0x08, 0x18, 0x00, 0x1d,
0x03, 0x90, 0x0a, 0x98, 0xc5, 0x43, 0x00, 0x26, 0x04, 0x94, 0x8c, 0xe0, 0xa0, 0x5d, 0x00, 0x28,
0x08, 0xd0, 0x03, 0x99, 0x89, 0x5d, 0x81, 0x42, 0x1a, 0xd2, 0x40, 0x1a, 0x19, 0xe0, 0xc0, 0x46,
0x01, 0x00, 0x03, 0x00, 0x79, 0x19, 0x00, 0x20, 0xc8, 0x62, 0xc8, 0x65, 0x39, 0x46, 0x5c, 0x31,
0x75, 0xe0, 0xc0, 0x46, 0x00, 0x01, 0x00, 0x40, 0xe1, 0x17, 0x00, 0x10, 0x70, 0x01, 0x00, 0x20,
0xf0, 0x01, 0x00, 0x20, 0x50, 0x02, 0x00, 0x20, 0x00, 0x08, 0x00, 0x40, 0x90, 0x02, 0x00, 0x20,
0x08, 0x1a, 0x65, 0x28, 0x03, 0xdb, 0x78, 0x19, 0x00, 0x21, 0xc1, 0x65, 0xc1, 0x66, 0xa0, 0x5d,
0x01, 0xf0, 0xb7, 0xf9, 0x01, 0x46, 0xff, 0xf7, 0x8d, 0xf9, 0x06, 0x99, 0xff, 0xf7, 0xdb, 0xf9,
0x04, 0x46, 0xf1, 0xb2, 0x5b, 0x48, 0x24, 0x30, 0x00, 0x29, 0x0a, 0x95, 0x09, 0x96, 0x03, 0xd0,
0x03, 0x29, 0x01, 0xd0, 0x57, 0x48, 0x28, 0x30, 0x00, 0x68, 0x01, 0xf0, 0xa2, 0xf9, 0x77, 0x21,
0xc9, 0x05, 0xff, 0xf7, 0xd0, 0xf9, 0x07, 0x46, 0x56, 0x49, 0xff, 0xf7, 0xcc, 0xf9, 0x08, 0x90,
0x20, 0x46, 0x05, 0x9e, 0x31, 0x46, 0xff, 0xf7, 0xc6, 0xf9, 0x0c, 0x99, 0xff, 0xf7, 0x6a, 0xf9,
0x05, 0x46, 0x20, 0x46, 0x0b, 0x99, 0xff, 0xf7, 0xbe, 0xf9, 0x01, 0x46, 0x20, 0x46, 0xff, 0xf7,
0xba, 0xf9, 0x01, 0x46, 0x28, 0x46, 0xff, 0xf7, 0x5d, 0xf9, 0x08, 0x99, 0xff, 0xf7, 0xb3, 0xf9,
0x08, 0x90, 0x38, 0x46, 0x48, 0x49, 0xff, 0xf7, 0xae, 0xf9, 0x04, 0x46, 0x44, 0x4f, 0x79, 0x68,
0x30, 0x46, 0xff, 0xf7, 0xa8, 0xf9, 0x0c, 0x99, 0xff, 0xf7, 0x4c, 0xf9, 0x05, 0x46, 0x79, 0x68,
0x0b, 0x98, 0xff, 0xf7, 0xa0, 0xf9, 0x79, 0x68, 0xff, 0xf7, 0x9d, 0xf9, 0x01, 0x46, 0x28, 0x46,
0xff, 0xf7, 0x40, 0xf9, 0x01, 0x46, 0x20, 0x46, 0xff, 0xf7, 0x95, 0xf9, 0x01, 0x46, 0x08, 0x98,
0xff, 0xf7, 0x38, 0xf9, 0x39, 0x46, 0x1c, 0x31, 0x04, 0x9c, 0x0a, 0x9d, 0x09, 0x9e, 0x49, 0x19,
0x08, 0x61, 0x2d, 0x1d, 0x76, 0x1c, 0x00, 0x2d, 0x00, 0xd0, 0x6f, 0xe7, 0x2d, 0x4e, 0xb0, 0x6c,
0x01, 0x99, 0xff, 0xf7, 0x80, 0xf9, 0x0b, 0x90, 0x30, 0x6d, 0x00, 0x9e, 0x31, 0x46, 0xff, 0xf7,
0x7a, 0xf9, 0xb9, 0x68, 0xff, 0xf7, 0x77, 0xf9, 0x0c, 0x9c, 0x21, 0x46, 0xff, 0xf7, 0x1a, 0xf9,
0x05, 0x46, 0x24, 0x48, 0x40, 0x6d, 0x31, 0x46, 0xff, 0xf7, 0x6d, 0xf9, 0xb9, 0x68, 0xff, 0xf7,
0x6a, 0xf9, 0xb9, 0x68, 0xff, 0xf7, 0x67, 0xf9, 0x01, 0x46, 0x28, 0x46, 0xff, 0xf7, 0x0a, 0xf9,
0x01, 0x46, 0x0b, 0x98, 0xff, 0xf7, 0x5f, 0xf9, 0x38, 0x61, 0x1a, 0x49, 0x88, 0x6d, 0x0d, 0x46,
0x01, 0x99, 0xff, 0xf7, 0x58, 0xf9, 0xb9, 0x68, 0xff, 0xf7, 0x55, 0xf9, 0x21, 0x46, 0xff, 0xf7,
0xf9, 0xf8, 0x04, 0x46, 0xe8, 0x6d, 0x31, 0x46, 0xff, 0xf7, 0x4d, 0xf9, 0xb9, 0x68, 0xff, 0xf7,
0x4a, 0xf9, 0xb9, 0x68, 0xff, 0xf7, 0x47, 0xf9, 0x01, 0x46, 0x20, 0x46, 0xff, 0xf7, 0xea, 0xf8,
0x01, 0x46, 0xe8, 0x6c, 0xff, 0xf7, 0x3f, 0xf9, 0x10, 0x49, 0xff, 0xf7, 0xe3, 0xf8, 0x08, 0x4b,
0x78, 0x61, 0x00, 0xbf, 0x00, 0xbf, 0x03, 0x20, 0x58, 0x70, 0x02, 0x9c, 0x07, 0x9e, 0x98, 0x20,
0x31, 0x58, 0x80, 0x22, 0x0a, 0x43, 0x32, 0x50, 0x30, 0x68, 0x20, 0x43, 0x30, 0x60, 0x31, 0xe6,
0xf0, 0x01, 0x00, 0x20, 0x70, 0x01, 0x00, 0x20, 0x00, 0x08, 0x00, 0x40, 0x01, 0x53, 0x4d, 0x41,
0xe0, 0x02, 0x00, 0x20, 0x52, 0xb8, 0x5e, 0x3f, 0xb8, 0x1e, 0x05, 0x3e, 0x00, 0x00, 0xe0, 0xc0,
0x00, 0x20, 0x01, 0xe0, 0x00, 0xbf, 0x40, 0x1c, 0xc1, 0xb2, 0x18, 0x29, 0xfa, 0xd3, 0x05, 0x21,
0x08, 0x48, 0x02, 0x68, 0x00, 0x2a, 0x05, 0xda, 0x01, 0x22, 0x52, 0x02, 0x00, 0x23, 0x49, 0x1e,
0xf7, 0xd1, 0x01, 0xe0, 0x03, 0x68, 0x00, 0x22, 0x03, 0x48, 0x83, 0x70, 0x81, 0x6f, 0x89, 0x18,
0x81, 0x67, 0x70, 0x47, 0x84, 0x00, 0x00, 0x40, 0x70, 0x01, 0x00, 0x20, 0x10, 0xb5, 0x04, 0x46,
0x03, 0x48, 0x04, 0x70, 0xff, 0xf7, 0xfa, 0xfa, 0x20, 0x46, 0xff, 0xf7, 0x27, 0xfb, 0x10, 0xbd,
0x70, 0x01, 0x00, 0x20, 0x02, 0x48, 0x01, 0x68, 0x49, 0x1c, 0x01, 0x60, 0x70, 0x47, 0xc0, 0x46,
0x68, 0x01, 0x00, 0x20, 0x70, 0xb5, 0x04, 0x46, 0x7c, 0x20, 0x15, 0x4d, 0x60, 0x21, 0x29, 0x54,
0x7d, 0x20, 0x01, 0x21, 0x29, 0x54, 0x00, 0xf0, 0x47, 0xf8, 0xc4, 0x20, 0x00, 0x26, 0x2e, 0x50,
0x10, 0x48, 0x01, 0x68, 0xff, 0x22, 0x91, 0x43, 0xb0, 0x22, 0x0a, 0x43, 0x02, 0x60, 0xff, 0xf7,
0xd5, 0xfa, 0x2e, 0x60, 0xae, 0x60, 0xee, 0x60, 0x2e, 0x61, 0x6e, 0x61, 0xae, 0x61, 0xee, 0x61,
0x2e, 0x62, 0x6e, 0x62, 0x00, 0x2c, 0x04, 0xd0, 0xc5, 0x20, 0x40, 0x21, 0x29, 0x54, 0x00, 0x21,
0x29, 0x54, 0x05, 0x48, 0x05, 0x49, 0x01, 0x60, 0x00, 0x21, 0x81, 0x60, 0x70, 0xbd, 0xc0, 0x46,
0x04, 0x00, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 0x0c, 0x00, 0x40, 0xff, 0x07, 0x00, 0x00,
0x70, 0xb5, 0x0b, 0x4e, 0x35, 0x46, 0x1c, 0x35, 0x0a, 0x4b, 0x1c, 0x68, 0xb0, 0x42, 0x04, 0xd3,
0xa8, 0x42, 0x02, 0xd8, 0x01, 0x25, 0xad, 0x02, 0x01, 0xe0, 0x01, 0x25, 0x6d, 0x02, 0xac, 0x43,
0x1c, 0x60, 0x01, 0x70, 0x00, 0x2a, 0x02, 0xd0, 0x18, 0x68, 0x28, 0x43, 0x18, 0x60, 0x70, 0xbd,
0xf0, 0x00, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x03, 0x20, 0x40, 0x02, 0x0c, 0x49, 0x0a, 0x68,
0x82, 0x43, 0x0a, 0x60, 0x0b, 0x48, 0x00, 0x21, 0x01, 0x60, 0x41, 0x60, 0x81, 0x60, 0xc1, 0x60,
0x01, 0x61, 0x41, 0x61, 0x81, 0x61, 0xc1, 0x61, 0x01, 0x62, 0x41, 0x62, 0x81, 0x62, 0x81, 0x65,
0xc1, 0x65, 0x01, 0x66, 0x41, 0x66, 0x81, 0x66, 0xc1, 0x66, 0x01, 0x67, 0x41, 0x67, 0x70, 0x47,
0x00, 0x08, 0x00, 0x40, 0x98, 0x00, 0x00, 0x40, 0xf8, 0xb5, 0x27, 0x4d, 0x28, 0x89, 0x01, 0xf0,
0x40, 0xf8, 0x01, 0x46, 0x25, 0x4c, 0x20, 0x69, 0xff, 0xf7, 0x6d, 0xf8, 0x61, 0x69, 0xff, 0xf7,
0x11, 0xf8, 0xe9, 0x79, 0x89, 0x00, 0x65, 0x18, 0xe8, 0x62, 0xe8, 0x69, 0xe9, 0x6a, 0xff, 0xf7,
0x5a, 0xf8, 0xe8, 0x63, 0xe8, 0x6b, 0xe9, 0x6c, 0xff, 0xf7, 0x04, 0xf8, 0xe8, 0x65, 0x2e, 0x46,
0x5c, 0x36, 0x2f, 0x46, 0x4c, 0x37, 0xe8, 0x6d, 0x3c, 0x35, 0x00, 0x24, 0x21, 0x46, 0x01, 0xf0,
0x04, 0xf8, 0x00, 0x28, 0x01, 0xd1, 0x00, 0x20, 0x30, 0x60, 0x30, 0x68, 0x38, 0x60, 0x14, 0x4f,
0x38, 0x6e, 0x29, 0x68, 0xff, 0xf7, 0x47, 0xf8, 0x05, 0x46, 0x78, 0x6e, 0x31, 0x68, 0xff, 0xf7,
0x42, 0xf8, 0x01, 0x46, 0x28, 0x46, 0xfe, 0xf7, 0xe5, 0xff, 0x05, 0x46, 0x21, 0x46, 0x00, 0xf0,
0xde, 0xff, 0x00, 0x28, 0x08, 0xd1, 0x0b, 0x4e, 0x28, 0x46, 0x31, 0x46, 0x00, 0xf0, 0xc9, 0xff,
0x00, 0x28, 0x2c, 0x46, 0x00, 0xd1, 0x34, 0x46, 0x20, 0x46, 0x01, 0xf0, 0x01, 0xf8, 0x02, 0x49,
0x48, 0x81, 0x00, 0xbf, 0x00, 0xbf, 0xf8, 0xbd, 0xf0, 0x01, 0x00, 0x20, 0xe0, 0x02, 0x00, 0x20,
0x70, 0x01, 0x00, 0x20, 0x00, 0xfc, 0x7f, 0x46, 0xb0, 0xb5, 0x0c, 0x46, 0x13, 0x49, 0x40, 0x18,
0xff, 0xf7, 0xbf, 0xf8, 0x41, 0x21, 0x09, 0x06, 0xff, 0xf7, 0x15, 0xf8, 0x35, 0x21, 0x09, 0x06,
0xff, 0xf7, 0x11, 0xf8, 0x05, 0x46, 0x00, 0xbf, 0x00, 0xbf, 0x0d, 0x48, 0x00, 0x6f, 0x0d, 0x49,
0xff, 0xf7, 0x09, 0xf8, 0x01, 0x46, 0x28, 0x46, 0xff, 0xf7, 0x05, 0xf8, 0x00, 0xf0, 0x6a, 0xf8,
0x09, 0x49, 0x89, 0x69, 0xfe, 0xf7, 0xff, 0xff, 0x45, 0x21, 0x09, 0x06, 0xfe, 0xf7, 0xfb, 0xff,
0x00, 0xf0, 0xe2, 0xff, 0x00, 0xf0, 0x0a, 0xf8, 0x20, 0x80, 0xb0, 0xbd, 0x00, 0x00, 0xf0, 0xff,
0x70, 0x01, 0x00, 0x20, 0x10, 0x02, 0xce, 0x3f, 0xe0, 0x02, 0x00, 0x20, 0xfe, 0xb5, 0x02, 0x46,
0x0a, 0x43, 0x01, 0x26, 0xf4, 0x07, 0x00, 0x2a, 0x46, 0xd0, 0x00, 0x24, 0x24, 0x4a, 0x04, 0xe0,
0xa4, 0x18, 0xc3, 0x0f, 0x49, 0x00, 0x19, 0x43, 0x40, 0x00, 0xc3, 0x0a, 0x4d, 0x05, 0x1d, 0x43,
0xcb, 0x0a, 0x2b, 0x43, 0x00, 0x2b, 0xf3, 0xd0, 0x05, 0xe0, 0xf2, 0x02, 0xa4, 0x18, 0x42, 0x08,
0xc8, 0x07, 0x10, 0x43, 0x49, 0x08, 0x02, 0x0b, 0x0b, 0x05, 0x13, 0x43, 0x0a, 0x0b, 0x1a, 0x43,
0x00, 0x2a, 0xf2, 0xd1, 0xb2, 0x02, 0x02, 0x92, 0x0b, 0x22, 0x23, 0xe0, 0x01, 0x92, 0x02, 0x46,
0x0b, 0x46, 0x00, 0xf0, 0xf5, 0xfe, 0x4b, 0x05, 0xc2, 0x0a, 0x1a, 0x43, 0x4b, 0x02, 0xc0, 0x0d,
0x18, 0x43, 0xcb, 0x0d, 0x03, 0x43, 0x00, 0x2b, 0x37, 0x46, 0x35, 0x46, 0x00, 0xd1, 0x1d, 0x46,
0xea, 0x40, 0x1f, 0x26, 0x6e, 0x40, 0xc9, 0x0a, 0x48, 0x00, 0xb0, 0x40, 0x10, 0x43, 0x02, 0x9e,
0xa2, 0x19, 0x00, 0x2b, 0x00, 0xd0, 0x14, 0x46, 0xe9, 0x40, 0x01, 0x9a, 0x52, 0x1e, 0x76, 0x10,
0x02, 0x96, 0x3e, 0x46, 0x00, 0x2a, 0xd9, 0xd1, 0x20, 0x46, 0x03, 0xb0, 0xf0, 0xbd, 0xc0, 0x46,
0x00, 0xf8, 0xff, 0xff, 0xf8, 0xb5, 0x04, 0x46, 0x00, 0x25, 0x29, 0x46, 0x00, 0xf0, 0x37, 0xff,
0x01, 0x46, 0x8f, 0x20, 0xc0, 0x05, 0x00, 0x29, 0x00, 0xd0, 0x62, 0x48, 0x21, 0x46, 0xfe, 0xf7,
0x8a, 0xff, 0x00, 0xf0, 0x5d, 0xff, 0x09, 0x21, 0x09, 0x04, 0x88, 0x42, 0x00, 0xd9, 0xb5, 0xe0,
0x5d, 0x49, 0x41, 0x18, 0x00, 0x29, 0x0b, 0x46, 0x00, 0xda, 0x03, 0x46, 0x5b, 0x48, 0x1a, 0x18,
0xc8, 0x17, 0x01, 0x21, 0x0e, 0x06, 0x86, 0x19, 0x59, 0x48, 0x30, 0x40, 0x06, 0x01, 0x00, 0x2a,
0x00, 0xda, 0x06, 0x46, 0xb0, 0x00, 0x00, 0x2a, 0x00, 0xda, 0x1a, 0x46, 0x55, 0x4b, 0xd3, 0x18,
0x00, 0x2b, 0x00, 0xda, 0x30, 0x46, 0x00, 0x2b, 0x00, 0xda, 0x13, 0x46, 0x52, 0x4a, 0x9a, 0x18,
0x00, 0x2a, 0x04, 0xdb, 0x40, 0x00, 0x8b, 0x07, 0x98, 0x42, 0x01, 0xd9, 0x8e, 0xe0, 0x1a, 0x46,
0x4e, 0x4b, 0xd3, 0x18, 0x45, 0x08, 0x45, 0x19, 0x00, 0x2b, 0x00, 0xda, 0x05, 0x46, 0xa8, 0x08,
0x28, 0x18, 0x00, 0x2b, 0x00, 0xda, 0x13, 0x46, 0x49, 0x4a, 0x9a, 0x18, 0x00, 0x2a, 0x00, 0xda,
0x28, 0x46, 0xc5, 0x08, 0x45, 0x19, 0x00, 0x2a, 0x00, 0xda, 0x1a, 0x46, 0x45, 0x4b, 0xd3, 0x18,
0x00, 0x2b, 0x00, 0xda, 0x05, 0x46, 0x28, 0x09, 0x28, 0x18, 0x00, 0x2b, 0x00, 0xda, 0x13, 0x46,
0x41, 0x4a, 0x9a, 0x18, 0x00, 0x2a, 0x00, 0xda, 0x28, 0x46, 0x45, 0x09, 0x45, 0x19, 0x00, 0x2a,
0x00, 0xda, 0x1a, 0x46, 0x3d, 0x4b, 0xd3, 0x18, 0x00, 0x2b, 0x00, 0xda, 0x05, 0x46, 0xa8, 0x09,
0x2e, 0x18, 0x00, 0x2b, 0x00, 0xda, 0x13, 0x46, 0x39, 0x48, 0x1f, 0x18, 0x00, 0x2f, 0x00, 0xda,
0x2e, 0x46, 0xf0, 0x09, 0x30, 0x18, 0x00, 0x2f, 0x00, 0xda, 0x1f, 0x46, 0x35, 0x4a, 0xba, 0x18,
0x00, 0x2a, 0x00, 0xda, 0x30, 0x46, 0x03, 0x0a, 0xc3, 0x18, 0x00, 0x2a, 0x00, 0xda, 0x3a, 0x46,
0x0d, 0x02, 0x2a, 0x42, 0x00, 0xd0, 0x18, 0x46, 0x43, 0x0a, 0xc3, 0x18, 0x80, 0x25, 0x2a, 0x42,
0x00, 0xd0, 0x18, 0x46, 0x83, 0x0a, 0xc3, 0x18, 0x40, 0x25, 0x2a, 0x42, 0x00, 0xd0, 0x18, 0x46,
0xc3, 0x0a, 0xc3, 0x18, 0x20, 0x25, 0x2a, 0x42, 0x00, 0xd0, 0x18, 0x46, 0x03, 0x0b, 0xc3, 0x18,
0x10, 0x25, 0x2a, 0x42, 0x00, 0xd0, 0x18, 0x46, 0x43, 0x0b, 0xc3, 0x18, 0x08, 0x25, 0x2a, 0x42,
0x00, 0xd0, 0x18, 0x46, 0x83, 0x0b, 0xc3, 0x18, 0x04, 0x25, 0x2a, 0x42, 0x00, 0xd0, 0x18, 0x46,
0xc3, 0x0b, 0xc3, 0x18, 0x02, 0x25, 0x2a, 0x42, 0x00, 0xd0, 0x18, 0x46, 0x03, 0x0c, 0xc3, 0x18,
0x0a, 0x42, 0x00, 0xd0, 0x18, 0x46, 0x00, 0xf0, 0xac, 0xfe, 0x6f, 0x21, 0xc9, 0x05, 0xfe, 0xf7,
0xda, 0xfe, 0x05, 0x46, 0x00, 0x21, 0x20, 0x46, 0x00, 0xf0, 0x87, 0xfe, 0x00, 0x28, 0x05, 0xd1,
0x7f, 0x20, 0xc0, 0x05, 0x29, 0x46, 0xfe, 0xf7, 0x0b, 0xff, 0x05, 0x46, 0x28, 0x46, 0x01, 0xb0,
0xf0, 0xbd, 0xc0, 0x46, 0x00, 0x00, 0x80, 0xc7, 0x6f, 0x74, 0xfa, 0xff, 0x38, 0x3a, 0xfd, 0xff,
0x00, 0x00, 0x01, 0xff, 0x1c, 0x9d, 0xfe, 0xff, 0x8e, 0x4e, 0xff, 0xff, 0x33, 0x98, 0xff, 0xff,
0xe0, 0xc6, 0xff, 0xff, 0xd9, 0xe1, 0xff, 0xff, 0x7b, 0xf0, 0xff, 0xff, 0x1f, 0xf8, 0xff, 0xff,
0x08, 0xfc, 0xff, 0xff, 0x02, 0xfe, 0xff, 0xff, 0xf0, 0xb5, 0x8d, 0xb0, 0x08, 0x90, 0x00, 0x25,
0x0c, 0x95, 0x0b, 0x95, 0x0a, 0x95, 0x09, 0x95, 0x24, 0x20, 0xf0, 0x4f, 0x01, 0xe0, 0x3d, 0x50,
0x00, 0x1d, 0x34, 0x28, 0xfb, 0xd1, 0x3b, 0x20, 0x07, 0x90, 0x3a, 0x21, 0x39, 0x22, 0x38, 0x23,
0x3e, 0x68, 0x01, 0x20, 0xeb, 0x4c, 0xa6, 0x42, 0x00, 0xd0, 0xcd, 0xe1, 0xe8, 0x4e, 0xf3, 0x5c,
0x01, 0x2b, 0x00, 0xd0, 0xc8, 0xe1, 0xb2, 0x5c, 0x01, 0x2a, 0x00, 0xd0, 0xc4, 0xe1, 0x71, 0x5c,
0x01, 0x29, 0x00, 0xd0, 0xc0, 0xe1, 0x07, 0x9c, 0x31, 0x5d, 0x01, 0x29, 0x00, 0xd0, 0xbb, 0xe1,
0x08, 0x98, 0x05, 0x72, 0xb0, 0x8f, 0x00, 0x28, 0x00, 0xd1, 0x85, 0xe0, 0x00, 0xf0, 0x49, 0xfe,
0x31, 0x46, 0x06, 0x46, 0xc8, 0x8f, 0x00, 0xf0, 0x44, 0xfe, 0x21, 0x06, 0xfe, 0xf7, 0x73, 0xfe,
0x07, 0x90, 0x79, 0x20, 0xc1, 0x05, 0x30, 0x46, 0xfe, 0xf7, 0x6d, 0xfe, 0x06, 0x46, 0xd6, 0x49,
0xfe, 0xf7, 0x10, 0xfe, 0xd5, 0x49, 0xfe, 0xf7, 0x66, 0xfe, 0x04, 0x46, 0xd4, 0x49, 0x30, 0x46,
0xfe, 0xf7, 0x08, 0xfe, 0x01, 0x46, 0x20, 0x46, 0xfe, 0xf7, 0x9a, 0xfe, 0x00, 0xf0, 0x48, 0xff,
0xd0, 0x49, 0xfe, 0xf7, 0x58, 0xfe, 0x01, 0x46, 0x07, 0x98, 0xfe, 0xf7, 0x54, 0xfe, 0x04, 0x46,
0xcd, 0x49, 0x30, 0x46, 0xfe, 0xf7, 0x4f, 0xfe, 0x01, 0x46, 0x20, 0x46, 0xfe, 0xf7, 0x88, 0xfe,
0xca, 0x49, 0xfe, 0xf7, 0x48, 0xfe, 0x04, 0x46, 0x7f, 0x20, 0xc6, 0x05, 0x20, 0x46, 0x31, 0x46,
0x00, 0xf0, 0xe5, 0xfd, 0x00, 0x28, 0x07, 0xd1, 0xc5, 0x49, 0x20, 0x46, 0x00, 0xf0, 0xd1, 0xfd,
0x00, 0x28, 0x26, 0x46, 0x00, 0xd1, 0xc2, 0x4e, 0xc2, 0x49, 0x30, 0x46, 0xfe, 0xf7, 0x70, 0xfe,
0x00, 0xf0, 0xcc, 0xff, 0xc0, 0x49, 0x04, 0x46, 0x06, 0x94, 0xfe, 0xf7, 0x2c, 0xfe, 0x07, 0x90,
0xb3, 0x48, 0x00, 0x88, 0x00, 0xf0, 0xf5, 0xfd, 0x1d, 0x21, 0x4e, 0x06, 0x31, 0x46, 0xfe, 0xf7,
0x22, 0xfe, 0x01, 0x46, 0x07, 0x98, 0xfe, 0xf7, 0xc5, 0xfd, 0x07, 0x90, 0x78, 0x62, 0xb7, 0x49,
0x20, 0x46, 0xfe, 0xf7, 0x18, 0xfe, 0x04, 0x46, 0xa9, 0x48, 0xc0, 0x89, 0x00, 0xf0, 0xe1, 0xfd,
0x31, 0x46, 0xfe, 0xf7, 0x10, 0xfe, 0x01, 0x46, 0x20, 0x46, 0xfe, 0xf7, 0xb3, 0xfd, 0x05, 0x90,
0xb8, 0x62, 0xaf, 0x49, 0x06, 0x98, 0xfe, 0xf7, 0x06, 0xfe, 0x04, 0x46, 0xa0, 0x49, 0x08, 0x46,
0x80, 0x8b, 0x00, 0xf0, 0xce, 0xfd, 0x31, 0x46, 0x9d, 0x4e, 0xfe, 0xf7, 0xfc, 0xfd, 0x01, 0x46,
0x20, 0x46, 0xfe, 0xf7, 0x9f, 0xfd, 0x17, 0xe0, 0x30, 0x88, 0x00, 0xf0, 0xc2, 0xfd, 0x1d, 0x21,
0x4c, 0x06, 0x21, 0x46, 0xfe, 0xf7, 0xef, 0xfd, 0x07, 0x90, 0x78, 0x62, 0xf0, 0x89, 0x00, 0xf0,
0xb8, 0xfd, 0x21, 0x46, 0xfe, 0xf7, 0xe7, 0xfd, 0x05, 0x90, 0xb8, 0x62, 0xb0, 0x8b, 0x00, 0xf0,
0xb0, 0xfd, 0x21, 0x46, 0xfe, 0xf7, 0xdf, 0xfd, 0x04, 0x90, 0xf8, 0x62, 0x70, 0x8d, 0x00, 0xf0,
0xa8, 0xfd, 0x1d, 0x21, 0x49, 0x06, 0xfe, 0xf7, 0xd6, 0xfd, 0x38, 0x63, 0x34, 0x21, 0x79, 0x5c,
0x0f, 0x22, 0xd4, 0x43, 0x06, 0x91, 0x01, 0x29, 0x00, 0xd0, 0x93, 0xe0, 0x03, 0x90, 0xb8, 0x6b,
0x4b, 0x21, 0x89, 0x00, 0x00, 0x22, 0x88, 0x42, 0x07, 0xd8, 0x40, 0x1c, 0xb8, 0x63, 0x08, 0x9a,
0x10, 0x7a, 0x04, 0x21, 0x01, 0x43, 0x11, 0x72, 0x01, 0x22, 0xf9, 0x6b, 0x89, 0x48, 0x81, 0x42,
0x07, 0x98, 0x05, 0x9e, 0x11, 0xd3, 0x20, 0x46, 0x05, 0xe0, 0x39, 0x18, 0x4a, 0x6a, 0x4a, 0x61,
0x4a, 0x6b, 0x4a, 0x62, 0x00, 0x1d, 0x00, 0x28, 0xf7, 0xd1, 0x01, 0x20, 0xf8, 0x63, 0x08, 0x9a,
0x10, 0x7a, 0x02, 0x21, 0x01, 0x43, 0x11, 0x72, 0x6c, 0xe0, 0x01, 0x91, 0x02, 0x92, 0x7e, 0x49,
0x00, 0xf0, 0x37, 0xfd, 0x00, 0x28, 0x0a, 0xd1, 0x39, 0x6c, 0x7c, 0x48, 0x42, 0x1c, 0x91, 0x42,
0x02, 0x9a, 0x06, 0xd2, 0x49, 0x1c, 0x39, 0x64, 0x81, 0x42, 0x02, 0xd8, 0x4b, 0xe0, 0x00, 0x20,
0x38, 0x64, 0x79, 0x69, 0x07, 0x98, 0x00, 0xf0, 0x40, 0xfd, 0x00, 0x28, 0x01, 0xd1, 0x07, 0x98,
0x78, 0x61, 0xb9, 0x69, 0x30, 0x46, 0x00, 0xf0, 0x38, 0xfd, 0x00, 0x28, 0x00, 0xd1, 0xbe, 0x61,
0xf9, 0x69, 0x04, 0x98, 0x00, 0xf0, 0x15, 0xfd, 0x00, 0x28, 0x01, 0xd1, 0x04, 0x98, 0xf8, 0x61,
0x39, 0x6a, 0x03, 0x9e, 0x30, 0x46, 0x00, 0xf0, 0x0c, 0xfd, 0x00, 0x28, 0x00, 0xd1, 0x3e, 0x62,
0x79, 0x68, 0x07, 0x9e, 0x30, 0x46, 0x00, 0xf0, 0x20, 0xfd, 0x00, 0x28, 0x00, 0xd1, 0x7e, 0x60,
0xb9, 0x68, 0x05, 0x9e, 0x30, 0x46, 0x00, 0xf0, 0x18, 0xfd, 0x00, 0x28, 0x00, 0xd1, 0xbe, 0x60,
0xf9, 0x68, 0x04, 0x9e, 0x30, 0x46, 0x00, 0xf0, 0xf4, 0xfc, 0x00, 0x28, 0x00, 0xd1, 0xfe, 0x60,
0x39, 0x69, 0x03, 0x9e, 0x30, 0x46, 0x00, 0xf0, 0xec, 0xfc, 0x00, 0x28, 0x00, 0xd1, 0x3e, 0x61,
0x02, 0x9a, 0x00, 0x2a, 0x09, 0xd0, 0x04, 0x20, 0x03, 0xe0, 0x39, 0x18, 0x09, 0x69, 0x39, 0x50,
0x00, 0x1d, 0x14, 0x28, 0xf9, 0xd1, 0x00, 0x2a, 0x0c, 0xd1, 0x01, 0x98, 0x40, 0x1c, 0xf8, 0x63,
0x08, 0xe0, 0x39, 0x19, 0x48, 0x6b, 0x49, 0x69, 0xfe, 0xf7, 0x35, 0xfd, 0x09, 0xa9, 0x09, 0x19,
0x08, 0x61, 0x24, 0x1d, 0x00, 0x2c, 0xf4, 0xd1, 0x0b, 0x98, 0x49, 0x49, 0x07, 0x90, 0xfe, 0xf7,
0x32, 0xfd, 0x48, 0x49, 0xfe, 0xf7, 0xd6, 0xfc, 0x04, 0x46, 0x0c, 0x98, 0x46, 0x49, 0xfe, 0xf7,
0x2a, 0xfd, 0x01, 0x46, 0x20, 0x46, 0xfe, 0xf7, 0xcd, 0xfc, 0x05, 0x90, 0x0a, 0x98, 0x43, 0x49,
0xfe, 0xf7, 0x21, 0xfd, 0x42, 0x49, 0xfe, 0xf7, 0xc5, 0xfc, 0x00, 0xf0, 0x73, 0xfd, 0x41, 0x49,
0xfe, 0xf7, 0x19, 0xfd, 0x06, 0x46, 0x40, 0x4c, 0x21, 0x46, 0x00, 0xf0, 0xd4, 0xfc, 0x00, 0x28,
0x00, 0xd1, 0x34, 0x46, 0x3d, 0x49, 0x07, 0x98, 0xfe, 0xf7, 0x0d, 0xfd, 0x3c, 0x49, 0xfe, 0xf7,
0xb1, 0xfc, 0x00, 0xf0, 0x5f, 0xfd, 0x3b, 0x49, 0xfe, 0xf7, 0xac, 0xfc, 0x35, 0x49, 0xfe, 0xf7,
0x02, 0xfd, 0x06, 0x46, 0x29, 0x46, 0x00, 0xf0, 0xa2, 0xfc, 0x00, 0x28, 0x07, 0xd1, 0x36, 0x49,
0x30, 0x46, 0x00, 0xf0, 0x8e, 0xfc, 0x00, 0x28, 0x35, 0x46, 0x00, 0xd1, 0x32, 0x4d, 0x38, 0x6b,
0x39, 0x69, 0x00, 0xf0, 0xb0, 0xfc, 0x00, 0x28, 0x01, 0xd0, 0x30, 0x4f, 0x14, 0xe0, 0x05, 0x98,
0x00, 0xf0, 0x40, 0xfd, 0x2e, 0x49, 0xfe, 0xf7, 0x8d, 0xfc, 0x06, 0x46, 0x2d, 0x4f, 0x39, 0x46,
0x00, 0xf0, 0x85, 0xfc, 0x00, 0x28, 0x07, 0xd1, 0x2b, 0x49, 0x30, 0x46, 0x00, 0xf0, 0x71, 0xfc,
0x00, 0x28, 0x37, 0x46, 0x00, 0xd1, 0x28, 0x4f, 0x08, 0x9e, 0x06, 0x98, 0x30, 0x70, 0x38, 0x46,
0x00, 0xf0, 0xa6, 0xfc, 0x70, 0x80, 0x28, 0x46, 0x00, 0xf0, 0xa2, 0xfc, 0xb0, 0x80, 0x20, 0x46,
0x00, 0xf0, 0x9e, 0xfc, 0xf0, 0x80, 0x00, 0x20, 0x0d, 0xb0, 0xf0, 0xbd, 0x90, 0x02, 0x00, 0x20,
0x50, 0x02, 0x00, 0x20, 0x01, 0x53, 0x4d, 0x41, 0x33, 0x93, 0x88, 0xc3, 0x29, 0x5c, 0x8d, 0x41,
0x33, 0x33, 0xed, 0xc1, 0x81, 0x95, 0xc3, 0x40, 0x25, 0x06, 0x05, 0x41, 0x4b, 0x1f, 0x90, 0x41,
0x00, 0x00, 0xc8, 0x42, 0xec, 0x51, 0x38, 0x41, 0x1f, 0x85, 0x6b, 0x3e, 0xe1, 0x7a, 0x94, 0x3e,
0x9a, 0x99, 0x19, 0x3e, 0x81, 0x51, 0x01, 0x00, 0x00, 0x00, 0xc0, 0x41, 0xff, 0xa2, 0x02, 0x00,
0x14, 0xae, 0xc7, 0xbf, 0x00, 0x00, 0x18, 0x41, 0xd7, 0xa3, 0xf0, 0x3e, 0xcd, 0xcc, 0xcc, 0x3f,
0xf6, 0x28, 0xec, 0xc0, 0x00, 0x00, 0x7a, 0x44, 0x00, 0xff, 0x7f, 0x47, 0x14, 0xae, 0xe7, 0xbf,
0x00, 0x00, 0x80, 0xbf, 0x8f, 0xc2, 0xf5, 0xbe, 0x00, 0x40, 0x9c, 0x46, 0x00, 0x00, 0xc8, 0x43,
0xe6, 0x09, 0x9d, 0xc3, 0x00, 0x00, 0xbe, 0x43, 0x00, 0xe8, 0x7d, 0x47, 0x70, 0xb5, 0x0c, 0x46,
0x06, 0x46, 0x0d, 0x4d, 0x28, 0x46, 0x24, 0x30, 0x0c, 0x49, 0x34, 0x22, 0x00, 0xf0, 0xed, 0xfb,
0x01, 0x20, 0x01, 0x2e, 0x0e, 0xd8, 0x69, 0x6a, 0x09, 0x4a, 0x91, 0x42, 0x0a, 0xd1, 0x54, 0x21,
0x69, 0x5c, 0x89, 0x07, 0x06, 0xd4, 0x2c, 0x35, 0x14, 0x22, 0x20, 0x46, 0x29, 0x46, 0x00, 0xf0,
0xdc, 0xfb, 0x00, 0x20, 0x70, 0xbd, 0xc0, 0x46, 0xf0, 0x01, 0x00, 0x20, 0x00, 0x38, 0x00, 0x10,
0x02, 0x53, 0x4d, 0x41, 0x70, 0xb5, 0x1c, 0x4c, 0x62, 0x6a, 0x1c, 0x4b, 0x9a, 0x42, 0x31, 0xd1,
0x00, 0xbf, 0x00, 0xbf, 0x01, 0x28, 0x2b, 0xd8, 0x17, 0x20, 0x40, 0x02, 0x18, 0x4d, 0x28, 0x64,
0x01, 0x20, 0xc6, 0x02, 0x28, 0x68, 0x30, 0x42, 0xfc, 0xd1, 0x20, 0x46, 0x2c, 0x30, 0x00, 0x29,
0x06, 0xd0, 0x14, 0x22, 0x00, 0xf0, 0xb9, 0xfb, 0x60, 0x6d, 0x02, 0x21, 0x88, 0x43, 0x06, 0xe0,
0x14, 0x21, 0xff, 0x22, 0x00, 0xf0, 0xc3, 0xfb, 0x61, 0x6d, 0x02, 0x20, 0x08, 0x43, 0x60, 0x65,
0x24, 0x34, 0x00, 0x20, 0x0a, 0xe0, 0x21, 0x68, 0xe9, 0x63, 0x07, 0x21, 0x49, 0x02, 0x01, 0x43,
0x29, 0x64, 0x29, 0x68, 0x31, 0x42, 0xfc, 0xd1, 0x40, 0x1c, 0x24, 0x1d, 0x0d, 0x28, 0xf2, 0xd1,
0x00, 0xbf, 0x00, 0xbf, 0x70, 0xbd, 0xc0, 0x46, 0xf0, 0x01, 0x00, 0x20, 0x02, 0x53, 0x4d, 0x41,
0x04, 0x0c, 0x00, 0x40, 0x70, 0x47, 0xc0, 0x46, 0xf0, 0xb5, 0x99, 0xb0, 0xa4, 0x4f, 0x00, 0x24,
0xbc, 0x67, 0x20, 0x46, 0xff, 0xf7, 0x2e, 0xfb, 0xa2, 0x49, 0xc0, 0x39, 0xa2, 0x48, 0x41, 0x60,
0xff, 0x21, 0x12, 0x91, 0x09, 0x06, 0xa1, 0x4b, 0x1a, 0x68, 0x8a, 0x43, 0x03, 0x21, 0x18, 0x91,
0x89, 0x07, 0x11, 0x43, 0x19, 0x60, 0x84, 0x60, 0x07, 0x26, 0x06, 0x60, 0x16, 0x94, 0x3c, 0x61,
0xf0, 0x22, 0x02, 0x21, 0x81, 0x50, 0x01, 0x21, 0x17, 0x91, 0x81, 0x50, 0x04, 0x21, 0x81, 0x50,
0x10, 0x21, 0x81, 0x50, 0x08, 0x21, 0x14, 0x91, 0x07, 0x92, 0x81, 0x50, 0x94, 0x4d, 0x2c, 0x46,
0x24, 0x34, 0x94, 0x49, 0x34, 0x22, 0x20, 0x46, 0x00, 0xf0, 0x5f, 0xfb, 0x2a, 0x46, 0x17, 0x20,
0x43, 0x02, 0x51, 0x6a, 0x90, 0x4d, 0x91, 0x48, 0x81, 0x42, 0x17, 0xd0, 0x50, 0x62, 0x16, 0x98,
0xc0, 0x43, 0x50, 0x65, 0x2b, 0x64, 0x17, 0x98, 0xc0, 0x02, 0x29, 0x68, 0x01, 0x42, 0xfc, 0xd1,
0x00, 0x21, 0x09, 0xe0, 0x22, 0x68, 0xea, 0x63, 0x72, 0x02, 0x0a, 0x43, 0x2a, 0x64, 0x2a, 0x68,
0x02, 0x42, 0xfc, 0xd1, 0x49, 0x1c, 0x24, 0x1d, 0x0d, 0x29, 0xf3, 0xd1, 0x11, 0x93, 0xfe, 0xf7,
0xb7, 0xfd, 0xff, 0xf7, 0xad, 0xfa, 0x16, 0x98, 0x78, 0x70, 0x2f, 0x21, 0xc8, 0x43, 0x2f, 0x30,
0x38, 0x70, 0x17, 0x98, 0x03, 0x07, 0x28, 0x68, 0x00, 0x0f, 0x7d, 0x4c, 0xd0, 0x22, 0x06, 0x92,
0x7c, 0x4a, 0x00, 0x28, 0x1a, 0xd0, 0x28, 0x68, 0x98, 0x42, 0x17, 0xd3, 0x16, 0x98, 0xc0, 0x43,
0x15, 0x90, 0x79, 0x4b, 0x21, 0xcb, 0xed, 0x43, 0x08, 0x3b, 0xa8, 0x42, 0x0e, 0xd1, 0x98, 0x68,
0x13, 0x90, 0xdd, 0x68, 0x15, 0x98, 0x45, 0x40, 0x13, 0x98, 0xa8, 0x42, 0x06, 0xd1, 0x18, 0x69,
0x10, 0x40, 0x72, 0x4d, 0xa8, 0x42, 0x00, 0xd0, 0x23, 0x46, 0x1c, 0x46, 0x70, 0x48, 0x09, 0x02,
0x18, 0x9b, 0x5b, 0x02, 0x18, 0x93, 0xb8, 0x33, 0xf8, 0x61, 0x3b, 0x62, 0x79, 0x62, 0xb9, 0x62,
0x20, 0x69, 0x10, 0x40, 0x17, 0x99, 0x0d, 0x02, 0x49, 0x02, 0x68, 0x4a, 0x90, 0x42, 0x15, 0x91,
0x13, 0x95, 0x00, 0xd0, 0xd2, 0xe0, 0x90, 0x20, 0x20, 0x58, 0x0f, 0x21, 0x09, 0x91, 0x08, 0x40,
0xe0, 0x35, 0x12, 0x99, 0x09, 0x02, 0x63, 0x4a, 0x0f, 0x28, 0x13, 0xd0, 0xa0, 0x6a, 0x13, 0x46,
0x02, 0x0c, 0x3a, 0x62, 0x0a, 0x46, 0xff, 0x32, 0x02, 0x40, 0xfa, 0x61, 0x60, 0x6a, 0x02, 0x0c,
0x18, 0x40, 0xb8, 0x62, 0x1a, 0x40, 0x7a, 0x62, 0x1a, 0x46, 0xe0, 0x6a, 0x05, 0x0c, 0x10, 0x40,
0x07, 0x90, 0x15, 0x40, 0x05, 0x95, 0x60, 0x69, 0x03, 0x0c, 0x13, 0x40, 0x22, 0x6b, 0x0d, 0x92,
0x65, 0x6b, 0xa2, 0x6b, 0x0a, 0x92, 0xe2, 0x6b, 0x0b, 0x92, 0x22, 0x6a, 0x17, 0x92, 0x04, 0x93,
0xfb, 0x62, 0x0a, 0x46, 0xff, 0x32, 0x02, 0x40, 0x00, 0x02, 0x08, 0x40, 0x8a, 0x42, 0x00, 0xd8,
0x10, 0x46, 0x00, 0xf0, 0x1e, 0xfb, 0xf1, 0x06, 0xfe, 0xf7, 0x4d, 0xfb, 0x0c, 0x90, 0x0b, 0x98,
0x48, 0x49, 0x0a, 0x46, 0x10, 0x40, 0x12, 0x90, 0x13, 0x98, 0xff, 0x30, 0x0a, 0x99, 0x01, 0x40,
0x0e, 0x91, 0x17, 0x99, 0x01, 0x40, 0x17, 0x91, 0x20, 0x6c, 0x10, 0x40, 0x10, 0x90, 0xe1, 0x69,
0x08, 0x0c, 0x11, 0x40, 0x0f, 0x91, 0x10, 0x40, 0x11, 0x90, 0x46, 0x20, 0x20, 0x5a, 0x08, 0x90,
0x30, 0x48, 0x05, 0x40, 0x28, 0x46, 0x00, 0xf0, 0xfc, 0xfa, 0x77, 0x21, 0xc9, 0x05, 0x00, 0x91,
0xfe, 0xf7, 0x29, 0xfb, 0x03, 0x90, 0x0d, 0x9e, 0x30, 0x46, 0x37, 0x49, 0x0d, 0x46, 0x28, 0x40,
0x00, 0xf0, 0xef, 0xfa, 0x7b, 0x21, 0xc9, 0x05, 0xfe, 0xf7, 0x1d, 0xfb, 0x02, 0x90, 0x30, 0x0c,
0x28, 0x40, 0x00, 0xf0, 0xe6, 0xfa, 0x3d, 0x21, 0x09, 0x06, 0xfe, 0xf7, 0x14, 0xfb, 0x0d, 0x90,
0x0a, 0x98, 0x00, 0x0c, 0x1f, 0x4d, 0x28, 0x40, 0x00, 0xf0, 0xdb, 0xfa, 0x00, 0x9e, 0x31, 0x46,
0xfe, 0xf7, 0x09, 0xfb, 0x01, 0x90, 0x0b, 0x98, 0x00, 0x0c, 0x28, 0x40, 0x00, 0xf0, 0xd1, 0xfa,
0x31, 0x46, 0xfe, 0xf7, 0x00, 0xfb, 0x0b, 0x90, 0xa5, 0x69, 0x28, 0x46, 0x21, 0x49, 0x08, 0x40,
0x00, 0xf0, 0xc7, 0xfa, 0x09, 0x99, 0x8c, 0x06, 0x21, 0x46, 0xfe, 0xf7, 0xf4, 0xfa, 0x0a, 0x90,
0x28, 0x0c, 0x17, 0x9d, 0x1b, 0x49, 0x08, 0x40, 0x00, 0xf0, 0xbb, 0xfa, 0x75, 0x21, 0xc9, 0x05,
0xfe, 0xf7, 0xe9, 0xfa, 0x09, 0x90, 0x08, 0x98, 0xfa, 0x49, 0x08, 0x40, 0x00, 0xf0, 0xb1, 0xfa,
0x31, 0x46, 0xfe, 0xf7, 0xe0, 0xfa, 0x08, 0x90, 0x04, 0x98, 0x00, 0xf0, 0xaa, 0xfa, 0x21, 0x46,
0x02, 0x9c, 0xfe, 0xf7, 0xd8, 0xfa, 0x01, 0x9a, 0x03, 0x9b, 0x07, 0x99, 0x05, 0x9e, 0x3f, 0xe0,
0x70, 0x01, 0x00, 0x20, 0xff, 0x1f, 0x00, 0x00, 0x10, 0xe0, 0x00, 0xe0, 0x20, 0xed, 0x00, 0xe0,
0xf0, 0x01, 0x00, 0x20, 0x00, 0x38, 0x00, 0x10, 0x04, 0x0c, 0x00, 0x40, 0x02, 0x53, 0x4d, 0x41,
0x00, 0x3c, 0x00, 0x10, 0x00, 0x00, 0xff, 0xff, 0x00, 0x40, 0x00, 0x10, 0x00, 0x00, 0xa5, 0xa5,
0xd7, 0x23, 0x00, 0x00, 0xff, 0x7f, 0x00, 0x00, 0xff, 0x3f, 0x00, 0x00, 0x11, 0x98, 0xe0, 0x30,
0xf8, 0x62, 0x7f, 0x20, 0xc0, 0x05, 0x0c, 0x90, 0xe1, 0x48, 0x11, 0x90, 0x00, 0x1d, 0x12, 0x90,
0x14, 0x31, 0x10, 0x91, 0x2e, 0x46, 0xe0, 0x36, 0x28, 0x46, 0xc4, 0x30, 0x0e, 0x90, 0x6b, 0x35,
0xdc, 0x48, 0x08, 0x90, 0xdc, 0x4b, 0xdd, 0x4c, 0xdd, 0x48, 0x0d, 0x90, 0xdd, 0x4a, 0xde, 0x48,
0x0a, 0x90, 0xde, 0x48, 0x09, 0x90, 0xde, 0x48, 0x0f, 0x90, 0xf0, 0x21, 0xdd, 0x48, 0x0b, 0x92,
0x3b, 0x63, 0x7c, 0x63, 0x0d, 0x9b, 0xbb, 0x63, 0x08, 0x9b, 0xfb, 0x63, 0x3a, 0x64, 0x0b, 0x9a,
0x7a, 0x64, 0x0a, 0x9a, 0xba, 0x64, 0x09, 0x9a, 0xfa, 0x64, 0x0c, 0x9a, 0x3a, 0x67, 0x78, 0x67,
0x08, 0x46, 0x00, 0xf0, 0x4e, 0xfa, 0x1f, 0x21, 0x4c, 0x06, 0x21, 0x46, 0xfe, 0xf7, 0x7b, 0xfa,
0x38, 0x66, 0x30, 0x46, 0x00, 0xf0, 0x45, 0xfa, 0x21, 0x46, 0xfe, 0xf7, 0x74, 0xfa, 0x78, 0x66,
0x28, 0x46, 0x13, 0x9e, 0x30, 0x40, 0x00, 0xf0, 0x3c, 0xfa, 0x04, 0x46, 0xe8, 0xb2, 0x00, 0xf0,
0x38, 0xfa, 0x21, 0x46, 0xfe, 0xf7, 0x5f, 0xfa, 0xb8, 0x66, 0x0e, 0x9d, 0x2e, 0x40, 0x70, 0x42,
0xfe, 0xf7, 0x07, 0xfb, 0x79, 0x21, 0x17, 0x91, 0xce, 0x05, 0x31, 0x46, 0xfe, 0xf7, 0x5b, 0xfa,
0x04, 0x46, 0xe8, 0xb2, 0x00, 0xf0, 0x25, 0xfa, 0x31, 0x46, 0xfe, 0xf7, 0x54, 0xfa, 0x01, 0x46,
0x20, 0x46, 0xfe, 0xf7, 0xf7, 0xf9, 0xf8, 0x66, 0xb0, 0x48, 0x45, 0x1c, 0x0f, 0x9c, 0x20, 0x46,
0x28, 0x40, 0x40, 0x42, 0xfe, 0xf7, 0xed, 0xfa, 0x31, 0x46, 0xfe, 0xf7, 0x44, 0xfa, 0x13, 0x90,
0xaa, 0x48, 0x04, 0x40, 0x20, 0x46, 0x00, 0xf0, 0x0c, 0xfa, 0x31, 0x46, 0xfe, 0xf7, 0x3b, 0xfa,
0x01, 0x46, 0x13, 0x98, 0xfe, 0xf7, 0xde, 0xf9, 0x38, 0x65, 0x10, 0x9c, 0x20, 0x46, 0x28, 0x40,
0x40, 0x42, 0xfe, 0xf7, 0xd6, 0xfa, 0x75, 0x21, 0xce, 0x05, 0x31, 0x46, 0xfe, 0xf7, 0x2b, 0xfa,
0x13, 0x90, 0x9e, 0x48, 0x04, 0x40, 0x20, 0x46, 0x00, 0xf0, 0xf3, 0xf9, 0x31, 0x46, 0xfe, 0xf7,
0x22, 0xfa, 0x01, 0x46, 0x13, 0x98, 0xfe, 0xf7, 0xc5, 0xf9, 0x78, 0x65, 0x11, 0x9c, 0x20, 0x46,
0x28, 0x40, 0x40, 0x42, 0xfe, 0xf7, 0xbd, 0xfa, 0x31, 0x46, 0xfe, 0xf7, 0x14, 0xfa, 0x13, 0x90,
0x92, 0x48, 0x04, 0x40, 0x20, 0x46, 0x00, 0xf0, 0xdc, 0xf9, 0x31, 0x46, 0xfe, 0xf7, 0x0b, 0xfa,
0x01, 0x46, 0x13, 0x98, 0xfe, 0xf7, 0xae, 0xf9, 0xb8, 0x65, 0x12, 0x9e, 0x35, 0x40, 0x68, 0x42,
0xfe, 0xf7, 0xa7, 0xfa, 0x0f, 0x21, 0x8c, 0x06, 0x21, 0x46, 0xfe, 0xf7, 0xfc, 0xf9, 0x05, 0x46,
0x86, 0x48, 0x06, 0x40, 0x30, 0x46, 0x00, 0xf0, 0xc4, 0xf9, 0x21, 0x46, 0xfe, 0xf7, 0xf3, 0xf9,
0x01, 0x46, 0x28, 0x46, 0xfe, 0xf7, 0x96, 0xf9, 0xf8, 0x65, 0x00, 0xbf, 0x00, 0xbf, 0x01, 0x24,
0x89, 0x4e, 0x8a, 0x4d, 0xb1, 0xe0, 0x01, 0x20, 0x38, 0x70, 0xae, 0xe0, 0x22, 0x46, 0x8a, 0x40,
0x87, 0x49, 0x0a, 0x42, 0x00, 0xd1, 0xd3, 0xe0, 0xfe, 0xf7, 0x0a, 0xfd, 0xa5, 0xe0, 0xfe, 0xf7,
0xdd, 0xfb, 0xff, 0xf7, 0x41, 0xf9, 0x28, 0x68, 0x15, 0x99, 0x08, 0x43, 0x28, 0x60, 0x00, 0x20,
0x30, 0x63, 0x28, 0x68, 0x14, 0x99, 0x88, 0x43, 0x28, 0x60, 0x28, 0x68, 0x20, 0x43, 0x28, 0x60,
0xf0, 0x6f, 0xf0, 0x67, 0xf0, 0x6f, 0xf0, 0x67, 0x8f, 0xe0, 0x05, 0x20, 0x0b, 0x21, 0xc9, 0x43,
0x72, 0x58, 0x00, 0x2a, 0x04, 0xda, 0x40, 0x1e, 0xf8, 0xd1, 0x16, 0x99, 0x15, 0x98, 0x01, 0xe0,
0x71, 0x58, 0x00, 0x20, 0xba, 0x6f, 0x10, 0x18, 0xb8, 0x67, 0xc8, 0xb2, 0x7a, 0x78, 0x82, 0x42,
0x7b, 0xd0, 0x16, 0x9a, 0x3a, 0x61, 0x79, 0x70, 0x31, 0x78, 0x21, 0x42, 0x02, 0xd0, 0x31, 0x68,
0xa1, 0x43, 0x31, 0x60, 0x00, 0x28, 0x68, 0xd0, 0xce, 0x28, 0x1d, 0xd0, 0xc2, 0x28, 0x2b, 0xd0,
0xcc, 0x28, 0x2e, 0xd0, 0x0e, 0x28, 0x5e, 0xd1, 0x30, 0x46, 0x58, 0x30, 0x50, 0x21, 0x00, 0x22,
0x13, 0x92, 0x65, 0x4b, 0x98, 0x47, 0x30, 0x46, 0x68, 0x30, 0x02, 0x21, 0x13, 0x9a, 0x62, 0x4b,
0x98, 0x47, 0x30, 0x46, 0x6c, 0x30, 0x03, 0x21, 0x13, 0x9a, 0x5f, 0x4b, 0x98, 0x47, 0x30, 0x46,
0x70, 0x30, 0x01, 0x21, 0x13, 0x9a, 0x43, 0xe0, 0x38, 0x20, 0x31, 0x5c, 0x06, 0x9a, 0x91, 0x42,
0x05, 0xd0, 0x30, 0x5c, 0x06, 0x99, 0x49, 0x1c, 0xc9, 0xb2, 0x88, 0x42, 0x3d, 0xd1, 0x01, 0x20,
0x00, 0x21, 0xff, 0xf7, 0x17, 0xfd, 0x38, 0xe0, 0xfe, 0xf7, 0x62, 0xfb, 0x53, 0x48, 0x38, 0x61,
0x33, 0xe0, 0x30, 0x46, 0x58, 0x30, 0x00, 0x21, 0x13, 0x91, 0x0a, 0x46, 0x4e, 0x4b, 0x98, 0x47,
0x30, 0x46, 0x5c, 0x30, 0x13, 0x99, 0x0a, 0x46, 0x4b, 0x4b, 0x98, 0x47, 0x30, 0x46, 0x60, 0x30,
0x13, 0x99, 0x0a, 0x46, 0x48, 0x4b, 0x98, 0x47, 0x30, 0x46, 0x64, 0x30, 0x13, 0x99, 0x0a, 0x46,
0x45, 0x4b, 0x98, 0x47, 0x30, 0x46, 0x68, 0x30, 0x13, 0x99, 0x0a, 0x46, 0x42, 0x4b, 0x98, 0x47,
0x30, 0x46, 0x6c, 0x30, 0x13, 0x99, 0x0a, 0x46, 0x3f, 0x4b, 0x98, 0x47, 0x30, 0x46, 0x70, 0x30,
0x13, 0x99, 0x0a, 0x46, 0x3c, 0x4b, 0x98, 0x47, 0x30, 0x46, 0x74, 0x30, 0x13, 0x99, 0x0a, 0x46,
0x39, 0x4b, 0x98, 0x47, 0x01, 0xe0, 0x00, 0x20, 0x78, 0x70, 0x79, 0x78, 0x30, 0x46, 0x74, 0x30,
0x49, 0x1c, 0xc9, 0xb2, 0x22, 0x46, 0xff, 0xf7, 0x83, 0xf8, 0xb8, 0x6f, 0x00, 0x28, 0x15, 0xd0,
0x30, 0x68, 0x40, 0x21, 0x01, 0x43, 0x31, 0x60, 0x28, 0x68, 0x18, 0x99, 0x08, 0x43, 0x28, 0x60,
0x78, 0x20, 0x39, 0x5c, 0x30, 0x46, 0x64, 0x30, 0x00, 0x22, 0xff, 0xf7, 0x71, 0xf8, 0x17, 0x98,
0x39, 0x5c, 0x30, 0x46, 0x68, 0x30, 0x22, 0x46, 0xff, 0xf7, 0x6a, 0xf8, 0xb8, 0x78, 0x39, 0x78,
0x88, 0x42, 0x02, 0xd0, 0xff, 0xf7, 0x1a, 0xf8, 0x38, 0x78, 0x21, 0x28, 0xdd, 0xd0, 0x81, 0x1e,
0x03, 0x29, 0x00, 0xd2, 0x30, 0xe7, 0x01, 0x46, 0xc0, 0x39, 0x11, 0x29, 0x00, 0xd8, 0x25, 0xe7,
0x00, 0x28, 0x00, 0xd1, 0x2b, 0xe7, 0x01, 0x28, 0x00, 0xd1, 0x3e, 0xe7, 0xb1, 0x28, 0x00, 0xd1,
0x22, 0xe7, 0xf0, 0x28, 0x00, 0xd0, 0x16, 0xe7, 0x20, 0x46, 0xff, 0xf7, 0x13, 0xf8, 0xbf, 0xf3,
0x4f, 0x8f, 0x13, 0x20, 0xc0, 0x43, 0x13, 0x49, 0x03, 0x4a, 0x11, 0x50, 0xbf, 0xf3, 0x4f, 0x8f,
0x00, 0xbf, 0xfd, 0xe7, 0xff, 0x1f, 0x00, 0x00, 0x20, 0xed, 0x00, 0xe0, 0xff, 0x3f, 0x00, 0x00,
0x29, 0x7c, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x41, 0x00, 0x20, 0x7c, 0x41, 0x00, 0x8c, 0x15, 0x44,
0x00, 0x74, 0x8d, 0x43, 0x00, 0x00, 0x60, 0x41, 0x00, 0x00, 0x0f, 0x43, 0x00, 0x00, 0xe0, 0x40,
0x20, 0x74, 0x00, 0x00, 0x00, 0x80, 0xbb, 0x42, 0x98, 0x00, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40,
0x01, 0x00, 0x03, 0x00, 0x04, 0x00, 0xfa, 0x05, 0xe1, 0x17, 0x00, 0x10, 0xb5, 0x0e, 0x00, 0x10,
0xf0, 0xb5, 0x1f, 0xb4, 0x86, 0xb0, 0x00, 0x20, 0x00, 0x90, 0x01, 0x90, 0x02, 0x90, 0x06, 0x98,
0x06, 0x99, 0x80, 0xb2, 0x04, 0x90, 0x07, 0x98, 0x09, 0x0c, 0x02, 0x04, 0x00, 0x14, 0x11, 0x43,
0x07, 0x90, 0x00, 0x27, 0x08, 0x9d, 0x09, 0x98, 0x06, 0x91, 0x3e, 0x46, 0x3c, 0x46, 0x03, 0x90,
0x03, 0x98, 0xa9, 0xb2, 0x02, 0x04, 0x00, 0x0c, 0x03, 0x90, 0x04, 0x98, 0x2d, 0x0c, 0x15, 0x43,
0x48, 0x43, 0x00, 0x21, 0x22, 0x46, 0x00, 0xf0, 0xa7, 0xf8, 0xc7, 0x19, 0x71, 0x41, 0x10, 0x34,
0x0e, 0x46, 0x40, 0x2c, 0xec, 0xdb, 0x38, 0x46, 0x02, 0x9a, 0x00, 0xf0, 0x9d, 0xf8, 0x00, 0x9a,
0x01, 0x9b, 0x80, 0x18, 0x00, 0x90, 0x59, 0x41, 0x02, 0x98, 0x01, 0x91, 0x10, 0x30, 0x02, 0x90,
0x40, 0x28, 0xcc, 0xdb, 0x00, 0x98, 0x0b, 0xb0, 0xf0, 0xbd, 0x03, 0x46, 0x0b, 0x43, 0x9b, 0x07,
0x03, 0xd0, 0x09, 0xe0, 0x08, 0xc9, 0x12, 0x1f, 0x08, 0xc0, 0x04, 0x2a, 0xfa, 0xd2, 0x03, 0xe0,
0x0b, 0x78, 0x03, 0x70, 0x40, 0x1c, 0x49, 0x1c, 0x52, 0x1e, 0xf9, 0xd2, 0x70, 0x47, 0xd2, 0xb2,
0x01, 0xe0, 0x02, 0x70, 0x40, 0x1c, 0x49, 0x1e, 0xfb, 0xd2, 0x70, 0x47, 0x00, 0x22, 0xf6, 0xe7,
0x10, 0xb5, 0x13, 0x46, 0x0a, 0x46, 0x04, 0x46, 0x19, 0x46, 0xff, 0xf7, 0xf0, 0xff, 0x20, 0x46,
0x10, 0xbd, 0x01, 0x22, 0xd2, 0x07, 0x00, 0x28, 0x00, 0xdb, 0x10, 0x1a, 0x00, 0x29, 0x00, 0xdb,
0x51, 0x1a, 0x81, 0x42, 0x01, 0xd8, 0x01, 0x20, 0x70, 0x47, 0x00, 0x20, 0x70, 0x47, 0x01, 0x22,
0xd2, 0x07, 0x00, 0x28, 0x00, 0xdb, 0x10, 0x1a, 0x00, 0x29, 0x00, 0xdb, 0x51, 0x1a, 0x81, 0x42,
0x01, 0xd2, 0x01, 0x20, 0x70, 0x47, 0x00, 0x20, 0x70, 0x47, 0x01, 0x22, 0xd2, 0x07, 0x00, 0x28,
0x00, 0xdb, 0x10, 0x1a, 0x00, 0x29, 0x00, 0xdb, 0x51, 0x1a, 0x81, 0x42, 0x01, 0xd3, 0x01, 0x20,
0x70, 0x47, 0x00, 0x20, 0x70, 0x47, 0x01, 0x22, 0xd2, 0x07, 0x00, 0x28, 0x00, 0xdb, 0x10, 0x1a,
0x00, 0x29, 0x00, 0xdb, 0x51, 0x1a, 0x81, 0x42, 0x01, 0xd9, 0x01, 0x20, 0x70, 0x47, 0x00, 0x20,
0x70, 0x47, 0x10, 0xb5, 0x00, 0x22, 0x96, 0x23, 0x11, 0x46, 0xfe, 0xf7, 0x11, 0xf9, 0x10, 0xbd,
0x41, 0x00, 0x40, 0x02, 0x01, 0x22, 0x40, 0x0a, 0xd2, 0x05, 0x09, 0x0e, 0x80, 0x18, 0x7f, 0x29,
0x01, 0xda, 0x00, 0x20, 0x70, 0x47, 0x96, 0x29, 0x03, 0xdc, 0x96, 0x22, 0x51, 0x1a, 0xc8, 0x40,
0x70, 0x47, 0x96, 0x39, 0x88, 0x40, 0x70, 0x47, 0x41, 0x00, 0x0a, 0x0e, 0x40, 0x02, 0x01, 0x21,
0x40, 0x0a, 0xc9, 0x05, 0x10, 0xb5, 0x40, 0x18, 0x7f, 0x2a, 0x02, 0xda, 0x00, 0x20, 0x01, 0x46,
0x10, 0xbd, 0x00, 0x21, 0x96, 0x2a, 0x03, 0xdc, 0x96, 0x23, 0x9a, 0x1a, 0xd0, 0x40, 0x10, 0xbd,
0x96, 0x3a, 0x00, 0xf0, 0x01, 0xf8, 0x10, 0xbd, 0x10, 0xb5, 0x20, 0x2a, 0x04, 0xdb, 0x01, 0x46,
0x20, 0x3a, 0x91, 0x40, 0x00, 0x20, 0x10, 0xbd, 0x91, 0x40, 0x20, 0x23, 0x9c, 0x1a, 0x03, 0x46,
0xe3, 0x40, 0x19, 0x43, 0x90, 0x40, 0x10, 0xbd, 0x41, 0x00, 0x08, 0x02, 0x00, 0xd0, 0x04, 0x20,
0x0a, 0x0e, 0x01, 0xd0, 0x01, 0x22, 0x10, 0x43, 0x09, 0x0e, 0xff, 0x29, 0x01, 0xd1, 0x02, 0x21,
0x08, 0x43, 0x01, 0x28, 0x00, 0xd1, 0x05, 0x20, 0x70, 0x47, 0x10, 0xb5, 0x7f, 0x20, 0x00, 0x21,
0xc0, 0x05, 0xfe, 0xf7, 0x15, 0xf8, 0x10, 0xbd, 0x10, 0xb5, 0x01, 0x21, 0xfe, 0xf7, 0x4e, 0xf8,
0x10, 0xbd, 0x10, 0xb5, 0x00, 0x21, 0x08, 0x46, 0xfe, 0xf7, 0x0a, 0xf8, 0x10, 0xbd, 0x10, 0xb5,
0x07, 0x20, 0x61, 0x21, 0x00, 0x07, 0xfe, 0xf7, 0x41, 0xf8, 0x10, 0xbd, 0x5e, 0x21, 0x10, 0xb5,
0xc9, 0x43, 0x08, 0x07, 0xfe, 0xf7, 0x3a, 0xf8, 0x10, 0xbd, 0x02, 0xe0, 0x08, 0xc8, 0x12, 0x1f,
0x08, 0xc1, 0x00, 0x2a, 0xfa, 0xd1, 0x70, 0x47, 0x70, 0x47, 0x00, 0x20, 0x01, 0xe0, 0x01, 0xc1,
0x12, 0x1f, 0x00, 0x2a, 0xfb, 0xd1, 0x70, 0x47, 0x01, 0x49, 0x08, 0x60, 0x70, 0x47, 0x00, 0x00,
0x60, 0x00, 0x00, 0x20, 0xf8, 0xb5, 0x04, 0x46, 0x99, 0x21, 0x40, 0x00, 0x09, 0x06, 0x3f, 0x4a,
0x00, 0x25, 0x41, 0x18, 0x91, 0x42, 0x3f, 0xd8, 0x02, 0x21, 0x20, 0x46, 0xfe, 0xf7, 0x16, 0xf8,
0xfe, 0xf7, 0x20, 0xf8, 0x06, 0x46, 0xfe, 0xf7, 0x47, 0xf8, 0x07, 0x46, 0x01, 0x21, 0xc9, 0x43,
0x30, 0x46, 0xfe, 0xf7, 0x0b, 0xf8, 0x21, 0x46, 0xfd, 0xf7, 0x89, 0xff, 0x04, 0x46, 0x34, 0x49,
0xfd, 0xf7, 0x89, 0xff, 0x33, 0x49, 0xfd, 0xf7, 0x2d, 0xff, 0x21, 0x46, 0xfd, 0xf7, 0x83, 0xff,
0x31, 0x49, 0xfd, 0xf7, 0x27, 0xff, 0x21, 0x46, 0xfd, 0xf7, 0x7d, 0xff, 0x2f, 0x49, 0xfd, 0xf7,
0x21, 0xff, 0x21, 0x46, 0xfd, 0xf7, 0x77, 0xff, 0x01, 0x46, 0xb8, 0x07, 0x04, 0x0f, 0x2c, 0x48,
0x78, 0x44, 0x00, 0x59, 0xfd, 0xf7, 0x6f, 0xff, 0x2a, 0x49, 0x79, 0x44, 0x09, 0x59, 0xfd, 0xf7,
0x11, 0xff, 0x29, 0x49, 0x79, 0x44, 0x09, 0x59, 0xfd, 0xf7, 0x0c, 0xff, 0xb9, 0x10, 0x00, 0x2d,
0x27, 0xd1, 0xfd, 0xf7, 0xdb, 0xff, 0xf8, 0xbd, 0xe1, 0x43, 0x49, 0x00, 0x09, 0x0e, 0x06, 0xd0,
0x67, 0x21, 0x09, 0x06, 0x88, 0x42, 0x0c, 0xd2, 0x7f, 0x20, 0xc0, 0x05, 0xf8, 0xbd, 0x01, 0x21,
0xc9, 0x05, 0x20, 0x46, 0xcc, 0x42, 0x01, 0xd1, 0x00, 0x20, 0xf8, 0xbd, 0xff, 0xf7, 0x74, 0xff,
0xf8, 0xbd, 0x1a, 0x49, 0x88, 0x42, 0x0a, 0xd9, 0x02, 0x20, 0xff, 0xf7, 0x95, 0xff, 0x00, 0x2c,
0x02, 0xda, 0xff, 0xf7, 0x7b, 0xff, 0xf8, 0xbd, 0xff, 0xf7, 0x71, 0xff, 0xf8, 0xbd, 0x01, 0x25,
0x9a, 0xe7, 0xfd, 0xf7, 0xb3, 0xff, 0x04, 0x00, 0x03, 0xd0, 0xff, 0x20, 0xc0, 0x05, 0x84, 0x42,
0x02, 0xd1, 0x02, 0x20, 0xff, 0xf7, 0x80, 0xff, 0x20, 0x46, 0xff, 0xf7, 0x3d, 0xff, 0x04, 0x28,
0x01, 0xd1, 0xff, 0xf7, 0x63, 0xff, 0x20, 0x46, 0xf8, 0xbd, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x1e,
0x81, 0xa4, 0x1d, 0x3c, 0x20, 0x6e, 0x63, 0x3d, 0xef, 0xfd, 0x75, 0x3e, 0x17, 0x72, 0x31, 0x3f,
0x2c, 0x04, 0x00, 0x00, 0x12, 0x04, 0x00, 0x00, 0xf8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x86,
0xf8, 0xb5, 0x04, 0x46, 0x99, 0x21, 0x40, 0x00, 0x09, 0x06, 0x48, 0x4a, 0x00, 0x25, 0x41, 0x18,
0x91, 0x42, 0x46, 0xd8, 0x46, 0x49, 0x20, 0x46, 0xfd, 0xf7, 0x05, 0xff, 0xfd, 0xf7, 0x8a, 0xff,
0x06, 0x46, 0xfd, 0xf7, 0xb1, 0xff, 0x07, 0x46, 0x42, 0x49, 0x30, 0x46, 0xfd, 0xf7, 0xfb, 0xfe,
0x00, 0x90, 0x41, 0x49, 0x30, 0x46, 0xfd, 0xf7, 0xf6, 0xfe, 0x21, 0x46, 0xfd, 0xf7, 0xef, 0xfe,
0x00, 0x99, 0xfd, 0xf7, 0xe8, 0xfe, 0x04, 0x46, 0x3c, 0x49, 0xfd, 0xf7, 0xec, 0xfe, 0x3c, 0x49,
0xfd, 0xf7, 0x90, 0xfe, 0x21, 0x46, 0xfd, 0xf7, 0xe6, 0xfe, 0x3a, 0x49, 0xfd, 0xf7, 0x8a, 0xfe,
0x21, 0x46, 0xfd, 0xf7, 0xe0, 0xfe, 0x38, 0x49, 0xfd, 0xf7, 0x84, 0xfe, 0x21, 0x46, 0xfd, 0xf7,
0xda, 0xfe, 0x01, 0x46, 0xb8, 0x07, 0x04, 0x0f, 0x34, 0x48, 0x78, 0x44, 0x00, 0x59, 0xfd, 0xf7,
0xd2, 0xfe, 0x33, 0x49, 0x79, 0x44, 0x09, 0x59, 0xfd, 0xf7, 0x74, 0xfe, 0x31, 0x49, 0x79, 0x44,
0x09, 0x59, 0xfd, 0xf7, 0x6f, 0xfe, 0xb9, 0x10, 0x00, 0x2d, 0x2a, 0xd1, 0xfd, 0xf7, 0x3e, 0xff,
0xf8, 0xbd, 0xe1, 0x43, 0x49, 0x00, 0x09, 0x0e, 0x09, 0xd0, 0x67, 0x21, 0x09, 0x06, 0x88, 0x42,
0x0f, 0xd2, 0x7f, 0x21, 0xc9, 0x05, 0x20, 0x46, 0xfd, 0xf7, 0x5c, 0xfe, 0xf8, 0xbd, 0x01, 0x21,
0xc9, 0x05, 0x20, 0x46, 0xcc, 0x42, 0x01, 0xd1, 0x00, 0x20, 0xf8, 0xbd, 0xff, 0xf7, 0xd4, 0xfe,
0xf8, 0xbd, 0x21, 0x49, 0x88, 0x42, 0x0a, 0xd9, 0x02, 0x20, 0xff, 0xf7, 0xf5, 0xfe, 0x00, 0x2c,
0x02, 0xda, 0xff, 0xf7, 0xdb, 0xfe, 0xf8, 0xbd, 0xff, 0xf7, 0xd1, 0xfe, 0xf8, 0xbd, 0x01, 0x25,
0x90, 0xe7, 0xfd, 0xf7, 0x13, 0xff, 0x04, 0x00, 0x09, 0xd0, 0xff, 0x20, 0xc0, 0x05, 0x84, 0x42,
0x0b, 0xd1, 0x02, 0x20, 0xff, 0xf7, 0xe0, 0xfe, 0xff, 0xf7, 0xc1, 0xfe, 0xf8, 0xbd, 0x02, 0x20,
0xff, 0xf7, 0xda, 0xfe, 0xff, 0xf7, 0xc2, 0xfe, 0xf8, 0xbd, 0x20, 0x46, 0xff, 0xf7, 0x94, 0xfe,
0x04, 0x28, 0x01, 0xd1, 0xff, 0xf7, 0xba, 0xfe, 0x20, 0x46, 0xf8, 0xbd, 0x00, 0x00, 0x50, 0x1e,
0x3b, 0xaa, 0xb8, 0x40, 0xf4, 0xfd, 0x05, 0x37, 0x00, 0x70, 0x31, 0x3e, 0x12, 0xbb, 0x2a, 0x3d,
0x12, 0xbb, 0x2a, 0x3e, 0xff, 0xff, 0xff, 0x3e, 0xff, 0xff, 0x7f, 0x3f, 0x82, 0x02, 0x00, 0x00,
0x68, 0x02, 0x00, 0x00, 0x4e, 0x02, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x85, 0xf8, 0xb5, 0x01, 0x21,
0xc9, 0x05, 0x7f, 0x22, 0x00, 0x26, 0x41, 0x1a, 0x12, 0x06, 0x91, 0x42, 0x7e, 0xd2, 0x01, 0x21,
0xc9, 0x04, 0x41, 0x18, 0xca, 0x15, 0x01, 0x23, 0x41, 0x02, 0x1b, 0x07, 0xc9, 0x18, 0x4d, 0x0f,
0x7f, 0x21, 0x7f, 0x3a, 0x2b, 0x05, 0xc9, 0x05, 0xb6, 0x18, 0x5c, 0x18, 0xd2, 0x05, 0x87, 0x1a,
0x30, 0x46, 0x28, 0x43, 0x3a, 0xd0, 0x21, 0x46, 0x38, 0x46, 0xfd, 0xf7, 0xeb, 0xfd, 0x00, 0x90,
0x21, 0x46, 0x38, 0x46, 0xfd, 0xf7, 0x37, 0xfe, 0x00, 0x99, 0xfd, 0xf7, 0x79, 0xfe, 0x07, 0x46,
0x01, 0x46, 0xfd, 0xf7, 0x38, 0xfe, 0x3f, 0x49, 0x00, 0x90, 0xfd, 0xf7, 0x34, 0xfe, 0x3e, 0x49,
0xfd, 0xf7, 0xd8, 0xfd, 0x04, 0x46, 0x38, 0x46, 0x00, 0x99, 0xfd, 0xf7, 0x2c, 0xfe, 0x21, 0x46,
0xfd, 0xf7, 0x29, 0xfe, 0x01, 0x46, 0x39, 0x48, 0xad, 0x00, 0x78, 0x44, 0x40, 0x59, 0xfd, 0xf7,
0xc9, 0xfd, 0x04, 0x46, 0x36, 0x49, 0x38, 0x46, 0xfd, 0xf7, 0x1d, 0xfe, 0x21, 0x46, 0xfd, 0xf7,
0xc1, 0xfd, 0x04, 0x46, 0x30, 0x46, 0xfd, 0xf7, 0xbc, 0xfe, 0x32, 0x49, 0x79, 0x44, 0x49, 0x59,
0xfd, 0xf7, 0xb8, 0xfd, 0x21, 0x46, 0xfd, 0xf7, 0xb5, 0xfd, 0xf8, 0xbd, 0x38, 0x46, 0xfd, 0xf7,
0x02, 0xfe, 0x05, 0x46, 0x2c, 0x49, 0xfd, 0xf7, 0x06, 0xfe, 0x2c, 0x49, 0xfd, 0xf7, 0xaa, 0xfd,
0x29, 0x46, 0xfd, 0xf7, 0x00, 0xfe, 0x2a, 0x49, 0xfd, 0xf7, 0xa4, 0xfd, 0x29, 0x46, 0xfd, 0xf7,
0xfa, 0xfd, 0x28, 0x49, 0xfd, 0xf7, 0x9e, 0xfd, 0x04, 0x46, 0x29, 0x46, 0x08, 0x46, 0xfd, 0xf7,
0xf2, 0xfd, 0x21, 0x46, 0xfd, 0xf7, 0xef, 0xfd, 0x04, 0x46, 0x23, 0x49, 0x28, 0x46, 0xfd, 0xf7,
0xea, 0xfd, 0x21, 0x46, 0xfd, 0xf7, 0x8e, 0xfd, 0x04, 0x46, 0x20, 0x49, 0x28, 0x46, 0xfd, 0xf7,
0xe2, 0xfd, 0x21, 0x46, 0xfd, 0xf7, 0x86, 0xfd, 0xf8, 0xbd, 0xff, 0xe7, 0xff, 0x22, 0x41, 0x00,
0x12, 0x06, 0x91, 0x42, 0x02, 0xd9, 0xff, 0xf7, 0xff, 0xfd, 0xf8, 0xbd, 0xff, 0x22, 0xd2, 0x05,
0x90, 0x42, 0xfa, 0xd0, 0x14, 0x02, 0xa0, 0x42, 0x05, 0xd9, 0x01, 0x20, 0xff, 0xf7, 0x1c, 0xfe,
0xff, 0xf7, 0xf7, 0xfd, 0xf8, 0xbd, 0x41, 0x00, 0x05, 0xd0, 0x16, 0x26, 0xf6, 0x43, 0x17, 0x21,
0xfd, 0xf7, 0x3c, 0xfe, 0x63, 0xe7, 0x02, 0x20, 0xff, 0xf7, 0x0e, 0xfe, 0xff, 0xf7, 0xdd, 0xfd,
0x60, 0x40, 0xf8, 0xbd, 0xc9, 0xd5, 0x13, 0x3f, 0x4e, 0x38, 0x76, 0x3f, 0x52, 0x01, 0x00, 0x00,
0x3b, 0xaa, 0x38, 0x40, 0x10, 0x01, 0x00, 0x00, 0x0e, 0x9c, 0x8c, 0x3e, 0xd0, 0xc2, 0xb8, 0xbe,
0xe1, 0x39, 0xf6, 0x3e, 0x3b, 0xaa, 0x38, 0xbf, 0x29, 0x3b, 0xaa, 0x3b, 0x00, 0x00, 0xb8, 0x3f,
0x00, 0x00, 0x80, 0x3f, 0x00, 0x30, 0x98, 0x3f, 0x00, 0x00, 0xb5, 0x3f, 0x00, 0x40, 0xd7, 0x3f,
0x00, 0x00, 0x00, 0x00, 0x32, 0x0a, 0x7e, 0x39, 0x7f, 0x66, 0x1e, 0x39, 0x5b, 0x99, 0x1f, 0x39,
0x00, 0x00, 0x80, 0x3f, 0xf0, 0x37, 0x98, 0x3f, 0xf3, 0x04, 0xb5, 0x3f, 0xfd, 0x44, 0xd7, 0x3f,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2e, 0x3e, 0x00, 0xd0, 0xa4, 0x3e, 0x00, 0x30, 0xeb, 0x3e,
0x00, 0xc0, 0x15, 0x3f, 0x00, 0x50, 0x33, 0x3f, 0x00, 0xa0, 0x4e, 0x3f, 0x00, 0x20, 0x68, 0x3f,
0x00, 0x00, 0x00, 0x00, 0xdf, 0xcf, 0x51, 0x36, 0x9a, 0x97, 0xf0, 0x37, 0x19, 0xf0, 0xa9, 0x38,
0xdf, 0xcf, 0xd1, 0x35, 0x89, 0x47, 0x8e, 0x34, 0xa8, 0xfe, 0x6c, 0x39, 0x93, 0xb6, 0x1f, 0x39,
0x00, 0x00, 0x80, 0x3f, 0x00, 0x30, 0x98, 0x3f, 0x00, 0x00, 0xb5, 0x3f, 0x00, 0x40, 0xd7, 0x3f,
0x00, 0x00, 0x00, 0x00, 0x32, 0x0a, 0x7e, 0x39, 0x7f, 0x66, 0x1e, 0x39, 0x5b, 0x99, 0x1f, 0x39,
0x00, 0x00, 0x80, 0x3f, 0xf0, 0x37, 0x98, 0x3f, 0xf3, 0x04, 0xb5, 0x3f, 0xfd, 0x44, 0xd7, 0x3f,
0x0f, 0x00, 0x3e, 0x03, 0xaf, 0xaf, 0xaf, 0xaf, 0x0f, 0x00, 0x01, 0x00, 0x0f, 0x00, 0x29, 0x00,
0x66, 0x80, 0xbc, 0xac, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x66, 0x80, 0xbc, 0xac,
0x83, 0x01, 0x01, 0x00, 0xf0, 0x2e, 0x00, 0x10, 0x60, 0x00, 0x00, 0x20, 0x10, 0x00, 0x00, 0x00,
0xca, 0x29, 0x00, 0x10, 0x00, 0x2f, 0x00, 0x10, 0x70, 0x00, 0x00, 0x20, 0xe0, 0x06, 0x00, 0x00,
0xda, 0x29, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x02, 0x03, 0x01, 0xfe, 0x2b, 0x05, 0x1c, 0xc2,
};

View File

@ -0,0 +1,75 @@
/***************************************************************************
This is a example for ENS160 flash programming
Written by Christoph Friese for Sciosense / 8-April-2020
***************************************************************************/
#include <Wire.h>
int ArduinoLED = 13;
//-------------------------------------------------------------
//ENS160 related items
//-------------------------------------------------------------
#include "ScioSense_ENS160.h" // ENS160 library
ScioSense_ENS160 ens160(ENS160_I2CADDR_0);
//sciosense_ENS160 ens160(ENS160_I2CADDR_1);
#include "clare_fw_app_production_v2.3.1.h"
/*--------------------------------------------------------------------------
SETUP function
initiate sensor
--------------------------------------------------------------------------*/
void setup() {
bool ok;
//-------------------------------------------------------------
// General setup steps
//-------------------------------------------------------------
Serial.begin(115200);
while (!Serial) {}
//Switch on LED for init
pinMode(ArduinoLED, OUTPUT);
digitalWrite(ArduinoLED, LOW);
Serial.println("ENS160 flash example");
delay(1000);
//-------------------------------------------------------------
//ENS160 related items
//-------------------------------------------------------------
Serial.print("Init ");
ok = ens160.begin(1,1);
Serial.println();
if (ens160.available()) {
// Print ENS160 version
Serial.print("Current rev: "); Serial.print(ens160.getMajorRev());
Serial.print("."); Serial.print(ens160.getMinorRev());
Serial.print("."); Serial.println(ens160.getBuild());
ok = ens160.flash(image_data, sizeof(image_data));
if (ok) {
// Print ENS160 version
Serial.print("Updated rev: "); Serial.print(ens160.getMajorRev());
Serial.print("."); Serial.print(ens160.getMinorRev());
Serial.print("."); Serial.println(ens160.getBuild());
} else {
Serial.println("--- FAILED ---");
}
}
}
/*--------------------------------------------------------------------------
MAIN LOOP FUNCTION
Cylce every 1000ms and perform action
--------------------------------------------------------------------------*/
void loop() {
}

View File

@ -0,0 +1,60 @@
#######################################
# Syntax Coloring Map
#######################################
# https://spencer.bliven.us/index.php/2012/01/18/arduino-ide-keywords/
# KEYWORD1 Classes, datatypes, and C++ keywords
# KEYWORD2 Methods and functions
# KEYWORD3 setup and loop functions, as well as the Serial keywords
# LITERAL1 Constants
# LITERAL2 Built-in variables (unused by default)
#######################################
# Classes, datatypes (KEYWORD1)
#######################################
ENS160 KEYWORD1
ens160 KEYWORD1
sciosense_ens160 KEYWORD1
SCIOSENSE_ENS160 KEYWORD1
ScioSense_ens160 KEYWORD1
#######################################
# Methods and Functions (KEYWORD2)
#######################################
begin KEYWORD2
available KEYWORD2
setMode KEYWORD2
initCustomMode KEYWORD2
addCustomStep KEYWORD2
measure KEYWORD2
set_envdata210 KEYWORD2
getMajorRev KEYWORD2
getMinorRev KEYWORD2
getBuild KEYWORD2
getIAQ KEYWORD2
getTVOC KEYWORD2
geteCO2 KEYWORD2
getNO2 KEYWORD2
getHP0 KEYWORD2
getHP0BL KEYWORD2
getHP1 KEYWORD2
getHP1BL KEYWORD2
getHP2 KEYWORD2
getHP2BL KEYWORD2
getHP3 KEYWORD2
getHP3BL KEYWORD2
flash KEYWORD2
######################################
# Constants (LITERAL1)
#######################################
ENS160_I2CADDR_0 LITERAL1
ENS160_I2CADDR_1 LITERAL1
ENS160_OPMODE_IDLE LITERAL1
ENS160_OPMODE_STD LITERAL1
ENS160_OPMODE_CUSTOM LITERAL1

View File

@ -0,0 +1,9 @@
name=ScioSense ENS160
version=1.0.0
author=Christoph Friese
maintainer=Christoph Friese
sentence=Arduino library for the ENS160 digital four channel MOX gas sensor with I2C interface from ams
paragraph=This library controls the ENS160. The main feature of this library is performing a single shot measurement, retrieving the measurement data.
category=Device Control
url=https://github.com/sciosense/ens160
architectures=*

View File

@ -0,0 +1,547 @@
/*
ScioSense_ENS160.h - Library for the ENS160 sensor with I2C interface from ScioSense
2020 Apr 06 v3 Christoph Friese Changed nomenclature to ScioSense as product shifted from ams
2020 Feb 15 v2 Giuseppe Pasetti Corrected firmware flash option
2019 May 05 v1 Christoph Friese Created
based on application note "ENS160 Software Integration.pdf" rev 0.01
*/
#include "ScioSense_ENS160.h"
#include "math.h"
ScioSense_ENS160::ScioSense_ENS160(uint8_t slaveaddr) {
this->_slaveaddr = slaveaddr;
this->_ADDR = -1;
this->_nINT = -1;
this->_nCS = -1;
}
ScioSense_ENS160::ScioSense_ENS160(uint8_t ADDR, uint8_t nCS, uint8_t nINT) {
this->_slaveaddr = ENS160_I2CADDR_0;
this->_ADDR = ADDR;
this->_nINT = nINT;
this->_nCS = nCS;
}
ScioSense_ENS160::ScioSense_ENS160(uint8_t slaveaddr, uint8_t ADDR, uint8_t nCS, uint8_t nINT) {
this->_slaveaddr = slaveaddr;
this->_ADDR = ADDR;
this->_nINT = nINT;
this->_nCS = nCS;
}
// Init I2C communication, resets ENS160 and checks its PART_ID. Returns false on I2C problems or wrong PART_ID.
bool ScioSense_ENS160::begin(bool debug, bool bootloader)
{
bool result;
//uint16_t partid;
uint8_t i2cbuf[2];
debugENS160 = debug;
//Set pin levels
if (this->_ADDR > -1) {
pinMode(this->_ADDR, OUTPUT);
digitalWrite(this->_ADDR, LOW);
}
if (this->_nINT > -1) pinMode(this->_nINT, INPUT_PULLUP);
if (this->_nCS > -1) {
pinMode(this->_nCS, OUTPUT);
digitalWrite(this->_nCS, HIGH);
}
//init I2C
_i2c_init();
if (debugENS160) {
Serial.println("begin() - I2C init done");
}
delay(ENS160_BOOTING); // Wait to boot after reset
this->_available = false;
result = this->reset();
this->_available = this->checkPartID();
if (this->_available) {
//sciosenseEither select bootloader or idle mode
if (bootloader) {
result = this->setMode(ENS160_OPMODE_BOOTLOADER);
} else {
result = this->setMode(ENS160_OPMODE_IDLE);
}
result = this->clearCommand();
result = this->getFirmware();
}
if (debugENS160) {
if (bootloader) {
Serial.println("ENS160 in bootloader mode");
} else {
Serial.println("ENS160 in idle mode");
}
}
return this->_available;
}
// Sends a reset to the ENS160. Returns false on I2C problems.
bool ScioSense_ENS160::reset(void)
{
uint8_t result = this->write8(_slaveaddr, ENS160_REG_OPMODE, ENS160_OPMODE_RESET);
if (debugENS160) {
Serial.print("reset() result: ");
Serial.println(result == 0 ? "ok" : "nok");
}
delay(ENS160_BOOTING); // Wait to boot after reset
return result == 0;
}
//Reads the part ID and confirms valid sensor
bool ScioSense_ENS160::checkPartID(void) {
uint8_t i2cbuf[2];
uint16_t part_id;
uint8_t result = this->read(_slaveaddr, ENS160_REG_PART_ID, i2cbuf, 2);
part_id = i2cbuf[1] | ((uint16_t)i2cbuf[0] << 8);
if (debugENS160) {
Serial.print("checkPartID() result: ");
Serial.println(part_id == ENS160_PARTID ? "ok" : "nok");
}
delay(ENS160_BOOTING); // Wait to boot after reset
return part_id == ENS160_PARTID;
}
//Initialize idle mode and confirms
bool ScioSense_ENS160::clearCommand(void) {
uint8_t status;
uint8_t result;
result = this->write8(_slaveaddr, ENS160_REG_COMMAND, ENS160_COMMAND_NOP);
result = this->write8(_slaveaddr, ENS160_REG_COMMAND, ENS160_COMMAND_CLRGPR);
if (debugENS160) {
Serial.print("clearCommand() result: ");
Serial.println(result == 0 ? "ok" : "nok");
}
delay(ENS160_BOOTING); // Wait to boot after reset
status = this->read8(_slaveaddr, ENS160_REG_DATA_STATUS);
if (debugENS160) {
Serial.print("clearCommand() status: 0x");
Serial.println(status, HEX);
}
delay(ENS160_BOOTING); // Wait to boot after reset
return result == 0;
}
bool ScioSense_ENS160::getFirmware() {
uint8_t i2cbuf[3];
uint8_t result;
this->clearCommand();
delay(ENS160_BOOTING); // Wait to boot after reset
result = this->write8(_slaveaddr, ENS160_REG_COMMAND, ENS160_COMMAND_GET_APPVER);
result = this->read(_slaveaddr, ENS160_REG_GPR_READ_4, i2cbuf, 3);
this->_fw_ver_major = i2cbuf[0];
this->_fw_ver_minor = i2cbuf[1];
this->_fw_ver_build = i2cbuf[2];
if (debugENS160) {
Serial.println(this->_fw_ver_major);
Serial.println(this->_fw_ver_minor);
Serial.println(this->_fw_ver_build);
Serial.print("getFirmware() result: ");
Serial.println(result == 0 ? "ok" : "nok");
}
delay(ENS160_BOOTING); // Wait to boot after reset
return result == 0;
}
bool ScioSense_ENS160::setMode(uint8_t mode) {
uint8_t result;
result = this->write8(_slaveaddr, ENS160_REG_OPMODE, mode);
if (debugENS160) {
Serial.print("setMode() activate result: ");
Serial.println(result == 0 ? "ok" : "nok");
}
delay(ENS160_BOOTING); // Wait to boot after reset
return result == 0;
}
// Define custom mode with number of steps
bool ScioSense_ENS160::initCustomMode(uint16_t stepNum) {
uint8_t result;
if (stepNum > 0) {
this->_stepCount = stepNum;
result = this->setMode(ENS160_OPMODE_IDLE);
result = this->clearCommand();
result = this->write8(_slaveaddr, ENS160_REG_COMMAND, ENS160_COMMAND_SETSEQ);
} else {
result = 1;
}
delay(ENS160_BOOTING); // Wait to boot after reset
return result == 0;
}
// Add custom mode step with definition of temperatures, duration and measurement
bool ScioSense_ENS160::addCustomStep(uint16_t time, bool measureHP0, bool measureHP1, bool measureHP2, bool measureHP3, uint16_t tempHP0, uint16_t tempHP1, uint16_t tempHP2, uint16_t tempHP3) {
uint8_t result;
uint8_t seq_ack;
uint8_t temp;
if (debugENS160) {
Serial.print("setCustomMode() write step ");
Serial.println(this->_stepCount);
}
delay(ENS160_BOOTING); // Wait to boot after reset
temp = (uint8_t)((time / 24) << 6);
if (measureHP0) temp = temp | 0x20;
if (measureHP1) temp = temp | 0x10;
if (measureHP2) temp = temp | 0x8;
if (measureHP3) temp = temp | 0x4;
result = this->write8(_slaveaddr, ENS160_REG_GPR_WRITE_0, temp);
temp = (uint8_t)((time / 24) >> 2);
result = this->write8(_slaveaddr, ENS160_REG_GPR_WRITE_1, temp);
result = this->write8(_slaveaddr, ENS160_REG_GPR_WRITE_2, (uint8_t)(tempHP0/2));
result = this->write8(_slaveaddr, ENS160_REG_GPR_WRITE_3, (uint8_t)(tempHP1/2));
result = this->write8(_slaveaddr, ENS160_REG_GPR_WRITE_4, (uint8_t)(tempHP2/2));
result = this->write8(_slaveaddr, ENS160_REG_GPR_WRITE_5, (uint8_t)(tempHP3/2));
result = this->write8(_slaveaddr, ENS160_REG_GPR_WRITE_6, (uint8_t)(this->_stepCount - 1));
if (this->_stepCount == 0) {
result = this->write8(_slaveaddr, ENS160_REG_GPR_WRITE_7, 0);
} else {
result = this->write8(_slaveaddr, ENS160_REG_GPR_WRITE_7, 128);
}
delay(ENS160_BOOTING);
seq_ack = this->read8(_slaveaddr, ENS160_REG_GPR_READ_7);
delay(ENS160_BOOTING); // Wait to boot after reset
if ((ENS160_SEQ_ACK_COMPLETE | this->_stepCount) != seq_ack) {
this->_stepCount = this->_stepCount - 1;
return 0;
} else {
return 1;
}
}
// Performs one single shot temperature and relative humidity measurement.
bool ScioSense_ENS160::measure(bool waitForNew)
{
bool ok;
uint8_t i2cbuf[8];
uint8_t status;
uint8_t result;
// Set default status for early bail out
if (debugENS160) Serial.println("Start measurement");
// Either wait that new data is available (might take up to 1sec) or proceed even with old data
if (waitForNew) {
do {
delay(ENS160_BOOTING);
status = this->read8(_slaveaddr, ENS160_REG_DATA_STATUS);
if (debugENS160) {
Serial.print("Status: ");
Serial.println(status);
}
} while (!IS_NEW_DATA_AVAILABLE(status));
} else {
status = this->read8(_slaveaddr, ENS160_REG_DATA_STATUS);
}
// Read predictions
if (IS_NEWDAT(status)) {
result = this->read(_slaveaddr, ENS160_REG_DATA_AQI, i2cbuf, 7);
_data_tvoc = i2cbuf[1] | ((uint16_t)i2cbuf[2] << 8);
_data_eco2 = i2cbuf[3] | ((uint16_t)i2cbuf[4] << 8);
}
// Read raw resistance values
if (IS_NEWGPR(status)) {
result = this->read(_slaveaddr, ENS160_REG_GPR_READ_0, i2cbuf, 8);
_hp0_rs = CONVERT_RS_RAW2OHMS_F((uint32_t)(i2cbuf[0] | ((uint16_t)i2cbuf[1] << 8)));
_hp1_rs = CONVERT_RS_RAW2OHMS_F((uint32_t)(i2cbuf[2] | ((uint16_t)i2cbuf[3] << 8)));
_hp2_rs = CONVERT_RS_RAW2OHMS_F((uint32_t)(i2cbuf[4] | ((uint16_t)i2cbuf[5] << 8)));
_hp3_rs = CONVERT_RS_RAW2OHMS_F((uint32_t)(i2cbuf[6] | ((uint16_t)i2cbuf[7] << 8)));
}
// Read baselines
if ((IS_NEWGPR(status)) or (IS_NEWDAT(status))) {
result = this->read(_slaveaddr, ENS160_REG_DATA_BL, i2cbuf, 8);
_hp0_bl = CONVERT_RS_RAW2OHMS_F((uint32_t)(i2cbuf[0] | ((uint16_t)i2cbuf[1] << 8)));
_hp1_bl = CONVERT_RS_RAW2OHMS_F((uint32_t)(i2cbuf[2] | ((uint16_t)i2cbuf[3] << 8)));
_hp2_bl = CONVERT_RS_RAW2OHMS_F((uint32_t)(i2cbuf[4] | ((uint16_t)i2cbuf[5] << 8)));
_hp3_bl = CONVERT_RS_RAW2OHMS_F((uint32_t)(i2cbuf[6] | ((uint16_t)i2cbuf[7] << 8)));
result = this->read(_slaveaddr, ENS160_REG_DATA_MISR, i2cbuf, 1);
_misr = i2cbuf[0];
}
return ok==0;
}
// Writes t and h (in ENS210 format) to ENV_DATA. Returns false on I2C problems.
bool ScioSense_ENS160::set_envdata210(uint16_t t, uint16_t h) {
uint16_t trh;
uint8_t trh_in[4];
trh = (uint16_t)((t + 273.15f) * 64.0f);
trh_in[0] = trh & 0xff;
trh_in[1] = (trh >> 8) & 0xff;
trh = (uint16_t)(h * 512.0f);
trh_in[2] = trh & 0xff;
trh_in[3] = (trh >> 8) & 0xff;
uint8_t result = this->write(_slaveaddr, ENS160_REG_TEMP_IN, trh_in, 4);
return result;
}
// A helper function to read back and verify status of command
int ScioSense_ENS160::blCMDWriteVerify(uint8_t command) {
uint8_t status[2];
uint8_t result = this->write8(_slaveaddr, ENS160_REG_COMMAND, ENS160_COMMAND_NOP);
Serial.print("1. Write 0x");Serial.print(ENS160_COMMAND_NOP,HEX);
Serial.print(" with result 0x");Serial.println(result,HEX);
result = this->write8(_slaveaddr, ENS160_REG_COMMAND, command);
Serial.print("2. Write 0x");Serial.print(command,HEX);
Serial.print(" with result 0x");Serial.println(result,HEX);
do {
if (command == ENS160_BL_CMD_WRITE) delay(100);
else delay(2000);
result = this->read(_slaveaddr, ENS160_REG_DATA_STATUS, status, 1);
Serial.print("3. Read DATA_STATUS with 0x");
Serial.print(status[0],HEX);
Serial.print("\t0x");
Serial.println(status[0] & ENS160_DATA_STATUS_NEWGPR);
} while (!(status[0] & ENS160_DATA_STATUS_NEWGPR));
result = this->read(_slaveaddr, ENS160_REG_GPR_READ_6, status, 2);
Serial.print("4. Read GPR_READ_6 with 0x");
Serial.print(status[0],HEX);
Serial.print("\t0x");
Serial.println(status[1],HEX);
if (status[1] != command + 1) {
// status[0] is the MSB 8bit of AMS_ERR_BL_XXX error code
// documented in the ENS160 Bootloader User Guide.
return status[0];
}
return 0;
}
// Flashes the firmware of the ENS160 with size bytes from image - image _must_ be in PROGMEM
/*bool ScioSense_ENS160::flash(const uint8_t * app_img, int size) {
int error = 0;
int idx = 0;
uint8_t result = this->write8(_slaveaddr,ENS160_REG_OPMODE,ENS160_OPMODE_BOOTLOADER);
delay(ENS160_BOOTING); // Wait to boot after reset
// Write magic word and start bootloader
result = this->write(_slaveaddr, ENS160_REG_GPR_WRITE_0, ENS160_BL_MAGIC, 4);
error = blCMDWriteVerify(ENS160_BL_CMD_START);
if (error) {
Serial.print("Write failed ENS160_BL_CMD_START. Error code: ");
Serial.println(error);
return false;
} else {
Serial.print("Write success ENS160_BL_CMD_START.");
}
// Erase stored baseline
error = blCMDWriteVerify(ENS160_BL_CMD_ERASE_BLINE);
if (error) {
Serial.print("Write failed ENS160_BL_CMD_ERASE_BLINE. Error code: ");
Serial.println(error);
return false;
} else {
Serial.print("Write success ENS160_BL_CMD_ERASE_BLINE.");
}
// Erase application FLASH memory
error = blCMDWriteVerify(ENS160_BL_CMD_ERASE_APP);
if (error) {
Serial.print("Write failed ENS160_BL_CMD_ERASE_APP. Error code: ");
Serial.println(error);
return false;
} else {
Serial.print("Write success ENS160_BL_CMD_ERASE_APP.");
}
// Write application binary in pieces of 8 bytes
uint8_t len = 0;
for(idx = 0; idx < size; idx+=8) {
int len = (size - idx) < 8 ? (size - idx) : 8;
Serial.println(size);
Serial.println(len);
Serial.println(idx);
uint8_t ram[8];
memcpy_P(ram, app_img, len); // Copy up to 8 bytes from PROGMEM to RAM
result = this->write(_slaveaddr, ENS160_REG_GPR_WRITE_0, ram, len);
error = blCMDWriteVerify(ENS160_BL_CMD_WRITE);
if (error) {
Serial.print("Write failed ENS160_BL_CMD_WRITE. Error code: ");
Serial.println(error);
return false;
}
app_img += len;
}
// idx should match sizeof(app_img);
if(idx != size) {
Serial.println("Failed to complete application image update.");
return false;
} else {
Serial.println("Write success of complete application image.");
}
// Verify application FLASH memory
error = blCMDWriteVerify(ENS160_BL_CMD_VERIFY);
if (error) {
Serial.print("Write failed ENS160_BL_CMD_VERIFY. Error code: ");
Serial.println(error);
return false;
} else {
Serial.print("Write success ENS160_BL_CMD_VERIFY.");
}
// Verify application FLASH memory
error = blCMDWriteVerify(ENS160_BL_CMD_EXITBL);
if (error) {
Serial.print("Write failed ENS160_BL_CMD_EXITBL. Error code: ");
Serial.println(error);
return false;
} else {
Serial.print("Write success ENS160_BL_CMD_EXITBL.");
}
this->reset();
result = this->clearCommand();
result = this->getFirmware();
return true;
}
*/
/****************************************************************************/
/* General functions */
/****************************************************************************/
void ScioSense_ENS160::_i2c_init()
{
Wire.begin();
}
/**************************************************************************/
uint8_t ScioSense_ENS160::read8(uint8_t addr, byte reg)
{
uint8_t ret;
this->read(addr, reg, &ret, 1);
return ret;
}
uint8_t ScioSense_ENS160::read(uint8_t addr, uint8_t reg, uint8_t *buf, uint8_t num)
{
uint8_t pos = 0;
uint8_t result = 0;
if (debugENS160) {
Serial.print("I2C read address: 0x");
Serial.print(addr, HEX);
Serial.print(" - register: 0x");
Serial.println(reg, HEX);
}
//on arduino we need to read in 32 byte chunks
while(pos < num){
uint8_t read_now = min((uint8_t)32, (uint8_t)(num - pos));
Wire.beginTransmission((uint8_t)addr);
Wire.write((uint8_t)reg + pos);
result = Wire.endTransmission();
Wire.requestFrom((uint8_t)addr, read_now);
for(int i=0; i<read_now; i++){
buf[pos] = Wire.read();
pos++;
}
}
return result;
}
/**************************************************************************/
uint8_t ScioSense_ENS160::write8(uint8_t addr, byte reg, byte value)
{
uint8_t result = this->write(addr, reg, &value, 1);
return result;
}
uint8_t ScioSense_ENS160::write(uint8_t addr, uint8_t reg, uint8_t *buf, uint8_t num)
{
if (debugENS160) {
Serial.print("I2C write address: 0x");
Serial.print(addr, HEX);
Serial.print(" - register: 0x");
Serial.print(reg, HEX);
Serial.print(" - value:");
for (int i = 0; i<num; i++) {
Serial.print(" 0x");
Serial.print(buf[i], HEX);
}
Serial.println();
}
Wire.beginTransmission((uint8_t)addr);
Wire.write((uint8_t)reg);
Wire.write((uint8_t *)buf, num);
uint8_t result = Wire.endTransmission();
return result;
}
/**************************************************************************/

View File

@ -0,0 +1,195 @@
/*
ScioSense_ENS160.h - Library for the ENS160 sensor with I2C interface from ScioSense
2020 Apr 06 v2 Christoph Friese Changed nomenclature to ScioSense as product shifted from ams
2020 Feb 15 v2 Giuseppe Pasetti Corrected firmware flash option
2019 May 05 v1 Christoph Friese Created
based on application note "ENS160 Software Integration.pdf" rev 0.01
*/
#ifndef __SCIOSENSE_ENS160_H_
#define __SCIOSENSE_ENS160_H_
#if (ARDUINO >= 100)
#include "Arduino.h"
#else
#include "WProgram.h"
#endif
#include <Wire.h>
// Chip constants
#define ENS160_PARTID 0x6001
#define ENS160_BOOTING 50
// 7-bit I2C slave address of the ENS160
#define ENS160_I2CADDR_0 0x52 //ADDR low
#define ENS160_I2CADDR_1 0x53 //ADDR high
// ENS160 registers for version V0
#define ENS160_REG_PART_ID 0x00 // 2 byte register
#define ENS160_REG_OPMODE 0x10
#define ENS160_REG_CONFIG 0x11
#define ENS160_REG_COMMAND 0x12
#define ENS160_REG_TEMP_IN 0x13
#define ENS160_REG_RH_IN 0x15
#define ENS160_REG_DATA_STATUS 0x20
#define ENS160_REG_DATA_AQI 0x21
#define ENS160_REG_DATA_TVOC 0x22
#define ENS160_REG_DATA_ECO2 0x24
#define ENS160_REG_DATA_BL 0x28
#define ENS160_REG_DATA_T 0x30
#define ENS160_REG_DATA_RH 0x32
#define ENS160_REG_DATA_MISR 0x38
#define ENS160_REG_GPR_WRITE_0 0x40
#define ENS160_REG_GPR_WRITE_1 ENS160_REG_GPR_WRITE_0 + 1
#define ENS160_REG_GPR_WRITE_2 ENS160_REG_GPR_WRITE_0 + 2
#define ENS160_REG_GPR_WRITE_3 ENS160_REG_GPR_WRITE_0 + 3
#define ENS160_REG_GPR_WRITE_4 ENS160_REG_GPR_WRITE_0 + 4
#define ENS160_REG_GPR_WRITE_5 ENS160_REG_GPR_WRITE_0 + 5
#define ENS160_REG_GPR_WRITE_6 ENS160_REG_GPR_WRITE_0 + 6
#define ENS160_REG_GPR_WRITE_7 ENS160_REG_GPR_WRITE_0 + 7
#define ENS160_REG_GPR_READ_0 0x48
#define ENS160_REG_GPR_READ_4 ENS160_REG_GPR_READ_0 + 4
#define ENS160_REG_GPR_READ_6 ENS160_REG_GPR_READ_0 + 6
#define ENS160_REG_GPR_READ_7 ENS160_REG_GPR_READ_0 + 7
//ENS160 data register fields
#define ENS160_COMMAND_NOP 0x00
#define ENS160_COMMAND_CLRGPR 0xCC
#define ENS160_COMMAND_GET_APPVER 0x0E
#define ENS160_COMMAND_SETTH 0x02
#define ENS160_COMMAND_SETSEQ 0xC2
#define ENS160_OPMODE_RESET 0xF0
#define ENS160_OPMODE_DEP_SLEEP 0x00
#define ENS160_OPMODE_IDLE 0x01
#define ENS160_OPMODE_STD 0x02
#define ENS160_OPMODE_INTERMEDIATE 0x03
#define ENS160_OPMODE_CUSTOM 0xC0
#define ENS160_OPMODE_D0 0xD0
#define ENS160_OPMODE_D1 0xD1
#define ENS160_OPMODE_BOOTLOADER 0xB0
#define ENS160_BL_CMD_START 0x02
#define ENS160_BL_CMD_ERASE_APP 0x04
#define ENS160_BL_CMD_ERASE_BLINE 0x06
#define ENS160_BL_CMD_WRITE 0x08
#define ENS160_BL_CMD_VERIFY 0x0A
#define ENS160_BL_CMD_GET_BLVER 0x0C
#define ENS160_BL_CMD_GET_APPVER 0x0E
#define ENS160_BL_CMD_EXITBL 0x12
#define ENS160_SEQ_ACK_NOTCOMPLETE 0x80
#define ENS160_SEQ_ACK_COMPLETE 0xC0
#define IS_ENS160_SEQ_ACK_NOT_COMPLETE(x) (ENS160_SEQ_ACK_NOTCOMPLETE == (ENS160_SEQ_ACK_NOTCOMPLETE & (x)))
#define IS_ENS160_SEQ_ACK_COMPLETE(x) (ENS160_SEQ_ACK_COMPLETE == (ENS160_SEQ_ACK_COMPLETE & (x)))
#define ENS160_DATA_STATUS_NEWDAT 0x02
#define ENS160_DATA_STATUS_NEWGPR 0x01
#define IS_NEWDAT(x) (ENS160_DATA_STATUS_NEWDAT == (ENS160_DATA_STATUS_NEWDAT & (x)))
#define IS_NEWGPR(x) (ENS160_DATA_STATUS_NEWGPR == (ENS160_DATA_STATUS_NEWGPR & (x)))
#define IS_NEW_DATA_AVAILABLE(x) (0 != ((ENS160_DATA_STATUS_NEWDAT | ENS160_DATA_STATUS_NEWGPR ) & (x)))
#define CONVERT_RS_RAW2OHMS_I(x) (1 << ((x) >> 11))
#define CONVERT_RS_RAW2OHMS_F(x) (pow (2, (float)(x) / 2048))
static uint8_t ENS160_BL_MAGIC[4] = {0x53, 0xCE, 0x1A, 0xBF};
class ScioSense_ENS160 {
public:
ScioSense_ENS160(uint8_t slaveaddr = ENS160_I2CADDR_0); // Constructor using slave address (5A or 5B)
ScioSense_ENS160(uint8_t ADDR, uint8_t nCS, uint8_t nINT); // Constructor with pin definition
ScioSense_ENS160(uint8_t slaveaddr, uint8_t ADDR, uint8_t nCS, uint8_t nINT); // Constructor with slave address and pin definition
bool begin(bool debug=false, bool bootloader=false); // init i2c interface, get partID und uID. Returns false on I2C problems or wrong PART_ID.
bool available() { return this->_available; }
bool setMode(uint8_t mode);
bool initCustomMode(uint16_t stepNum);
bool addCustomStep(uint16_t time, bool measureHP0, bool measureHP1, bool measureHP2, bool measureHP3, uint16_t tempHP0, uint16_t tempHP1, uint16_t tempHP2, uint16_t tempHP3);
bool measure(bool waitForNew = true); // perfrom measurement and stores result in internal variables
bool set_envdata210(uint16_t t, uint16_t h); // Writes t and h (in ENS210 format) to ENV_DATA. Returns false on I2C problems.
uint8_t getMajorRev() {return this->_fw_ver_major; }
uint8_t getMinorRev() {return this->_fw_ver_minor; }
uint8_t getBuild() {return this->_fw_ver_build; }
uint8_t getAQI() {return this->_data_aqi; }
uint16_t getTVOC() {return this->_data_tvoc; }
uint16_t geteCO2() {return this->_data_eco2; }
uint32_t getHP0() {return this->_hp0_rs; }
uint32_t getHP1() {return this->_hp1_rs; }
uint32_t getHP2() {return this->_hp2_rs; }
uint32_t getHP3() {return this->_hp3_rs; }
uint32_t getHP0BL() {return this->_hp0_bl; }
uint32_t getHP1BL() {return this->_hp1_bl; }
uint32_t getHP2BL() {return this->_hp2_bl; }
uint32_t getHP3BL() {return this->_hp3_bl; }
uint8_t getMISR() {return this->_misr; }
// bool flash(const uint8_t * app_img, int size); // Flashes the firmware of the CCS811 with size bytes from image - image _must_ be in PROGMEM
private:
uint8_t _ADDR;
uint8_t _nINT;
uint8_t _nCS;
bool debugENS160 = false;
bool reset(void); // Sends a reset to the ENS160. Returns false on I2C problems.
bool checkPartID();
bool clearCommand(void);
bool getFirmware();
int blCMDWriteVerify(uint8_t command);
bool _available = false; // ENS160 available
uint8_t _fw_ver_major;
uint8_t _fw_ver_minor;
uint8_t _fw_ver_build;
uint16_t _stepCount; // Counter for custom sequence
uint8_t _data_aqi;
uint16_t _data_tvoc;
uint16_t _data_eco2;
uint32_t _hp0_rs;
uint32_t _hp0_bl;
uint32_t _hp1_rs;
uint32_t _hp1_bl;
uint32_t _hp2_rs;
uint32_t _hp2_bl;
uint32_t _hp3_rs;
uint32_t _hp3_bl;
uint16_t _temp;
int _slaveaddr; // Slave address of the ENS160
uint8_t _misr;
//Isotherm, HP0 252°C / HP1 350°C / HP2 250°C / HP3 324°C / measure every 1008ms
uint8_t _seq_steps[1][8] = {
{ 0x7C, 0x0A, 0x7E, 0xAF, 0xAF, 0xA2, 0x00, 0x80 },
};
/****************************************************************************/
/* General functions */
/****************************************************************************/
void _i2c_init();
uint8_t read8(uint8_t addr, byte reg);
uint8_t read(uint8_t addr, uint8_t reg, uint8_t *buf, uint8_t num);
uint8_t write8(uint8_t addr, byte reg, byte value);
uint8_t write(uint8_t addr, uint8_t reg, uint8_t *buf, uint8_t num);
};
#endif

View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2020 Sciosense
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@ -0,0 +1,41 @@
# ScioSense ENS210
Arduino library for the ENS210 temperature & humidity sensor with I2C interface from ScioSense
It is based on a library written by Maarten Pennings. Thanks for all the work.
https://github.com/maarten-pennings/ENS210
## Introduction
This project is an Arduino *library*. It implements a driver with examples for the ENS210. The ENS210 chip is a digital temperature & humidity sensor with an I2C interface.
The driver in this Arduino library is based on the code supplied by *Sciosense*, the manufacturer of the chip.
Note that the ENS210 requires a supply voltage of 1.71V .. 1.98V.
## Links
The ENS210 is made by [Sciosense](http://www.sciosense.com).
- The datasheet and further documents regading the ENS210 can be downloaded here
https://www.sciosense.com/products/relative-humidity-and-temperature-sensors/ens210-relative-humidity-and-temperature-sensor/
## Prerequisites
It is assumed that
- The Arduino IDE has been installed.
If not, refer to "Install the Arduino Desktop IDE" on the
[Arduino site](https://www.arduino.cc/en/Guide/HomePage).
- The library directory is at its default location.
For me, that is `C:\Users\sciosense\Documents\Arduino\libraries`.
## Installation
Installation steps
- Visit the project page for the Arduino CCS811 library.
- Click the green button Clone or download on the right side.
- From the pop-up choose Download ZIP.
- In Arduino IDE, select Sketch > Include Library > Manage Libraries ... and browse to the just downloaded ZIP file.
- When the IDE is ready this README.md should be located at e.g. `C:\Users\sciosense\Documents\Arduino\libraries\sciosense_ens210\README.md`.
## Build an example
To build an example sketch
- (Re)start Arduino.
- Open File > Example > Examples from Custom Libraries > ENS210 > ENS210basic.
- Make sure Tools > Board lists the correct board.
- Select Sketch > Verify/Compile.
### ScioSense is a Joint Venture of ams AG

View File

@ -0,0 +1,71 @@
/***************************************************************************
This is a example for ENS210 basic reading
Written by Christoph Friese for Sciosense / 8-April-2020
***************************************************************************/
#include <Wire.h>
#define ArduinoIDE true
int ArduinoLED = 13;
//-------------------------------------------------------------
//ENS210 related items
//-------------------------------------------------------------
#include "ScioSense_ENS210.h"
ScioSense_ENS210 ens210;
/*--------------------------------------------------------------------------
SETUP function
initiate sensor
--------------------------------------------------------------------------*/
void setup() {
bool ok;
//-------------------------------------------------------------
// General setup steps
//-------------------------------------------------------------
Serial.begin(9600);
while (!Serial) {}
//Switch on LED for init
pinMode(ArduinoLED, OUTPUT);
digitalWrite(ArduinoLED, LOW);
if (ArduinoIDE) {
Serial.println("ENS210 example");
delay(1000);
}
if (ArduinoIDE) Serial.print("ENS210...");
ok = ens210.begin();
if (ArduinoIDE) Serial.println(ens210.available() ? "done." : "failed!");
ens210.setSingleMode(false);
//blink LED
digitalWrite(ArduinoLED, HIGH);
delay(100);
digitalWrite(ArduinoLED, LOW);
}
/*--------------------------------------------------------------------------
MAIN LOOP FUNCTION
Cylce every 1000ms and perform action
--------------------------------------------------------------------------*/
void loop() {
if (ens210.available()) ens210.measure();
if (ArduinoIDE) {
Serial.print("Temperature: ");Serial.print(ens210.getTempCelsius());Serial.print("°C\t");
Serial.print("Humidity: "); Serial.print(ens210.getHumidityPercent());Serial.println("%");
} else {
Serial.print(ens210.getTempCelsius());Serial.print(",");
Serial.print(ens210.getHumidityPercent());Serial.println("");
}
delay(1000);
}

View File

@ -0,0 +1,47 @@
#######################################
# Syntax Coloring Map
#######################################
# https://spencer.bliven.us/index.php/2012/01/18/arduino-ide-keywords/
# KEYWORD1 Classes, datatypes, and C++ keywords
# KEYWORD2 Methods and functions
# KEYWORD3 setup and loop functions, as well as the Serial keywords
# LITERAL1 Constants
# LITERAL2 Built-in variables (unused by default)
#######################################
# Classes, datatypes (KEYWORD1)
#######################################
ENS210 KEYWORD1
ens210 KEYWORD1
#######################################
# Methods and Functions (KEYWORD2)
#######################################
begin KEYWORD2
setSingleMode KEYWORD2
available KEYWORD2
getPartID KEYWORD2
getHighUID KEYWORD2
measure KEYWORD2
getTempKelvin KEYWORD2
getTempCelsius KEYWORD2
getTempFahrenheit KEYWORD2
getHumidityPercent KEYWORD2
getAbsoluteHumidityPercent KEYWORD2
getStatusT KEYWORD2
getDataT KEYWORD2
getStatusH KEYWORD2
getDataH KEYWORD2
status_str KEYWORD2
correction_set KEYWORD2
correction_get KEYWORD2
######################################
# Constants (LITERAL1)
#######################################
ENS210_STATUS_I2CERROR LITERAL1
ENS210_STATUS_CRCERROR LITERAL1
ENS210_STATUS_INVALID LITERAL1
ENS210_STATUS_OK LITERAL1

View File

@ -0,0 +1,9 @@
name=ScioSense ENS210
version=3.0.0
author=Christoph Friese
maintainer=Christoph Friese
sentence=Arduino library for the ENS210 digital temperature & humidity sensor with I2C interface from ScioSense
paragraph=This library controls the ENS210. The main feature of this library is performing a single shot measurement, retrieving the measurement data.
category=Device Control
url=https://github.com/sciosense/ens210
architectures=*

View File

@ -0,0 +1,447 @@
/*
ScioSense_ENS210.h - Library for the ENS210 relative humidity and temperature sensor with I2C interface from ScioSense
2020 Apr 06 v3 Christoph Friese Changed nomenclature to ScioSense as product shifted from ams
2018 Aug 28 v2 Christoph Friese Adjusted I2C communication
2017 Aug 01 v1 Maarten Pennings Created
*/
#include "ScioSense_ENS210.h"
#include <assert.h>
// Compute the CRC-7 of 'val' (should only have 17 bits)
// https://en.wikipedia.org/wiki/Cyclic_redundancy_check#Computation
static uint32_t crc7( uint32_t val )
{
// Setup polynomial
uint32_t pol= CRC7POLY;
// Align polynomial with data
pol = pol << (DATA7WIDTH-CRC7WIDTH-1);
// Loop variable (indicates which bit to test, start with highest)
uint32_t bit = DATA7MSB;
// Make room for CRC value
val = val << CRC7WIDTH;
bit = bit << CRC7WIDTH;
pol = pol << CRC7WIDTH;
// Insert initial vector
val |= CRC7IVEC;
// Apply division until all bits done
while( bit & (DATA7MASK<<CRC7WIDTH) ) {
if( bit & val ) val ^= pol;
bit >>= 1;
pol >>= 1;
}
return val;
}
// Init I2C communication, resets ENS210 and checks its PART_ID. Returns false on I2C problems or wrong PART_ID.
// Stores solder correction.
bool ScioSense_ENS210::begin(bool debug)
{
bool result;
debugENS210 = debug;
//init I2C
_i2c_init();
if (debugENS210) {
Serial.println("ens210 debug - I2C init done");
}
// Record solder correction
this->_soldercorrection= 0;
this->_available = false;
this->_singleMode = true;
this->_t_data = -1;
this->_h_data = -1;
this->lowpower(false);
result = getversion();
if(this->_partID == ENS210_PARTID ) {
this->_available = true;
}
return result;
}
// Sends a reset to the ENS210. Returns false on I2C problems.
bool ScioSense_ENS210::reset(void)
{
uint8_t result = this->write8(_slaveaddress, ENS210_REG_SYS_CTRL, 0x80);
if (debugENS210) {
Serial.print("ens210 debug - reset: 0x");
Serial.println(result,HEX);
}
delay(ENS210_BOOTING); // Wait to boot after reset
return result==0;
}
// Sets ENS210 to low (true) or high (false) power. Returns false on I2C problems.
bool ScioSense_ENS210::lowpower(bool enable)
{
uint8_t power = enable ? 0x01: 0x00;
uint8_t result = this->write8(this->_slaveaddress, ENS210_REG_SYS_CTRL, power);
if (debugENS210) {
Serial.print("ens210 debug - lowpower: 0x");
Serial.println(result,HEX);
}
delay(ENS210_BOOTING); // Wait boot-time after power switch
return result==0;
}
// Reads PART_ID and UID of ENS210. Returns false on I2C problems.
bool ScioSense_ENS210::getversion()//(uint16_t partid, uint64_t uid)
{
bool ok;
uint8_t i2cbuf[8];
uint8_t result;
// Must disable low power to read PART_ID or UID
ok= lowpower(false); if(!ok) goto errorexit;
// Read the PART_ID
result = this->read(this->_slaveaddress, ENS210_REG_PART_ID, i2cbuf, 2);
if (debugENS210) {
Serial.print("ens210 debug - PART_ID I2C result: 0x");
Serial.println(result, HEX);
}
//this->_partID = (uint16_t)(i2cbuf[1]*256U + i2cbuf[0]*1U);
this->_partID = (uint16_t)(((uint16_t)i2cbuf[1] << 8) | ((uint16_t)i2cbuf[0]));
if (debugENS210) {
Serial.print("PART_ID: 0x");
Serial.println(this->_partID,HEX);
}
// Read the UID
result = this->read(_slaveaddress, ENS210_REG_UID,i2cbuf,8);
if (debugENS210) {
Serial.print("ens210 debug - UID 0x");
Serial.println(result,HEX);
}
this->_uID = (uint64_t)((uint64_t)i2cbuf[7]<<56 | (uint64_t)i2cbuf[6]<<48 | (uint64_t)i2cbuf[5]<<40 | (uint64_t)i2cbuf[4]<<32 | (uint64_t)i2cbuf[3]<<24 | (uint64_t)i2cbuf[2]<<16 | (uint64_t)i2cbuf[1]<<8 | (uint64_t)i2cbuf[0]);
//for( int i=0; i<8; i++) ((uint8_t*)this->_uID)[i]=i2cbuf[i]; //((uint8_t*)this->_uID)[i]=i2cbuf[i];
this->_uIDhi = (uint32_t)(this->_uID >> 32);
this->_uIDlo = (uint32_t)(this->_uID & 0xFFFFFFFF);
if (debugENS210) {
Serial.print("UID hi 0x");
Serial.print(this->_uIDhi,HEX);
Serial.print(" - 0x");
Serial.println(this->_uIDlo,HEX);
}
// Go back to default power mode (low power enabled)
ok= lowpower(true); if(!ok) goto errorexit;
// Success
return true;
errorexit:
// Try to go back to default mode (low power enabled)
ok= lowpower(true);
// Hopefully enabling low power was successful; but there was an error before that anyhow
return false;
}
// Configures ENS210 measurement mode
// false for continuous mode / true for single shot measurement. Returns false on I2C problems.
bool ScioSense_ENS210::setSingleMode(bool enable)
{
this->_singleMode = enable;
uint8_t mode = enable ? 0x00: 0x03;
uint8_t result = this->write8(_slaveaddress, ENS210_REG_SENS_RUN, mode);
if (debugENS210) {
Serial.print("ens210 debug - start mode 0x");
Serial.print(mode,HEX);
Serial.print(" - result 0x");
Serial.println(result,HEX);
}
return result==0;
}
// Performs one single shot temperature and relative humidity measurement.
void ScioSense_ENS210::measure() //int * t_data, int * t_status, int * h_data, int * h_status )
{
bool ok;
// Set default status for early bail out
if (debugENS210) Serial.println("Start measurement");
this->_t_status = ENS210_STATUS_I2CERROR;
this->_h_status = ENS210_STATUS_I2CERROR;
// Start a single shot measurement
if (this->_singleMode)
{
uint8_t result = this->write8(_slaveaddress, ENS210_REG_SENS_RUN, 0x00);
if (debugENS210) {
Serial.print("ens210 debug - start single 0x");
Serial.println(result,HEX);
}
}
//Trigger measurement
uint8_t result = this->write8(_slaveaddress, ENS210_REG_SENS_START, 0x03);
if (debugENS210) {
Serial.print("ens210 debug - trigger measurement 0x");
Serial.println(result,HEX);
}
// Wait for measurement to complete
if (this->_singleMode) delay(ENS210_THCONV_SINGLE_MS);
else delay(ENS210_THCONV_CONT_MS);
// Get the measurement data
if (debugENS210) Serial.println("Start measurement");
ok = readValue(); if(!ok) return;
if (debugENS210) Serial.println("Measurement ok");
}
// Reads measurement data from the ENS210. Returns false on I2C problems.
bool ScioSense_ENS210::readValue() //uint32_t *t_val, uint32_t *h_val)
{
uint8_t i2cbuf[6];
uint8_t valid;
uint32_t crc;
uint32_t payload;
uint8_t crc_ok;
// Read T_VAL and H_VAL
uint8_t result = this->read(_slaveaddress, ENS210_REG_T_VAL, i2cbuf, 6);
if (debugENS210) {
Serial.print("ens210 debug - readValue:");
Serial.println(result);
Serial.print(i2cbuf[0],HEX); Serial.print("\t");
Serial.print(i2cbuf[1],HEX); Serial.print("\t");
Serial.print(i2cbuf[2],HEX); Serial.print("\t");
Serial.print(i2cbuf[3],HEX); Serial.print("\t");
Serial.print(i2cbuf[4],HEX); Serial.print("\t");
Serial.print(i2cbuf[5],HEX); Serial.println("\t");
}
// Retrieve and pack bytes into t_val and h_val
uint32_t t_val= (uint32_t)((uint32_t)i2cbuf[2]<<16 | (uint32_t)i2cbuf[1]<<8 | (uint32_t)i2cbuf[0]);
this->_t_data = (t_val>>0) & 0xffff;
valid = (t_val>>16) & 0x1;
crc = (t_val>>17) & 0x7f;
payload = (t_val>>0 ) & 0x1ffff;
crc_ok = crc7(payload)==crc;
if( !crc_ok ) this->_t_status = ENS210_STATUS_CRCERROR;
else if( !valid ) this->_t_status = ENS210_STATUS_INVALID;
else this->_t_status = ENS210_STATUS_OK;
if (debugENS210) {
Serial.print("_t_data 0x");
Serial.print(t_val,HEX);
Serial.print(" - 0x");
Serial.println(this->_t_data,HEX);
Serial.print("Valid: ");
Serial.print(valid);
Serial.print(" Status: ");
Serial.println(this->_t_status);
}
uint32_t h_val= (uint32_t)((uint32_t)i2cbuf[5]<<16 | (uint32_t)i2cbuf[4]<<8 | (uint32_t)i2cbuf[3]);
this->_h_data = (h_val>>0) & 0xffff;
valid = (h_val>>16) & 0x1;
crc = (h_val>>17) & 0x7f;
payload = (h_val>>0 ) & 0x1ffff;
crc_ok= crc7(payload)==crc;
if( !crc_ok ) this->_h_status= ENS210_STATUS_CRCERROR;
else if( !valid ) this->_h_status= ENS210_STATUS_INVALID;
else this->_h_status= ENS210_STATUS_OK;
if (debugENS210) {
Serial.print("_h_data 0x");
Serial.print(h_val,HEX);
Serial.print(" - 0x");
Serial.println(this->_h_data,HEX);
Serial.print("Valid: ");
Serial.print(valid);
Serial.print(" Status: ");
Serial.println(this->_h_status);
}
// Success
return true;
}
// Converts a status (ENS210_STATUS_XXX) to a human readable string.
const char * ScioSense_ENS210::status_str( int status )
{
switch( status ) {
case ENS210_STATUS_I2CERROR : return "i2c-error";
case ENS210_STATUS_CRCERROR : return "crc-error";
case ENS210_STATUS_INVALID : return "data-invalid";
case ENS210_STATUS_OK : return "ok";
default : return "unknown-status";
}
}
// Convert raw `t_data` temperature to Kelvin (also applies the solder correction).
// The output value is in Kelvin multiplied by parameter `multiplier`.
float ScioSense_ENS210::getTempKelvin()
{
// Force 32 bits
float t = this->_t_data & 0xFFFF;
// Compensate for soldering effect
t-= _soldercorrection;
// Return m*K. This equals m*(t/64) = (m*t)/64
// Note m is the multiplier, K is temperature in Kelvin, t is raw t_data value.
// Uses K=t/64.
return t/64; //IDIV(t,64);
}
// Convert raw `t_data` temperature to Celsius (also applies the solder correction).
// The output value is in Celsius multiplied by parameter `multiplier`.
float ScioSense_ENS210::getTempCelsius()
{
//assert( (1<=multiplier) && (multiplier<=1024) );
// Force 32 bits
float t= this->_t_data & 0xFFFF;
// Compensate for soldering effect
t-= _soldercorrection;
// Return m*C. This equals m*(K-273.15) = m*K - 27315*m/100 = m*t/64 - 27315*m/100
// Note m is the multiplier, C is temperature in Celsius, K is temperature in Kelvin, t is raw t_data value.
// Uses C=K-273.15 and K=t/64.
return t/64 - 27315L/100; //IDIV(t,64) - IDIV(27315L,100);
}
// Convert raw `t_data` temperature to Fahrenheit (also applies the solder correction).
float ScioSense_ENS210::getTempFahrenheit()
{
float t= this->_t_data & 0xFFFF;
// Compensate for soldering effect
t-= _soldercorrection;
// Return m*F. This equals m*(1.8*(K-273.15)+32) = m*(1.8*K-273.15*1.8+32) = 1.8*m*K-459.67*m = 9*m*K/5 - 45967*m/100 = 9*m*t/320 - 45967*m/100
// Note m is the multiplier, F is temperature in Fahrenheit, K is temperature in Kelvin, t is raw t_data value.
// Uses F=1.8*(K-273.15)+32 and K=t/64.
return 9*t/320 - 45967/100; //IDIV(9*t,320) - IDIV(45967L,100);
// The first multiplication stays below 32 bits (t:16, multiplier:11, 9:4)
// The second multiplication stays below 32 bits (multiplier:10, 45967:16)
}
// Convert raw `h_data` relative humidity to %RH.
float ScioSense_ENS210::getHumidityPercent()
{
float h= this->_h_data & 0xFFFF;
// Return m*H. This equals m*(h/512) = (m*h)/512
// Note m is the multiplier, H is the relative humidity in %RH, h is raw h_data value.
// Uses H=h/512.
return h/512; //IDIV(h, 512);
}
// Convert raw `h_data` absolute humidity to %RH.
#define MOLAR_MASS_OF_WATER 18.01534
#define UNIVERSAL_GAS_CONSTANT 8.21447215
float ScioSense_ENS210::getAbsoluteHumidityPercent()
{
//taken from https://carnotcycle.wordpress.com/2012/08/04/how-to-convert-relative-humidity-to-absolute-humidity/
//precision is about 0.1°C in range -30 to 35°C
//August-Roche-Magnus 6.1094 exp(17.625 x T)/(T + 243.04)
//Buck (1981) 6.1121 exp(17.502 x T)/(T + 240.97)
//reference https://www.eas.ualberta.ca/jdwilson/EAS372_13/Vomel_CIRES_satvpformulae.html // Use Buck (1981)
return (6.1121 * pow(2.718281828,(17.67* this->getTempCelsius())/(this->getTempCelsius() + 243.5))* this->getHumidityPercent() *MOLAR_MASS_OF_WATER)/((273.15+ this->getTempCelsius() )*UNIVERSAL_GAS_CONSTANT);
}
// Sets the solder correction (default is 50mK) - only used by the `toXxx` functions.
void ScioSense_ENS210::correction_set(int correction)
{
assert( -1*64<correction && correction<+1*64 ); // A correction of more than 1 Kelvin does not make sense (but the 1K is arbitrary)
this->_soldercorrection = correction;
}
/****************************************************************************/
/* General functions */
/****************************************************************************/
void ScioSense_ENS210::_i2c_init()
{
Wire.begin();
}
/**************************************************************************/
uint8_t ScioSense_ENS210::read8(uint8_t addr, byte reg)
{
uint8_t ret;
this->read(addr, reg, &ret, 1);
return ret;
}
uint8_t ScioSense_ENS210::read(uint8_t addr, uint8_t reg, uint8_t *buf, uint8_t num)
{
uint8_t pos = 0;
uint8_t result = 0;
if (debugENS210) {
Serial.print("I2C read address: 0x");
Serial.print(addr, HEX);
Serial.print(" - register: 0x");
Serial.println(reg, HEX);
}
//on arduino we need to read in 32 byte chunks
while(pos < num){
uint8_t read_now = 32;//min((uint8_t)32, (uint8_t)(num - pos));
Wire.beginTransmission((uint8_t)addr);
Wire.write((uint8_t)reg + pos);
result = Wire.endTransmission();
Wire.requestFrom((uint8_t)addr, read_now);
//for(int i=0; i<read_now; i++){
for(int i=0; i<num; i++){
buf[pos] = Wire.read();
if (debugENS210) {
Serial.print("Pos: ");
Serial.print(pos);
Serial.print(" - Value: 0x");
Serial.println(buf[pos], HEX);
}
pos++;
}
}
return result;
}
/**************************************************************************/
uint8_t ScioSense_ENS210::write8(uint8_t addr, byte reg, byte value)
{
uint8_t result = this->write(addr, reg, &value, 1);
return result;
}
uint8_t ScioSense_ENS210::write(uint8_t addr, uint8_t reg, uint8_t *buf, uint8_t num)
{
if (debugENS210) {
Serial.print("I2C write address: 0x");
Serial.print(addr, HEX);
Serial.print(" - register: 0x");
Serial.print(reg, HEX);
Serial.print(" - value: 0x");
for (int i = 0; i<num; i++) {
Serial.print(" 0x");
Serial.print(buf[i], HEX);
}
Serial.println();
}
Wire.beginTransmission((uint8_t)addr);
Wire.write((uint8_t)reg);
Wire.write((uint8_t *)buf, num);
uint8_t result = Wire.endTransmission();
return result;
}

View File

@ -0,0 +1,121 @@
/*
ScioSense_ENS210.h - Library for the ENS210 relative humidity and temperature sensor with I2C interface from ScioSense
2020 Apr 06 v3 Chrsitoph Friese Changed nomenclature to ScioSense as product shifted from ams
2018 Aug 28 v2 Christoph Friese Adjusted I2C communication
2017 Aug 01 v1 Maarten Pennings Created
*/
#ifndef __SCIOSENSE_ENS210_H_
#define __SCIOSENSE_ENS210_H_
#if (ARDUINO >= 100)
#include "Arduino.h"
#else
#include "WProgram.h"
#endif
#include <Wire.h>
// Chip constants
#define ENS210_PARTID 0x0210 // The expected part id of the ENS210
#define ENS210_BOOTING 2 // Booting time in ms (also after reset, or going to high power)
#define ENS210_THCONV_SINGLE_MS 130 // Conversion time in ms for single shot T/H measurement
#define ENS210_THCONV_CONT_MS 238 // Conversion time in ms for continuous T/H measurement
// Addresses of the ENS210 registers
#define ENS210_REG_PART_ID 0x00
#define ENS210_REG_UID 0x04
#define ENS210_REG_SYS_CTRL 0x10
#define ENS210_REG_SYS_STAT 0x11
#define ENS210_REG_SENS_RUN 0x21
#define ENS210_REG_SENS_START 0x22
#define ENS210_REG_SENS_STOP 0x23
#define ENS210_REG_SENS_STAT 0x24
#define ENS210_REG_T_VAL 0x30
#define ENS210_REG_H_VAL 0x33
// Division macro (used in conversion functions), implementing integer division with rounding.
// It supports both positive and negative dividends (n), but ONLY positive divisors (d).
//#define IDIV(n,d) ((n)>0 ? ((n)+(d)/2)/(d) : ((n)-(d)/2)/(d))
// 7654 3210
// Polynomial 0b 1000 1001 ~ x^7+x^3+x^0
// 0x 8 9
#define CRC7WIDTH 7 // A 7 bits CRC has polynomial of 7th order, which has 8 terms
#define CRC7POLY 0x89 // The 8 coefficients of the polynomial
#define CRC7IVEC 0x7F // Initial vector has all 7 bits high
// Payload data
#define DATA7WIDTH 17
#define DATA7MASK ((1UL<<DATA7WIDTH)-1) // 0b 0 1111 1111 1111 1111
#define DATA7MSB (1UL<<(DATA7WIDTH-1)) // 0b 1 0000 0000 0000 0000
// Measurement status as output by `measure()` and `extract()`.
// Note that the ENS210 provides a "value" (`t_val` or `h_val` each 24 bit).
// A "value" consists of a payload (17 bit) and a CRC (7 bit) over that payload.
// The payload consists of a valid flag (1 bit) and the actual measurement "data" (`t_data` or `h_data`, 16 bit)
#define ENS210_STATUS_I2CERROR 4 // There was an I2C communication error, `read`ing the value.
#define ENS210_STATUS_CRCERROR 3 // The value was read, but the CRC over the payload (valid and data) does not match.
#define ENS210_STATUS_INVALID 2 // The value was read, the CRC matches, but the data is invalid (e.g. the measurement was not yet finished).
#define ENS210_STATUS_OK 1 // The value was read, the CRC matches, and data is valid.
class ScioSense_ENS210 {
public:
bool begin(bool debug=false); // init i2c interface, get partID und uID. Returns false on I2C problems or wrong PART_ID.
bool setSingleMode(bool enable); // false for continuous mode / true for single shot measurement. Returns false on I2C problems.
bool available() { return this->_available; }
uint16_t getPartID() { return this->_partID; }
uint32_t getHighUID(bool high) { uint32_t result = high ? this->_uIDhi : this->_uIDlo; return result; }
void measure(); // perfrom measurement and stores result in internal variables
float getTempKelvin (); // Converts and returns data (from `measure`) in Kelvin
float getTempCelsius (); // Converts and returns data (from `measure`) in Celsius
float getTempFahrenheit (); // Converts and returns data (from `measure`) in Fahrenheit
float getHumidityPercent(); // Converts and returns data (from `measure`) in %RH
float getAbsoluteHumidityPercent(); // Converts and returns data (from `measure`) in %aH
char getStatusT() { return this->_t_status; } // Converts a status (ENS210_STATUS_XXX) to a human readable string.
uint32_t getDataT() { return this->_t_data; }
char getStatusH() { return this->_h_status; } // Converts a status (ENS210_STATUS_XXX) to a human readable string.
uint32_t getDataH() { return this->_h_data; }
static const char * status_str( int status ); // Converts a status (ENS210_STATUS_XXX) to a human readable string.
// Optionally set a solder `correction` (units: 1/64K, default from `begin` is 0).
// See "Effect of Soldering on Temperature Readout" in "Design-Guidelines" from
// https://download.ams.com/ENVIRONMENTAL-SENSORS/ENS210/Documentation
void correction_set(int correction=50*64/1000); // Sets the solder correction (default is 50mK) - only used by the `toXxx()` functions.
int correction_get() {return this->_soldercorrection;} // Gets the solder correction.
private:
bool debugENS210 = false;
bool reset(void); // Sends a reset to the ENS210. Returns false on I2C problems.
bool lowpower(bool enable); // Sets ENS210 to low (true) or high (false) power. Returns false on I2C problems.
bool getversion(); // Reads PART_ID and UID of ENS210. Returns false on I2C problems.
bool readValue(); // Reads measurement data from the ENS210. Returns false on I2C problems.
bool _available = false; // ENS210 available
uint16_t _partID; // Part ID of ENS210, should be 0x210
uint64_t _uID; // Unique ID of this specific ENS210
uint32_t _uIDhi; // First 32bit of unique ID of this specific ENS210
uint32_t _uIDlo; // Second 32bit of unique ID of this specific ENS210
bool _singleMode = true; // Measurement mode: true single shot / false continuous
uint32_t _t_data;
uint8_t _t_status;
uint32_t _h_data;
uint8_t _h_status;
uint8_t _slaveaddress = 0x43; // Slave address of ENS210
uint8_t _soldercorrection; // Correction due to soldering (in 1/64K); subtracted from `t_data` by conversion functions.
/****************************************************************************/
/* General functions */
/****************************************************************************/
uint8_t write8(uint8_t addr, byte reg, byte value);
uint8_t read8(uint8_t addr, byte reg);
uint8_t read(uint8_t addr, uint8_t reg, uint8_t *buf, uint8_t num);
uint8_t write(uint8_t addr, uint8_t reg, uint8_t *buf, uint8_t num);
void _i2c_init();
};
#endif