最简单片机可执行KNN算法
接手一个简单的水位预警项目,没使用传统规则进行判断,使用机器学习算法进行判断:
已完成代码如下,接下来就是扩大训练集,11个样本的数据肯定是不够的
每个传感器0表示未超出,1表示超出,最后也是:1表示水位预警,0表示正常工作。
每5s采集一次数据,进行判断,如果判断为水位超出液面,那就发出警报(BEEP = 1, WARNING = 1)
//头文件引入#include#include#include#include#include//宏定义#define N 11 //训练集有1000组数据#define K 5 //设置KNN临近距离为5#define CIRCLE 5 //设置周期为5秒#define SIZE 2 //设置通用交换函数交换字节大小//引脚定义sbit S1 = P0^1; //传感器1sbit S2 = P0^2; //传感器2sbit S3 = P0^3; //传感器3sbit BEEP = P3^4; //蜂鸣器sbit WARNING = P3^5; //预警引脚//相关常量、变量定义code unsigned char DataSet[N][16] = { //训练数据集,每组数据16个特征,对应3个传感器5秒内数据,以及对应的结果:是否溢出{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1},{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1},{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1},{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0},{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},{0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},{0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},{1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},{1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}; unsigned int Dis[N][2]; //每组数据2个元素,对应15份传感器数据距离,以及结果//通用交换函数void swap(void *a, void *b) { unsigned char buffer[SIZE]; memcpy(buffer, a, SIZE); memcpy(a, b, SIZE); memcpy(b, buffer, SIZE);}//knn算法预测结果unsigned char KnnPredict(unsigned char *Data) { unsigned char i, j, result; unsigned char sum = 0; for (i = 0; i < N; i++) { unsigned int tmp = 0; for (j = 0; j < 15; j++) { tmp = tmp + (DataSet[i][j] - Data[j]) * (DataSet[i][j] - Data[j]); } Dis[i][0] = sqrt(tmp); Dis[i][1] = DataSet[i][15]; } for (i = 0; i < N - 1; i++) { for (j = 0; j < N - i - 1; j++) { if (Dis[j][0] > Dis[j + 1][0]) { swap(&Dis[j][0], &Dis[j + 1][0]); swap(&Dis[j][1], &Dis[j + 1][1]); } } } for (i = 0; i < K; i++) { sum = sum + Dis[i][1]; } result = sum / K; return result;}//延时函数,延时t秒void Delay(unsigned char t) { unsigned int i, j; for (i = 0; i < 10000 * t; i++) { for (j = 0; j < 124; j++) { } }}//主函数void main(){ while(1) { unsigned char Data[15] = {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0};//测试数据 unsigned char i; for (i = 0; i < CIRCLE; i++) { //获取一个周期(5秒)内的所有传感器数据,3个为一组,共5组15个 Data[i * 3] = S1; //Data[0], Data[3] ... Data[12]记录1-5秒内传感器1的数据 Data[i * 3 + 1] = S2; //Data[1], Data[4] ... Data[13]记录1-5秒内传感器2的数据 Data[i * 3 + 2] = S3; //Data[2], Data[5] ... Data[14]记录1-5秒内传感器3的数据 Delay(1); //延时1秒 } if (KnnPredict(Data) == 1) { //如果判断为水位超出 BEEP = 1; //蜂鸣器发声 WARNING = 1; //发出警报信号 } }}
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
暂时没有评论,来抢沙发吧~