2019년 12월 2일 월요일

Get number of new mails from GMail on Wemos D1 mini ESP8266

Wemos D1 mini ESP8266 을 이용해서 Gmail 의 새편지 갯수 구하기


ESP8266 에서 Gmail 접속을 위해서는 Gmail 의 보안 수준을 설정해야 한다.
https://myaccount.google.com/lesssecureapps 에서 'ON'
8x8 도트매트릭스 MAX7219는 SPI로 통신하는데 핀제어로 자료를 보낸다.
5V    - MAX7219 VCC
GND - MAX7219 GND
PIN2 - MAX7219 DIN (MOSI)
PIN0 - MAX7219 CS
PIN4 - MAX7219 CLK
전원인가후 WiFi 에 접속하고, Gmail 에 접속해서 새편지 갯수를 가져온다.
새편지가 있으면 숫자를 보여주고 새편지가 없으면 점을 하나 찍는다.
약 2분마다 새편지 확인을 반복한다.



#include <ESP8266WiFi.h>
#include <ESP8266WiFiMulti.h>
#include <WiFiClientSecure.h>

#define GMAIL_ID_PW  "id@gmail.com:password"
#define WIFI_SSID    "wifi_ssid"
#define WIFI_PW      "wifi_password"

#define MAX7219_CS   0
#define MAX7219_DIN  2
#define MAX7219_CLK  4

const byte EngFont[8*17] = {
    0x00,0x7E,0xFF,0x81,0x81,0xFF,0x7E,0x00,    // Number 0
    0x00,0x00,0x21,0x7F,0xFF,0x01,0x00,0x00,    // Number 1
    0x00,0x43,0xC7,0x8D,0x99,0xF1,0x61,0x00,    // Number 2
    0x00,0x42,0xC3,0x91,0x91,0xFF,0x6E,0x00,    // Number 3
    0x00,0x0C,0x1C,0x34,0x64,0xFF,0x04,0x00,    // Number 4
    0x00,0xF2,0xF3,0x91,0x91,0x9F,0x8E,0x00,    // Number 5
    0x00,0x7E,0xFF,0x91,0x91,0xDF,0x4E,0x00,    // Number 6
    0x00,0x80,0x80,0x8F,0xBF,0xF0,0xC0,0x00,    // Number 7
    0x00,0x6E,0xFF,0x91,0x91,0xFF,0x6E,0x00,    // Number 8
    0x00,0x70,0xF9,0x89,0x89,0xFF,0x7E,0x00,    // Number 9
    0x00,0x00,0x00,0x06,0x06,0x00,0x00,0x00,    // WiFi .
    0x00,0x08,0x10,0x16,0x16,0x10,0x08,0x00,    // WiFi o
    0x20,0x48,0x50,0x56,0x56,0x50,0x48,0x20,    // WiFi O
    0x7E,0x62,0x52,0x4A,0x4A,0x52,0x62,0x7E,    // Mail check
    0xF8,0xA8,0xA8,0x00,0x1F,0x12,0x12,0x0C,    // Error Parse
    0xF8,0xA8,0xA8,0x00,0x0E,0x11,0x11,0x0A,    // Error Connect
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00     // Empty
};

ESP8266WiFiMulti gWifi;
int gStatus;
int gTic;
int gNum;
byte mPrevChar;

void Max7219Command (byte reg, byte data) {
    digitalWrite (MAX7219_CS, LOW);
    for (byte i=0; i<8; i++) {
        digitalWrite (MAX7219_CLK, LOW);
        digitalWrite (MAX7219_DIN, (reg<<i)&128);
        digitalWrite (MAX7219_CLK, HIGH);
    }
    for (byte i=0; i<8; i++) {
        digitalWrite (MAX7219_CLK, LOW);
        digitalWrite (MAX7219_DIN, (data<<i)&128);
        digitalWrite (MAX7219_CLK, HIGH);
    }
    digitalWrite (MAX7219_CS,  HIGH);
    digitalWrite (MAX7219_DIN, HIGH);
}

void Max7219Put (byte c) {
    mPrevChar = c;
    for (int i=0; i<8; i++) {
        if (c < 64) Max7219Command (8-i, EngFont[c*8+i]);
        else Max7219Command (8-i, ((c>>3)&7)==i ? 128>>(c&7) : 0);
    }
}

void Max7219Fade (byte c) {
    byte a, b, o=mPrevChar;
    delay (0);
    for (a=1; a<32; a++) {
        for (b=a; b<32; b++) Max7219Put (o);
        for (b=0; b< a; b++) Max7219Put (c);
    }
}

void Max7219Bf (byte c) {
    Max7219Fade (16);
    Max7219Fade (c);
}

const char int2base[65] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
void Text2Base64 (const char *rp, char *wp) {
    int i, len, bits;
    for (len=strlen(rp); 0<len; len-=3) {
        for (i=0; i<3; i++) ((char *)&bits)[2-i] = (i < len) ? *rp++ : 0;
        for (i=0; i<4; i++) *wp++ = (len < i) ? '=' : int2base[(bits>>((3-i)*6))&63];
    }
    *wp = 0;
}

int GetGmailHttp () {
    WiFiClientSecure client;
    char base64[64];
    int num;
    
    client.setInsecure ();
    if (!client.connect ("mail.google.com", 443)) return 15;
    
    Text2Base64 (GMAIL_ID_PW, base64);
    client.print (
        "GET /mail/feed/atom HTTP/1.1\r\n"
        "Host: mail.google.com\r\n"
        "Connection: close\r\n"
        "Authorization: Basic "
    );
    client.print (base64);
    client.print ("\r\n\r\n");
    
    num = 14;
    while (client.connected ()) {
        client.readStringUntil ('<');
        String tn = client.readStringUntil ('<');
        if (tn == "fullcount") {
            num = client.readStringUntil ('<').toInt ();
            if (9 < num) num = 9;
            break;
        }
    }
    client.stop ();
    return num;
}

void loop() {
    delay (1000);
    
    if (gWifi.run () != WL_CONNECTED) {
        gStatus = 0;
        gTic = (gTic+1) % 3;
        Max7219Fade (10+gTic);
        return;
    }
    
    if (gStatus == 0) {
        gStatus = 1;
        gTic = -1;
        gNum = -1;
    }
    
    gTic = (gTic + 1) & 63;
    if (gNum == 0) Max7219Bf (64+gTic);
    if (gTic) {
        if (0 < gNum) Max7219Bf (gNum);
        return;
    }
    
    if (gNum) Max7219Bf (13);
    gNum = GetGmailHttp ();
    if (gNum == 0) Max7219Bf (64+(++gTic));
    else Max7219Bf (gNum);
}

void setup() {
    gStatus = 0;
    gTic =  0;
    pinMode (MAX7219_DIN, OUTPUT);
    pinMode (MAX7219_CLK, OUTPUT);
    pinMode (MAX7219_CS,  OUTPUT);
    digitalWrite (MAX7219_DIN, HIGH);
    digitalWrite (MAX7219_CLK, HIGH);
    digitalWrite (MAX7219_CS,  HIGH);
    delay (50);
    
    Max7219Command (12, 1);
    Max7219Command (11, 7);
    Max7219Command ( 9, 0);
    Max7219Command (15, 0);
    Max7219Command (10, 0);
    Max7219Command (12, 1);
    Max7219Put (16);
    gWifi.addAP (WIFI_SSID, WIFI_PW);
    delay (500);
    
    Max7219Fade (10);
}