1. 程式人生 > >瑞薩sk-s7g2之旅(4)結束(滴液檢測)

瑞薩sk-s7g2之旅(4)結束(滴液檢測)

  關於瑞薩的學習就此結束。對於這塊強大的開發板,我很慶幸有這個機會能夠學習它。在窮其一生的追求路上,這是一個腳印。因為時間和學業還有種種的原因,我只能停止關於瑞薩板的學習,在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");
}

硬體端:

為保證工程的完整性,我將整個工程上傳。這裡將不在進行程式碼展示。