basic function OK
This commit is contained in:
parent
32e1eb8958
commit
97d17ada7c
|
@ -0,0 +1,24 @@
|
|||
# 各省对应的 LED 位
|
||||
|
||||
此表为 Mapuino 上实际闪烁的 LED 所在省级行政区与 HTTP 报文中 `data0`、`data1` 字段的对应关系。
|
||||
|
||||
| 省 | 字段 | 位 | 省 | 字段 | 位 |
|
||||
|----|-----|----|----|------|---|
|
||||
| 新疆 | data0 | 0 | 内蒙古 | data0 | 1 |
|
||||
| 黑龙江 | data0 | 2 | 吉林 | data0 | 3 |
|
||||
| 辽宁 | data0 | 4 | 北京 | data0 | 5 |
|
||||
| 天津 | data0 | 6 | 青海 | data0 | 7 |
|
||||
| 甘肃 | data0 | 8 | 宁夏 | data0 | 9 |
|
||||
| 陕西 | data0 | 10 | 山西 | data0 | 11 |
|
||||
| 河北 | data0 | 12 | 山东 | data0 | 13 |
|
||||
| 河南 | data0 | 14 | 西藏 | data0 | 15 |
|
||||
| 四川 | data0 | 16 | 重庆 | data0 | 17 |
|
||||
| 湖北 | data0 | 18 | 安徽 | data0 | 19 |
|
||||
| 江苏 | data0 | 20 | 云南 | data0 | 21 |
|
||||
| 贵州 | data0 | 22 | 湖南 | data0 | 23 |
|
||||
| 江西 | data0 | 24 | 浙江 | data0 | 25 |
|
||||
| 上海 | data0 | 26 | 广西 | data0 | 27 |
|
||||
| 广东 | data0 | 28 | 福建 | data0 | 29 |
|
||||
| 海南 | data0 | 30 | 澳门 | data0 | 31 |
|
||||
| 香港 | data1 | 0 | 台湾 | data1 | 1 |
|
||||
| World | data1 | 2 |
|
|
@ -0,0 +1,20 @@
|
|||
#include <Arduino.h>
|
||||
#include <ESP8266WiFi.h>
|
||||
#include <ESP8266HTTPClient.h>
|
||||
#include <WiFiClient.h>
|
||||
#include <ArduinoJson.h>
|
||||
|
||||
class ClientNetwork
|
||||
{
|
||||
private:
|
||||
String url;
|
||||
StaticJsonDocument<512> receivedData;
|
||||
HTTPClient* http;
|
||||
STATUS status;
|
||||
|
||||
public:
|
||||
ClientNetwork();
|
||||
STATUS FetchNewData();
|
||||
uint32_t GetData0();
|
||||
uint32_t GetData1();
|
||||
};
|
|
@ -0,0 +1,15 @@
|
|||
#include <Arduino.h>
|
||||
#include <ESP8266WiFi.h>
|
||||
#include <ESP8266WebServer.h>
|
||||
|
||||
class ConfigManager
|
||||
{
|
||||
private:
|
||||
IPAddress localIp;
|
||||
IPAddress gateway;
|
||||
IPAddress subnet;
|
||||
public:
|
||||
ESP8266WebServer httpServer;
|
||||
ConfigManager();
|
||||
void ProcessConfig();
|
||||
};
|
|
@ -0,0 +1,12 @@
|
|||
#include <Arduino.h>
|
||||
#include <TM1638plus.h>
|
||||
|
||||
class DisplayPanel
|
||||
{
|
||||
private:
|
||||
TM1638plus* ledMap;
|
||||
|
||||
public:
|
||||
DisplayPanel();
|
||||
void DisplayLedMap(uint32_t data0, uint32_t data1);
|
||||
};
|
|
@ -0,0 +1,11 @@
|
|||
#include <Arduino.h>
|
||||
|
||||
class FuncButton
|
||||
{
|
||||
private:
|
||||
uint8_t pressedTime;
|
||||
|
||||
public:
|
||||
FuncButton();
|
||||
void Scan();
|
||||
};
|
|
@ -0,0 +1,10 @@
|
|||
// Topuino and Topuino_Server must share this header file
|
||||
|
||||
#define CPU_PERCENT "CPU_PERCENT"
|
||||
#define MEM_PERCENT "MEM_PERCENT"
|
||||
#define DISK0_PERCENT "DISK_PERCENT"
|
||||
#define DISK1_PERCENT "DISK1_PERCENT"
|
||||
#define DISK_READ_RATE "DISK_READ_RATE"
|
||||
#define DISK_WRITE_RATE "DISK_WRITE_RATE"
|
||||
#define NET_SENT_RATE "NET_SENT_RATE"
|
||||
#define NET_RECV_RATE "NET_RECV_RATE"
|
|
@ -0,0 +1,21 @@
|
|||
#include <Arduino.h>
|
||||
#include <Ticker.h>
|
||||
|
||||
#define STATUS_LED_PIN 2
|
||||
|
||||
class StatusBlink
|
||||
{
|
||||
private:
|
||||
Ticker flipper;
|
||||
|
||||
public:
|
||||
enum BlinkRate {
|
||||
RateAlwaysOn,
|
||||
Rate5Hz,
|
||||
Rate2Hz,
|
||||
Rate0_5Hz,
|
||||
RateAlwaysOff,
|
||||
};
|
||||
StatusBlink();
|
||||
void SetBlinkRate(BlinkRate rate);
|
||||
};
|
|
@ -0,0 +1,19 @@
|
|||
#include <Arduino.h>
|
||||
|
||||
class UserData
|
||||
{
|
||||
private:
|
||||
String ReadEepromString(uint32_t offset);
|
||||
void WriteEepromString(String data, uint32_t offset);
|
||||
public:
|
||||
UserData();
|
||||
bool UserDataValid();
|
||||
void ConfirmData();
|
||||
void EraseData();
|
||||
String GetWifiSsid();
|
||||
void SetWifiSsid(String ssid);
|
||||
String GetWifiPasswd();
|
||||
void SetWifiPasswd(String password);
|
||||
String GetDeviceUuid();
|
||||
void SetDeviceUuid(String uuid);
|
||||
};
|
46
lib/README
46
lib/README
|
@ -1,46 +0,0 @@
|
|||
|
||||
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
|
|
@ -12,3 +12,6 @@
|
|||
platform = espressif8266
|
||||
board = esp12e
|
||||
framework = arduino
|
||||
lib_deps =
|
||||
gavinlyonsrepo/TM1638plus@^1.7.0
|
||||
bblanchon/ArduinoJson@^6.18.3
|
||||
|
|
|
@ -0,0 +1,61 @@
|
|||
#include "client_network.h"
|
||||
#include "status_blink.h"
|
||||
#include "user_data.h"
|
||||
#include "func_button.h"
|
||||
|
||||
extern StatusBlink* statusLed;
|
||||
extern UserData* userdataManager;
|
||||
extern FuncButton* funcButton;
|
||||
|
||||
ClientNetwork::ClientNetwork()
|
||||
{
|
||||
WiFi.begin(userdataManager->GetWifiSsid(), userdataManager->GetWifiPasswd());
|
||||
|
||||
statusLed->SetBlinkRate(StatusBlink::BlinkRate::Rate2Hz);
|
||||
while (WiFi.status() != WL_CONNECTED)
|
||||
{
|
||||
delay(1000);
|
||||
funcButton->Scan();
|
||||
}
|
||||
statusLed->SetBlinkRate(StatusBlink::BlinkRate::RateAlwaysOff);
|
||||
url = "http://iot.vvzero.com/mapuino/hardwareAPI?UUID=";
|
||||
url += userdataManager->GetDeviceUuid();
|
||||
status = FAIL;
|
||||
}
|
||||
|
||||
STATUS ClientNetwork::FetchNewData()
|
||||
{
|
||||
status = FAIL;
|
||||
if (WiFi.status() == WL_CONNECTED) {
|
||||
WiFiClient client;
|
||||
http = new HTTPClient();
|
||||
if (http->begin(client, url)) {
|
||||
if (http->GET() == HTTP_CODE_OK) {
|
||||
if (deserializeJson(receivedData, http->getString().c_str()) == DeserializationError::Code::Ok) {
|
||||
status = OK;
|
||||
}
|
||||
}
|
||||
http->end();
|
||||
}
|
||||
delete http;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
uint32_t ClientNetwork::GetData0()
|
||||
{
|
||||
if (status != OK) {
|
||||
return 0;
|
||||
} else {
|
||||
return (uint32_t)receivedData["DATA0"];
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t ClientNetwork::GetData1()
|
||||
{
|
||||
if (status != OK) {
|
||||
return 0;
|
||||
} else {
|
||||
return (uint32_t)receivedData["DATA1"];
|
||||
}
|
||||
}
|
|
@ -0,0 +1,88 @@
|
|||
#include "config_manager.h"
|
||||
#include "status_blink.h"
|
||||
#include "user_data.h"
|
||||
|
||||
#define SSID "Topuino"
|
||||
#define PASSWORD "vvzero.com"
|
||||
|
||||
extern StatusBlink* statusLed;
|
||||
extern ConfigManager* configManager;
|
||||
extern UserData* userdataManager;
|
||||
|
||||
static String configPage("\
|
||||
<!DOCTYPE html>\
|
||||
<html>\
|
||||
<head>\
|
||||
<title>Topuino</title>\
|
||||
<meta name='viewport' content='width=device-width, initial-scale=1, user-scalable=no' />\
|
||||
<link rel='shortcut icon' href='data:,'>\
|
||||
</head>\
|
||||
<body>\
|
||||
<h1 style='text-align: center; font-size: 40px'>Topuino Config Page</h1>\
|
||||
<form action='/setup' method='POST'>\
|
||||
<div style='text-align: center'>\
|
||||
<div style='font-size: 20px; margin-bottom: 15px'>\
|
||||
<label for='ssid'><b>Wi-Fi SSID</b></label>\
|
||||
<input type='text' name='ssid' required>\
|
||||
</div>\
|
||||
<div style='font-size: 20px; margin-bottom: 15px'>\
|
||||
<label for='psw'><b>Wi-Fi Password</b></label>\
|
||||
<input type='password' name='psw' required>\
|
||||
</div>\
|
||||
<div style='font-size: 20px; margin-bottom: 15px'>\
|
||||
<label for='uuid'><b>Device ID</b></label>\
|
||||
<input type='text' name='uuid' required>\
|
||||
</div>\
|
||||
<div style='font-size: 20px'>\
|
||||
<button type='submit'>Commit</button>\
|
||||
</div>\
|
||||
</div>\
|
||||
</form>\
|
||||
</body>\
|
||||
</html>\
|
||||
");
|
||||
|
||||
|
||||
static void handleOnConnect()
|
||||
{
|
||||
configManager->httpServer.send(200, "text/html", configPage);
|
||||
}
|
||||
|
||||
static void handleOnCommit()
|
||||
{
|
||||
if (configManager->httpServer.hasArg("ssid") && configManager->httpServer.hasArg("psw") && configManager->httpServer.hasArg("uuid")) {
|
||||
userdataManager->SetWifiSsid(configManager->httpServer.arg("ssid"));
|
||||
userdataManager->SetWifiPasswd(configManager->httpServer.arg("psw"));
|
||||
userdataManager->SetDeviceUuid(configManager->httpServer.arg("uuid"));
|
||||
userdataManager->ConfirmData();
|
||||
configManager->httpServer.send(200, "text/html", "OK");
|
||||
delay(200);
|
||||
ESP.restart();
|
||||
} else {
|
||||
configManager->httpServer.send(200, "text/html", "ERROR");
|
||||
}
|
||||
}
|
||||
|
||||
ConfigManager::ConfigManager() :
|
||||
localIp(192,168,1,1),
|
||||
gateway(192,168,1,1),
|
||||
subnet(255,255,255,0),
|
||||
httpServer(80)
|
||||
{
|
||||
statusLed->SetBlinkRate(StatusBlink::BlinkRate::Rate0_5Hz);
|
||||
WiFi.softAPConfig(localIp, gateway, subnet);
|
||||
WiFi.softAP(SSID, PASSWORD);
|
||||
delay(100);
|
||||
|
||||
httpServer.on("/", handleOnConnect);
|
||||
httpServer.on("/setup", handleOnCommit);
|
||||
|
||||
httpServer.begin();
|
||||
}
|
||||
|
||||
void ConfigManager::ProcessConfig()
|
||||
{
|
||||
while (1) {
|
||||
httpServer.handleClient();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
#include "display.h"
|
||||
|
||||
#define STROBE_TM1 13
|
||||
#define CLOCK_TM 4 // clock = GPIO connected to clock line of module
|
||||
#define DIO_TM 5 // data = GPIO connected to data line of module
|
||||
#define HIGH_FREQ false //default false, If using a high freq CPU > ~100 MHZ set to true.
|
||||
|
||||
DisplayPanel::DisplayPanel()
|
||||
{
|
||||
// Constructor object (GPIO STB , GPIO CLOCK , GPIO DIO, use high freq MCU)
|
||||
ledMap = new TM1638plus(STROBE_TM1, CLOCK_TM, DIO_TM, HIGH_FREQ);
|
||||
ledMap->displayBegin();
|
||||
}
|
||||
|
||||
void DisplayPanel::DisplayLedMap(uint32_t data0, uint32_t data1)
|
||||
{
|
||||
ledMap->display7Seg(0, data0 % 0x100);
|
||||
ledMap->display7Seg(1, data0 / 0x100 % 0x100);
|
||||
ledMap->display7Seg(2, data0 / 0x10000 % 0x100);
|
||||
ledMap->display7Seg(3, data0 / 0x1000000);
|
||||
ledMap->display7Seg(4, data1 % 0x100);
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
#include "func_button.h"
|
||||
#include "user_data.h"
|
||||
|
||||
#define FUNC_BTN 0
|
||||
#define PRESSED_STATUS LOW
|
||||
|
||||
extern UserData* userdataManager;
|
||||
|
||||
FuncButton::FuncButton()
|
||||
{
|
||||
pinMode(FUNC_BTN, INPUT);
|
||||
pressedTime = 0;
|
||||
}
|
||||
|
||||
void FuncButton::Scan()
|
||||
{
|
||||
if (digitalRead(FUNC_BTN) == PRESSED_STATUS) {
|
||||
pressedTime++;
|
||||
} else {
|
||||
pressedTime = 0;
|
||||
}
|
||||
if (pressedTime > 5) {
|
||||
userdataManager->EraseData();
|
||||
ESP.restart();
|
||||
}
|
||||
}
|
41
src/main.cpp
41
src/main.cpp
|
@ -1,9 +1,40 @@
|
|||
#include <Arduino.h>
|
||||
#include "display.h"
|
||||
#include "client_network.h"
|
||||
#include "monitor_items.h"
|
||||
#include "status_blink.h"
|
||||
#include "config_manager.h"
|
||||
#include "user_data.h"
|
||||
#include "func_button.h"
|
||||
|
||||
void setup() {
|
||||
// put your setup code here, to run once:
|
||||
DisplayPanel* displayPanel;
|
||||
ClientNetwork* netClient;
|
||||
StatusBlink* statusLed;
|
||||
UserData* userdataManager;
|
||||
ConfigManager* configManager;
|
||||
FuncButton* funcButton;
|
||||
|
||||
void setup()
|
||||
{
|
||||
statusLed = new StatusBlink();
|
||||
userdataManager = new UserData();
|
||||
displayPanel = new DisplayPanel();
|
||||
funcButton = new FuncButton();
|
||||
|
||||
if (!userdataManager->UserDataValid()) {
|
||||
configManager = new ConfigManager();
|
||||
configManager->ProcessConfig();
|
||||
} else {
|
||||
netClient = new ClientNetwork();
|
||||
}
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// put your main code here, to run repeatedly:
|
||||
}
|
||||
void loop()
|
||||
{
|
||||
delay(1000);
|
||||
funcButton->Scan();
|
||||
if (netClient->FetchNewData() != OK) {
|
||||
return;
|
||||
}
|
||||
displayPanel->DisplayLedMap(netClient->GetData0(), netClient->GetData1());
|
||||
}
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
#include "status_blink.h"
|
||||
|
||||
StatusBlink::StatusBlink()
|
||||
{
|
||||
pinMode(STATUS_LED_PIN, OUTPUT);
|
||||
digitalWrite(STATUS_LED_PIN, HIGH);
|
||||
}
|
||||
|
||||
static void BlinkTask()
|
||||
{
|
||||
digitalWrite(STATUS_LED_PIN, !digitalRead(STATUS_LED_PIN)); // set pin to the opposite state
|
||||
}
|
||||
|
||||
void StatusBlink::SetBlinkRate(BlinkRate rate)
|
||||
{
|
||||
switch (rate)
|
||||
{
|
||||
case BlinkRate::RateAlwaysOn:
|
||||
flipper.detach();
|
||||
digitalWrite(STATUS_LED_PIN, LOW);
|
||||
break;
|
||||
case BlinkRate::RateAlwaysOff:
|
||||
flipper.detach();
|
||||
digitalWrite(STATUS_LED_PIN, HIGH);
|
||||
break;
|
||||
case BlinkRate::Rate5Hz:
|
||||
flipper.attach(0.1, BlinkTask);
|
||||
break;
|
||||
case BlinkRate::Rate2Hz:
|
||||
flipper.attach(0.25, BlinkTask);
|
||||
break;
|
||||
case BlinkRate::Rate0_5Hz:
|
||||
flipper.attach(1.0, BlinkTask);
|
||||
break;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,85 @@
|
|||
#include "user_data.h"
|
||||
#include <EEPROM.h>
|
||||
|
||||
#define MAX_USER_DATA_SIZE 0x200
|
||||
|
||||
#define VALIDATION_MAGIC 0xaa
|
||||
|
||||
#define GENERAL_FEILD_SIZE 0x20
|
||||
|
||||
#define VALIDATION_OFFSET 0x00
|
||||
#define SSID_OFFSET 0x20
|
||||
#define PASSWORD_OFFSET 0x40
|
||||
#define UUID_OFFSET 0x60
|
||||
|
||||
UserData::UserData()
|
||||
{
|
||||
EEPROM.begin(MAX_USER_DATA_SIZE);
|
||||
}
|
||||
|
||||
String UserData::ReadEepromString(uint32_t offset)
|
||||
{
|
||||
String result;
|
||||
char readByte;
|
||||
|
||||
for (uint32_t addr = offset; (readByte = EEPROM.read(addr)) != '\0'; addr++) {
|
||||
result += readByte;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void UserData::WriteEepromString(String data, uint32_t offset)
|
||||
{
|
||||
for (uint32_t i = 0; i < data.length(); i++) {
|
||||
EEPROM.write(i + offset, data[i]);
|
||||
}
|
||||
EEPROM.write(data.length() + offset, 0x00);
|
||||
}
|
||||
|
||||
bool UserData::UserDataValid()
|
||||
{
|
||||
byte validation = EEPROM.read(VALIDATION_OFFSET);
|
||||
return validation == VALIDATION_MAGIC;
|
||||
}
|
||||
|
||||
void UserData::ConfirmData()
|
||||
{
|
||||
EEPROM.write(VALIDATION_OFFSET, VALIDATION_MAGIC);
|
||||
EEPROM.commit();
|
||||
}
|
||||
|
||||
void UserData::EraseData()
|
||||
{
|
||||
EEPROM.write(VALIDATION_OFFSET, 0x00);
|
||||
EEPROM.commit();
|
||||
}
|
||||
|
||||
String UserData::GetWifiSsid()
|
||||
{
|
||||
return ReadEepromString(SSID_OFFSET);
|
||||
}
|
||||
|
||||
void UserData::SetWifiSsid(String ssid)
|
||||
{
|
||||
return WriteEepromString(ssid, SSID_OFFSET);
|
||||
}
|
||||
|
||||
String UserData::GetWifiPasswd()
|
||||
{
|
||||
return ReadEepromString(PASSWORD_OFFSET);
|
||||
}
|
||||
|
||||
void UserData::SetWifiPasswd(String password)
|
||||
{
|
||||
return WriteEepromString(password, PASSWORD_OFFSET);
|
||||
}
|
||||
|
||||
String UserData::GetDeviceUuid()
|
||||
{
|
||||
return ReadEepromString(UUID_OFFSET);
|
||||
}
|
||||
|
||||
void UserData::SetDeviceUuid(String uuid)
|
||||
{
|
||||
return WriteEepromString(uuid, UUID_OFFSET);
|
||||
}
|
11
test/README
11
test/README
|
@ -1,11 +0,0 @@
|
|||
|
||||
This directory is intended for PlatformIO Unit Testing 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/page/plus/unit-testing.html
|
Loading…
Reference in New Issue