commit 5098586216fb203e12a5a1991906c6a03bb38c31 Author: Paul Warren Date: Wed Apr 19 22:02:59 2023 +1000 Initial version diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..fc68a0b --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +.pio +*~ +*credential.h + diff --git a/include/README b/include/README new file mode 100644 index 0000000..194dcd4 --- /dev/null +++ b/include/README @@ -0,0 +1,39 @@ + +This directory is intended for project header files. + +A header file is a file containing C declarations and macro definitions +to be shared between several project source files. You request the use of a +header file in your project source file (C, C++, etc) located in `src` folder +by including it, with the C preprocessing directive `#include'. + +```src/main.c + +#include "header.h" + +int main (void) +{ + ... +} +``` + +Including a header file produces the same results as copying the header file +into each source file that needs it. Such copying would be time-consuming +and error-prone. With a header file, the related declarations appear +in only one place. If they need to be changed, they can be changed in one +place, and programs that include the header file will automatically use the +new version when next recompiled. The header file eliminates the labor of +finding and changing all the copies as well as the risk that a failure to +find one copy will result in inconsistencies within a program. + +In C, the usual convention is to give header files names that end with `.h'. +It is most portable to use only letters, digits, dashes, and underscores in +header file names, and at most one dot. + +Read more about using header files in official GCC documentation: + +* Include Syntax +* Include Operation +* Once-Only Headers +* Computed Includes + +https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html diff --git a/include/epd.h b/include/epd.h new file mode 100644 index 0000000..b36eca7 --- /dev/null +++ b/include/epd.h @@ -0,0 +1,156 @@ +/********************************************************************************************************* +* +* File : epd.h +* Hardware Environment: +* Build Environment : RealView MDK-ARM Version: 4.74 +* Version : V1.0 +* By : V +* +* (c) Copyright 2005-2015, WaveShare +* http://www.waveshare.net +* All Rights Reserved +* +*********************************************************************************************************/ +#ifndef EPD_H + #define EPD_H + + +#define CMD_SIZE 512 + +/* +frame format +*/ +#define FRAME_B 0xA5 +#define FRAME_E0 0xCC +#define FRAME_E1 0x33 +#define FRAME_E2 0xC3 +#define FRAME_E3 0x3C + + +/* +color define +*/ +#define WHITE 0x03 +#define GRAY 0x02 +#define DARK_GRAY 0x01 +#define BLACK 0x00 + +/* +command define +*/ +#define CMD_HANDSHAKE 0x00 //handshake +#define CMD_SET_BAUD 0x01 //set baud +#define CMD_READ_BAUD 0x02 //read baud +#define CMD_MEMORYMODE 0x07 //set memory mode +#define CMD_STOPMODE 0x08 //enter stop mode +#define CMD_UPDATE 0x0A //update +#define CMD_SCREEN_ROTATION 0x0D //set screen rotation +#define CMD_LOAD_FONT 0x0E //load font +#define CMD_LOAD_PIC 0x0F //load picture + +#define CMD_SET_COLOR 0x10 //set color +#define CMD_SET_EN_FONT 0x1E //set english font +#define CMD_SET_CH_FONT 0x1F //set chinese font + +#define CMD_DRAW_PIXEL 0x20 //set pixel +#define CMD_DRAW_LINE 0x22 //draw line +#define CMD_FILL_RECT 0x24 //fill rectangle +#define CMD_DRAW_CIRCLE 0x26 //draw circle +#define CMD_FILL_CIRCLE 0x27 //fill circle +#define CMD_DRAW_TRIANGLE 0x28 //draw triangle +#define CMD_FILL_TRIANGLE 0x29 //fill triangle +#define CMD_CLEAR 0x2E //clear screen use back color + +#define CMD_DRAW_STRING 0x30 //draw string + +#define CMD_DRAW_BITMAP 0x70 //draw bitmap + + +/* +FONT +*/ +#define GBK32 0x01 +#define GBK48 0x02 +#define GBK64 0x03 + +#define ASCII32 0x01 +#define ASCII48 0x02 +#define ASCII64 0x03 + + + +/* +Memory Mode +*/ +#define MEM_NAND 0 +#define MEM_TF 1 + +/* +set screen rotation +*/ +#define EPD_NORMAL 0 //screen normal +#define EPD_INVERSION 1 //screen inversion + + +void epd_init(void); +void epd_reset(void); +void epd_wakeup(void); + +void epd_handshake(void); +void epd_set_memory(unsigned char mode); +void epd_enter_stopmode(void); +void epd_update(void); +void epd_screen_rotation(unsigned char mode); +void epd_load_font(void); +void epd_load_pic(void); + + +void epd_set_color(unsigned char color, unsigned char bkcolor); +void epd_set_en_font(unsigned char font); +void epd_set_ch_font(unsigned char font); + +void epd_draw_pixel(int x0, int y0); +void epd_draw_line(int x0, int y0, int x1, int y1); +void epd_fill_rect(int x0, int y0, int x1, int y1); +void epd_draw_circle(int x0, int y0, int r); +void epd_fill_circle(int x0, int y0, int r); +void epd_draw_triangle(int x0, int y0, int x1, int y1, int x2, int y2); +void epd_fill_triangle(int x0, int y0, int x1, int y1, int x2, int y2); +void epd_clear(void); + +void epd_disp_char(unsigned char ch, int x0, int y0); +void epd_disp_string(const void * p, int x0, int y0); + +void epd_disp_bitmap(const void * p, int x0, int y0); + + + +#endif + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/include/main.h b/include/main.h new file mode 100644 index 0000000..c17cd07 --- /dev/null +++ b/include/main.h @@ -0,0 +1,11 @@ +void ledOn(void); +void ledOff(void); +void wait(void); +void wifi(); +void ntpUpdate(); +void disp_digit(int digit, int xpos); +void disp_time(int hours, int minutes); +void printDateTime(int update_epd); +void weatherUpdate(void); + + diff --git a/lib/README b/lib/README new file mode 100644 index 0000000..6debab1 --- /dev/null +++ b/lib/README @@ -0,0 +1,46 @@ + +This directory is intended for project specific (private) libraries. +PlatformIO will compile them to static libraries and link into executable file. + +The source code of each library should be placed in a an own separate directory +("lib/your_library_name/[here are source files]"). + +For example, see a structure of the following two libraries `Foo` and `Bar`: + +|--lib +| | +| |--Bar +| | |--docs +| | |--examples +| | |--src +| | |- Bar.c +| | |- Bar.h +| | |- library.json (optional, custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html +| | +| |--Foo +| | |- Foo.c +| | |- Foo.h +| | +| |- README --> THIS FILE +| +|- platformio.ini +|--src + |- main.c + +and a contents of `src/main.c`: +``` +#include +#include + +int main (void) +{ + ... +} + +``` + +PlatformIO Library Dependency Finder will find automatically dependent +libraries scanning project source files. + +More information about PlatformIO Library Dependency Finder +- https://docs.platformio.org/page/librarymanager/ldf.html diff --git a/platformio.ini b/platformio.ini new file mode 100644 index 0000000..28eb307 --- /dev/null +++ b/platformio.ini @@ -0,0 +1,18 @@ +; PlatformIO Project Configuration File +; +; Build options: build flags, source filter +; Upload options: custom upload port, speed and extra flags +; Library options: dependencies, extra library storages +; Advanced options: extra scripting +; +; Please visit documentation for the other options and examples +; https://docs.platformio.org/page/projectconf.html + +[env:d1_mini] +platform = espressif8266 +board = d1_mini +framework = arduino +lib_deps = + bblanchon/ArduinoJson@^6.19.4 + jchristensen/Timezone@^1.2.4 + plerup/EspSoftwareSerial@^6.17.0 diff --git a/src/epd.cpp b/src/epd.cpp new file mode 100644 index 0000000..1ff7469 --- /dev/null +++ b/src/epd.cpp @@ -0,0 +1,766 @@ +/********************************************************************************************************* +* +* File : epd.c +* Hardware Environment: +* Build Environment : RealView MDK-ARM Version: 4.74 +* Version : V1.0 +* By : V +* +* (c) Copyright 2005-2014, WaveShare +* http://www.waveshare.net +* All Rights Reserved +* +*********************************************************************************************************/ +#include "epd.h" +#include +#include + + +const int wake_up = D7; +const int reset = D8; + +SoftwareSerial mySerial(D5,D6); + +/* +command define +*/ +static const unsigned char _cmd_handshake[8] = {0xA5, 0x00, 0x09, CMD_HANDSHAKE, 0xCC, 0x33, 0xC3, 0x3C}; //CMD_HANDSHAKE +static const unsigned char _cmd_read_baud[8] = {0xA5, 0x00, 0x09, CMD_READ_BAUD, 0xCC, 0x33, 0xC3, 0x3C}; //CMD_READ_BAUD +static const unsigned char _cmd_stopmode[8] = {0xA5, 0x00, 0x09, CMD_STOPMODE, 0xCC, 0x33, 0xC3, 0x3C}; //CMD_STOPMODE +static const unsigned char _cmd_update[8] = {0xA5, 0x00, 0x09, CMD_UPDATE, 0xCC, 0x33, 0xC3, 0x3C}; //CMD_UPDATE +static const unsigned char _cmd_load_font[8] = {0xA5, 0x00, 0x09, CMD_LOAD_FONT, 0xCC, 0x33, 0xC3, 0x3C}; //CMD_LOAD_FONT +static const unsigned char _cmd_load_pic[8] = {0xA5, 0x00, 0x09, CMD_LOAD_PIC, 0xCC, 0x33, 0xC3, 0x3C}; //CMD_LOAD_PIC + + + + +static unsigned char _cmd_buff[CMD_SIZE]; + + + +/* +private function +*/ +static void _putchars(const unsigned char * ptr, int n); +static unsigned char _verify(const void * ptr, int n); + + + +/******************************************************************************* +* Function Name : static void _putchars(const unsigned char * ptr, int n) +* Description : +* Input : +* Output : None +* Return : +* Attention : None +*******************************************************************************/ +static void _putchars(const unsigned char * ptr, int n) +{ + int i, x; + + for(i = 0; i < n; i++) + { + x = ptr[i]; + mySerial.write(x); + } +} +/******************************************************************************* +* Function Name : static unsigned char _verify(const void * ptr, int n) +* Description : +* Input : ptr + n +* Output : None +* Return : +*******************************************************************************/ +static unsigned char _verify(const void * ptr, int n) +{ + int i; + unsigned char * p = (unsigned char *)ptr; + unsigned char result; + + for(i = 0, result = 0; i < n; i++) + { + result ^= p[i]; + } + + return result; +} + + + + +/******************************************************************************* +* Function Name : void epd_init(void) +* Description : +* Input : +* Output : None +* Return : +* Attention : None +*******************************************************************************/ +void epd_init(void) +{ + mySerial.begin(115200); + pinMode(wake_up, OUTPUT); + digitalWrite(wake_up, LOW); + pinMode(reset, OUTPUT); + digitalWrite(reset, LOW); +} +/******************************************************************************* +* Function Name : void epd_reset(void) +* Description : +* Input : +* Output : None +* Return : +* Attention : None +*******************************************************************************/ +void epd_reset(void) +{ + digitalWrite(reset, LOW); + delayMicroseconds(1000); + digitalWrite(reset, HIGH); + delayMicroseconds(5000); + digitalWrite(reset, LOW); + delay(3000); +} +/******************************************************************************* +* Function Name : void epd_init(void) +* Description : +* Input : +* Output : None +* Return : +* Attention : None +*******************************************************************************/ +void epd_wakeup(void) +{ + digitalWrite(wake_up, LOW); + delayMicroseconds(1000); + digitalWrite(wake_up, HIGH); + delayMicroseconds(50000); + digitalWrite(wake_up, LOW); + delay(10); +} + +/******************************************************************************* +* Function Name : void epd_handshake(void) +* Description : +* Input : +* Output : None +* Return : +* Attention : None +*******************************************************************************/ +void epd_handshake(void) +{ + memcpy(_cmd_buff, _cmd_handshake, 8); + _cmd_buff[8] = _verify(_cmd_buff, 8); + + _putchars(_cmd_buff, 9); +} +/******************************************************************************* +* Function Name : void epd_set_baud(long baud) +* Description : set uart baud +* Input : +* Output : None +* Return : +* Attention : None +*******************************************************************************/ +void epd_set_baud(long baud) +{ + _cmd_buff[0] = FRAME_B; + + _cmd_buff[1] = 0x00; + _cmd_buff[2] = 0x0D; + + _cmd_buff[3] = CMD_SET_BAUD; + + _cmd_buff[4] = (baud >> 24) & 0xFF; + _cmd_buff[5] = (baud >> 16) & 0xFF; + _cmd_buff[6] = (baud >> 8) & 0xFF; + _cmd_buff[7] = baud & 0xFF; + + _cmd_buff[8] = FRAME_E0; + _cmd_buff[9] = FRAME_E1; + _cmd_buff[10] = FRAME_E2; + _cmd_buff[11] = FRAME_E3; + _cmd_buff[12] = _verify(_cmd_buff, 12); + + _putchars(_cmd_buff, 13); + + delay(10); + mySerial.begin(baud); +} +/******************************************************************************* +* Function Name : void epd_read_baud(void) +* Description : read uart baud +* Input : +* Output : None +* Return : +* Attention : None +*******************************************************************************/ +void epd_read_baud(void) +{ + memcpy(_cmd_buff, _cmd_read_baud, 8); + _cmd_buff[8] = _verify(_cmd_buff, 8); + + _putchars(_cmd_buff, 9); +} +/******************************************************************************* +* Function Name : void epd_set_memory(unsigned char mode) +* Description : +* Input : +* Output : None +* Return : +* Attention : None +*******************************************************************************/ +void epd_set_memory(unsigned char mode) +{ + _cmd_buff[0] = FRAME_B; + + _cmd_buff[1] = 0x00; + _cmd_buff[2] = 0x0A; + + _cmd_buff[3] = CMD_MEMORYMODE; + + _cmd_buff[4] = mode; + + _cmd_buff[5] = FRAME_E0; + _cmd_buff[6] = FRAME_E1; + _cmd_buff[7] = FRAME_E2; + _cmd_buff[8] = FRAME_E3; + _cmd_buff[9] = _verify(_cmd_buff, 9); + + _putchars(_cmd_buff, 10); +} + +/******************************************************************************* +* Function Name : void epd_enter_stopmode(void) +* Description : +* Input : +* Output : None +* Return : +* Attention : None +*******************************************************************************/ +void epd_enter_stopmode(void) +{ + memcpy(_cmd_buff, _cmd_stopmode, 8); + _cmd_buff[8] = _verify(_cmd_buff, 8); + + _putchars(_cmd_buff, 9); +} +/******************************************************************************* +* Function Name : void epd_update(void) +* Description : +* Input : +* Output : None +* Return : +* Attention : None +*******************************************************************************/ +void epd_update(void) +{ + memcpy(_cmd_buff, _cmd_update, 8); + _cmd_buff[8] = _verify(_cmd_buff, 8); + + _putchars(_cmd_buff, 9); +} +/******************************************************************************* +* Function Name : void epd_screen_rotation(unsigned char mode) +* Description : +* Input : +* Output : None +* Return : +* Attention : None +*******************************************************************************/ +void epd_screen_rotation(unsigned char mode) +{ + _cmd_buff[0] = FRAME_B; + + _cmd_buff[1] = 0x00; + _cmd_buff[2] = 0x0A; + + _cmd_buff[3] = CMD_SCREEN_ROTATION; + + _cmd_buff[4] = mode; + + _cmd_buff[5] = FRAME_E0; + _cmd_buff[6] = FRAME_E1; + _cmd_buff[7] = FRAME_E2; + _cmd_buff[8] = FRAME_E3; + _cmd_buff[9] = _verify(_cmd_buff, 9); + + _putchars(_cmd_buff, 10); +} +/******************************************************************************* +* Function Name : void epd_load_font(void) +* Description : +* Input : +* Output : None +* Return : +* Attention : None +*******************************************************************************/ +void epd_load_font(void) +{ + memcpy(_cmd_buff, _cmd_load_font, 8); + _cmd_buff[8] = _verify(_cmd_buff, 8); + + _putchars(_cmd_buff, 9); +} +/******************************************************************************* +* Function Name : void epd_load_pic(void) +* Description : +* Input : +* Output : None +* Return : +* Attention : None +*******************************************************************************/ +void epd_load_pic(void) +{ + memcpy(_cmd_buff, _cmd_load_pic, 8); + _cmd_buff[8] = _verify(_cmd_buff, 8); + + _putchars(_cmd_buff, 9); +} +/******************************************************************************* +* Function Name : void epd_set_color(unsigned char color, unsigned char bkcolor) +* Description : +* Input : +* Output : None +* Return : +* Attention : None +*******************************************************************************/ +void epd_set_color(unsigned char color, unsigned char bkcolor) +{ + _cmd_buff[0] = FRAME_B; + + _cmd_buff[1] = 0x00; + _cmd_buff[2] = 0x0B; + + _cmd_buff[3] = CMD_SET_COLOR; + + _cmd_buff[4] = color; + _cmd_buff[5] = bkcolor; + + _cmd_buff[6] = FRAME_E0; + _cmd_buff[7] = FRAME_E1; + _cmd_buff[8] = FRAME_E2; + _cmd_buff[9] = FRAME_E3; + _cmd_buff[10] = _verify(_cmd_buff, 10); + + _putchars(_cmd_buff, 11); +} +/******************************************************************************* +* Function Name : void epd_set_en_font(unsigned char font) +* Description : +* Input : +* Output : None +* Return : +* Attention : None +*******************************************************************************/ +void epd_set_en_font(unsigned char font) +{ + _cmd_buff[0] = FRAME_B; + + _cmd_buff[1] = 0x00; + _cmd_buff[2] = 0x0A; + + _cmd_buff[3] = CMD_SET_EN_FONT; + + _cmd_buff[4] = font; + + _cmd_buff[5] = FRAME_E0; + _cmd_buff[6] = FRAME_E1; + _cmd_buff[7] = FRAME_E2; + _cmd_buff[8] = FRAME_E3; + _cmd_buff[9] = _verify(_cmd_buff, 9); + + _putchars(_cmd_buff, 10); +} +/******************************************************************************* +* Function Name : void epd_set_ch_font(unsigned char font) +* Description : +* Input : +* Output : None +* Return : +* Attention : None +*******************************************************************************/ +void epd_set_ch_font(unsigned char font) +{ + _cmd_buff[0] = FRAME_B; + + _cmd_buff[1] = 0x00; + _cmd_buff[2] = 0x0A; + + _cmd_buff[3] = CMD_SET_CH_FONT; + + _cmd_buff[4] = font; + + _cmd_buff[5] = FRAME_E0; + _cmd_buff[6] = FRAME_E1; + _cmd_buff[7] = FRAME_E2; + _cmd_buff[8] = FRAME_E3; + _cmd_buff[9] = _verify(_cmd_buff, 9); + + _putchars(_cmd_buff, 10); +} +/******************************************************************************* +* Function Name : void epd_draw_pixel(int x0, int y0) +* Description : +* Input : +* Output : None +* Return : +* Attention : None +*******************************************************************************/ +void epd_draw_pixel(int x0, int y0) +{ + _cmd_buff[0] = FRAME_B; + + _cmd_buff[1] = 0x00; + _cmd_buff[2] = 0x0D; + + _cmd_buff[3] = CMD_DRAW_PIXEL; + + _cmd_buff[4] = (x0 >> 8) & 0xFF; + _cmd_buff[5] = x0 & 0xFF; + _cmd_buff[6] = (y0 >> 8) & 0xFF; + _cmd_buff[7] = y0 & 0xFF; + + _cmd_buff[8] = FRAME_E0; + _cmd_buff[9] = FRAME_E1; + _cmd_buff[10] = FRAME_E2; + _cmd_buff[11] = FRAME_E3; + _cmd_buff[12] = _verify(_cmd_buff, 12); + + _putchars(_cmd_buff, 13); +} +/******************************************************************************* +* Function Name : void epd_draw_line(int x0, int y0, int x1, int y1) +* Description : +* Input : +* Output : None +* Return : +* Attention : None +*******************************************************************************/ +void epd_draw_line(int x0, int y0, int x1, int y1) +{ + _cmd_buff[0] = FRAME_B; + + _cmd_buff[1] = 0x00; + _cmd_buff[2] = 0x11; + + _cmd_buff[3] = CMD_DRAW_LINE; + + _cmd_buff[4] = (x0 >> 8) & 0xFF; + _cmd_buff[5] = x0 & 0xFF; + _cmd_buff[6] = (y0 >> 8) & 0xFF; + _cmd_buff[7] = y0 & 0xFF; + _cmd_buff[8] = (x1 >> 8) & 0xFF; + _cmd_buff[9] = x1 & 0xFF; + _cmd_buff[10] = (y1 >> 8) & 0xFF; + _cmd_buff[11] = y1 & 0xFF; + + _cmd_buff[12] = FRAME_E0; + _cmd_buff[13] = FRAME_E1; + _cmd_buff[14] = FRAME_E2; + _cmd_buff[15] = FRAME_E3; + _cmd_buff[16] = _verify(_cmd_buff, 16); + + _putchars(_cmd_buff, 17); +} +/******************************************************************************* +* Function Name : void epd_fill_rect(int x0, int y0, int x1, int y1) +* Description : +* Input : +* Output : None +* Return : +* Attention : None +*******************************************************************************/ +void epd_fill_rect(int x0, int y0, int x1, int y1) +{ + _cmd_buff[0] = FRAME_B; + + _cmd_buff[1] = 0x00; + _cmd_buff[2] = 0x11; + + _cmd_buff[3] = CMD_FILL_RECT; + + _cmd_buff[4] = (x0 >> 8) & 0xFF; + _cmd_buff[5] = x0 & 0xFF; + _cmd_buff[6] = (y0 >> 8) & 0xFF; + _cmd_buff[7] = y0 & 0xFF; + _cmd_buff[8] = (x1 >> 8) & 0xFF; + _cmd_buff[9] = x1 & 0xFF; + _cmd_buff[10] = (y1 >> 8) & 0xFF; + _cmd_buff[11] = y1 & 0xFF; + + _cmd_buff[12] = FRAME_E0; + _cmd_buff[13] = FRAME_E1; + _cmd_buff[14] = FRAME_E2; + _cmd_buff[15] = FRAME_E3; + _cmd_buff[16] = _verify(_cmd_buff, 16); + + _putchars(_cmd_buff, 17); +} +/******************************************************************************* +* Function Name : void epd_draw_circle(int x0, int y0, int r) +* Description : +* Input : +* Output : None +* Return : +* Attention : None +*******************************************************************************/ +void epd_draw_circle(int x0, int y0, int r) +{ + _cmd_buff[0] = FRAME_B; + + _cmd_buff[1] = 0x00; + _cmd_buff[2] = 0x0F; + + _cmd_buff[3] = CMD_DRAW_CIRCLE; + + _cmd_buff[4] = (x0 >> 8) & 0xFF; + _cmd_buff[5] = x0 & 0xFF; + _cmd_buff[6] = (y0 >> 8) & 0xFF; + _cmd_buff[7] = y0 & 0xFF; + _cmd_buff[8] = (r >> 8) & 0xFF; + _cmd_buff[9] = r & 0xFF; + + + _cmd_buff[10] = FRAME_E0; + _cmd_buff[11] = FRAME_E1; + _cmd_buff[12] = FRAME_E2; + _cmd_buff[13] = FRAME_E3; + _cmd_buff[14] = _verify(_cmd_buff, 14); + + _putchars(_cmd_buff, 15); +} +/******************************************************************************* +* Function Name : void epd_fill_circle(int x0, int y0, int r) +* Description : +* Input : +* Output : None +* Return : +* Attention : None +*******************************************************************************/ +void epd_fill_circle(int x0, int y0, int r) +{ + _cmd_buff[0] = FRAME_B; + + _cmd_buff[1] = 0x00; + _cmd_buff[2] = 0x0F; + + _cmd_buff[3] = CMD_FILL_CIRCLE; + + _cmd_buff[4] = (x0 >> 8) & 0xFF; + _cmd_buff[5] = x0 & 0xFF; + _cmd_buff[6] = (y0 >> 8) & 0xFF; + _cmd_buff[7] = y0 & 0xFF; + _cmd_buff[8] = (r >> 8) & 0xFF; + _cmd_buff[9] = r & 0xFF; + + + _cmd_buff[10] = FRAME_E0; + _cmd_buff[11] = FRAME_E1; + _cmd_buff[12] = FRAME_E2; + _cmd_buff[13] = FRAME_E3; + _cmd_buff[14] = _verify(_cmd_buff, 14); + + _putchars(_cmd_buff, 15); +} +/******************************************************************************* +* Function Name : void epd_draw_triangle(int x0, int y0, int x1, int y1, int x2, int y2) +* Description : +* Input : +* Output : None +* Return : +* Attention : None +*******************************************************************************/ +void epd_draw_triangle(int x0, int y0, int x1, int y1, int x2, int y2) +{ + _cmd_buff[0] = FRAME_B; + + _cmd_buff[1] = 0x00; + _cmd_buff[2] = 0x15; + + _cmd_buff[3] = CMD_DRAW_TRIANGLE; + + _cmd_buff[4] = (x0 >> 8) & 0xFF; + _cmd_buff[5] = x0 & 0xFF; + _cmd_buff[6] = (y0 >> 8) & 0xFF; + _cmd_buff[7] = y0 & 0xFF; + _cmd_buff[8] = (x1 >> 8) & 0xFF; + _cmd_buff[9] = x1 & 0xFF; + _cmd_buff[10] = (y1 >> 8) & 0xFF; + _cmd_buff[11] = y1 & 0xFF; + _cmd_buff[12] = (x2 >> 8) & 0xFF; + _cmd_buff[13] = x2 & 0xFF; + _cmd_buff[14] = (y2 >> 8) & 0xFF; + _cmd_buff[15] = y2 & 0xFF; + + _cmd_buff[16] = FRAME_E0; + _cmd_buff[17] = FRAME_E1; + _cmd_buff[18] = FRAME_E2; + _cmd_buff[19] = FRAME_E3; + _cmd_buff[20] = _verify(_cmd_buff, 20); + + _putchars(_cmd_buff, 21); +} +/******************************************************************************* +* Function Name : void epd_fill_triangle(int x0, int y0, int x1, int y1, int x2, int y2) +* Description : +* Input : +* Output : None +* Return : +* Attention : None +*******************************************************************************/ +void epd_fill_triangle(int x0, int y0, int x1, int y1, int x2, int y2) +{ + _cmd_buff[0] = FRAME_B; + + _cmd_buff[1] = 0x00; + _cmd_buff[2] = 0x15; + + _cmd_buff[3] = CMD_FILL_TRIANGLE; + + _cmd_buff[4] = (x0 >> 8) & 0xFF; + _cmd_buff[5] = x0 & 0xFF; + _cmd_buff[6] = (y0 >> 8) & 0xFF; + _cmd_buff[7] = y0 & 0xFF; + _cmd_buff[8] = (x1 >> 8) & 0xFF; + _cmd_buff[9] = x1 & 0xFF; + _cmd_buff[10] = (y1 >> 8) & 0xFF; + _cmd_buff[11] = y1 & 0xFF; + _cmd_buff[12] = (x2 >> 8) & 0xFF; + _cmd_buff[13] = x2 & 0xFF; + _cmd_buff[14] = (y2 >> 8) & 0xFF; + _cmd_buff[15] = y2 & 0xFF; + + _cmd_buff[16] = FRAME_E0; + _cmd_buff[17] = FRAME_E1; + _cmd_buff[18] = FRAME_E2; + _cmd_buff[19] = FRAME_E3; + _cmd_buff[20] = _verify(_cmd_buff, 20); + + _putchars(_cmd_buff, 21); +} +/******************************************************************************* +* Function Name : void epd_clear(void) +* Description : +* Input : +* Output : None +* Return : +* Attention : None +*******************************************************************************/ +void epd_clear(void) +{ + _cmd_buff[0] = FRAME_B; + + _cmd_buff[1] = 0x00; + _cmd_buff[2] = 0x09; + + _cmd_buff[3] = CMD_CLEAR; + + _cmd_buff[4] = FRAME_E0; + _cmd_buff[5] = FRAME_E1; + _cmd_buff[6] = FRAME_E2; + _cmd_buff[7] = FRAME_E3; + _cmd_buff[8] = _verify(_cmd_buff, 8); + + _putchars(_cmd_buff, 9); +} + +/******************************************************************************* +* Function Name : void epd_disp_char(unsigned char ch, int x0, int y0); +* Description : +* Input : +* Output : None +* Return : +* Attention : None +*******************************************************************************/ +void epd_disp_char(unsigned char ch, int x0, int y0) +{ + unsigned char buff[2]; + + buff[0] = ch; + buff[1] = 0; + + epd_disp_string(buff, x0, y0); +} +/******************************************************************************* +* Function Name : void epd_disp_string(const void * p, int x0, int y0) +* Description : +* Input : +* Output : None +* Return : +* Attention : None +*******************************************************************************/ +void epd_disp_string(const void * p, int x0, int y0) +{ + int string_size; + unsigned char * ptr = (unsigned char *)p; + + + string_size = strlen((const char *)ptr); + string_size += 14; + + _cmd_buff[0] = FRAME_B; + + _cmd_buff[1] = (string_size >> 8) & 0xFF; + _cmd_buff[2] = string_size & 0xFF; + + _cmd_buff[3] = CMD_DRAW_STRING; + + _cmd_buff[4] = (x0 >> 8) & 0xFF; + _cmd_buff[5] = x0 & 0xFF; + _cmd_buff[6] = (y0 >> 8) & 0xFF; + _cmd_buff[7] = y0 & 0xFF; + + strcpy((char *)(&_cmd_buff[8]), (const char *)ptr); + + string_size -= 5; + + _cmd_buff[string_size] = FRAME_E0; + _cmd_buff[string_size + 1] = FRAME_E1; + _cmd_buff[string_size + 2] = FRAME_E2; + _cmd_buff[string_size + 3] = FRAME_E3; + _cmd_buff[string_size + 4] = _verify(_cmd_buff, string_size + 4); + + _putchars(_cmd_buff, string_size + 5); +} +/******************************************************************************* +* Function Name : void epd_disp_bitmap(const void * p, int x0, int y0) +* Description : +* Input : +* Output : None +* Return : +* Attention : None +*******************************************************************************/ +void epd_disp_bitmap(const void * p, int x0, int y0) +{ + int string_size; + unsigned char * ptr = (unsigned char *)p; + + string_size = strlen((const char *)ptr); + string_size += 14; + + _cmd_buff[0] = FRAME_B; + + _cmd_buff[1] = (string_size >> 8) & 0xFF; + _cmd_buff[2] = string_size & 0xFF; + + _cmd_buff[3] = CMD_DRAW_BITMAP; + + _cmd_buff[4] = (x0 >> 8) & 0xFF; + _cmd_buff[5] = x0 & 0xFF; + _cmd_buff[6] = (y0 >> 8) & 0xFF; + _cmd_buff[7] = y0 & 0xFF; + + strcpy((char *)(&_cmd_buff[8]), (const char *)ptr); + + string_size -= 5; + + _cmd_buff[string_size] = FRAME_E0; + _cmd_buff[string_size + 1] = FRAME_E1; + _cmd_buff[string_size + 2] = FRAME_E2; + _cmd_buff[string_size + 3] = FRAME_E3; + _cmd_buff[string_size + 4] = _verify(_cmd_buff, string_size + 4); + + _putchars(_cmd_buff, string_size + 5); +} diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..d77be36 --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,359 @@ +/* + * Copyright Paul Warren 2019 + * + * Released under the terms of the GPLv3 license. + * + *D1Mini: Colour : UART Module + * D5: White : DOUT + * D6: Green : DIN + * D7: Yellow : Wake Up + * D8: Blue : Reset + * + * + */ +#include +#include +#include +#include +#include +#include + +#include "epd.h" +#include "credential.h" +#include "main.h" + +// BOM, see bom_rrd2.py +const String ds_url = "http://pwarren.id.au/darksky/bom.json"; + +bool ds_done = false; + +// Timezone bits + +// Australia Eastern Time Zone (Sydney, Melbourne) +TimeChangeRule aEDT = {"AEDT", First, Sun, Oct, 2, 660}; // UTC + 11 hours +TimeChangeRule aEST = {"AEST", First, Sun, Apr, 3, 600}; // UTC + 10 hours +Timezone ausET(aEDT, aEST); +TimeChangeRule *tcr; + + +// when to wake up the display and get going +int wakeup_seconds = 50; + + +// Network clients +WiFiClient wfclient; +WiFiUDP ntpUDP; +HTTPClient http; +NTPClient timeClient(ntpUDP, "pi.lan", 0, 60000); //use internal ntp server, update every 10 minutes, taking in to account the 9 seconds it takes to update the screen for the current time + +//NTPClient timeClient(ntpUDP, "au.pool.ntp.org", 0, 60000); //use external ntp server, update every 10 minutes + +// defined in "credentials.h" +const char* ssid = ssid_name; // The SSID (name) of your Wi-Fi network +const char* password = ssid_pass; // The password of the Wi-Fi network + +const int led = LED_BUILTIN; + +// Font width +int dwidth = 185; + +// yes this seems backwards but it works... +void ledOn(void) { digitalWrite(led, LOW);} +void ledOff(void) { digitalWrite(led, HIGH);} +void wait(void) { delay(1500);} + + +// globals for the temperature :( +const char* current_outside; +const char* current_bedroom; +const char* current_lounge; + +void setup() { + pinMode(led, OUTPUT); + ledOff(); + + wifi_set_sleep_type(LIGHT_SLEEP_T); + + epd_init(); + epd_wakeup(); + epd_set_memory(MEM_NAND); + epd_set_color(BLACK, WHITE); + epd_set_en_font(ASCII64); + epd_clear(); + + Serial.begin(115200); // Start serial communication + Serial.setTimeout(2000); + while (!Serial) { } + Serial.println("\r\n\r\nSTARTING\r\n"); + + wifi(); + timeClient.begin(); + ntpUpdate(); + /* weatherUpdate(); + printDateTime(1); + + epd_update(); + wait(); */ + ledOff(); +} + +void wifi() { + WiFi.persistent(false); + WiFi.mode(WIFI_OFF); + WiFi.mode(WIFI_STA); + WiFi.begin(ssid, password); // Access WiFi + + Serial.print("Connecting to "); + Serial.print(ssid); + Serial.print(" ..."); + + while (WiFi.status() != WL_CONNECTED) { // Wait for WiFi to connect + delay(250); + Serial.print("."); + } + + Serial.println('\n'); + Serial.println("WiFi connection established"); + Serial.print("Device's IP address is "); + Serial.println(WiFi.localIP()); // Show device's IP address +} + +void ntpUpdate() { + if (timeClient.update()) { + setTime(timeClient.getEpochTime()); + } +} + + +void disp_digit(int digit, int xpos){ + // digit: digit to display + // xpos: X digit position, indexed at 1 + + int dpos = 0; + int ypos = 0; + dpos = ((xpos - 1) * dwidth); + if (xpos > 2) { + dpos += 60; // account for colon + } + switch (digit) { + case 0: + epd_disp_bitmap("0.JPG", dpos, ypos); + break; + case 1: + epd_disp_bitmap("1.JPG", dpos, ypos); + break; + case 2: + epd_disp_bitmap("2.JPG", dpos, ypos); + break; + case 3: + epd_disp_bitmap("3.JPG", dpos, ypos); + break; + case 4: + epd_disp_bitmap("4.JPG", dpos, ypos); + break; + case 5: + epd_disp_bitmap("5.JPG", dpos, ypos); + break; + case 6: + epd_disp_bitmap("6.JPG", dpos, ypos); + break; + case 7: + epd_disp_bitmap("7.JPG", dpos, ypos); + break; + case 8: + epd_disp_bitmap("8.JPG", dpos, ypos); + break; + case 9: + epd_disp_bitmap("9.JPG", dpos, ypos); + break; + } + // wait(); +} + +void disp_time(int hours, int minutes) { + + // first digit of hours + if (hours > 19) { + disp_digit(2, 1); + hours -= 20; + } else if (hours > 9) { + disp_digit(1, 1); + hours -= 10; + } else { + disp_digit(0, 1); + } + + // second hours digit + disp_digit(hours, 2); + + epd_disp_bitmap("COLO.JPG", 2 * dwidth, 0); + delay(500); + + // first minutes digit + if (minutes > 49) { + disp_digit(5, 3); + minutes -= 50; + } else if (minutes > 39) { + disp_digit(4, 3); + minutes -= 40; + } else if (minutes > 29) { + disp_digit(3, 3); + minutes -= 30; + } else if (minutes > 19) { + disp_digit(2, 3); + minutes -= 20; + } else if (minutes > 9) { + disp_digit(1, 3); + minutes -= 10; + } else { + disp_digit(0, 3); + } + + // second minutes digit + disp_digit(minutes, 4); + +} + + +void printDateTime(int update_epd) +{ + char buf[64]; + + time_t t; + t = ausET.toLocal(now()+60, &tcr); + + char m[4]; // temporary storage for month string (DateStrings.cpp uses shared buffer) + strncpy(m, monthShortStr(month(t)), 4); + sprintf(buf, "%.2d:%.2d:%.2d", hour(t), minute(t), second(t)); + Serial.print(buf); Serial.print(" "); + + if (update_epd > 0) { + Serial.println("Adding Time"); + disp_time(hour(t), minute(t)); + } + + sprintf(buf, "%s %.2d %s %d", + dayShortStr(weekday(t)), + day(t), + m, + year(t)); + + Serial.println(buf); + + if (update_epd > 0) { + Serial.println("Adding Date"); + epd_set_en_font(ASCII64); + epd_disp_string(buf, 50, 225); + } +} + +void weatherUpdate(void) { + char buf[64]; + const size_t capacity = 4*JSON_OBJECT_SIZE(3) + JSON_OBJECT_SIZE(4) + 150; + DynamicJsonDocument jsonBuffer(capacity); + + http.begin(wfclient, ds_url); + int httpCode = http.GET(); + + if (httpCode > 0) { + auto error = deserializeJson(jsonBuffer, http.getString()); + if (error) { + Serial.print("Failed to parse json"); + return; + } + http.end(); + + const char* today_day = jsonBuffer["today"]["day"]; // "Wednesday" + const char* today_icon = jsonBuffer["today"]["icon"]; // "sunny.jpg" + int today_max = jsonBuffer["today"]["max"]; // "27" + + const char* tomorrow_day = jsonBuffer["tomorrow"]["day"]; // "Thursday" + const char* tomorrow_icon = jsonBuffer["tomorrow"]["icon"]; // "sunny.jpg" + int tomorrow_max = jsonBuffer["tomorrow"]["max"]; // "31" + + const char* day_after_day = jsonBuffer["day_after"]["day"]; // "Friday" + const char* day_after_icon = jsonBuffer["day_after"]["icon"]; // "pcloud.jpg" + int day_after_max = jsonBuffer["day_after"]["max"]; // "33" + + int current_outside = jsonBuffer["current"]["outside"]; + int current_bedroom = jsonBuffer["current"]["bedroom"]; + int current_lounge = jsonBuffer["current"]["lounge"]; + + Serial.println("Updating EPD with weather"); + + epd_set_en_font(ASCII64); + + //Today + epd_disp_bitmap(today_icon, 0, 290); + epd_disp_string(today_day, 0, 536); + sprintf(buf, "%d", today_max); + epd_disp_string(buf, 75, 460); + + //Tomorrow + epd_disp_bitmap(tomorrow_icon, 267, 290); + epd_disp_string(tomorrow_day, 260, 536); + sprintf(buf, "%d", tomorrow_max); + epd_disp_string(buf, 352, 460); + + //Day After + epd_disp_bitmap(day_after_icon, 533, 290); + epd_disp_string(day_after_day, 533, 536); + sprintf(buf, "%d", day_after_max); + epd_disp_string(buf, 615, 460); + + //Serial.println("Adding Temps"); + sprintf(buf, "E: %d I: %d", + current_outside, + current_lounge); + //Serial.println(buf); + epd_disp_string(buf, 500, 225); + + } else { + Serial.print("Error on HTTP Request: "); + Serial.println(httpCode); + } + +} + +void loop() { + int sleep_seconds = 0; + + Serial.println("Back from sleep!"); + + if (WiFi.status() != WL_CONNECTED) { + wifi(); + } + + ntpUpdate(); + + if (second(now()) >= wakeup_seconds) { + epd_wakeup(); + epd_clear(); + weatherUpdate(); + Serial.print("Weather details sent: "); + Serial.println(second(now())); + printDateTime(1); + Serial.println("Waiting on minute to change"); + while (second(now()) != 0) { + delay(500); + } + + } + Serial.println("EPD Update"); + epd_update(); + delay(4000); + Serial.println("EPD Stop"); + epd_enter_stopmode(); + + sleep_seconds = wakeup_seconds - second(now()); + + if (sleep_seconds < 0) { + sleep_seconds = 10; + } + + Serial.print("Sleeping for: "); + Serial.println(sleep_seconds); + + delay(sleep_seconds * 1000); + +} diff --git a/test/README b/test/README new file mode 100644 index 0000000..9b1e87b --- /dev/null +++ b/test/README @@ -0,0 +1,11 @@ + +This directory is intended for PlatformIO Test Runner and project tests. + +Unit Testing is a software testing method by which individual units of +source code, sets of one or more MCU program modules together with associated +control data, usage procedures, and operating procedures, are tested to +determine whether they are fit for use. Unit testing finds problems early +in the development cycle. + +More information about PlatformIO Unit Testing: +- https://docs.platformio.org/en/latest/advanced/unit-testing/index.html