Electronics
Input Device
For my final project the critical component I would need for Spiral 1 is a current sensor. Why? My project will involve the usage of Fuel Cells to convert Hydrogen into a power supply for energy consumption. So I decided to do a little bit of research about current sensor.
Current sensor as the name suggests - measure electric current. There are different ways to measure current and there are different types of current sensors catered to read AC or DC. As such there is a wide variety of current sensing modules out there. This is a summary of the different sensors based on my research
Type | Current Transformer | Shunt | Hall Effect | Rogowski Coil |
---|---|---|---|---|
Current | AC | AC & DC | AC & DC | AC |
How does it work? | Converts high current to a lower current by dividing it. The stepped-down/ divided output is sent to ammeters and other instruments for monitoring purposes, as well as to relays and other systems for protection applications in power systems. | Detect voltage drop across a precisely calibrated shunt resistor. A shunt resistor is designed with low-resistance resistor to measure electrical current by generating a small, proportional voltage drop. This ensures that the impact on the original circuit is minimal, and the measurement is accurate. | Generation of a voltage difference when a current-carrying conductor is placed in a magnetic field. These sensors operate without physical contact, making them ideal where galvanic isolation between the current source and their output is crucial. | Rogowski coil measures the rate of change of the magnetic field around a conductor to determine the alternating current. They do not apply to DC applications. |
Accuracy | High | High | Medium | Low |
Range | High | Low because it requires direct contact | Medium | Medium |
Isolation | Yes | No | Yes | Yes |
Cost | Moderate to High | Low to Moderate | Moderate | Moderate |
Application | Metering & Billing, Energy Management Systems, etc | Ammeters, Battery Management systems, Power supplies etc | General-purpose current sensing | High-frequency AC current measurement, power quality analysis. |
Sources:
- What are the major types of Current Sensors
- Which current sensor is right for your project?
- 7 Current Sensors tested
Based on the research I think for my first spiral - the most appropriate would be the Shunt sensor. Fuel Cells operate in DC and I would like to an accurate reading as the Fuel Cell supplies power to be used - converted from the Hydrogen Gas.
Current Sensor INA219
The INA219 is a current shunt and power monitor with an I2C- or SMBUS-compatible interface. It monitors:
- Shunt voltage drop (voltage drop measured across a low-resistance shunt resistor, used to calculate the current flowing through a circuit.)
- Bus supply voltage (electrical potential difference between the conductors or “buses” in an electrical power distribution system, serving as a common voltage level for multiple circuits and components to connect and operate.)
- Direct readouts of current in amperes.
- An additional multiplying register calculates power in watts.
Because it comes in I2C interface(SDA/SCL) straightforward to connect and communicate with microcontrollers. It can handle high side current measuring, up to +26VDC, even though it is powered with 3 or 5V and enables bi-directional current measurements of up to 3.2Amp.
Here is the data sheet
In general this is how the sensor works
Programming
Original Code from here Appropriated for ILI9341 and Xiao ESP32S3 Display
For this program - we will be measuring an LED Diode with a power supply from Elaine-duino. This is the system diagram. As you can see for Vin+ and Vin-, there should be a closed connection for us to fully measure the voltage, current, and power of the load. In the case with this LED Diode, 3V from the Elaine-duino is supplying power to the LED Diode and it closes with Ground Pin.
The complete system diagram with the ILI9341 display looks like this.
#include <Wire.h>
#include <Adafruit_INA219.h>
#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Adafruit_ILI9341.h>
Adafruit_INA219 ina219;
// Define pins for the ILI9341 display
#define TFT_RST A0
#define TFT_DC A1
#define TFT_CS D7 // SS
#define TFT_MOSI D10 // MOSI
#define TFT_MISO D9
#define TFT_CLK D8 // SCK
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_RST);
float current_mA = 0;
float loadvoltage = 0;
float power_mW = 0;
void setup(void) {
Serial.begin(115200);
while (!Serial) {
// will pause Zero, Leonardo, etc until serial console opens
delay(1);
}
uint32_t currentFrequency;
if (!ina219.begin()) {
Serial.println("Failed to find INA219 chip");
while (1) {
delay(10);
}
}
tft.begin();
tft.setRotation(3); // Adjust based on your display orientation
tft.fillScreen(ILI9341_BLACK);
Serial.println("Measuring voltage and current with INA219 ...");
}
void loop(void) {
float shuntvoltage = 0;
float busvoltage = 0;
current_mA = 0;
loadvoltage = 0;
power_mW = 0;
shuntvoltage = ina219.getShuntVoltage_mV();
busvoltage = ina219.getBusVoltage_V();
current_mA = ina219.getCurrent_mA();
power_mW = ina219.getPower_mW();
loadvoltage = busvoltage + (shuntvoltage / 1000);
Serial.print("Load Voltage: "); Serial.print(loadvoltage); Serial.println(" V");
Serial.print("Current: "); Serial.print(current_mA); Serial.println(" mA");
Serial.print("Power: "); Serial.print(power_mW); Serial.println(" mW");
Serial.println("");
tft.fillScreen(ILI9341_BLACK);
voltCurrent();
delay(2000);
tft.fillScreen(ILI9341_BLACK);
powerr();
delay(2000);
}
void voltCurrent() {
tft.setTextSize(2); // Draw 2X-scale text
tft.setTextColor(ILI9341_WHITE);
tft.setCursor(0, 0); // Start at top-left corner
tft.print(loadvoltage);
tft.print("V");
tft.setCursor(0, 40); // Adjust cursor position based on text size
tft.print(current_mA);
tft.print("mA");
}
void powerr() {
tft.setTextSize(2); // Draw 2X-scale text
tft.setTextColor(ILI9341_WHITE);
tft.setCursor(0, 60); // Adjust cursor position based on text size
tft.print(power_mW);
tft.print("mW");
}
Takeaways
- As we can see the voltage reading is consistent at around ~3.24V
- The current reading comes out in a negative value of -34.20 mA. This actually signifies the current direction. A positive value indicates current flowing from the INA219’s Vin+ to Vin-, while a negative value indicates the opposite - current flowing from Vin- to Vin+. However since we have a load in between Vin+ and Vin- (LED), the current will have a negative sign as it flows from the power source (Vin+) to the load (Vin-).
- The Blue LED Diode consumes 112 mW of Power.
Output Device
My final project requires to use Display as an output - I explored 3 displays which were
- OLED LCD Display SSD1306, an I2C Display
- TFT ILI9225, SPI Display
- TFT ILI9341, SPI Display
128x64 OLED Display SSD1306
OLED Display is made of self-illuminating pixels that emit light when current is passes through. It has no backlight and has superior contrast ratios and true blacks (pixels can completely turn off).
This particular inexpensive OLED Display is easily available and easy to use for starters. It has many Arduino library support. Moreover, it requires less pins to be used compared to other displays due to I2C connection (SDA/SCL). It is compatible with many display libraries - but the most widely used one is the Adafruit GFX Library, the ‘core’ class that all other graphics libraries derive from.
I used the standardised Wokwi animation programming to test out this SSD1306 display is working.
As you can see this code displays a simple eye animation. To get your image displayed you need to convert it intp Bitmap.Use image2cpp tool to convert any images to Bitmap. For more information how to use image2cpp, check out this tutorial
When you convert your image to bitmap code - the image data is stored in a PROGMEM
array. PROGMEM is a keyword used to store data in the microcontroller’s program memory (flash memory) instead of RAM.
This is because image data, especially for animations, can can quickly fill up the limited RAM space in MCUs. By storing the bitmap code in PROGMEM you keep your RAM available for more function while still having access to the image data.
The animation data can be understood through
FRAME_DELAY
: This variable defines the delay between animation frames in milliseconds (42ms).FRAME_WIDTH
,FRAME_HEIGHT:
: This variable defines the width and height of each animation frame (64p x 64p)FRAME_COUNT
: This variable defines the total number of frames in the animation (calculated from the size of the frames array).
Testing out with Elaine’s Devlopment Board (using Xiao ESP32S3) - System Diagram
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
// Define OLED
#define SCREEN_I2C_ADDR 0x3C // or 0x3C
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
#define OLED_RST_PIN -1 // Reset pin (-1 if not available)
Adafruit_SSD1306 display(128, 64, &Wire, OLED_RST_PIN);
// OLED Animation: eye
// Code auto-generated by https://wokwi.com/animator, graphics by icons8.com
#define FRAME_DELAY (42)
#define FRAME_WIDTH (64)
#define FRAME_HEIGHT (64)
#define FRAME_COUNT (sizeof(frames) / sizeof(frames[0]))
const byte PROGMEM frames[][512] = {
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,31,248,0,0,0,0,0,1,255,255,128,0,0,0,0,15,255,255,240,0,0,0,0,63,248,31,252,0,0,0,0,255,0,0,255,0,0,0,3,252,0,0,63,192,0,0,7,248,0,0,31,224,0,0,31,184,7,224,29,248,0,0,62,112,15,240,14,124,0,0,124,112,31,248,14,62,0,1,240,96,63,252,6,15,128,3,224,96,63,252,6,7,192,7,192,96,63,252,6,3,224,15,0,96,63,252,6,0,240,30,0,96,63,252,6,0,120,60,0,96,63,252,6,0,60,120,0,112,31,248,14,0,30,120,0,112,31,248,14,0,30,60,0,48,7,224,12,0,60,30,0,56,0,0,28,0,120,15,0,28,0,0,56,0,240,7,128,28,0,0,56,1,224,3,192,14,0,0,112,3,192,0,240,7,0,0,224,15,0,0,120,3,192,3,192,30,0,0,62,1,248,31,128,124,0,0,15,0,255,255,0,240,0,0,7,192,63,252,3,224,0,0,1,240,0,0,15,128,0,0,0,126,0,0,126,0,0,0,0,31,192,3,248,0,0,0,0,7,255,255,224,0,0,0,0,0,255,255,0,0,0,0,0,0,7,224,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,31,248,0,0,0,0,0,1,255,255,128,0,0,0,0,15,255,255,240,0,0,0,0,63,248,31,252,0,0,0,0,255,0,0,255,0,0,0,3,252,0,0,63,192,0,0,7,248,0,0,31,224,0,0,31,184,7,224,29,248,0,0,62,112,15,240,14,124,0,0,124,112,31,248,14,62,0,1,240,96,63,252,6,15,128,3,224,96,63,252,6,7,192,7,192,96,63,252,6,3,224,15,0,96,63,252,6,0,240,30,0,96,63,252,6,0,120,60,0,96,63,252,6,0,60,120,0,112,31,248,14,0,30,120,0,112,31,248,14,0,30,60,0,48,7,224,12,0,60,30,0,56,0,0,28,0,120,15,0,28,0,0,56,0,240,7,128,28,0,0,56,1,224,3,192,14,0,0,112,3,192,0,240,7,0,0,224,15,0,0,120,3,192,3,192,30,0,0,62,1,248,31,128,124,0,0,15,0,255,255,0,240,0,0,7,192,63,252,3,224,0,0,1,240,0,0,15,128,0,0,0,126,0,0,126,0,0,0,0,31,192,3,248,0,0,0,0,7,255,255,224,0,0,0,0,0,255,255,0,0,0,0,0,0,7,224,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,31,248,0,0,0,0,0,1,255,255,128,0,0,0,0,15,255,255,240,0,0,0,0,63,248,31,252,0,0,0,0,255,0,0,255,0,0,0,3,252,0,0,63,192,0,0,7,248,0,0,31,224,0,0,31,184,7,224,29,248,0,0,62,112,15,240,14,124,0,0,124,112,31,248,14,62,0,1,240,96,63,252,6,15,128,3,224,96,63,252,6,7,192,7,192,96,63,252,6,3,224,15,0,96,63,252,6,0,240,30,0,96,63,252,6,0,120,60,0,96,63,252,6,0,60,120,0,112,31,248,14,0,30,120,0,112,31,248,14,0,30,60,0,48,7,224,12,0,60,30,0,56,0,0,28,0,120,15,0,28,0,0,56,0,240,7,128,28,0,0,56,1,224,3,192,14,0,0,112,3,192,0,240,7,0,0,224,15,0,0,120,3,192,3,192,30,0,0,62,1,248,31,128,124,0,0,15,0,255,255,0,240,0,0,7,192,63,252,3,224,0,0,1,240,0,0,15,128,0,0,0,126,0,0,126,0,0,0,0,31,192,3,248,0,0,0,0,7,255,255,224,0,0,0,0,0,255,255,0,0,0,0,0,0,7,224,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,31,248,0,0,0,0,0,1,255,255,128,0,0,0,0,15,255,255,240,0,0,0,0,63,248,31,252,0,0,0,0,255,0,0,255,0,0,0,3,252,0,0,63,192,0,0,7,248,0,0,31,224,0,0,31,184,7,224,29,248,0,0,62,112,15,240,14,124,0,0,124,112,31,248,14,62,0,1,240,96,63,252,6,15,128,3,224,96,63,252,6,7,192,7,192,96,63,252,6,3,224,15,0,96,63,252,6,0,240,30,0,96,63,252,6,0,120,60,0,96,63,252,6,0,60,120,0,112,31,248,14,0,30,120,0,112,31,248,14,0,30,60,0,48,7,224,12,0,60,30,0,56,0,0,28,0,120,15,0,28,0,0,56,0,240,7,128,28,0,0,56,1,224,3,192,14,0,0,112,3,192,0,240,7,0,0,224,15,0,0,120,3,192,3,192,30,0,0,62,1,248,31,128,124,0,0,15,0,255,255,0,240,0,0,7,192,63,252,3,224,0,0,1,240,0,0,15,128,0,0,0,126,0,0,126,0,0,0,0,31,192,3,248,0,0,0,0,7,255,255,224,0,0,0,0,0,255,255,0,0,0,0,0,0,7,224,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,31,248,0,0,0,0,0,1,255,255,128,0,0,0,0,15,255,255,240,0,0,0,0,63,255,255,252,0,0,0,0,255,255,255,255,0,0,0,3,255,252,63,255,192,0,0,7,254,0,0,127,224,0,0,31,248,7,224,31,248,0,0,63,240,15,240,15,252,0,0,127,112,31,248,14,254,0,1,252,96,63,252,6,63,128,3,240,96,63,252,6,15,192,7,192,96,63,252,6,7,224,15,128,96,63,252,6,1,240,30,0,96,63,252,6,0,248,60,0,96,63,252,6,0,60,120,0,112,31,248,14,0,30,120,0,112,31,248,14,0,30,60,0,48,7,224,12,0,60,30,0,56,0,0,28,0,120,15,0,28,0,0,56,0,240,7,128,28,0,0,56,1,224,3,192,14,0,0,112,3,192,0,240,7,0,0,224,15,0,0,120,3,192,3,192,30,0,0,62,1,248,31,128,124,0,0,15,0,255,255,0,240,0,0,7,192,63,252,3,224,0,0,1,240,0,0,15,128,0,0,0,126,0,0,126,0,0,0,0,31,192,3,248,0,0,0,0,7,255,255,224,0,0,0,0,0,255,255,0,0,0,0,0,0,7,224,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,31,248,0,0,0,0,0,1,255,255,128,0,0,0,0,15,255,255,240,0,0,0,0,63,248,31,252,0,0,0,0,255,0,0,255,0,0,0,3,248,0,0,31,192,0,0,7,224,0,0,7,224,0,0,31,128,0,0,1,248,0,0,62,0,0,0,0,124,0,0,124,3,255,255,192,62,0,1,240,255,255,255,255,15,128,3,231,255,255,255,255,231,192,7,255,240,63,252,15,255,224,15,254,96,63,252,6,127,240,31,240,96,63,252,6,15,248,63,128,96,63,252,6,1,252,124,0,112,31,248,14,0,62,120,0,112,31,248,14,0,30,60,0,48,7,224,12,0,60,30,0,56,0,0,28,0,120,15,0,28,0,0,56,0,240,7,128,28,0,0,56,1,224,3,192,14,0,0,112,3,192,0,240,7,0,0,224,15,0,0,120,3,192,3,192,30,0,0,62,1,248,31,128,124,0,0,15,0,255,255,0,240,0,0,7,192,63,252,3,224,0,0,1,240,0,0,15,128,0,0,0,126,0,0,126,0,0,0,0,31,192,3,248,0,0,0,0,7,255,255,224,0,0,0,0,0,255,255,0,0,0,0,0,0,7,224,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,31,248,0,0,0,0,0,1,255,255,128,0,0,0,0,15,255,255,240,0,0,0,0,63,248,31,252,0,0,0,0,255,0,0,255,0,0,0,3,248,0,0,31,192,0,0,7,224,0,0,7,224,0,0,31,128,0,0,1,248,0,0,62,0,0,0,0,124,0,0,124,0,0,0,0,62,0,1,240,0,0,0,0,15,128,3,224,0,0,0,0,7,192,7,128,0,0,0,0,1,224,15,0,0,0,0,0,0,240,30,0,0,0,0,0,0,120,60,0,0,0,0,0,0,60,127,255,255,255,255,255,255,254,127,255,255,255,255,255,255,254,60,0,120,15,240,30,0,60,30,0,56,0,0,28,0,120,15,0,28,0,0,56,0,240,7,128,28,0,0,56,1,224,3,192,14,0,0,112,3,192,0,240,7,0,0,224,15,0,0,120,3,192,3,192,30,0,0,62,1,248,31,128,124,0,0,15,0,255,255,0,240,0,0,7,192,63,252,3,224,0,0,1,240,0,0,15,128,0,0,0,126,0,0,126,0,0,0,0,31,192,3,248,0,0,0,0,7,255,255,224,0,0,0,0,0,255,255,0,0,0,0,0,0,7,224,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,31,248,0,0,0,0,0,1,255,255,128,0,0,0,0,15,255,255,240,0,0,0,0,63,248,31,252,0,0,0,0,255,0,0,255,0,0,0,3,248,0,0,31,192,0,0,7,224,0,0,7,224,0,0,31,128,0,0,1,248,0,0,62,0,0,0,0,124,0,0,124,0,0,0,0,62,0,1,240,0,0,0,0,15,128,3,224,0,0,0,0,7,192,7,128,0,0,0,0,1,224,15,0,0,0,0,0,0,240,30,0,0,0,0,0,0,120,60,0,0,0,0,0,0,60,120,0,0,0,0,0,0,30,124,0,0,0,0,0,0,62,63,128,0,0,0,0,1,252,31,240,0,0,0,0,15,248,15,254,0,0,0,0,127,240,7,255,224,0,0,7,255,224,3,207,255,0,0,255,243,192,0,241,255,255,255,255,143,0,0,120,15,255,255,240,30,0,0,62,1,255,255,128,124,0,0,15,0,255,255,0,240,0,0,7,192,63,252,3,224,0,0,1,240,0,0,15,128,0,0,0,126,0,0,126,0,0,0,0,31,192,3,248,0,0,0,0,7,255,255,224,0,0,0,0,0,255,255,0,0,0,0,0,0,7,224,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,31,248,0,0,0,0,0,1,255,255,128,0,0,0,0,15,255,255,240,0,0,0,0,63,248,31,252,0,0,0,0,255,0,0,255,0,0,0,3,248,0,0,31,192,0,0,7,224,0,0,7,224,0,0,31,128,0,0,1,248,0,0,62,0,0,0,0,124,0,0,124,0,0,0,0,62,0,1,240,0,0,0,0,15,128,3,224,0,0,0,0,7,192,7,128,0,0,0,0,1,224,15,0,0,0,0,0,0,240,30,0,0,0,0,0,0,120,60,0,0,0,0,0,0,60,120,0,0,0,0,0,0,30,120,0,0,0,0,0,0,30,60,0,0,0,0,0,0,60,31,0,0,0,0,0,0,248,15,128,0,0,0,0,1,240,7,192,0,0,0,0,3,224,3,240,0,0,0,0,15,192,0,252,0,0,0,0,63,0,0,127,0,0,0,0,254,0,0,63,192,0,0,3,252,0,0,15,240,0,0,15,240,0,0,7,254,0,0,127,224,0,0,1,255,224,7,255,128,0,0,0,127,255,255,254,0,0,0,0,31,255,255,248,0,0,0,0,7,255,255,224,0,0,0,0,0,255,255,0,0,0,0,0,0,7,224,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,31,248,0,0,0,0,0,1,255,255,128,0,0,0,0,15,255,255,240,0,0,0,0,63,248,31,252,0,0,0,0,255,0,0,255,0,0,0,3,248,0,0,31,192,0,0,7,224,0,0,7,224,0,0,31,128,0,0,1,248,0,0,62,0,0,0,0,124,0,0,124,0,0,0,0,62,0,1,240,0,0,0,0,15,128,3,224,0,0,0,0,7,192,7,128,0,0,0,0,1,224,15,0,0,0,0,0,0,240,30,0,0,0,0,0,0,120,60,0,0,0,0,0,0,60,120,0,0,0,0,0,0,30,120,0,0,0,0,0,0,30,60,0,0,0,0,0,0,60,30,0,0,0,0,0,0,120,15,0,0,0,0,0,0,240,7,128,0,0,0,0,1,224,3,224,0,0,0,0,7,192,1,240,0,0,0,0,15,128,0,248,0,0,0,0,31,0,0,254,0,0,0,0,127,0,0,31,128,0,0,1,248,0,0,7,224,0,0,7,224,0,0,3,248,0,0,31,192,0,0,0,255,0,0,255,0,0,0,0,127,224,7,252,0,0,0,0,127,255,255,252,0,0,0,0,1,255,255,136,0,0,0,0,0,31,248,0,0,0,0,0,0,1,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,31,248,0,0,0,0,0,1,255,255,128,0,0,0,0,15,255,255,240,0,0,0,0,63,248,31,252,0,0,0,0,255,0,0,255,0,0,0,3,248,0,0,31,192,0,0,7,224,0,0,7,224,0,0,31,128,0,0,1,248,0,0,62,0,0,0,0,124,0,0,124,0,0,0,0,62,0,1,240,0,0,0,0,15,128,3,224,0,0,0,0,7,192,7,128,0,0,0,0,1,224,15,0,0,0,0,0,0,240,30,0,0,0,0,0,0,120,60,0,0,0,0,0,0,60,120,0,0,0,0,0,0,30,120,0,0,0,0,0,0,30,60,0,0,0,0,0,0,60,30,0,0,0,0,0,0,120,15,0,0,0,0,0,0,240,7,128,0,0,0,0,1,224,3,224,0,0,0,0,7,192,1,240,0,0,0,0,15,128,0,248,0,0,0,0,31,0,1,254,0,0,0,0,127,128,3,223,128,0,0,1,251,192,3,135,224,0,0,7,225,192,0,3,248,0,0,31,192,0,0,0,255,0,0,255,0,0,0,0,127,224,7,252,0,0,0,0,127,255,255,252,0,0,0,0,97,255,255,156,0,0,0,0,224,31,248,12,0,0,0,0,224,1,128,12,0,0,0,0,0,1,128,0,0,0,0,0,0,1,128,0,0,0,0,0,0,1,128,0,0,0,0,0,0,1,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,31,248,0,0,0,0,0,1,255,255,128,0,0,0,0,15,255,255,240,0,0,0,0,63,248,31,252,0,0,0,0,255,0,0,255,0,0,0,3,248,0,0,31,192,0,0,7,224,0,0,7,224,0,0,31,128,0,0,1,248,0,0,62,0,0,0,0,124,0,0,124,0,0,0,0,62,0,1,240,0,0,0,0,15,128,3,224,0,0,0,0,7,192,7,128,0,0,0,0,1,224,15,0,0,0,0,0,0,240,30,0,0,0,0,0,0,120,60,0,0,0,0,0,0,60,120,0,0,0,0,0,0,30,120,0,0,0,0,0,0,30,60,0,0,0,0,0,0,60,30,0,0,0,0,0,0,120,15,0,0,0,0,0,0,240,7,128,0,0,0,0,1,224,3,224,0,0,0,0,7,192,1,240,0,0,0,0,15,128,0,248,0,0,0,0,31,0,1,254,0,0,0,0,127,128,3,159,128,0,0,1,249,192,7,135,224,0,0,7,225,224,7,3,248,0,0,31,192,224,14,0,255,0,0,255,0,112,12,0,127,224,7,252,0,48,0,0,127,255,255,252,0,0,0,0,97,255,255,156,0,0,0,0,224,31,248,12,0,0,0,0,224,1,128,14,0,0,0,0,224,1,128,14,0,0,0,0,192,1,128,14,0,0,0,1,192,1,128,6,0,0,0,0,128,1,128,6,0,0,0,0,0,1,128,0,0,0,0,0,0,1,128,0,0,0,0,0,0,1,128,0,0,0,0,0,0,1,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,31,248,0,0,0,0,0,1,255,255,128,0,0,0,0,15,255,255,240,0,0,0,0,63,248,31,252,0,0,0,0,255,0,0,255,0,0,0,3,248,0,0,31,192,0,0,7,224,0,0,7,224,0,0,31,128,0,0,1,248,0,0,62,0,0,0,0,124,0,0,124,0,0,0,0,62,0,1,240,0,0,0,0,15,128,3,224,0,0,0,0,7,192,7,128,0,0,0,0,1,224,15,0,0,0,0,0,0,240,30,0,0,0,0,0,0,120,60,0,0,0,0,0,0,60,120,0,0,0,0,0,0,30,120,0,0,0,0,0,0,30,60,0,0,0,0,0,0,60,30,0,0,0,0,0,0,120,15,0,0,0,0,0,0,240,7,128,0,0,0,0,1,224,3,224,0,0,0,0,7,192,1,240,0,0,0,0,15,128,0,248,0,0,0,0,31,0,1,254,0,0,0,0,127,128,3,159,128,0,0,1,249,192,7,135,224,0,0,7,225,224,7,3,248,0,0,31,192,224,14,0,255,0,0,255,0,112,12,0,127,224,7,252,0,48,0,0,127,255,255,252,0,0,0,0,97,255,255,156,0,0,0,0,224,31,248,12,0,0,0,0,224,1,128,14,0,0,0,0,224,1,128,14,0,0,0,0,192,1,128,14,0,0,0,1,192,1,128,6,0,0,0,0,128,1,128,6,0,0,0,0,0,1,128,0,0,0,0,0,0,1,128,0,0,0,0,0,0,1,128,0,0,0,0,0,0,1,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,31,248,0,0,0,0,0,1,255,255,128,0,0,0,0,15,255,255,240,0,0,0,0,63,248,31,252,0,0,0,0,255,0,0,255,0,0,0,3,248,0,0,31,192,0,0,7,224,0,0,7,224,0,0,31,128,0,0,1,248,0,0,62,0,0,0,0,124,0,0,124,0,0,0,0,62,0,1,240,0,0,0,0,15,128,3,224,0,0,0,0,7,192,7,128,0,0,0,0,1,224,15,0,0,0,0,0,0,240,30,0,0,0,0,0,0,120,60,0,0,0,0,0,0,60,120,0,0,0,0,0,0,30,120,0,0,0,0,0,0,30,60,0,0,0,0,0,0,60,30,0,0,0,0,0,0,120,15,0,0,0,0,0,0,240,7,128,0,0,0,0,1,224,3,224,0,0,0,0,7,192,1,240,0,0,0,0,15,128,0,248,0,0,0,0,31,0,1,254,0,0,0,0,127,128,3,159,128,0,0,1,249,192,7,135,224,0,0,7,225,224,7,3,248,0,0,31,192,224,14,0,255,0,0,255,0,112,12,0,127,224,7,252,0,48,0,0,127,255,255,252,0,0,0,0,97,255,255,156,0,0,0,0,224,31,248,12,0,0,0,0,224,1,128,14,0,0,0,0,224,1,128,14,0,0,0,0,192,1,128,14,0,0,0,1,192,1,128,6,0,0,0,0,128,1,128,6,0,0,0,0,0,1,128,0,0,0,0,0,0,1,128,0,0,0,0,0,0,1,128,0,0,0,0,0,0,1,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,31,248,0,0,0,0,0,1,255,255,128,0,0,0,0,15,255,255,240,0,0,0,0,63,248,31,252,0,0,0,0,255,0,0,255,0,0,0,3,248,0,0,31,192,0,0,7,224,0,0,7,224,0,0,31,128,0,0,1,248,0,0,62,0,0,0,0,124,0,0,124,0,0,0,0,62,0,1,240,0,0,0,0,15,128,3,224,0,0,0,0,7,192,7,128,0,0,0,0,1,224,15,0,0,0,0,0,0,240,30,0,0,0,0,0,0,120,60,0,0,0,0,0,0,60,120,0,0,0,0,0,0,30,120,0,0,0,0,0,0,30,60,0,0,0,0,0,0,60,30,0,0,0,0,0,0,120,15,0,0,0,0,0,0,240,7,128,0,0,0,0,1,224,3,224,0,0,0,0,7,192,1,240,0,0,0,0,15,128,0,248,0,0,0,0,31,0,1,254,0,0,0,0,127,128,3,159,128,0,0,1,249,192,7,135,224,0,0,7,225,224,7,3,248,0,0,31,192,224,14,0,255,0,0,255,0,112,12,0,127,224,7,252,0,48,0,0,127,255,255,252,0,0,0,0,97,255,255,156,0,0,0,0,224,31,248,12,0,0,0,0,224,1,128,14,0,0,0,0,224,1,128,14,0,0,0,0,192,1,128,14,0,0,0,1,192,1,128,6,0,0,0,0,128,1,128,6,0,0,0,0,0,1,128,0,0,0,0,0,0,1,128,0,0,0,0,0,0,1,128,0,0,0,0,0,0,1,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,31,248,0,0,0,0,0,1,255,255,128,0,0,0,0,15,255,255,240,0,0,0,0,63,248,31,252,0,0,0,0,255,0,0,255,0,0,0,3,248,0,0,31,192,0,0,7,224,0,0,7,224,0,0,31,128,0,0,1,248,0,0,62,0,0,0,0,124,0,0,124,0,0,0,0,62,0,1,240,0,0,0,0,15,128,3,224,0,0,0,0,7,192,7,128,0,0,0,0,1,224,15,0,0,0,0,0,0,240,30,0,0,0,0,0,0,120,60,0,0,0,0,0,0,60,120,0,0,0,0,0,0,30,120,0,0,0,0,0,0,30,60,0,0,0,0,0,0,60,30,0,0,0,0,0,0,120,15,0,0,0,0,0,0,240,7,128,0,0,0,0,1,224,3,224,0,0,0,0,7,192,1,240,0,0,0,0,15,128,0,248,0,0,0,0,31,0,1,254,0,0,0,0,127,128,3,159,128,0,0,1,249,192,7,135,224,0,0,7,225,224,7,3,248,0,0,31,192,224,14,0,255,0,0,255,0,112,12,0,127,224,7,252,0,48,0,0,127,255,255,252,0,0,0,0,97,255,255,156,0,0,0,0,224,31,248,12,0,0,0,0,224,1,128,14,0,0,0,0,224,1,128,14,0,0,0,0,192,1,128,14,0,0,0,1,192,1,128,6,0,0,0,0,128,1,128,6,0,0,0,0,0,1,128,0,0,0,0,0,0,1,128,0,0,0,0,0,0,1,128,0,0,0,0,0,0,1,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,31,248,0,0,0,0,0,1,255,255,128,0,0,0,0,15,255,255,240,0,0,0,0,63,248,31,252,0,0,0,0,255,0,0,255,0,0,0,3,248,0,0,31,192,0,0,7,224,0,0,7,224,0,0,31,128,0,0,1,248,0,0,62,0,0,0,0,124,0,0,124,0,0,0,0,62,0,1,240,0,0,0,0,15,128,3,224,0,0,0,0,7,192,7,128,0,0,0,0,1,224,15,0,0,0,0,0,0,240,30,0,0,0,0,0,0,120,60,0,0,0,0,0,0,60,120,0,0,0,0,0,0,30,120,0,0,0,0,0,0,30,60,0,0,0,0,0,0,60,30,0,0,0,0,0,0,120,15,0,0,0,0,0,0,240,7,128,0,0,0,0,1,224,3,224,0,0,0,0,7,192,1,240,0,0,0,0,15,128,0,248,0,0,0,0,31,0,1,254,0,0,0,0,127,128,3,159,128,0,0,1,249,192,7,135,224,0,0,7,225,224,7,3,248,0,0,31,192,224,14,0,255,0,0,255,0,112,12,0,127,224,7,252,0,48,0,0,127,255,255,252,0,0,0,0,97,255,255,156,0,0,0,0,224,31,248,12,0,0,0,0,224,1,128,14,0,0,0,0,224,1,128,14,0,0,0,0,192,1,128,14,0,0,0,1,192,1,128,6,0,0,0,0,128,1,128,6,0,0,0,0,0,1,128,0,0,0,0,0,0,1,128,0,0,0,0,0,0,1,128,0,0,0,0,0,0,1,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,31,248,0,0,0,0,0,1,255,255,128,0,0,0,0,15,255,255,240,0,0,0,0,63,248,31,252,0,0,0,0,255,0,0,255,0,0,0,3,248,0,0,31,192,0,0,7,224,0,0,7,224,0,0,31,128,0,0,1,248,0,0,62,0,0,0,0,124,0,0,124,0,0,0,0,62,0,1,240,0,0,0,0,15,128,3,224,0,0,0,0,7,192,7,128,0,0,0,0,1,224,15,0,0,0,0,0,0,240,30,0,0,0,0,0,0,120,60,0,0,0,0,0,0,60,120,0,0,0,0,0,0,30,120,0,0,0,0,0,0,30,60,0,0,0,0,0,0,60,30,0,0,0,0,0,0,120,15,0,0,0,0,0,0,240,7,128,0,0,0,0,1,224,3,224,0,0,0,0,7,192,1,240,0,0,0,0,15,128,0,248,0,0,0,0,31,0,1,254,0,0,0,0,127,128,3,159,128,0,0,1,249,192,7,135,224,0,0,7,225,224,7,3,248,0,0,31,192,224,14,0,255,0,0,255,0,112,12,0,127,224,7,252,0,48,0,0,127,255,255,252,0,0,0,0,97,255,255,156,0,0,0,0,224,31,248,12,0,0,0,0,224,1,128,14,0,0,0,0,224,1,128,14,0,0,0,0,192,1,128,14,0,0,0,1,192,1,128,6,0,0,0,0,128,1,128,6,0,0,0,0,0,1,128,0,0,0,0,0,0,1,128,0,0,0,0,0,0,1,128,0,0,0,0,0,0,1,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,31,248,0,0,0,0,0,1,255,255,128,0,0,0,0,15,255,255,240,0,0,0,0,63,248,31,252,0,0,0,0,255,0,0,255,0,0,0,3,248,0,0,31,192,0,0,7,224,0,0,7,224,0,0,31,128,0,0,1,248,0,0,62,0,0,0,0,124,0,0,124,0,0,0,0,62,0,1,240,0,0,0,0,15,128,3,224,0,0,0,0,7,192,7,128,0,0,0,0,1,224,15,0,0,0,0,0,0,240,30,0,0,0,0,0,0,120,60,0,0,0,0,0,0,60,120,0,0,0,0,0,0,30,120,0,0,0,0,0,0,30,60,0,0,0,0,0,0,60,30,0,0,0,0,0,0,120,15,0,0,0,0,0,0,240,7,128,0,0,0,0,1,224,3,224,0,0,0,0,7,192,1,240,0,0,0,0,15,128,0,248,0,0,0,0,31,0,1,254,0,0,0,0,127,128,3,223,128,0,0,1,251,192,3,135,224,0,0,7,225,192,0,3,248,0,0,31,192,0,0,0,255,0,0,255,0,0,0,0,127,224,7,252,0,0,0,0,127,255,255,252,0,0,0,0,97,255,255,156,0,0,0,0,224,31,248,12,0,0,0,0,224,1,128,12,0,0,0,0,0,1,128,0,0,0,0,0,0,1,128,0,0,0,0,0,0,1,128,0,0,0,0,0,0,1,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,31,248,0,0,0,0,0,1,255,255,128,0,0,0,0,15,255,255,240,0,0,0,0,63,248,31,252,0,0,0,0,255,0,0,255,0,0,0,3,248,0,0,31,192,0,0,7,224,0,0,7,224,0,0,31,128,0,0,1,248,0,0,62,0,0,0,0,124,0,0,124,0,0,0,0,62,0,1,240,0,0,0,0,15,128,3,224,0,0,0,0,7,192,7,128,0,0,0,0,1,224,15,0,0,0,0,0,0,240,30,0,0,0,0,0,0,120,60,0,0,0,0,0,0,60,120,0,0,0,0,0,0,30,120,0,0,0,0,0,0,30,60,0,0,0,0,0,0,60,30,0,0,0,0,0,0,120,15,0,0,0,0,0,0,240,7,128,0,0,0,0,1,224,3,224,0,0,0,0,7,192,1,240,0,0,0,0,15,128,0,248,0,0,0,0,31,0,0,254,0,0,0,0,127,0,0,31,128,0,0,1,248,0,0,7,224,0,0,7,224,0,0,3,248,0,0,31,192,0,0,0,255,0,0,255,0,0,0,0,127,224,7,252,0,0,0,0,127,255,255,252,0,0,0,0,1,255,255,136,0,0,0,0,0,31,248,0,0,0,0,0,0,1,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,31,248,0,0,0,0,0,1,255,255,128,0,0,0,0,15,255,255,240,0,0,0,0,63,248,31,252,0,0,0,0,255,0,0,255,0,0,0,3,248,0,0,31,192,0,0,7,224,0,0,7,224,0,0,31,128,0,0,1,248,0,0,62,0,0,0,0,124,0,0,124,0,0,0,0,62,0,1,240,0,0,0,0,15,128,3,224,0,0,0,0,7,192,7,128,0,0,0,0,1,224,15,0,0,0,0,0,0,240,30,0,0,0,0,0,0,120,60,0,0,0,0,0,0,60,120,0,0,0,0,0,0,30,120,0,0,0,0,0,0,30,62,0,0,0,0,0,0,124,31,0,0,0,0,0,0,248,15,192,0,0,0,0,3,240,7,240,0,0,0,0,15,224,3,252,0,0,0,0,63,192,0,255,0,0,0,0,255,0,0,127,224,0,0,7,254,0,0,63,252,0,0,63,252,0,0,15,255,224,7,255,240,0,0,7,207,255,255,243,224,0,0,1,240,255,255,15,128,0,0,0,126,0,0,126,0,0,0,0,31,192,3,248,0,0,0,0,7,255,255,224,0,0,0,0,0,255,255,0,0,0,0,0,0,7,224,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,31,248,0,0,0,0,0,1,255,255,128,0,0,0,0,15,255,255,240,0,0,0,0,63,248,31,252,0,0,0,0,255,0,0,255,0,0,0,3,248,0,0,31,192,0,0,7,224,0,0,7,224,0,0,31,128,0,0,1,248,0,0,62,0,0,0,0,124,0,0,124,0,0,0,0,62,0,1,240,0,0,0,0,15,128,3,224,0,0,0,0,7,192,7,128,0,0,0,0,1,224,15,0,0,0,0,0,0,240,30,0,0,0,0,0,0,120,60,0,0,0,0,0,0,60,120,0,0,0,0,0,0,62,127,128,0,0,0,0,1,254,63,252,0,0,0,0,63,252,31,255,252,0,0,63,255,248,15,63,255,255,255,255,252,240,7,128,255,255,255,255,1,224,3,192,15,255,255,240,3,192,0,240,7,0,0,224,15,0,0,120,3,192,3,192,30,0,0,62,1,248,31,128,124,0,0,15,0,255,255,0,240,0,0,7,192,63,252,3,224,0,0,1,240,0,0,15,128,0,0,0,126,0,0,126,0,0,0,0,31,192,3,248,0,0,0,0,7,255,255,224,0,0,0,0,0,255,255,0,0,0,0,0,0,7,224,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,31,248,0,0,0,0,0,1,255,255,128,0,0,0,0,15,255,255,240,0,0,0,0,63,248,31,252,0,0,0,0,255,0,0,255,0,0,0,3,248,0,0,31,192,0,0,7,224,0,0,7,224,0,0,31,128,0,0,1,248,0,0,62,0,0,0,0,124,0,0,124,0,0,0,0,62,0,1,240,0,0,0,0,15,128,3,224,0,0,0,0,7,192,7,128,0,0,0,0,1,224,15,0,0,255,255,0,0,240,30,127,255,255,255,255,254,120,63,255,255,255,255,255,255,252,127,252,112,31,248,14,63,254,126,0,112,31,248,14,0,126,60,0,48,7,224,12,0,60,30,0,56,0,0,28,0,120,15,0,28,0,0,56,0,240,7,128,28,0,0,56,1,224,3,192,14,0,0,112,3,192,0,240,7,0,0,224,15,0,0,120,3,192,3,192,30,0,0,62,1,248,31,128,124,0,0,15,0,255,255,0,240,0,0,7,192,63,252,3,224,0,0,1,240,0,0,15,128,0,0,0,126,0,0,126,0,0,0,0,31,192,3,248,0,0,0,0,7,255,255,224,0,0,0,0,0,255,255,0,0,0,0,0,0,7,224,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,31,248,0,0,0,0,0,1,255,255,128,0,0,0,0,15,255,255,240,0,0,0,0,63,248,31,252,0,0,0,0,255,0,0,255,0,0,0,3,248,0,0,31,192,0,0,7,224,0,0,7,224,0,0,31,128,31,248,1,248,0,0,62,7,255,255,224,124,0,0,124,127,255,255,254,62,0,1,243,255,63,252,255,207,128,3,255,240,63,252,15,255,192,7,255,96,63,252,6,255,224,15,248,96,63,252,6,31,240,31,224,96,63,252,6,7,248,63,0,96,63,252,6,0,252,124,0,112,31,248,14,0,62,120,0,112,31,248,14,0,30,60,0,48,7,224,12,0,60,30,0,56,0,0,28,0,120,15,0,28,0,0,56,0,240,7,128,28,0,0,56,1,224,3,192,14,0,0,112,3,192,0,240,7,0,0,224,15,0,0,120,3,192,3,192,30,0,0,62,1,248,31,128,124,0,0,15,0,255,255,0,240,0,0,7,192,63,252,3,224,0,0,1,240,0,0,15,128,0,0,0,126,0,0,126,0,0,0,0,31,192,3,248,0,0,0,0,7,255,255,224,0,0,0,0,0,255,255,0,0,0,0,0,0,7,224,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,31,248,0,0,0,0,0,1,255,255,128,0,0,0,0,15,255,255,240,0,0,0,0,63,255,255,252,0,0,0,0,255,255,255,255,0,0,0,3,255,224,7,255,192,0,0,7,252,0,0,63,224,0,0,31,248,7,224,31,248,0,0,63,240,15,240,15,252,0,0,126,112,31,248,14,126,0,1,252,96,63,252,6,63,128,3,240,96,63,252,6,15,192,7,192,96,63,252,6,3,224,15,128,96,63,252,6,1,240,30,0,96,63,252,6,0,120,60,0,96,63,252,6,0,60,120,0,112,31,248,14,0,30,120,0,112,31,248,14,0,30,60,0,48,7,224,12,0,60,30,0,56,0,0,28,0,120,15,0,28,0,0,56,0,240,7,128,28,0,0,56,1,224,3,192,14,0,0,112,3,192,0,240,7,0,0,224,15,0,0,120,3,192,3,192,30,0,0,62,1,248,31,128,124,0,0,15,0,255,255,0,240,0,0,7,192,63,252,3,224,0,0,1,240,0,0,15,128,0,0,0,126,0,0,126,0,0,0,0,31,192,3,248,0,0,0,0,7,255,255,224,0,0,0,0,0,255,255,0,0,0,0,0,0,7,224,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,31,248,0,0,0,0,0,1,255,255,128,0,0,0,0,15,255,255,240,0,0,0,0,63,248,31,252,0,0,0,0,255,0,0,255,0,0,0,3,252,0,0,63,192,0,0,7,248,0,0,31,224,0,0,31,184,7,224,29,248,0,0,62,112,15,240,14,124,0,0,124,112,31,248,14,62,0,1,240,96,63,252,6,15,128,3,224,96,63,252,6,7,192,7,192,96,63,252,6,3,224,15,0,96,63,252,6,0,240,30,0,96,63,252,6,0,120,60,0,96,63,252,6,0,60,120,0,112,31,248,14,0,30,120,0,112,31,248,14,0,30,60,0,48,7,224,12,0,60,30,0,56,0,0,28,0,120,15,0,28,0,0,56,0,240,7,128,28,0,0,56,1,224,3,192,14,0,0,112,3,192,0,240,7,0,0,224,15,0,0,120,3,192,3,192,30,0,0,62,1,248,31,128,124,0,0,15,0,255,255,0,240,0,0,7,192,63,252,3,224,0,0,1,240,0,0,15,128,0,0,0,126,0,0,126,0,0,0,0,31,192,3,248,0,0,0,0,7,255,255,224,0,0,0,0,0,255,255,0,0,0,0,0,0,7,224,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,31,248,0,0,0,0,0,1,255,255,128,0,0,0,0,15,255,255,240,0,0,0,0,63,248,31,252,0,0,0,0,255,0,0,255,0,0,0,3,252,0,0,63,192,0,0,7,248,0,0,31,224,0,0,31,184,7,224,29,248,0,0,62,112,15,240,14,124,0,0,124,112,31,248,14,62,0,1,240,96,63,252,6,15,128,3,224,96,63,252,6,7,192,7,192,96,63,252,6,3,224,15,0,96,63,252,6,0,240,30,0,96,63,252,6,0,120,60,0,96,63,252,6,0,60,120,0,112,31,248,14,0,30,120,0,112,31,248,14,0,30,60,0,48,7,224,12,0,60,30,0,56,0,0,28,0,120,15,0,28,0,0,56,0,240,7,128,28,0,0,56,1,224,3,192,14,0,0,112,3,192,0,240,7,0,0,224,15,0,0,120,3,192,3,192,30,0,0,62,1,248,31,128,124,0,0,15,0,255,255,0,240,0,0,7,192,63,252,3,224,0,0,1,240,0,0,15,128,0,0,0,126,0,0,126,0,0,0,0,31,192,3,248,0,0,0,0,7,255,255,224,0,0,0,0,0,255,255,0,0,0,0,0,0,7,224,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,31,248,0,0,0,0,0,1,255,255,128,0,0,0,0,15,255,255,240,0,0,0,0,63,248,31,252,0,0,0,0,255,0,0,255,0,0,0,3,252,0,0,63,192,0,0,7,248,0,0,31,224,0,0,31,184,7,224,29,248,0,0,62,112,15,240,14,124,0,0,124,112,31,248,14,62,0,1,240,96,63,252,6,15,128,3,224,96,63,252,6,7,192,7,192,96,63,252,6,3,224,15,0,96,63,252,6,0,240,30,0,96,63,252,6,0,120,60,0,96,63,252,6,0,60,120,0,112,31,248,14,0,30,120,0,112,31,248,14,0,30,60,0,48,7,224,12,0,60,30,0,56,0,0,28,0,120,15,0,28,0,0,56,0,240,7,128,28,0,0,56,1,224,3,192,14,0,0,112,3,192,0,240,7,0,0,224,15,0,0,120,3,192,3,192,30,0,0,62,1,248,31,128,124,0,0,15,0,255,255,0,240,0,0,7,192,63,252,3,224,0,0,1,240,0,0,15,128,0,0,0,126,0,0,126,0,0,0,0,31,192,3,248,0,0,0,0,7,255,255,224,0,0,0,0,0,255,255,0,0,0,0,0,0,7,224,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}
};
void setup() {
display.begin(SSD1306_SWITCHCAPVCC, SCREEN_I2C_ADDR);
}
int frame = 0;
void loop() {
display.clearDisplay();
display.drawBitmap(32, 0, frames[frame], FRAME_WIDTH, FRAME_HEIGHT, 1);
display.display();
frame = (frame + 1) % FRAME_COUNT;
// delay(FRAME_DELAY);
}
I2C vs SPI?
The I2C’s display are often chosen because it is good enough for transferring small amounts of data and requires less pin to use. However for my project - I would require a bigger display with colour. Unfortunately I couldn’t find any I2C displays that fit the requirements. The cheap coloured display I could find readily available here in Indonesia are the TFT Displays. They mainly use SPI connections (MISO,MOSI,SCK,SS). As such these displays require more pins. Good thing my custom Elaineduino had enough pins to make sure these TFT displays could be programmed.
2.0” TFT ILI9225 LCD Screen
A thin-film-transistor liquid-crystal display (TFT LCD) is a type of LCD Display that uses thin-film-transistor technology. Each pixel in the display has a tiny transistor that controls the amount of light that passes through it. This allows for much more precise control over the image. TFT displays are considered “active matrix” displays. This means each pixel is controlled by its own transistor, allowing for sharper images and better viewing angles. Most TFT Displays uses the SPI module.
I bought this LCD Screen at first but realised that it has limited libraries compared to other TFT Screens. Please be aware that this particular TFT Display doesn’t support Adafruit GFX Library. The main library to be utilised is the TFT_22_ILI9225.h
Check more about ILI9225 from Arnov Sharma
In his documentation, this was how he used his TFT Display as a shield.
And so I adapted the pin-outs to Xiao ESP32S3
- CS = D7. In some forums, D7 was considered the Chip Select/Slave Select pin. However I found any digital pins would work with the Xiao ESP32.
- RST = A0 Following the analog pin placement.
- RS = A1 Following the analog pin placement.
- SDA = D10 The hardware names this pin SDA however the code labels it SDI and reserves it for MOSI. So I adapted to Xiao ESP32’s MOSI pin which is D10
- CLK = D8 The code suggests an SCK pin. SCK in Xiao ESP32 is D8
System Diagram
Code from Arnov Sharma
#include "SPI.h"
#include "TFT_22_ILI9225.h"
#include "math.h"
#define TFT_RST A0
#define TFT_RS A1
#define TFT_CS D7 // SS
#define TFT_SDI D10 // MOSI
#define TFT_CLK D8 // SCK
#define TFT_LED 0 // 0 if wired to +5V directly
#define TFT_BRIGHTNESS 200 // Initial brightness of TFT backlight (optional)
#define ROTATE_ANGLE 10 // Angle in degrees to rotate the triangle
struct _point
{
int16_t x;
int16_t y;
};
// Use hardware SPI (faster - on Uno: 13-SCK, 12-MISO, 11-MOSI)
TFT_22_ILI9225 tft = TFT_22_ILI9225(TFT_RST, TFT_RS, TFT_CS, TFT_SDI, TFT_CLK, TFT_LED);
// Variables and constants
_point c1, c2, c3, cc;
// Setup
void setup() {
tft.begin();
// Define triangle start coordinates
c1.x = 30; c1.y = 30;
c2.x = 120; c2.y = 80;
c3.x = 80; c3.y = 130;
// Determine the rotation point, i.e. the center of the triangle
cc = getCoordCentroid(c1, c2, c3);
tft.clear();
}
// Loop
void loop() {
// Calculate the number of steps to rotate the triangle a full rotation
int16_t steps = (int16_t)(360 / ROTATE_ANGLE);
// Draw solid triangle
tft.fillTriangle(30, 190, 80, 150, 130, 210, COLOR_BLUE);
for (int8_t i = 0; i < steps; i++) {
// Draw triangle
tft.drawTriangle(c1.x, c1.y, c2.x, c2.y, c3.x, c3.y, COLOR_GREEN);
// Rotate triangle
rotateTriangle(c1, c2, c3, cc, ROTATE_ANGLE);
delay(50);
}
delay(5000);
tft.clear();
}
// Get centroid of triangle
_point getCoordCentroid( _point a, _point b, _point c ) {
_point o;
o.x = (int16_t)((a.x + b.x + c.x) / 3);
o.y = (int16_t)((a.y + b.y + c.y) / 3);
return o;
}
// Rotate triangle around point r
void rotateTriangle( _point &a, _point &b, _point &c, _point r, int16_t deg ) {
// Convert degrees to radians
float angle = (float)deg * 1000 / 57296;
// Rotate each individual point
a = rotatePoint( r, angle, a);
b = rotatePoint( r, angle, b);
c = rotatePoint( r, angle, c);
}
// Rotate each point p around c
_point rotatePoint( _point c, float angle, _point p ) {
_point r;
// 1. translate point back to origin
// 2. rotate point
// 3. translate point back
r.x = cos(angle) * (p.x - c.x) - sin(angle) * (p.y - c.y) + c.x;
r.y = sin(angle) * (p.x - c.x) + cos(angle) * (p.y - c.y) + c.y;
return r;
}
TFT ILI9341 2.8” Display
This particular TFT Screen is widely used and has touchscreen capabilities. Adafruit GFX Library supports this display however the library TFT_eSPI is more widely used and works best for 32-bit processor MCUs. Since this library is more popular, there is also a significant amount of people in the community providing widgets and design contribution for the library.
To use this library follow this tutorial. It requires a specific set up.
HOWEVER
I couldn’t get this the eSPI Library to work at all with the Xiao ESP32.... so I just decided to program with the Adafruit GFX Library.
System Diagram
Example Code
Original Code from electronoob adapted for XIAO ESP32S3
/***************************************************
This is our GFX example for the Adafruit ILI9341 Breakout and Shield
----> http://www.adafruit.com/products/1651
Check out the links above for our tutorials and wiring diagrams
These displays use SPI to communicate, 4 or 5 pins are required to
interface (RST is optional)
Adafruit invests time and resources providing this open source code,
please support Adafruit and open-source hardware by purchasing
products from Adafruit!
Written by Limor Fried/Ladyada for Adafruit Industries.
MIT license, all text above must be included in any redistribution
****************************************************/
#define ILI9341_BLACK 0x0000 ///< 0, 0, 0
#define ILI9341_NAVY 0x000F ///< 0, 0, 123
#define ILI9341_DARKGREEN 0x03E0 ///< 0, 125, 0
#define ILI9341_DARKCYAN 0x03EF ///< 0, 125, 123
#define ILI9341_MAROON 0x7800 ///< 123, 0, 0
#define ILI9341_PURPLE 0x780F ///< 123, 0, 123
#define ILI9341_OLIVE 0x7BE0 ///< 123, 125, 0
#define ILI9341_LIGHTGREY 0xC618 ///< 198, 195, 198
#define ILI9341_DARKGREY 0x7BEF ///< 123, 125, 123
#define ILI9341_BLUE 0x001F ///< 0, 0, 255
#define ILI9341_GREEN 0x07E0 ///< 0, 255, 0
#define ILI9341_CYAN 0x07FF ///< 0, 255, 255
#define ILI9341_RED 0xF800 ///< 255, 0, 0
#define ILI9341_MAGENTA 0xF81F ///< 255, 0, 255
#define ILI9341_YELLOW 0xFFE0 ///< 255, 255, 0
#define ILI9341_WHITE 0xFFFF ///< 255, 255, 255
#define ILI9341_ORANGE 0xFD20 ///< 255, 165, 0
#define ILI9341_GREENYELLOW 0xAFE5 ///< 173, 255, 41
#define ILI9341_PINK 0xFC18 ///< 255, 130, 198
#include "SPI.h"
#include "Adafruit_GFX.h"
#include "Adafruit_ILI9341.h"
// For the Adafruit shield, these are the default.
#define TFT_RST A0
#define TFT_DC A1
#define TFT_CS D7 // SS
#define TFT_MOSI D10 // MOSI
#define TFT_MISO D9
#define TFT_CLK D8 // SCK
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_MOSI, TFT_CLK, TFT_RST, TFT_MISO);
void setup() {
Serial.begin(9600);
Serial.println("ILI9341 Test!");
tft.begin();
// read diagnostics (optional but can help debug problems)
uint8_t x = tft.readcommand8(ILI9341_RDMODE);
Serial.print("Display Power Mode: 0x"); Serial.println(x, HEX);
x = tft.readcommand8(ILI9341_RDMADCTL);
Serial.print("MADCTL Mode: 0x"); Serial.println(x, HEX);
x = tft.readcommand8(ILI9341_RDPIXFMT);
Serial.print("Pixel Format: 0x"); Serial.println(x, HEX);
x = tft.readcommand8(ILI9341_RDIMGFMT);
Serial.print("Image Format: 0x"); Serial.println(x, HEX);
x = tft.readcommand8(ILI9341_RDSELFDIAG);
Serial.print("Self Diagnostic: 0x"); Serial.println(x, HEX);
void loop(void) {
tft.fillScreen(ILI9341_NAVY);
tft.setCursor(0, 0);
tft.setTextColor(ILI9341_WHITE); tft.setTextSize(1);
tft.println("Hello World!");
tft.setTextColor(ILI9341_YELLOW); tft.setTextSize(2);
tft.println(1234.56);
tft.setTextColor(ILI9341_RED); tft.setTextSize(3);
tft.println(0xDEADBEEF, HEX);
tft.println();
tft.setTextColor(ILI9341_GREEN);
tft.setTextSize(5);
tft.println("Groop");
tft.setTextSize(2);
tft.println("I implore thee,");
tft.setTextSize(1);
tft.println("my foonting turlingdromes.");
tft.println("And hooptiously drangle me");
tft.println("with crinkly bindlewurdles,");
tft.println("Or I will rend thee");
tft.println("in the gobberwarts");
tft.println("with my blurglecruncheon,");
tft.println("see if I don't!");
delay(5000);
}
unsigned long testFillScreen() {
unsigned long start = micros();
tft.fillScreen(ILI9341_BLACK);
yield();
tft.fillScreen(ILI9341_RED);
yield();
tft.fillScreen(ILI9341_GREEN);
yield();
tft.fillScreen(ILI9341_BLUE);
yield();
tft.fillScreen(ILI9341_BLACK);
yield();
return micros() - start;
}
unsigned long testText() {
tft.fillScreen(ILI9341_BLACK);
unsigned long start = micros();
tft.setCursor(0, 0);
tft.setTextColor(ILI9341_WHITE); tft.setTextSize(1);
tft.println("Hello World!");
tft.setTextColor(ILI9341_YELLOW); tft.setTextSize(2);
tft.println(1234.56);
tft.setTextColor(ILI9341_RED); tft.setTextSize(3);
tft.println(0xDEADBEEF, HEX);
tft.println();
tft.setTextColor(ILI9341_GREEN);
tft.setTextSize(5);
tft.println("Groop");
tft.setTextSize(2);
tft.println("I implore thee,");
tft.setTextSize(1);
tft.println("my foonting turlingdromes.");
tft.println("And hooptiously drangle me");
tft.println("with crinkly bindlewurdles,");
tft.println("Or I will rend thee");
tft.println("in the gobberwarts");
tft.println("with my blurglecruncheon,");
tft.println("see if I don't!");
return micros() - start;
}
unsigned long testLines(uint16_t color) {
unsigned long start, t;
int x1, y1, x2, y2,
w = tft.width(),
h = tft.height();
tft.fillScreen(ILI9341_BLACK);
yield();
x1 = y1 = 0;
y2 = h - 1;
start = micros();
for(x2=0; x2<w; x2+=6) tft.drawLine(x1, y1, x2, y2, color);
x2 = w - 1;
for(y2=0; y2<h; y2+=6) tft.drawLine(x1, y1, x2, y2, color);
t = micros() - start; // fillScreen doesn't count against timing
yield();
tft.fillScreen(ILI9341_BLACK);
yield();
x1 = w - 1;
y1 = 0;
y2 = h - 1;
start = micros();
for(x2=0; x2<w; x2+=6) tft.drawLine(x1, y1, x2, y2, color);
x2 = 0;
for(y2=0; y2<h; y2+=6) tft.drawLine(x1, y1, x2, y2, color);
t += micros() - start;
yield();
tft.fillScreen(ILI9341_BLACK);
yield();
x1 = 0;
y1 = h - 1;
y2 = 0;
start = micros();
for(x2=0; x2<w; x2+=6) tft.drawLine(x1, y1, x2, y2, color);
x2 = w - 1;
for(y2=0; y2<h; y2+=6) tft.drawLine(x1, y1, x2, y2, color);
t += micros() - start;
yield();
tft.fillScreen(ILI9341_BLACK);
yield();
x1 = w - 1;
y1 = h - 1;
y2 = 0;
start = micros();
for(x2=0; x2<w; x2+=6) tft.drawLine(x1, y1, x2, y2, color);
x2 = 0;
for(y2=0; y2<h; y2+=6) tft.drawLine(x1, y1, x2, y2, color);
yield();
return micros() - start;
}
unsigned long testFastLines(uint16_t color1, uint16_t color2) {
unsigned long start;
int x, y, w = tft.width(), h = tft.height();
tft.fillScreen(ILI9341_BLACK);
start = micros();
for(y=0; y<h; y+=5) tft.drawFastHLine(0, y, w, color1);
for(x=0; x<w; x+=5) tft.drawFastVLine(x, 0, h, color2);
return micros() - start;
}
unsigned long testRects(uint16_t color) {
unsigned long start;
int n, i, i2,
cx = tft.width() / 2,
cy = tft.height() / 2;
tft.fillScreen(ILI9341_BLACK);
n = min(tft.width(), tft.height());
start = micros();
for(i=2; i<n; i+=6) {
i2 = i / 2;
tft.drawRect(cx-i2, cy-i2, i, i, color);
}
return micros() - start;
}
unsigned long testFilledRects(uint16_t color1, uint16_t color2) {
unsigned long start, t = 0;
int n, i, i2,
cx = tft.width() / 2 - 1,
cy = tft.height() / 2 - 1;
tft.fillScreen(ILI9341_BLACK);
n = min(tft.width(), tft.height());
for(i=n; i>0; i-=6) {
i2 = i / 2;
start = micros();
tft.fillRect(cx-i2, cy-i2, i, i, color1);
t += micros() - start;
// Outlines are not included in timing results
tft.drawRect(cx-i2, cy-i2, i, i, color2);
yield();
}
return t;
}
unsigned long testFilledCircles(uint8_t radius, uint16_t color) {
unsigned long start;
int x, y, w = tft.width(), h = tft.height(), r2 = radius * 2;
tft.fillScreen(ILI9341_BLACK);
start = micros();
for(x=radius; x<w; x+=r2) {
for(y=radius; y<h; y+=r2) {
tft.fillCircle(x, y, radius, color);
}
}
return micros() - start;
}
unsigned long testCircles(uint8_t radius, uint16_t color) {
unsigned long start;
int x, y, r2 = radius * 2,
w = tft.width() + radius,
h = tft.height() + radius;
// Screen is not cleared for this one -- this is
// intentional and does not affect the reported time.
start = micros();
for(x=0; x<w; x+=r2) {
for(y=0; y<h; y+=r2) {
tft.drawCircle(x, y, radius, color);
}
}
return micros() - start;
}
unsigned long testTriangles() {
unsigned long start;
int n, i, cx = tft.width() / 2 - 1,
cy = tft.height() / 2 - 1;
tft.fillScreen(ILI9341_BLACK);
n = min(cx, cy);
start = micros();
for(i=0; i<n; i+=5) {
tft.drawTriangle(
cx , cy - i, // peak
cx - i, cy + i, // bottom left
cx + i, cy + i, // bottom right
tft.color565(i, i, i));
}
return micros() - start;
}
unsigned long testFilledTriangles() {
unsigned long start, t = 0;
int i, cx = tft.width() / 2 - 1,
cy = tft.height() / 2 - 1;
tft.fillScreen(ILI9341_BLACK);
start = micros();
for(i=min(cx,cy); i>10; i-=5) {
start = micros();
tft.fillTriangle(cx, cy - i, cx - i, cy + i, cx + i, cy + i,
tft.color565(0, i*10, i*10));
t += micros() - start;
tft.drawTriangle(cx, cy - i, cx - i, cy + i, cx + i, cy + i,
tft.color565(i*10, i*10, 0));
yield();
}
return t;
}
unsigned long testRoundRects() {
unsigned long start;
int w, i, i2,
cx = tft.width() / 2 - 1,
cy = tft.height() / 2 - 1;
tft.fillScreen(ILI9341_BLACK);
w = min(tft.width(), tft.height());
start = micros();
for(i=0; i<w; i+=6) {
i2 = i / 2;
tft.drawRoundRect(cx-i2, cy-i2, i, i, i/8, tft.color565(i, 0, 0));
}
return micros() - start;
}
unsigned long testFilledRoundRects() {
unsigned long start;
int i, i2,
cx = tft.width() / 2 - 1,
cy = tft.height() / 2 - 1;
tft.fillScreen(ILI9341_BLACK);
start = micros();
for(i=min(tft.width(), tft.height()); i>20; i-=6) {
i2 = i / 2;
tft.fillRoundRect(cx-i2, cy-i2, i, i, i/8, tft.color565(0, i, 0));
yield();
}
return micros() - start;
}
Simple Menu with Rotary Encoder
Inspired by this video, I adapted the code for ILI9341 with the help of chatgpt.
#include <Adafruit_GFX.h>
#include <Adafruit_ILI9341.h>
// Define pins for the ILI9341 display
#define TFT_RST D4
#define TFT_DC D5
#define TFT_CS D3 // SS
#define TFT_MOSI D10 // MOSI
#define TFT_MISO D9
#define TFT_CLK D8 // SCK
// Define pins for the rotary encoder
#define ENCODER_CLK D0
#define ENCODER_DT D1
#define ENCODER_SW D2
Adafruit_ILI9341 display = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_RST);
int menuitem = 1;
int page = 1;
int volume = 50;
String language[3] = { "EN", "ES", "EL" };
int selectedLanguage = 0;
String difficulty[2] = { "EASY", "HARD" };
int selectedDifficulty = 0;
volatile boolean up = false;
volatile boolean down = false;
volatile boolean middle = false;
volatile int lastClk = HIGH;
unsigned long lastButtonPress = 0;
void setup() {
pinMode(ENCODER_CLK, INPUT_PULLUP);
pinMode(ENCODER_DT, INPUT_PULLUP);
pinMode(ENCODER_SW, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(ENCODER_CLK), readEncoder, CHANGE);
attachInterrupt(digitalPinToInterrupt(ENCODER_SW), readButton, FALLING);
display.begin();
display.setRotation(4);
display.fillScreen(ILI9341_BLACK);
drawMenu();
}
void loop() {
bool needRedraw = false;
if (up) {
up = false;
if (page == 1) {
if (menuitem > 1) {
menuitem--;
} else {
menuitem = 3;
}
needRedraw = true;
} else {
if (menuitem == 1 && volume > 0) {
volume--;
needRedraw = true;
} else if (menuitem == 2 && selectedLanguage > 0) {
selectedLanguage--;
needRedraw = true;
} else if (menuitem == 3 && selectedDifficulty > 0) {
selectedDifficulty--;
needRedraw = true;
}
}
}
if (down) {
down = false;
if (page == 1) {
if (menuitem < 3) {
menuitem++;
} else {
menuitem = 1;
}
needRedraw = true;
} else {
if (menuitem == 1 && volume < 100) {
volume++;
needRedraw = true;
} else if (menuitem == 2 && selectedLanguage < 2) {
selectedLanguage++;
needRedraw = true;
} else if (menuitem == 3 && selectedDifficulty < 1) {
selectedDifficulty++;
needRedraw = true;
}
}
}
if (middle) {
middle = false;
page = (page == 1) ? 2 : 1;
needRedraw = true;
}
if (needRedraw) {
drawMenu();
}
}
void drawMenu() {
display.fillScreen(ILI9341_BLACK);
display.setTextSize(2);
display.setTextColor(ILI9341_WHITE);
if (page == 1) {
display.setCursor(10, 10);
display.print("MAIN MENU");
display.setCursor(10, 40);
display.setTextColor(menuitem == 1 ? ILI9341_YELLOW : ILI9341_WHITE);
display.print("Volume");
display.setCursor(10, 70);
display.setTextColor(menuitem == 2 ? ILI9341_YELLOW : ILI9341_WHITE);
display.print("Language");
display.setCursor(10, 100);
display.setTextColor(menuitem == 3 ? ILI9341_YELLOW : ILI9341_WHITE);
display.print("Difficulty");
} else if (page == 2) {
display.setCursor(10, 10);
if (menuitem == 1) {
display.print("Volume");
display.setCursor(10, 40);
display.print(volume);
} else if (menuitem == 2) {
display.print("Language");
display.setCursor(10, 40);
display.print(language[selectedLanguage]);
} else if (menuitem == 3) {
display.print("Difficulty");
display.setCursor(10, 40);
display.print(difficulty[selectedDifficulty]);
}
}
}
void readEncoder() {
int clkValue = digitalRead(ENCODER_CLK);
if (clkValue != lastClk) {
if (digitalRead(ENCODER_DT) != clkValue) {
down = true;
} else {
up = true;
}
}
lastClk = clkValue;
}
void readButton() {
unsigned long currentTime = millis();
if (currentTime - lastButtonPress > 200) { // debounce time
middle = true;
lastButtonPress = currentTime;
}
}
Final Project - System Diagram
Based on my eplorations I have decided that the TFT ILI9341 would be the screen that I required for my final project. This is my finalised system diagram intended for the final project.
Electronics Design and Production
I started with this aspect first because for system integration I want to minimise as much wiring as possible. This will also affect how the enclosure would look like and since I want to make a compact handheld device - it is important that we start from what’s within.
As I was testing out my input and output devices during those weeks, I realised that there were too many wiring, and system integration wise this was just not it.
Knowing that the TFT ILI9341 Display is designed to be used as a shield for the Arduino UNO microcontrollers, I decided to design my board with that feature in mind. I decided to mainly have female headers on my board and that the components would sit in place directly on to the headers.
This was my initial sketch for the electronic design.
Once I have laid out the components and the wiring - I made the schematic, designed the sketch in Kicad and produced it.
For my pcb production, I was using the same settings as my electronic production week - Rico and Henk suggested that I used 4 offset instead of 2 for this board. The production took abit of time to prepare because I was using a used v-bit and had to figure out the offset height in our finicky CNC Milling Machine. I tried offseting from 0.3mm all the way to 0.01 to figure out the optimum offset.
Since 0.3mm wasn’t cutting through, I made an offset of 0.4mm - as a way of airpassing..... but turns out the machine instead started cutting the board - and cut was deeper than I expected. I didn’t know if I wanted to laugh or cry because it felt like all the preparation I did was a waste.
I made a mistake with the screw hole...... if you want to use a M3 screw… make sure that your screw diameter is at least 3.2mm and also I just happened to forget offseting the board when I had to drill the holes.
It looked like my board may be a problem… but when I got to stuffing and my board worked!
However there was a problem.... Initially I wanted to use a wire to in between the rotary encoder and the female header input, but Rico told me that it wouldn’t be ideal. I had to frankenstein my board in order to make sure I can get the rotary encoder to be plugged.
The rotary encoder also had to be modified. It will be impossible for me to have original orientation plugged in with the default header that it comes with. So I desoldered the header pin and customised the rotary encoder to plug directly onto the board.