首页 > 技术文章 > ESP8266 ESP-01制作B站粉丝计数器 | Arduino IDE开发ESP8266 | ESP8266存储读取用户数据

cai-zi 2020-11-28 12:32 原文

1.实物图

2.元件清单

 

 

 

 

3.原理图

 

4.Arduino程序

在程序中修改自己的B站UID和自己家的WiFi名称及密码即可。

/*B站粉丝计数器*/
/*************************************************************
  ESP8266 with 0.96寸 OLED 引脚
      VCC    <--->    VCC
      GND    <--->    GND
      SDA    <--->    SDA(D4 2)  
      SCL    <--->    SCL(D5 14)
 *************************************************************/
#if defined(ESP32) //ESP32
#include <WiFi.h>
#include <HTTPClient.h>
#include <WebServer.h>
#include <ESPmDNS.h>
#elif defined(ESP8266) //ESP8266
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <ESP8266WebServer.h>
#include <ESP8266mDNS.h>
#else
#error "Please check your mode setting,it must be esp8266 or esp32."
#endif

#include <ArduinoJson.h> //安装ArduinoJson库
#include <U8g2lib.h> // 安装U8g2库
#include <Wire.h>
#include <Ticker.h>
#include <EEPROM.h>

// 定时器
Ticker timer;
int count = 0;
boolean flag = true;

// JSON
DynamicJsonBuffer jsonBuffer(256); // ArduinoJson V5

// 显示屏  如果引脚不同需要在这里修改
//U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE, /* clock=*/ 14, /* data=*/ 2);  //NODEMCU
U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE, /* clock=*/ 2, /* data=*/ 0);  //ESP-01

// WiFi 名称与密码
const char *ssid = "xxxxxx"; //这里填你家中的wifi名称
const char *password = "xxxxxx";//这里填你家中的wifi密码


// B 站 API 网址
String NAME = "CaiZi";  //改成自己的名字
String UID  = "349576976";  //改成自己的UID
String followerUrl = "http://api.bilibili.com/x/relation/stat?vmid=" + UID;   // 粉丝数
String viewAndLikesUrl = "http://api.bilibili.com/x/space/upstat?mid=" + UID; // 播放数、点赞数

int follower = 0;   // 粉丝数
int view = 0;       // 播放数
int likes = 0;      // 获赞数
union long_value //联合体
{
  int follower;
  byte fans[2];
};
long_value followerE;//声明联合体
byte fan1;
byte fan2;
  
void setup()
{
  // OLED初始化
  u8g2.begin();
  u8g2.enableUTF8Print();
  u8g2.clearDisplay();
  // EEPROM初始化
  EEPROM.begin(512);//开辟512字节的空间
  fan1 = EEPROM.read(0);
  fan2 = EEPROM.read(1);
  followerE.fans[0] = fan1;//赋值给数组
  followerE.fans[1] = fan2;
  follower = followerE.follower;

  // 显示上次开机的粉丝数
  u8g2.setFontPosTop();
  u8g2.firstPage();
  do
  {
    displayNum();
  } 
  while (u8g2.nextPage());
    
  Serial.begin(115200);//设置串口波特率

  // WiFi 连接
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED)
  {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi connected");

  timer.attach(600, timerCallback); // 每隔10min
}

void loop()
{
  while (flag)
  {
    u8g2.firstPage();
    do
    {
      displayNum();
    } 
    while (u8g2.nextPage());
    // 获取粉丝数
    getFollower(followerUrl);
    // 获取播放数和点赞数
    getViewAndLikes(viewAndLikesUrl);
    flag = false;
  }
}

// OLED 显示数据
void displayNum()
{
//  u8g2.clearDisplay();
  u8g2.setFont(u8g2_font_osb41_tn);//设置41*41字体
  u8g2.setCursor(0, 8);
  u8g2.print(String(follower));
//  u8g2.setFont(u8g2_font_wqy12_t_gb2312b);//设置12*12字体
//  u8g2.setCursor(0, 0);
//  u8g2.print("      Bilibili " + String(NAME)); //改成自己的名字
//  u8g2.setCursor(0, 38);
//  u8g2.print("获赞数:" + String(likes));
//  u8g2.setCursor(0, 52);
//  u8g2.print("播放数:" + String(view));
}

// 定时器回调函数
void timerCallback()
{
  flag = true;
}

// 获取 B 站粉丝数
void getFollower(String url)
{
  HTTPClient http;
  http.begin(url);

  int httpCode = http.GET();
  Serial.printf("[HTTP] GET... code: %d\n", httpCode);

  if (httpCode == 200)
  {
    Serial.println("获取粉丝数成功!");
    String resBuff = http.getString();
//    Serial.println(resBuff);
    // ---------- ArduinoJson V5 ----------
    JsonObject &root = jsonBuffer.parseObject(resBuff);
    if (!root.success())
    {
      Serial.println("parseObject() failed");
      return;
    }
    follower = root["data"]["follower"];
    
    followerE.follower = follower;
    EEPROM.write(0, followerE.fans[0]); //EEPROM.write(位置,数据)
    EEPROM.write(1, followerE.fans[1]); //分成两字节存储
    EEPROM.commit();           //commit
    
    Serial.print("粉丝数: ");
    Serial.println(follower);
  }
  else
  {
    Serial.printf("[HTTP] GET... failed, error: %d\n", httpCode);
  }

  http.end();
}

// 获取 B 站播放数与获赞数
void getViewAndLikes(String url)
{
  HTTPClient http;
  http.begin(url);

  int httpCode = http.GET();
  Serial.printf("[HTTP] GET... code: %d\n", httpCode);

  if (httpCode == 200)
  {
    Serial.println("获取播放数、点赞数成功!");
    String resBuff = http.getString();
//    Serial.println(resBuff);
    
    JsonObject &root = jsonBuffer.parseObject(resBuff);
    if (!root.success())
    {
      Serial.println("parseObject() failed");
      return;
    }
    
    view = root["data"]["archive"]["view"];
    likes = root["data"]["likes"];
    Serial.print("点赞数: ");
    Serial.println(likes);
    Serial.print("播放数: ");
    Serial.println(view);
  }
  else
  {
    Serial.printf("[HTTP] GET... failed, error: %d\n", httpCode);
  }

  http.end();
}

5.烧录程序

将ESP8266与USB-TTL按照下面的接线图进行连接。必须使用下面这种免冷启动的(内部芯片为CH340C)

 

esp8266-01板的arduino烧写方式分享

  UTXD—–RXD

  URXD—–TXD

  CH_PD—-3.3v

  VCC——-3.3V

  GND——GND

  GPIO0—–GND

将连接好ESP8266的USB-TTL插在电脑上,

搭建开发环境请参考笔者这篇博客,Arduino IDE搭建ESP8266开发环境,文件下载过慢解决方法

然后对IDE进行如下设置,选择开发板:

你可以上传ESP8266WIFI的相关程序了。

  注意事项

  1.esp8266-01板对电压的要求很高,烧写时电源一定要采用3.3V左右。

  2.如果代码无法上传,并显示警告,请检查USB-TTL是否良好(某些USB-TTL烧写时无法打开串口,导致上传失败)。

  3.ESP8266与USB-TTL需要RX,TX交叉连接。

  4.CH_PD这个引脚无论是烧程序也好,烧完程序应用也好,都要接3.3V。

  5.GPIO0这个引脚在烧程序的时候必须接GND(接低电平),烧完程序后想要进行应用的话,必须将这个引脚拉高或者悬空。

 

参考:https://zhuanlan.zhihu.com/p/136243798

推荐阅读