Hardware components | ||||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
Software apps and online services | ||||||
| ||||||
| ||||||
Hand tools and fabrication machines | ||||||
| ||||||
|
The use of rotary knobs is an important aspect of the design of user interfaces in electronic devices (e.g. car MP3 player, microwave oven, washing machine). Generally, a knob is used to provide input to a device when grasped by an operator and turned, so that the degree of rotation corresponds to the desired input. A control knob works by turning a shaft which connects to the component which produces the actual input. Common control components used include potentiometers, variable capacitors, and rotary switches.
But all of these have disadvantages. Rotary knob may malfunction after using a long time. Most of the cases rotary knob become unresponsive for dust and friction. Besides resistive and capacitive knob are not very precise. Resistive and capacitive knob can be rotate limited number of 360 degree turns, most of the case only one turn with maximum 300 degree rotation.
To overcome the above limitations of traditional rotary knob, we can use 3D magnetic sensor as rotary knob. They are frictionless and no angle limitation. You can rotate this as much time as you need (unlimited multiple of 360 degrees).
I made a multi-functional desk clock with the option of controlling the home appliances remotely using WiFi. Wemos D1 Mini was used to access time, weather update and AC home appliances. For controlling the home appliances I used MQTT protocol. Cloud MQTT was used as MQTT Server. The interaction (controlling) is done by Infineon's 3D magnetic 2GO kit & Rotator Knob based on TLE493D. Before going the details please watch the demo video.
Features of the Project1. WiFi switch used to control home appliances remotely using MQTT
2. Internet clock
3. Alarm clock
4. Weather update
5. Single rotary knob for user interaction (controlling)
How I Made ThisI used Wemos D1 Mini as the main controller of the project. A 1.8 inch tft lcd is used to display the information. Infineon 3D magnetic sensor is used as rotary knob for user interaction. I designed a 3D printed enclosure for my device.
For easily connecting the display to the Wemos mini I made two breakout board for both Wemos mini and the TFT display using perfboard and female header. After making the breakout boards I attached two boards using jumper wires (white color wires in the picture). The connections between Wemos board and display are shown in the schematic.
For accessing all the menus and options I used Infineon's 3D Magnetic Sensor 2Go kit. The kit has integrated microcontroller with the magnetic sensor. The built in microcontroller is used to read the sensor using I2C channel. The sensor data is processed in built-in microcontroller and according the data three GPIO is controlled for generating button press for the Wemos board. The GPIO is used to act as physical button. I used three GPIO from the integrated microcontroller which are connected to the Wemos mini board through transistor. The logic is very simple. The output of the the microcontroller is connected to the base of the transistor. The collector of the transistor is connected to the input pin of the Wemos board and the emitter of the transistor is connected to the ground. When the microcontroller pin goes high transistor becomes on and make a short circuit between collector and emitter which a physical switch does.
To read the sensor data and control the GPIO you need to upload a sketch in the 2Go board. The sketch is attached in the code section. To know the details how to program 2Go board using Arduino environment follow the official github page: https://github.com/Infineon/TLE493D-3DMagnetic-Sensor.
After uploading the sketch on the kit I placed the kit in the box using hot glue so that it can not move on press or rotation. The knob should be place in a manner that it can easily rotate or press.
The whole connection is shown in the following image.
The desk clock can be used as WiFi switch. Using a WiFi switch you can control any electronic device remotely. I am using MQTT protocol for implementing WiFi switch. Wemos transmit an MQTT message on cloud MQTT server on the topic esp/test. You need to subscribe the topic to receive the message sent from the desk clock. To receive the message you need another WiFi device like ESP8266. I am using NodeMCU for receiving the mqtt message and controlling the devices according to the received message. A relay module is required to control the AC appliances.
If you are new in MQTT protocol you may read this nice tutorial: https://www.hivemq.com/blog/how-to-get-started-with-mqtt. For any MQTT communication a MQTT server is required and I am using a cloud based MQTT server name as CloudMQTT. The following image shows the received message from the desk clock.
If you are new on cloud MQTT you can read this documentation: https://www.cloudmqtt.com/docs.html
For testing I made a setup using NodeMCU and two AC lamp. The lamps are connected to the AC source through a relay module. The 5V relay module is connected to the NodeMCU board.
The complete device is like as following image. Home screen has 5 menu like Home Control, Internet Clock, Alarm Clock, Weather, and Setting. You can choose any menu by rotating the knob. The arrow mark shows the selected menu. You can go down by rotating the knob clockwise and go up by rotating the knob anti clockwise. To enter a menu just press the knob. To back from an option you need to double press on the knob.
Main-controller
Arduino/*
* The code is written for Multifunctional desk clock
* Date: 23 August 2018
* Md. Khairul Alam
* Tested on Wemos D1 Mini
*
*/
#include <Adafruit_GFX.h> // Core graphics library
#include <QDTech_8266.h> // Hardware-specific tft library
#include <SPI.h> // Required for tft library
#include <ESP8266WiFi.h> // ESP8266 specific wifi library
#include <WiFiUdp.h> // UDP library for NTP
#include <PubSubClient.h> // This library is for implementing MQTT
#define TFT_CS 15 // Chip select line for TFT display
#define TFT_DC 5 // Data/command line for TFT
#define TFT_RST 16 // Reset line for TFT (or connect to +5V)
#define BUFFPIXEL 20
// WiFi connection
const char ssid[] = "taifur&mafi"; // your wifi SSID
const char pass[] = "University"; // Your WiFi password
// MQTT Configuration
// You will get this info after creating a mqtt instance from www.cloudmqtt.com
const char* mqttServer = "m10.cloudmqtt.com";
const int mqttPort = 15373;
const char* mqttUser = "yataiehe";
const char* mqttPassword = "4ylvmEKxx2sR";
int hours_Offset_From_GMT = +6; // Change it according to your location
const char tzone[] = "New York";
WiFiServer server(80);
WiFiClient espClient;
PubSubClient client(espClient);
// A UDP instance to let us send and receive packets over UDP
WiFiUDP udp;
unsigned int localPort = 2390; // local port to listen for UDP packets
IPAddress timeServer(129, 6, 15, 28); // time.nist.gov NTP server
const int NTP_PACKET_SIZE = 48; // NTP time stamp is in the first 48 bytes of the message
byte packetBuffer[ NTP_PACKET_SIZE]; //buffer to hold incoming and outgoing packets
//Unix time in seconds
unsigned long epoch = 0;
unsigned long LastNTP = 0;
int hour, hour1;
int minute;
int blink=0, PM=0;
int RequestedTime = 0;
int TimeCheckLoop = 0;
////////////////////////////////////////////////////
#if defined(__SAM3X8E__)
#undef __FlashStringHelper::F(string_literal)
#define F(string_literal) string_literal
#endif
// Option 2: must use the hardware SPI pins
Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_RST);
/**********variables for color***********************/
int BLACK = 100;
int BLUE = 200;
int WHITE = 0;
int RED = 336;
int GREEN = 264;
// custom color variable for menu
int button1 = 100, button2 = 264, button3 = 336, button4 = 500, button5 = 7500;
/**********variables for home screen***********************/
int x = 12;
int width = 105;
int height = 25;
int roundness = 10;
int offset = 30;
int count = 0;
int flag = 0;
// variables for analog clcok
//uint32_t targetTime = 0; // for next 1 second timeout
uint8_t hh, mm, ss;
float sx = 0, sy = 1, mx = 1, my = 0, hx = -1, hy = 0; // Saved H, M, S x & y multipliers
float sdeg=0, mdeg=0, hdeg=0;
uint16_t osx=64, osy=64, omx=64, omy=64, ohx=64, ohy=64; // Saved H, M, S x & y coords
uint16_t x0=0, x1=0, yx = 0, yz = 0;
uint32_t targetTime = 0;
// variable for buttons
int btnUP = 4;
int btnOK = 0;
int btnDOWN = 2;
int pressedTime = 0;
bool onOffFlag = 0;
int whichScreenFlag = 0;
// custom bitmap for on/off logo
static const uint8_t PROGMEM onBitmap[] = {
0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00,
0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x03, 0xfe, 0x00, 0x00, 0x00, 0x03, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x3f, 0x80, 0x00, 0x00, 0x07, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x0f, 0xe0, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x03, 0xf0, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe,
0x00, 0x00, 0x00, 0x00, 0x0f, 0x80, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00,
0x00, 0x00, 0x00, 0x07, 0x80, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00,
0x00, 0x00, 0x03, 0xc0, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00,
0x00, 0x01, 0xe0, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00,
0x01, 0xf0, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00,
0xf0, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78,
0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x3f,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x7f, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x7f, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x7f, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x7f, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x7f, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x7f, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x7f, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0,
0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00,
0x00, 0x00, 0x00, 0x00, 0xf0, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00,
0x00, 0x00, 0x01, 0xf0, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00,
0x00, 0x01, 0xe0, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00,
0x03, 0xc0, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x07,
0x80, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x80,
0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00,
0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x3f,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x1f, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x03, 0xf0, 0x00, 0x00, 0x07, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x0f, 0xe0, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x3f, 0x80, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xf8, 0x03, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
static const uint8_t PROGMEM offBitmap[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00,
0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x7f,
0xc0, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, 0xfc, 0x00,
0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x07, 0xf0, 0x00, 0x00,
0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x0f, 0xc0, 0x00, 0x00, 0x0f,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x07, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x01, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0x80, 0x01, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xc0, 0x03, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xe0, 0x07, 0x80, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xe0, 0x0f, 0x80, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xf0, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8,
0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x1e,
0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x3c, 0x00,
0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x3c, 0x00, 0x00,
0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x3c, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x78, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x70, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x78, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xf8, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xf8, 0x0f, 0x80, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xf0, 0x07, 0x80, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xe0, 0x03, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xe0, 0x01, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0,
0x01, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00,
0xf8, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x7e,
0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x1f, 0x00,
0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x0f, 0xc0, 0x00,
0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x07, 0xf0, 0x00, 0x00,
0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x01, 0xfc, 0x00, 0x01, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x7f, 0xc0, 0x1f, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0x80, 0x00, 0x00
};
void setup(void) {
Serial.begin(9600);
SPI.setClockDivider(SPI_CLOCK_DIV2);
tft.init();
tft.setRotation(0); // 0 - Portrait, 1 - Lanscape
tft.fillScreen(WHITE);
Serial.println("init");
//button pins are define as input, internal pull up resistor are enabled
pinMode(btnUP, INPUT_PULLUP);
pinMode(btnOK, INPUT_PULLUP);
pinMode(btnDOWN, INPUT_PULLUP);
//connect to wifi
ConnectToAP();
//configure mqtt connection
mqtt_config();
//start udp communication
udp.begin(localPort);
//sent request to server for current time
Request_Time();
delay(2000);
Check_Time();
/*
while (!Check_Time());
{
delay(2000);
TimeCheckLoop++;
if (TimeCheckLoop > 5)
{
Request_Time();
}
}
*/
//update tft with default home screen with five menus
updateHomeScreen();
homeText();
//this flag variable is used to detect active screen
whichScreenFlag = 1; //1 means home screen
}
//callback function for mqtt data receive
//this function automatically invocked on mqtt message received
void callback(char* topic, byte* payload, unsigned int length) {
Serial.print("Message arrived in topic: ");
Serial.println(topic);
Serial.print("Message:");
for (int i = 0; i < length; i++) {
Serial.print((char)payload[i]);
}
Serial.println();
Serial.println("-----------------------");
}
void loop (){
client.loop(); //mqtt client
if(digitalRead(btnUP)==0){
// count variable set to max 5 for 5 menus
count<=5?++count:count=0;
// this delay is required to avoid multiple press or false trigger
delay(1000);
}
if(digitalRead(btnDOWN)==0){
count>=0?count--:count=5;
delay(1000);
}
if(digitalRead(btnOK)==0){
// this loop count how much time the button keep low
// if it pass specific time, a long press is considered
while(digitalRead(btnOK)==0){
pressedTime++;
if(pressedTime>110) break;
delay(10);
}
//if time less than 100ms, a short press is considered
if(pressedTime<100){
shortPress();
}
else if(pressedTime>100){
longPress();
delay(2500);
}
pressedTime=0;
}
//up down arrow mark to select a menu
//position updated automatically on button press
if(whichScreenFlag==1){
noArrowMark();
arrowMark();
}
//this is the menu for home appliances control
//same as home screen and arrow mark is required for selecting specific appliance
if(whichScreenFlag==11){
noArrowMark();
arrowMark();
}
//flag for internet clock
if(whichScreenFlag==12){
processTime();
updateTime();
}
}
void updateHomeScreen(){
//draw menu option as home screen
tft.drawRoundRect(x, 5, width, height, roundness, button1);
tft.fillRoundRect(x, 5, width, height, roundness, button1);
tft.drawRoundRect(x, 35, width, height, roundness, button2);
tft.fillRoundRect(x, 35, width, height, roundness, button2);
tft.drawRoundRect(x, 65, width, height, roundness, button3);
tft.fillRoundRect(x, 65, width, height, roundness, button3);
tft.drawRoundRect(x, 95, width, height, roundness, button4);
tft.fillRoundRect(x, 95, width, height, roundness, button4);
tft.drawRoundRect(x, 125, width, height, roundness, button5);
tft.fillRoundRect(x, 125, width, height, roundness, button5);
}
void automationScreen(){
//menu option for home automation
tft.drawRoundRect(x, 5, width, height, roundness, button3);
tft.fillRoundRect(x, 5, width, height, roundness, button3);
tft.drawRoundRect(x, 35, width, height, roundness, button4);
tft.fillRoundRect(x, 35, width, height, roundness, button4);
tft.drawRoundRect(x, 65, width, height, roundness, button1);
tft.fillRoundRect(x, 65, width, height, roundness, button1);
tft.drawRoundRect(x, 95, width, height, roundness, button2);
tft.fillRoundRect(x, 95, width, height, roundness, button2);
tft.drawRoundRect(x, 125, width, height, roundness, button5);
tft.fillRoundRect(x, 125, width, height, roundness, button5);
}
void homeText(){
//show text on the menu option
printText("Home Control", 50,25,13,1);
printText("Internet Clock", 350,25,43,1);
printText("Alarm Clock", 250,25,73,1);
printText("Weather", 750,25,103,1);
printText("Setting", 0,25,133,1);
}
void automationText(){
printText("Bedroom Light", 50,25,13,1);
printText("Bedroom Fan", 350,25,43,1);
printText("Kitchen Light", 250,25,73,1);
printText("Bathroom Light", 0,25,103,1);
printText("Coffee Maker", 0,25,133,1);
}
void arrowMark(){
//arrow position updated according to the count value
//count value is updated on button press
//means arrow position updated on button press
tft.fillTriangle(0, 8+offset*count, 0, 24+offset*count, 12, 16+offset*count, 305);
}
void noArrowMark(){
//erase previous arrow mark
tft.fillTriangle(0, 8+offset*(count-1), 0, 24+offset*(count-1), 12, 16+offset*(count-1), 0);
tft.fillTriangle(0, 8+offset*(count+1), 0, 24+offset*(count+1), 12, 16+offset*(count+1), 0);
}
void printText(char *text, uint16_t color, int x, int y,int textSize)
{
tft.setCursor(x, y);
tft.setTextColor(color);
tft.setTextSize(textSize);
tft.setTextWrap(true);
tft.print(text);
}
void alarmScreen(){
//this is for alarm screen
tft.fillScreen (WHITE);
printText("Set Alarm Time:", RED,20,20,1);
printText("Set Alarm Date:", RED,20,65,1);
tft.drawRoundRect(5, 120, 50, 30, roundness, button1);
tft.fillRoundRect(5, 120, 50, 30, roundness, button1);
tft.drawRoundRect(70, 120, 50, 30, roundness, button1);
tft.fillRoundRect(70, 120, 50, 30, roundness, button1);
printText("Set", GREEN,22,130,1);
printText("Clear", GREEN,80,130,1);
printText("07:25 AM", BLACK,17,35,2);
printText("15/08/18", BLACK,17,80,2);
}
void ConnectToAP()
{
// Serial.print("Connecting to wifi... ");
WiFi.begin(ssid, pass);
while (WiFi.status() != WL_CONNECTED) {
delay(300);
}
}
void DecodeEpoch(unsigned long currentTime)
{
// print the hour, minute and second:
//Serial.print("The UTC time is "); // UTC is the time at Greenwich Meridian (GMT)
//Serial.println(epoch);
//Serial.print((epoch % 86400L) / 3600); // print the hour (86400 equals secs per day)
// Serial.print(':');
if ( ((epoch % 3600) / 60) < 10 ) {
// In the first 10 minutes of each hour, we'll want a leading '0'
// Serial.print('0');
}
// Serial.print((epoch % 3600) / 60); // print the minute (3600 equals secs per minute)
// Serial.print(':');
if ( (epoch % 60) < 10 ) {
// In the first 10 seconds of each minute, we'll want a leading '0'
// Serial.print('0');
}
//Serial.println(epoch % 60); // print the second
//Update for local zone
currentTime = currentTime + (hours_Offset_From_GMT * 60 * 60);
//Serial.print("The current local time is ");
//Serial.print((currentTime % 86400L) / 3600); // print the hour (86400 equals secs per day)
//Serial.print(':');
if ( ((currentTime % 3600) / 60) < 10 ) {
// In the first 10 minutes of each hour, we'll want a leading '0'
// Serial.print('0');
}
// Serial.print((currentTime % 3600) / 60); // print the minute (3600 equals secs per minute)
// Serial.print(':');
if ( (currentTime % 60) < 10 ) {
// In the first 10 seconds of each minute, we'll want a leading '0'
// Serial.print('0');
}
//Serial.println(currentTime % 60); // print the second
hour = (currentTime % 86400L) / 3600;
hh=hour;
if(hour >= 12) {
hour = hour-12;
PM=1;
}
else {
PM=0;
}
if(hour == 0) hour = 12;
minute = (currentTime % 3600) / 60;
mm=minute;
ss=currentTime % 60;
}
void Request_Time()
{
// Serial.println("Getting Time");
sendNTPpacket(timeServer); // send an NTP packet to a time server
}
bool Check_Time()
{
int cb = udp.parsePacket();
if (!cb) {
// Serial.println("no packet yet");
return false;
}
else {
// Serial.print("packet received, length=");
// Serial.println(cb);
// We've received a packet, read the data from it
udp.read(packetBuffer, NTP_PACKET_SIZE); // read the packet into the buffer
//the timestamp starts at byte 40 of the received packet and is four bytes,
// or two words, long. First, extract the two words:
unsigned long highWord = word(packetBuffer[40], packetBuffer[41]);
unsigned long lowWord = word(packetBuffer[42], packetBuffer[43]);
// combine the four bytes (two words) into a long integer
// this is NTP time (seconds since Jan 1 1900):
unsigned long secsSince1900 = highWord << 16 | lowWord;
//Serial.print("Seconds since Jan 1 1900 = " );
// Serial.println(secsSince1900);
// now convert NTP time into everyday time:
//Serial.print("Unix time = ");
// Unix time starts on Jan 1 1970. In seconds, that's 2208988800:
const unsigned long seventyYears = 2208988800UL;
// subtract seventy years:
epoch = secsSince1900 - seventyYears;
LastNTP = millis();
RequestedTime = 0;
TimeCheckLoop = 0;
return true;
}
}
// send an NTP request to the time server at the given address
unsigned long sendNTPpacket(IPAddress & address)
{
// Serial.println("sending NTP packet...");
// set all bytes in the buffer to 0
memset(packetBuffer, 0, NTP_PACKET_SIZE);
// Initialize values needed to form NTP request
// (see URL above for details on the packets)
packetBuffer[0] = 0b11100011; // LI, Version, Mode
packetBuffer[1] = 0; // Stratum, or type of clock
packetBuffer[2] = 6; // Polling Interval
packetBuffer[3] = 0xEC; // Peer Clock Precision
// 8 bytes of zero for Root Delay & Root Dispersion
packetBuffer[12] = 49;
packetBuffer[13] = 0x4E;
packetBuffer[14] = 49;
packetBuffer[15] = 52;
// all NTP fields have been given values, now
// you can send a packet requesting a timestamp:
udp.beginPacket(address, 123); //NTP requests are to port 123
udp.write(packetBuffer, NTP_PACKET_SIZE);
udp.endPacket();
}
void processTime(){
int SecondsSinceLastNTP = (millis() - LastNTP) / 1000;
//Update NTP every 2 minutes
if (SecondsSinceLastNTP > 120 and RequestedTime == 0) {
Request_Time();
RequestedTime = 1;
}
if (RequestedTime == 1)
{
Check_Time();
TimeCheckLoop++;
if (TimeCheckLoop > 5)
{
RequestedTime = 0;
}
}
//Only Check_Time() should update epoch
DecodeEpoch(epoch + SecondsSinceLastNTP);
if (ss==60) {
ss=0;
mm++; // Advance minute
if(mm>59) {
mm=0;
hh++; // Advance hour
if (hh>23) {
hh=0;
}
}
}
delay(1000);
ss++;
}
void updateTime(){
//dt = clock.getDateTime();
//mm = dt.minute;
//ss = dt.second;
//hh = dt.hour;
if (targetTime < millis()) {
targetTime = millis()+1000;
// Pre-compute hand degrees, x & y coords for a fast screen update
sdeg = ss*6; // 0-59 -> 0-354
mdeg = mm*6+sdeg*0.01666667; // 0-59 -> 0-360 - includes seconds
hdeg = hh*30+mdeg*0.0833333; // 0-11 -> 0-360 - includes minutes and seconds
hx = cos((hdeg-90)*0.0174532925); hy = sin((hdeg-90)*0.0174532925);
mx = cos((mdeg-90)*0.0174532925); my = sin((mdeg-90)*0.0174532925);
sx = cos((sdeg-90)*0.0174532925); sy = sin((sdeg-90)*0.0174532925);
// Erase just old hand positions
tft.drawLine(ohx, ohy, 65, 65, BLACK);
tft.drawLine(omx, omy, 65, 65, BLACK);
tft.drawLine(osx, osy, 65, 65, BLACK);
// Draw new hand positions
tft.drawLine(hx*33+65, hy*33+65, 65, 65, WHITE);
tft.drawLine(mx*44+65, my*44+65, 65, 65, WHITE);
tft.drawLine(sx*47+65, sy*47+65, 65, 65, RED);
tft.fillCircle(65, 65, 3, RED);
// Update old x&y coords
osx = sx*47+65; osy = sy*47+65;
omx = mx*44+65; omy = my*44+65;
ohx = hx*33+65; ohy = hy*33+65;
watchMark();
tft.drawRoundRect(0, 130, 128, 30, 1, WHITE);
tft.fillRoundRect(0, 130, 128, 30, 1, WHITE);
// Update AM/PM
tft.drawCircle(63, 90, 9, GREEN);
if(PM==1)
printText("PM", 50,58,87,1);
else
printText("AM", 50,58,87,1);
//Update digital time
tft.setCursor (15, 138);
tft.setTextSize(2);
if(hh>12) {
if (hh<22) tft.print('0');
tft.print (hh-12);
} else {
if (hh<10) tft.print('0');
tft.print (hh);
}
tft.print (':');
if (mm<10) tft.print('0');
tft.print (mm);
tft.print (':');
if (ss<10) tft.print('0');
tft.print (ss);
if (hh>12) ;//tft.print("PM"); else tft.print ("AM");
}
}
//show 12, 3, 6, 9 on dial
void watchMark(){
printText("3", 50,108,60,1);
printText("9", 50,16,60,1);
printText("12", 50,58,18,1);
printText("6", 50,61,105,1);
}
void clockFace(){ //
tft.fillScreen (WHITE);
// Draw clock face
tft.fillCircle(64, 64, 61, BLUE);
tft.fillCircle(64, 64, 57, BLACK);
// Draw 12 lines
for(int i = 0; i<360; i+= 30) {
sx = cos((i-90)*0.0174532925);
sy = sin((i-90)*0.0174532925);
x0 = sx*57+64;
yx = sy*57+64;
x1 = sx*50+64;
yz = sy*50+64;
tft.drawLine(x0, yx, x1, yz, BLUE);
}
tft.fillCircle(65, 65, 3, RED);
tft.setCursor (34, 151);
tft.print(__DATE__);
targetTime = millis() + 1000;
flag = 0;
}
void shortPress(){
//whichScreenFlag helps to determine the current screen and count value helps
//to determine the selected nemu
if(whichScreenFlag==1 && count==0){
whichScreenFlag = 11;
}
else if(whichScreenFlag==1 && count==1){
whichScreenFlag = 12;
}
else if(whichScreenFlag==1 && count==2){
whichScreenFlag = 13;
}
else if(whichScreenFlag==1 && count==3){
whichScreenFlag = 14;
}
else if(whichScreenFlag==1 && count==4){
whichScreenFlag = 15;
}
else if(whichScreenFlag==11 && count==0){
whichScreenFlag = 111;
}
else if(whichScreenFlag==11 && count==1){
whichScreenFlag = 112;
}
else if(whichScreenFlag==11 && count==2){
whichScreenFlag = 113;
}
else if(whichScreenFlag==11 && count==3){
whichScreenFlag = 114;
}
else if(whichScreenFlag==11 && count==4){
whichScreenFlag = 115;
}
else if(whichScreenFlag==111){
if(onOffFlag==0){
whichScreenFlag = 1110;
}
else if(onOffFlag==1){
whichScreenFlag = 1111;
}
}
else if(whichScreenFlag==112){
if(onOffFlag==0){
whichScreenFlag = 1120;
}
else if(onOffFlag==1){
whichScreenFlag = 1121;
}
}
else if(whichScreenFlag==113){
if(onOffFlag==0){
whichScreenFlag = 1130;
}
else if(onOffFlag==1){
whichScreenFlag = 1131;
}
}
else if(whichScreenFlag==114){
if(onOffFlag==0){
whichScreenFlag = 1140;
}
else if(onOffFlag==1){
whichScreenFlag = 1141;
}
}
else if(whichScreenFlag==115){
if(onOffFlag==0){
whichScreenFlag = 1150;
}
else if(onOffFlag==1){
whichScreenFlag = 1151;
}
}
if(whichScreenFlag==1110){
whichScreenFlag=1111;
//this flag helps to determine the current state of the device
onOffFlag=1;
//sent an MQTT message to the topic
client.publish("esp/test", "load1on");
delay(200);
}
else if(whichScreenFlag==1111){
whichScreenFlag=1110;
onOffFlag=0;
client.publish("esp/test", "load1off");
delay(200);
}
if(whichScreenFlag==1120){
whichScreenFlag=1121;
onOffFlag=1;
client.publish("esp/test", "load2on");
delay(200);
}
else if(whichScreenFlag==1121){
whichScreenFlag=1120;
onOffFlag=0;
client.publish("esp/test", "load2off");
delay(200);
}
if(whichScreenFlag==1130){
whichScreenFlag=1131;
onOffFlag=1;
client.publish("esp/test", "load3on");
delay(200);
}
else if(whichScreenFlag==1131){
whichScreenFlag=1130;
onOffFlag=0;
client.publish("esp/test", "load3off");
delay(200);
}
if(whichScreenFlag==1140){
whichScreenFlag=1141;
onOffFlag=1;
client.publish("esp/test", "load4on");
delay(200);
}
else if(whichScreenFlag==1141){
whichScreenFlag=1140;
onOffFlag=0;
client.publish("esp/test", "load4off");
delay(200);
}
if(whichScreenFlag==1150){
whichScreenFlag=1151;
client.publish("esp/test", "load5on");
delay(200);
}
else if(whichScreenFlag==1151){
whichScreenFlag=1150;
client.publish("esp/test", "load5off");
delay(200);
}
Serial.println(whichScreenFlag);
setScreen();
}
void longPress(){
//for long press it goes back to previous option
if(whichScreenFlag==11||whichScreenFlag==12||whichScreenFlag==13||whichScreenFlag==14||whichScreenFlag==15){
whichScreenFlag = 1;
}
else if(whichScreenFlag==111||whichScreenFlag==112||whichScreenFlag==113||whichScreenFlag==114||whichScreenFlag==115 || whichScreenFlag>115){
whichScreenFlag = 11;
}
setScreen();
}
void onScreen(){
//show the on status of the load
tft.fillScreen(WHITE);
tft.setTextSize(2);
tft.setTextColor(GREEN);
tft.setCursor(30, 20);
tft.setTextWrap(true);
tft.print("Status");
tft.drawBitmap(4, 60, offBitmap, 120, 58, WHITE);
tft.setCursor(10, 79);
tft.setTextColor(WHITE);
tft.setTextSize(3);
tft.setTextWrap(true);
tft.print("OFF");
tft.drawBitmap(4, 60, onBitmap, 120, 58, RED);
tft.setCursor(78, 78);
tft.setTextColor(RED);
tft.setTextSize(3);
tft.setTextWrap(true);
tft.print("ON");
}
void offScreen(){
tft.fillScreen(WHITE);
tft.setTextSize(2);
tft.setTextColor(GREEN);
tft.setCursor(30, 20);
tft.setTextWrap(true);
tft.print("Status");
tft.drawBitmap(4, 60, onBitmap, 120, 58, WHITE);
tft.setCursor(78, 78);
tft.setTextColor(WHITE);
tft.setTextSize(3);
tft.setTextWrap(true);
tft.print("ON");
tft.drawBitmap(4, 60, offBitmap, 120, 58, RED);
tft.setCursor(10, 79);
tft.setTextColor(RED);
tft.setTextSize(3);
tft.setTextWrap(true);
tft.print("OFF");
}
void setScreen(){
//according to the flag appropriate screen shows on tft
if(whichScreenFlag == 1){
tft.fillScreen(WHITE);
updateHomeScreen();
homeText();
}
else if(whichScreenFlag == 11){
tft.fillScreen(WHITE);
automationScreen();
automationText();
}
else if(whichScreenFlag == 12){
tft.fillScreen(WHITE);
clockFace();
watchMark();
}
else if(whichScreenFlag == 13){
tft.fillScreen(WHITE);
alarmScreen();
}
else if(whichScreenFlag == 14){
//tft.fillScreen(WHITE);
//weatherScreen();
}
else if(whichScreenFlag == 15){
//tft.fillScreen(WHITE);
//settingScreen();
}
else if(whichScreenFlag == 111){
tft.fillScreen(WHITE);
if(whichScreenFlag == 1110)
offScreen();
else if(whichScreenFlag == 1111)
onScreen();
}
else if(whichScreenFlag == 112){
tft.fillScreen(WHITE);
if(whichScreenFlag == 1120)
offScreen();
else if(whichScreenFlag == 1121)
onScreen();
}
else if(whichScreenFlag == 113){
tft.fillScreen(WHITE);
if(whichScreenFlag == 1130)
offScreen();
else if(whichScreenFlag == 1131)
onScreen();
}
else if(whichScreenFlag == 114){
tft.fillScreen(WHITE);
if(whichScreenFlag == 1140)
offScreen();
else if(whichScreenFlag == 1141)
onScreen();
}
else if(whichScreenFlag == 1110 || whichScreenFlag == 1120 || whichScreenFlag == 1130 || whichScreenFlag == 1140 || whichScreenFlag == 1150){
tft.fillScreen(WHITE);
onScreen();
}
else if(whichScreenFlag == 1111 || whichScreenFlag == 1121 || whichScreenFlag == 1131 || whichScreenFlag == 1141 || whichScreenFlag == 1151){
tft.fillScreen(WHITE);
offScreen();
}
}
void mqtt_config(){
client.setServer(mqttServer, mqttPort);
client.setCallback(callback);
while (!client.connected()) {
Serial.println("Connecting to MQTT...");
if (client.connect("ESP8266Client", mqttUser, mqttPassword )) {
Serial.println("connected");
} else {
Serial.print("failed with state ");
Serial.print(client.state());
delay(2000);
}
}
client.publish("esp/test", "Hello from ESP8266");
client.subscribe("esp/test");
}
/*
* Md. Khairul Alam
* Date: 24 August 2018
* Modified from example code provided with library
* Download library from https://github.com/Infineon/TLE493D-3DMagnetic-Sensor
*/
#include <Tle493d.h>
Tle493d Tle493dMagnetic3DSensor = Tle493d();
float azimuthValue = 0;
int xValue = 0;
int previousValue = 0;
int currentValue = 0;
int previousXValue = 0;
int currentXValue = 0;
long counter;
int counterValue;
long previousTime = millis();
long pressTime = millis();
int pressCount = 0;
const int switchUP = 5;
const int switchDOWN = 3;
const int switchOK = 4;
void setup() {
Serial.begin(9600);
while (!Serial);
Tle493dMagnetic3DSensor.begin();
pinMode(switchUP, OUTPUT);
pinMode(switchDOWN, OUTPUT);
pinMode(switchOK, OUTPUT);
digitalWrite(switchUP, LOW);
digitalWrite(switchDOWN, LOW);
digitalWrite(switchOK, LOW);
}
void loop() {
Tle493dMagnetic3DSensor.updateData();
//Serial.println(Tle493dMagnetic3DSensor.getAzimuth());
//the actual value may be less than 1 (one)
//so the value is multiplied by 100 to make it grater than 1
//than the value is converted to int to use in if statement
azimuthValue = Tle493dMagnetic3DSensor.getAzimuth() * 100;
xValue = int(Tle493dMagnetic3DSensor.getX());
xValue = abs(xValue);
currentXValue = xValue;
//Serial.println(xValue);
delay(10);
int currentValue = int(azimuthValue);
//the aximuth value increase on counter clockwise rotation
if((currentValue-previousValue)>=20){
//make it high for 200ms to generate button press
digitalWrite(switchUP, HIGH);
delay(200);
digitalWrite(switchUP, LOW);
//delay(1000);
Serial.println("CCW\n");
}
//the aximuth value decrease on clockwise rotation
else if((currentValue-previousValue)<=-20){
digitalWrite(switchDOWN, HIGH);
delay(200);
digitalWrite(switchDOWN, LOW);
//delay(1000);
Serial.println("CW\n");
}
if((currentXValue - previousXValue)>15){
pressTime = millis();
pressCount++;
}
if((millis()-pressTime)>600){
if(pressCount==1){
digitalWrite(switchOK, HIGH);
delay(100);
digitalWrite(switchOK, LOW);
//delay(1000);
Serial.println("Short Press\n");
}
else if(pressCount==2){
//keep it high for enough time to detect long press from other side (wemos mini)
digitalWrite(switchOK, HIGH);
delay(2000);
digitalWrite(switchOK, LOW);
//delay(1000);
Serial.println("Double Press\n");
}
pressCount=0;
pressTime = millis();
}
/*
//can be implimented as double press if required
counter = millis();
counterValue = currentXValue;
if((currentXValue - counterValue)>-20){
if((millis() - counter)>1000){
if((millis() - previousTime)>7000){
Serial.println("Long Press\n");
previousTime = millis();
}
}
}
counterValue = 100;
*/
previousValue = currentValue;
previousXValue = currentXValue;
delay(100);
}
#include <ESP8266WiFi.h>
#include <PubSubClient.h>
const char* ssid = "taifur&mafi";
const char* password = "University";
const char* mqttServer = "m10.cloudmqtt.com";
const int mqttPort = 15373;
const char* mqttUser = "yataiehe";
const char* mqttPassword = "4ylvmEKxx2sR";
String msg = "";
int load1 = 14;
int load2 = 12;
int load3 = 13;
const int off = 0;
const int on = 1;
WiFiClient espClient;
PubSubClient client(espClient);
void setup() {
Serial.begin(115200);
pinMode(load1, OUTPUT);
pinMode(load2, OUTPUT);
pinMode(load3, OUTPUT);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.println("Connecting to WiFi..");
}
Serial.println("Connected to the WiFi network");
client.setServer(mqttServer, mqttPort);
client.setCallback(callback);
while (!client.connected()) {
Serial.println("Connecting to MQTT...");
if (client.connect("ESP8266Client", mqttUser, mqttPassword )) {
Serial.println("connected");
} else {
Serial.print("failed with state ");
Serial.print(client.state());
delay(2000);
}
}
//client.publish("esp/test", "Hello from ESP8266");
client.subscribe("esp/test");
}
void callback(char* topic, byte* payload, unsigned int length) {
Serial.print("Message arrived in topic: ");
Serial.println(topic);
//Serial.print("Message:");
for (int i = 0; i < length; i++) {
msg += (char)payload[i];
}
Serial.print("Msg = ");
Serial.println(msg);
//Serial.println("-----------------------");
if(msg=="load1off"){
Serial.println("Load 1 is off");
digitalWrite(load1, off);
}
if(msg=="load1on"){
Serial.println("Load 1 is on");
digitalWrite(load1, on);
}
if(msg=="load2off"){
Serial.println("Load 2 is off");
digitalWrite(load2, off);
}
if(msg=="load2on"){
Serial.println("Load 2 is on");
digitalWrite(load2, on);
}
if(msg=="load3off"){
Serial.println("Load 3 is off");
digitalWrite(load3, off);
}
if(msg=="load3on"){
Serial.println("Load 3 is on");
digitalWrite(load3, on);
}
msg = "";
delay(200);
}
void loop() {
client.loop();
}
Comments