B站粉丝数显示器代码解析学习

代码来源B站@会飞的阿卡林https://www.bilibili.com/video/BV14W41167tY

学习使用ESP8266的WIFI无线连接,在这里可以了解到SPI协议在Arduino中的使用,后来也使用ESP8266做了其他项目,阿卡林的项目对我帮助很大,结合后端可以实现不少的功能,作为物联网网关使用!

//硬件连接说明:
 //MAX7219 --- ESP8266
 //  VCC   --- 3V(3.3V)
 //  GND   --- G (GND)
 //  DIN   --- D7(GPIO13)
 //  CS    --- D1(GPIO5)
 //  CLK   --- D5(GPIO14)

代码各部分功能解析

/*2019/04/15更新说明:v1.2
  1. 删除串口监视器输入数字测试显示功能.
  2. 增加数码管显示故障码功能.
     E1--WiFi连接中断, 重连中.
     E2--HTTP请求错误, 当前网络不通畅或请求被拒.
     E3--API返回结果错误, 请检查输入的UID是否正确.
     E4--JSON格式错误, 请检查当前网络是否需要认证登陆.*/

/*2018/12/18更新说明:v1.1
  1. 上电后数码管显示初始化为"--------", 直到获取到粉丝数.
  2. 可从串口监视器输入数字测试显示连接是否正常, 波特率选择9600.*/

 //硬件连接说明:
 //MAX7219 --- ESP8266
 //  VCC   --- 3V(3.3V)
 //  GND   --- G (GND)
 //  DIN   --- D7(GPIO13)
 //  CS    --- D1(GPIO5)
 //  CLK   --- D5(GPIO14)

#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <ArduinoJson.h>
#include <SPI.h>                //引用SPI接口SPI接口包含MOSI, MISO,SCK,CS四根线。
                                //其中MOSI, MISO,SCK已经固定引脚。而CS为片选引脚,可随意选择哪个引脚作为CS.
//---------------修改此处""内的信息-----------------------
const char *ssid = "TOPSKY1";          //WiFi名
const char *password = "hzhhzhhzh";  //WiFi密码
String biliuid = "326499679";         //bilibili UID
//-------------------------------------------------------

const unsigned long HTTP_TIMEOUT = 5000;
WiFiClient client;
HTTPClient http;
String response;
int follower = 0;
const int slaveSelect = 5;     //设置片选引脚信号
const int scanLimit = 7;

void setup(){
    Serial.begin(9600);
    while (!Serial)
        continue;
    Serial.println("bilibili fans monitor, version v1.2");

    SPI.begin();                //初始化SPI
    pinMode(slaveSelect, OUTPUT);
    digitalWrite(slaveSelect, LOW);
    sendCommand(12, 1);         //关闭打开
    sendCommand(15, 0);         //显示测试,no
    sendCommand(10, 15);        //显示强度,15(最大)
    sendCommand(11, scanLimit); //ScanLimit扫描极限,8-1=7
    sendCommand(9, 255);        //解码模式,Code B decode for digits 7-0   数字7-0的代码B解码
    digitalWrite(slaveSelect, HIGH);
    initdisplay();              //显示准备模式
    Serial.println("LED Ready");

    Serial.print("Connecting WiFi...");
    WiFi.mode(WIFI_STA);
    WiFi.begin(ssid, password);
    while (WiFi.status() != WL_CONNECTED){
        delay(500);
        Serial.print(".");
    }
    Serial.println("");
    Serial.println("WiFi connected");
    Serial.println("IP address: ");
    Serial.println(WiFi.localIP());
}

bool getJson(){                                                                //获取json数据
    bool r = false;
    http.setTimeout(HTTP_TIMEOUT);
    http.begin("http://api.bilibili.com/x/relation/stat?vmid=" + biliuid);     //发送获取数据的指令
    //delay(1000);
    int httpCode = http.GET();                                                 //获取返回的json数据
    if (httpCode > 0){                                                         //判断是否有数据
        if (httpCode == HTTP_CODE_OK){
            response = http.getString();
            //Serial.println(response);
            r = true;
        }
    }else{
        Serial.printf("[HTTP] GET JSON failed, error: %s\n", http.errorToString(httpCode).c_str());
        errorCode(0x2);  //发送错误代码
        r = false;
    }
    http.end();
    return r;
}

bool parseJson(String json)  //分析json数据
{
    const size_t capacity = JSON_OBJECT_SIZE(4) + JSON_OBJECT_SIZE(5) + 70;
    DynamicJsonDocument doc(capacity);
    deserializeJson(doc, json);

    int code = doc["code"];
    const char *message = doc["message"];

    if (code != 0){
        Serial.print("[API]Code:");
        Serial.print(code);
        Serial.print(" Message:");
        Serial.println(message);
        errorCode(0x3);
        return false;
    }

    JsonObject data = doc["data"];           //获取Json的data数据
    unsigned long data_mid = data["mid"];    //获取data中的mid(uid)数据
    int data_follower = data["follower"];    //获取data中的fillower(粉丝数)数据
    if (data_mid == 0){
        Serial.println("[JSON] FORMAT ERROR");
        errorCode(0x4);
        return false;
    }
    Serial.print("UID: ");
    Serial.print(data_mid);
    Serial.print(" follower: ");
    Serial.println(data_follower);
    Serial.print("data: ");
    Serial.println(data);

    follower = data_follower;
    return true;
}

void sendCommand(int command, int value)             //放入数据
{
    digitalWrite(slaveSelect, LOW);
    SPI.transfer(command);                           //指定位置
    SPI.transfer(value);                             //发送数据
    digitalWrite(slaveSelect, HIGH);
}

void displayNumber(int number)                       //将数字展示在中间
{
    if (number < 0 || number > 99999999)
        return;
    int x = 1;
    int tmp = number;
    for (x = 1; tmp /= 10; x++);
    for (int i = 1; i < 9; i++)
    {
        if (i < (10 - x) / 2 || i >= (x / 2 + 5)){
            sendCommand(i, 0xf);
        }else{
            int character = number % 10;
            sendCommand(i, character);
            number /= 10;
        }
    }
}

void initdisplay()                               //显示加载状态
{
    sendCommand(8, 0xa);
    sendCommand(7, 0xa);
    sendCommand(6, 0xa);
    sendCommand(5, 0xa);
    sendCommand(4, 0xa);
    sendCommand(3, 0xa);
    sendCommand(2, 0xa);
    sendCommand(1, 0xa);
}

void loop()
{
    if (WiFi.status() == WL_CONNECTED){      //判断wifi是否还在连接
        if (getJson()){                      //获取数据
            if (parseJson(response)){        //分析数据
                displayNumber(follower);     //展示数据
            }
        }
    }else{
        Serial.println("[WiFi] Waiting to reconnect...");
        errorCode(0x1);
    }
    delay(1000);
}

void errorCode(byte errorcode)               //显示错误代码
{
    sendCommand(8, 0xa);
    sendCommand(7, 0xa);
    sendCommand(6, 0xa);
    sendCommand(5, 0xb);
    sendCommand(4, errorcode);
    sendCommand(3, 0xa);
    sendCommand(2, 0xa);
    sendCommand(1, 0xa);
}

教你做一个B站粉丝数显示器,只需20块钱!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值