Skip to content

Commit 2fc8cab

Browse files
authored
Merge pull request #77 from cool8cool/master
HUST_SmartMeter Team Name: SandSilicon
2 parents daef13e + 2ccb5d0 commit 2fc8cab

File tree

241 files changed

+60268
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

241 files changed

+60268
-0
lines changed
Lines changed: 199 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,199 @@
1+
# Smart Meter
2+
3+
This application is a prototype of **Smart Meter** designed on ARC IoT DK. It can measure household electricity consumption information, and then use **non-intrusive load identification technology** to identify electrical switch status. It uploads message to the **cloud platform**. The analog signal of current and Voltage is collected by **ATT7053AU** (*a power acquisition chip*).
4+
5+
- [Smart Meter](#smart-meter)
6+
- [Introduction](#introduction)
7+
- [Function](#function)
8+
- [Appearance](#appearance)
9+
- [Video](#video)
10+
- [Hardware and Software Setup](#hardware-and-software-setup)
11+
- [Required Hardware](#required-hardware)
12+
- [Required Software](#required-software)
13+
- [Hardware Connection](#hardware-connection)
14+
- [User Manual](#user-manual)
15+
- [Before Running This Application](#before-running-this-application)
16+
- [Run This Application](#run-this-application)
17+
18+
## Introduction
19+
The traditional meter can only measure the user's power consumption, but in today's more and more intelligent, concepts such as smart grid and smart home are gradually popularized and realized. Non-intrusive load identification uses meter data, combined with machine learning algorithms to analyze the power consumption status of all electrical equipment in the home. It is one of the key technologies for the refined management of power energy and the realization of the intelligentization of the whole house. This application embeds non-intrusive load identification technology into the end of the electric energy measurement equipment, and performs calculations on the end side to avoid waste of resources caused by a large amount of data upload, and at the same time, it can perform real-time load pattern recognition. This application is developed based on the Synopsys IoTDK platform, uses the Tensorflow Lite for Microcontroller neural network model for inference, and realizes the connection of device networking and the mobile phone and web pages of the cloud platform.
20+
21+
### Function
22+
* Measure the electrical power.
23+
* Real-time non-intrusive load identification.
24+
* upload the message to the cloud platform.
25+
26+
27+
### Appearance
28+
* **System View**
29+
<img src="./doc/pic/system architecture.png" alt="System Architecture" style="zoom:60%;" />
30+
31+
### Video
32+
33+
[Smart Meter with NILD][1]
34+
35+
## Hardware and Software Setup
36+
37+
### Required Hardware
38+
* Necessary Hardware:
39+
- ARC IoT Development Kit(IoT DK) *1
40+
- ATT7053AU *1
41+
- ESP8266 *1
42+
- OLED *1
43+
44+
### Required Software
45+
* DesignWare ARC MetaWare Development Toolkit 2021.03
46+
* [embARC open software platform][2]
47+
* [Tensorflow lite for microcontrollar][3] (the files have been all added into the projects)
48+
* Ali Cloud Platform
49+
* Serial port terminal, such as SecureCRT or Xshell
50+
* Python3.8
51+
* Tensorflow 2.5
52+
53+
### Hardware Connection
54+
1. Connect ATT7053AU module to IoT DK 2x18 Pin Extension Header (Using SPI0 interface and SPI0_CS1 Pin).
55+
2. Connect OLED module to IoT DK 2x18 Pin Extension Header (Using IIC0 interface).
56+
3. Connect ESP8266 module to IoT DK 12 Pin Pmod connector Pmod_C (Using UART0 interface).
57+
4. Make sure your power regulator connect is correct,including the voltage and polarity.
58+
59+
## User Manual
60+
61+
### Before Running This Application
62+
* Download source code of **Smart Meter** from github.
63+
* Make sure all connection is correct again.
64+
* Passing Zero or Fire Wire of Socket Wire through Current Transformer on ATT7053AU.
65+
* Connect the zero line and live line to the Potential Transformer on ATT7053AU.
66+
* If you want to use the cloud platform, set up your own hotspot SSID and password.
67+
68+
69+
### Run This Application
70+
1. To build this applicaiton, select the proper board version, core configuration and build with selected toolchain using this command `make BOARD=iotdk BD_VER=10 CUR_CORE=arcem9d TOOLCHAIN=mw run`.
71+
2. Open your serial terminal such as Tera-Term on PC, and configure it to right COM port and 115200bps.
72+
3. Interact using IoT DK , serial port terminal and cloud platform.
73+
74+
#### Makefile
75+
76+
- Add the path of libmli.a to application library
77+
78+
```
79+
# application library
80+
APPL_LIBS ?= third_party/arc_mli_iotdk_arcem9d/bin/libmli.a
81+
```
82+
83+
- Selected u8glib here, then you can use [u8glib API][4] in your application:
84+
85+
```
86+
MID_SEL = common u8glib
87+
```
88+
89+
90+
- Target options about IoT DK and toolchain:
91+
92+
```
93+
TOOLCHAIN=mw
94+
BOARD=iotdk
95+
BD_VER=10
96+
CUR_CORE=arcem9d
97+
```
98+
99+
- The relative series of the root directory, here the path of the Makefile is `./embarc_osp/application/smart_meter/src/makefile`:
100+
101+
```
102+
# root dir of embARC
103+
EMBARC_ROOT = ../../..
104+
```
105+
106+
- Directories of source files and header files, notice that it **is not recursive**:
107+
108+
```
109+
# application source dirs
110+
111+
APPL_CSRC_DIR = . \
112+
tensorflow/lite/c \
113+
tensorflow/lite/experimental/microfrontend/lib \
114+
./models
115+
116+
APPL_CXXSRC_DIR = . \
117+
./models \
118+
tensorflow/lite/core/api \
119+
tensorflow/lite/experimental/microfrontend/lib \
120+
tensorflow/lite/kernels \
121+
tensorflow/lite/kernels/internal \
122+
tensorflow/lite/micro \
123+
tensorflow/lite/micro/arc_iotdk \
124+
tensorflow/lite/micro/kernels \
125+
tensorflow/lite/micro/kernels/arc_mli \
126+
tensorflow/lite/micro/memory_planner \
127+
tensorflow/lite/micro/testing \
128+
129+
# application include dirs
130+
APPL_INC_DIR = . \
131+
./models \
132+
tensorflow/lite \
133+
tensorflow/lite/c \
134+
tensorflow/lite/core/api \
135+
tensorflow/lite/experimental/microfrontend/lib \
136+
tensorflow/lite/kernels \
137+
tensorflow/lite/kernels/internal \
138+
tensorflow/lite/micro \
139+
tensorflow/lite/micro/kernels \
140+
tensorflow/lite/micro/kernels/arc_mli \
141+
tensorflow/lite/micro/memory_planner \
142+
tensorflow/lite/micro/testing \
143+
tensorflow/lite/schema \
144+
third_party/arc_mli_iotdk_arcem9d/include \
145+
third_party/arc_mli_iotdk_arcem9d/include/api \
146+
third_party/flatbuffers/include \
147+
third_party/flatbuffers/include/flatbuffers \
148+
third_party/gemmlowp \
149+
third_party/gemmlowp/fixedpoint \
150+
third_party/gemmlowp/internal \
151+
third_party/kissfft \
152+
third_party/ruy
153+
```
154+
155+
#### Program flow chart
156+
<img src="./doc/pic/program flow chat.png" alt="Program flow chart" style="zoom:30%;" />
157+
158+
159+
160+
#### Tensorflow Lite for Microcontrollor
161+
162+
Placing the tflite model source code in `./models` folder.
163+
164+
| folder/file | Function |
165+
| ------------- | -------------------------------------------------------- |
166+
| models | include tflite models source code and header file |
167+
| recongnize.cc | use Tensorflow Lite for Microcontrollor to run inference |
168+
| recongnize.h | the header of recongnize.cc |
169+
170+
#### Driver
171+
172+
| folder/file | Function |
173+
| -------------- | ----------------------------------------------- |
174+
| spi_att7053.cc | att7053 spi drivers,include read,write,init API |
175+
| spi_att7053.h | the header of att7053 drivers |
176+
| my_uart.cc | uart drivers |
177+
| my_uart.h | the head of uart driver |
178+
179+
#### Network and Cloud Platform
180+
181+
| folder/file | Function |
182+
| ------------------ | ---------------------------------------------------- |
183+
| esp8266_network.cc | connect to the hotspot by esp8266 |
184+
| esp8266_network.h | the head of esp8266_network |
185+
| self_mqtt.cc | the functions of Message Queuing Telemetry Transport |
186+
| self_mqtt.h | the head of mqtt |
187+
188+
#### OLED Display
189+
190+
| folder/file | Function |
191+
| -------------------- | -------------------------------------------------------- |
192+
| display.cc | interface function for using OLED to display information |
193+
| display.h | the hearder of display |
194+
| ssd1306_app_config.h | Definition of OLED Interface |
195+
196+
[1]: https://v.youku.com/v_show/id_XNTE5MTkzMjQwNA==.html
197+
[2]: https://github.com/foss-for-synopsys-dwc-arc-processors/embarc_osp
198+
[3]: https://github.com/tensorflow/tflite-micro
199+
[4]: https://github.com/olikraus/u8glib/wiki
139 KB
Loading
226 KB
Loading
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
#include "data_provider.h"
2+
3+
const float xmean = 192.0; //用于归一化的均值,在模型训练前算得
4+
const float xstd = 168.07; //用于归一化的标准差
5+
const float input_scale = 0.0; //模型量化参数
6+
const int input_zero_point = 0; //模型量化参数
7+
const int windows_len = 12;
8+
9+
void get_data(ATT7053_DEF_PTR att7053 ,sample_data_node_ptr getdata)
10+
{
11+
getdata->IRMS = Read_Reg(att7053,Current1_Rms_Register);
12+
getdata->active_power = ((int32_t)Read_Reg(att7053,PowerP1_Register)<<16)>>16;
13+
getdata->reactive_power = ((int32_t)Read_Reg(att7053,PowerQ1_Register)<<16)>>16;
14+
getdata->apparent_power = Read_Reg(att7053,PowerS_Register);
15+
}
16+
17+
void data_container_init(sample_data_node data_cont[], uint32_t winlength)
18+
{
19+
for(uint32_t i=0;i<(winlength-1);i++){
20+
data_cont[i].next_ptr = &data_cont[i+1];
21+
}
22+
data_cont[winlength-1].next_ptr = data_cont;
23+
}
24+
25+
void data_provider(TfLiteTensor* input, sample_data_node_ptr data_buffer, int winlength)
26+
{
27+
float *inputdata = input->data.f;
28+
for(int i=0; i<winlength; i++){
29+
data_buffer = data_buffer->next_ptr;
30+
inputdata[i] = (data_buffer->active_power - xmean)/xstd;
31+
}
32+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
#ifndef DATA_PROVIDER_H
2+
#define DATA_PROVIDER_H
3+
4+
#include "embARC.h"
5+
#include "embARC_debug.h"
6+
#include "spi_att7053.h"
7+
#include "tensorflow/lite/c/common.h"
8+
9+
typedef struct _sample_data_node
10+
{
11+
uint32_t IRMS;
12+
int32_t active_power;
13+
int32_t reactive_power;
14+
uint32_t apparent_power;
15+
struct _sample_data_node* next_ptr;
16+
}sample_data_node,*sample_data_node_ptr;
17+
18+
19+
extern void get_data(ATT7053_DEF_PTR att7053, sample_data_node_ptr getdata);
20+
extern void data_container_init(sample_data_node data_cont[], uint32_t winlength);
21+
extern void data_provider(TfLiteTensor* input,sample_data_node_ptr data_buffer, int winlength);
22+
#endif
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
#include "display.h"
2+
3+
u8g_t u8g;
4+
5+
6+
void u8g_prepare(void)
7+
{
8+
u8g_SetFont(&u8g, u8g_font_6x10); /* set the current font and reset the font reference position to "Baseline" */
9+
u8g_SetFontRefHeightExtendedText(&u8g); /* define the calculation method for the ascent and descent of the current font */
10+
u8g_SetDefaultForegroundColor(&u8g); /* assign one of the default colors as current color index */
11+
u8g_SetFontPosTop(&u8g); /* set the reference position for the character and string draw procedure */
12+
}
13+
14+
void display_app_name(uint16_t kind_index)
15+
{
16+
u8g_prepare();
17+
switch (kind_index){
18+
case 0:
19+
u8g_DrawStr(&u8g, 30,20, "ALL OFF");
20+
break;
21+
case 1:
22+
u8g_DrawStr(&u8g, 30,20, "Fan ON");
23+
break;
24+
case 2:
25+
u8g_DrawStr(&u8g, 30,20, "DDS ON");
26+
break;
27+
case 3:
28+
u8g_DrawStr(&u8g, 30,20, "ALL ON");
29+
break;
30+
default:
31+
u8g_DrawStr(&u8g, 30,20, "None");
32+
break;
33+
}
34+
}
35+
36+
void display_app_power(uint16_t app_power)
37+
{ //显示实时的功率值
38+
char s[10][10] ;
39+
float t;
40+
t= app_power*0.05;
41+
sprintf(s[0], "POWER:%4.1fw", t);//将数据转化为字符串
42+
//u8g_DrawStr(&u8g, 0, 40, "POWER:");
43+
u8g_DrawStr(&u8g, 30, 40, s[0]);
44+
}
45+
46+
void m_u8g_init(void)
47+
{
48+
u8g_InitComFn(&u8g, &u8g_dev_ssd1306_128x64_2x_i2c, U8G_COM_SSD_I2C); /* create a new interface to a graphics display */
49+
u8g_Begin(&u8g); /* reset display and put it into default state */
50+
}
51+
52+
void display(uint16_t index,uint16_t display_power)
53+
{
54+
u8g_FirstPage(&u8g); /* marks the beginning of the picture loop; it cannot be used inside the picture loop */
55+
do {
56+
57+
u8g_DrawStr(&u8g, 15, 0, "HUST-SandSilicon");
58+
display_app_name(index);
59+
display_app_power(display_power);
60+
} while (u8g_NextPage(&u8g));
61+
}
62+
63+
void PrintEvent(sample_data_node_ptr front, int windows_len)
64+
{
65+
for(uint32_t i=0;i<windows_len;i++){
66+
front = front->next_ptr;
67+
EMBARC_PRINTF("%d,%d,%d\n",front->IRMS,-(front->active_power),-(front->reactive_power));
68+
}
69+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
#ifndef _DISPLAY_H_
2+
#define _DISPLAY_H_
3+
4+
5+
#include "embARC_toolchain.h"
6+
#include "embARC_error.h"
7+
#include "stdio.h"
8+
#include "data_provider.h"
9+
#include "board.h"
10+
/* middleware level*/
11+
#include "u8g.h"
12+
13+
void m_u8g_init(void);
14+
void display(uint16_t kind_index);
15+
void display(uint16_t kind_index,uint16_t display_power);
16+
void display_app_name(uint16_t kind_index);
17+
void display_app_power(uint16_t app_power);
18+
void PrintEvent(sample_data_node_ptr front, int windows_len);
19+
#endif

0 commit comments

Comments
 (0)