Initial version

This commit is contained in:
Paul Warren 2023-04-19 22:02:59 +10:00
commit 5098586216
9 changed files with 1410 additions and 0 deletions

4
.gitignore vendored Normal file
View File

@ -0,0 +1,4 @@
.pio
*~
*credential.h

39
include/README Normal file
View File

@ -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

156
include/epd.h Normal file
View File

@ -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

11
include/main.h Normal file
View File

@ -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);

46
lib/README Normal file
View File

@ -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 <Foo.h>
#include <Bar.h>
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

18
platformio.ini Normal file
View File

@ -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

766
src/epd.cpp Normal file
View File

@ -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 <Arduino.h>
#include <SoftwareSerial.h>
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);
}

359
src/main.cpp Normal file
View File

@ -0,0 +1,359 @@
/*
* Copyright Paul Warren 2019 <pwarren@pwarren.id.au>
*
* 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 <ESP8266HTTPClient.h>
#include <ESP8266WiFi.h>
#include <WiFiUdp.h>
#include <NTPClient.h>
#include <Timezone.h>
#include <ArduinoJson.h>
#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);
}

11
test/README Normal file
View File

@ -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