瑞薩sk-s7g2之旅(4)結束(滴液檢測)
阿新 • • 發佈:2018-12-10
關於瑞薩的學習就此結束。對於這塊強大的開發板,我很慶幸有這個機會能夠學習它。在窮其一生的追求路上,這是一個腳印。因為時間和學業還有種種的原因,我只能停止關於瑞薩板的學習,在3個月的學習中,我盡力學習,但是隻是學會了一些許的細枝末節的知識。發揮了這塊板子不到2%的作用。希望以後還有機會學習這類的板子,它帶給我的是人性化的開發體驗,以及其強大功能給予我的震撼。我在此提供我學習的成果專案,如有錯誤或不足還請指出,相互學習,共同進步。並在此感謝胡益華。
本專案,採用壓力感應來實現對滴液的檢測,並在上位機產生動畫,實現提醒的功能。
上位機端
程式碼如下:
/******************************************************************** ** 文 件 名:畫素點的簡單獲取 ** 創 建 人:yk ** 最後修改時間:2018年8月1日 *********************************************************************/ #include"iostream" #include"winsock2.h" #include"stdlib.h" #include"graphics.h" #include "time.h" #include"math.h" #include"conio.h" #pragma comment(lib,"ws2_32.lib") #pragma comment(lib,"Winmm.lib") using namespace std; time_t rawtime; class tcpsocket //定義tcpsocket型別函式集 { public: //定義各類函式 unsigned int establish(); //建立socket unsigned int Connect(const char *cp, u_short hostshortb); //連線服務端 char * communication(); //接受資料 void cls(); private: //定義變數 WSADATA date; SOCKET tcpclient; struct sockaddr_in adress; WORD sockVersion = MAKEWORD(2, 2); }; unsigned int tcpsocket::establish() //socket函式(客戶端) { if (WSAStartup(sockVersion, &date) != 0) //初始化 { return WSAGetLastError(); } tcpclient = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); //建立客戶端 if (tcpclient == INVALID_SOCKET) { return WSAGetLastError(); } return 0; } unsigned int tcpsocket::Connect(const char *IP, u_short hostshortb)//連線服務端 { int i = 0; xc:adress.sin_family= AF_INET; adress.sin_port= htons(hostshortb); adress.sin_addr.S_un.S_addr = inet_addr(IP); if (connect(tcpclient, (sockaddr *)&adress, sizeof(adress)) != SOCKET_ERROR) //建立連線 { i++; Sleep(1000); if (i > 10) { closesocket(tcpclient); return 1; } else goto xc; } return 0; } char * tcpsocket::communication() //客戶端接收資訊 { char recever[10]; recv(tcpclient, recever, 10, 0); return recever; } void tcpsocket::cls() //關閉客戶端 { closesocket(tcpclient); WSACleanup(); } class write //定義write型別函式集 { public: int write1( float j); int write2(int i); int write3(char * t1); int write4(char * t2); private: FILE * fp; }; int write::write1( float j) //定義函式write1 { if (!(fp = fopen(".\\information.txt", "a"))) //檔案成功開啟則將返回的指標賦值給指標標量fp { return 1; } fprintf(fp, "輸液量估計值%f,", j); //向指定檔案中輸出fp fclose(fp); //關閉fp return 0; } int write::write2(int i) //定義函式write2 { if (!(fp = fopen(".\\information.txt", "a"))) //檔案成功開啟則將返回的指標賦值給指標標量fp { return 1; } fprintf(fp, "第%d個病人,", i); //向指定檔案中輸出fp fclose(fp); //關閉fp return 0; } int write::write3(char * t1) //定義函式write3 { if (!(fp = fopen(".\\information.txt", "a"))) //檔案成功開啟則將返回的指標賦值給指標標量fp { return 1; } fprintf(fp, "開始時間%s,", t1); //向指定檔案中輸出fp fclose(fp); //關閉fp return 0; } int write::write4(char * t2) //定義函式write4 { if (!(fp = fopen(".\\information.txt", "a"))) //檔案成功開啟則將返回的指標賦值給指標標量fp { return 1; } fprintf(fp, "結束時間%s\n", t2); //向指定檔案中輸出fp fclose(fp); //關閉fp return 0; } int Fabs(int a) //定義函式Fabs,計算絕對值 { return a >= 0 ? a : -a; } int readwight() { cc:FILE *fp; char pf[3]; char as[] = "80"; int wight=0; if (!(fp = fopen(".\\wight.dat", "r"))) //檔案成功開啟則將返回的指標賦值給指標標量fp { fclose(fp); goto cc; } fscanf(fp, "%s",pf); fclose(fp); wight = atoi(pf); return wight; } void picturestart(int mode) //定義函式picturestart,繪製瓶子 { initgraph(640, 480); //初始化一個大小為640*480的圖形區域 setorigin(320, 240); //初始化原點座標。 setbkcolor(0x555555); //設定背景顏色 cleardevice(); //清屏 settextcolor(RGB(153, 153, 153)); //設定字型顏色 settextstyle(25, 25, "黑體"); //設定字型 outtextxy(-310, -240, "DOB"); //在當前游標x=-310,y=-240處輸入DOB settextstyle(15, 15, "宋體"); //設定字型 outtextxy(-320, -210, "狀態"); outtextxy(-320, -150, "模式"); if(mode==50)outtextxy(-320, -130, "100ml"); else if (mode == 1966)outtextxy(-320, -130, "250ml"); else if (mode == 150)outtextxy(-320, -130, "500ml"); setlinecolor(RGB(195, 195, 195)); //設定線條顏色 setlinestyle(PS_SOLID | PS_ENDCAP_FLAT, 20); //設定線條樣式為寬度為10,端點為平的實線 setfillcolor(RGB(37, 170, 226)); //設定矩形填充色 fillroundrect(-210, 200, 210, -200, 100, 100); //繪製一個可填充的帶圓角的矩形x=-240,240y=210,210 line(-210, -200, 210, -200); //繪製一條起點為(-240,-200)終點為(240,200)的線 line(-210, -210, -210, 100); //繪製一條起點為(-240,-210)終點為(-240,210)的線 line(210, -210, 210, 100); //繪製一條起點為(240,-210)終點為(240,100)的線 setlinecolor(RGB(37, 170, 226)); //設定線條的顏色 line(-200, -200, 200, -200); //繪製一條起點為(-230,-200)終點為(230,-200)的線 line(-200, -195, 200, -195); //繪製一條起點為(-230,-195)終點為(230,-195)的線 line(-190, -210, -190, 100); //繪製一條起點為(-220,-210)終點為(-220,100)的線 line(190, -210, 190, 100); //繪製一條起點為(220,-210)終點為(220,100)的線 } int flowup(int line1, int line_ok) //定義函式flowup,繪製未輸入的液體對應的矩形區域 { int NUM_ber = Fabs(line1 - line_ok); setlinestyle(PS_SOLID | PS_ENDCAP_FLAT, 1); //設定線條樣式為寬度為1,端點為平的實線 setlinecolor(RGB(37, 170, 226)); //設定線條顏色 for (int i = 0; i < NUM_ber; i++) { line(-200, line_ok, 200, line_ok); //繪製一條起點為(-230,line_ok)終點為(230,line_ok)的線 line_ok -= 1; Sleep(10); //延遲10s } return line_ok; } int flowdown(int line1, int line_ok) //定義函式flowdown,繪製已輸入的液體對應的矩形區域 { int NUM_ber = Fabs(line1 - line_ok); setlinestyle(PS_SOLID | PS_ENDCAP_FLAT, 1); //設定線條樣式為寬度為1,端點為平的實線 setlinecolor(0x555555); //設定線條顏色(已輸入的液體) for (int i = 0; i < NUM_ber; i++) { line(-200, line_ok, 200, line_ok); //繪製一條起點為(-230,line_ok)終點為(230,line_ok)的線 line_ok += 1; Sleep(10); //延遲10s } return line_ok; } int obtain(const char *ip, u_short hostshorta) //定義函式obtain,當socket未連線成功時顯示的內容 { int err = 0; tcpsocket dob; char *buf; int wight = 0; write DOB; //定義write型別函式的物件DOB if (dob.establish()) //建立客戶端失敗 { setlinestyle(PS_SOLID | PS_JOIN_BEVEL, 1); //畫一條寬度為1的實心斜線 settextstyle(15, 15, "楷體"); //設定字型型別為寬度15,高度15,楷體 settextcolor(WHITE); //設定字型顏色為白色 char str[] = " 發生了錯誤,SOCKET未能成"; char str1[] = "功啟用,請重啟程式與裝置,"; char str2[] = "並檢查ip.dat檔案和port.da"; char str3[] = "t檔案是否正確! "; outtextxy(-300, 0, str); //在x=-300,y=0處顯示str outtextxy(-300, 25, str1); //在x=-300,y=25處顯示str1 outtextxy(-300, 50, str2); //在x=-300,y=50處顯示str2 outtextxy(-300, 75, str3); //在x=-300,y=75處顯示str3 Sleep(1000); exit(0); } if (dob.Connect(ip, hostshorta)) //服務端連線失敗 { setlinestyle(PS_SOLID | PS_JOIN_BEVEL, 1); //畫一條寬度為1的實心斜線 settextstyle(15, 15, "楷體"); //設定字型型別為寬度15,高度15,楷體 settextcolor(WHITE); //設定字型顏色為白色 char str[] = " 發生了錯誤,SOCKET未能成"; char str1[] = "功連線,請重啟程式與裝置,"; char str2[] = "並檢查ip.dat檔案和port.da"; char str3[] = "t檔案是否正確! "; outtextxy(-300, 0, str); //在x=-300,y=0處顯示str outtextxy(-300, 25, str1); //在x=-300,y=25處顯示str1 outtextxy(-300, 50, str2); //在x=-300,y=50處顯示str2 outtextxy(-300, 75, str3); //在x=-300,y=75處顯示str3 Sleep(1000); exit(0); } buf = dob.communication(); //將接收的資訊傳遞給buf wight = atoi(buf); //將buf由string型轉換為int型,並賦值給wight dob.cls(); //關閉客戶端 return wight; } int deal() //定義函式deal,檢測液滴量估計值 { FILE *fp, *pf; //宣告FILE型別的,名為fp,pf的指標 const char *ip = NULL; //宣告char型指標 char str1[20]; char port1[10]; int date = 0; u_short hostshorta; fp = fopen(".\\ip.dat", "r"); //若將ip.dat檔案以只讀的方式成功開啟,則將返回的檔案指標賦值給fp pf = fopen(".\\port.dat", "r"); //若將port.dat檔案以只讀的方式成功開啟,則將返回的檔案指標賦值給pf fscanf(fp, "%s", str1); //從檔案指標fp中讀取字串,並賦值給str fscanf(pf, "%s", port1); //從檔案指標pf中讀取字串,並賦值給port fclose(fp); //關閉fp fclose(pf); //關閉pf ip = str1; //將str賦值給ip hostshorta = atoi(port1); //將port內的字串轉換為整數,並將返回值賦值給hostshorta date = obtain(ip, hostshorta); return date; //返回液滴量估計值 } int proportiondeal(double proportion) //定義函式proportiondeal,計算在液體剩餘的百分比時對應的高度 { int line_number = 400; return (int)(190 - proportion * line_number); //返回整型 } int linedeal(int line_define_number, double proportion) //定義函式linedeal,顯示輸液過程中矩形影象的動態變化 { int line_number = proportiondeal(proportion); //190- if (line_number > line_define_number) //輸液過程中 { line_define_number = flowdown(line_number, line_define_number); //記錄水位當前值 } else if (line_number == line_define_number) //開始輸液時 { Sleep(100); //延遲100s } else if (line_number< line_define_number) { line_define_number=flowup(line_number, line_define_number); } line_define_number = line_number; return line_define_number; } int start() { initgraph(640, 480); //初始化一個大小為640*480的圖形區域 setbkcolor(RGB(76, 115, 158)); //設定背景顏色 cleardevice(); //清屏 settextcolor(RGB(52, 60, 63)); settextstyle(100, 100, "黑體"); outtextxy(2, 1, "DOB"); settextcolor(RGB(222, 204, 106)); settextstyle(50, 50, "宋體"); outtextxy(1, 120, "A.100ML"); outtextxy(1, 190, "B.250ML"); outtextxy(1, 260, "C.500ML"); settextcolor(RGB(0, 0, 0)); settextstyle(18, 18, "楷體"); outtextxy(1, 340, "[請用左鍵單擊選擇或者鍵入字母並回車]"); settextcolor(RGB(255, 10, 10)); settextstyle(30, 30, "幼圓"); outtextxy(340, 1, "【退出】"); while (1) { mouse:MOUSEMSG m; char input; if (MouseHit()) { m = GetMouseMsg(); if (m.uMsg == WM_LBUTTONUP) { if ((m.y >= 120 && m.y <= 170) && (m.x >= 1 && m.x <= 350)) { return 1163; } if ((m.y >= 190 && m.y <= 240) && (m.x >= 1 && m.x <= 350)) { return 1966; } if ((m.y >= 260 && m.y <= 310) && (m.x >= 1 && m.x <= 350)) { return 150; } if ((m.y >= 1 && m.y <= 30) && (m.x >= 370 && m.x <= 550)) { exit(0); } goto mouse; } } else if (kbhit()) { input = _getch(); if (input == 'a' || input == 'A') { return 50; } if (input == 'b' || input == 'B') { return 100; } if (input == 'c' || input == 'C') { return 150; } goto mouse; } } } int control(int pol) //定義函式control ,顯示輸液的動態變化過程 { write DOB; //定義write型別函式的物件DOB float proportion = 0; int line_define_number = -210; int panduan = 0; float nn = 0; int count = 1; int tim = 0; int byte = 0; int head = 0,head1=0; int date = 0; char s[4] = {0}; while (1) { again:date = deal()-pol+42; //記錄液滴量估計值 if ((Fabs(head1 - date) <= 78)||head1==0||panduan>2) { panduan = 0; if (head == 0 || date > head) //開始輸液時 { if(tim==0) { DOB.write2(count); //記錄第幾個病人 time(&rawtime); //記錄秒數 DOB.write3(ctime(&rawtime)); //記錄開始的時間(事件被轉換為字串) } tim++; count++; head = date; head1 = date; line_define_number = -210; //sprintf(s, "%.3s", "99%"); outtextxy(-310, -185, "99%"); line_define_number = flowup(-210, line_define_number); //記錄水位當前值 } else if (head1 != 0 && date <= head) //輸液過程中 { head1 = date; DOB.write1(date); proportion = (float)date / (float)head; //計算液體剩餘量的百分比 nn = proportion * 100.0; byte = (int)nn; settextcolor(RGB(153, 153, 153)); settextstyle(15, 15, "宋體"); sprintf(s, "%f",nn ); //s[0]=(int)nn % 10; //s[1]=((int)nn-(int)nn % 10)/10; s[2] = '%'; s[3] = '\0'; outtextxy(-310, -185, s); if (proportion < 0.02 || date < 100) //當百分比小於20%或液體質量小於30g時 { line_define_number=flowdown(190, line_define_number); for(int i=0;i<15;i++) { mciSendString(_T("close bmusic"), NULL, 0, NULL); mciSendString(_T("open G:\\素材\\飛機大戰圖片音樂素材\\gotEnemy.mp3 alias bmusic"), NULL, 0, NULL); mciSendString(_T("play bmusic"), NULL, 0, NULL); Sleep(1000); }; time(&rawtime); //記錄秒數 DOB.write4(ctime(&rawtime)); //記錄結束時間 Sleep(2000); s[0] = 0; s[1] = 0; s[2] = 0; s[3] = 0; //return 0; int mode = 0; mode = start(); picturestart(mode); control(mode); } line_define_number = linedeal(line_define_number, proportion); //記錄結束時的水位當前值 } } else if ((Fabs(head1 - date) >= 78)) { panduan++; goto again; } } return 1; } int main() //主函式 { while(1) { int mode = 0; mode = start(); picturestart(mode); //展示圖片 control(mode); //顯示輸液的動態變化過程 } //system("pause"); }
硬體端:
為保證工程的完整性,我將整個工程上傳。這裡將不在進行程式碼展示。