#include <winsock2.h>
#include <windows.h>//引入wingdi.h
#include <stdio.h>
#include <math.h>
#include <time.h>
#include <conio.h>
#pragma comment(lib,"ws2_32.lib")
#define PI 3.1416
#define ORIGINX 0 //曲线起点X坐标
#define ORIGINY 200 //曲线起点Y坐标
#define LENGTHX 800 //X坐标轴长度
#define LENGTHY 300 //Y坐标轴长度
#define XDATALEN 100//X坐标数据量
HDC hdc = 0;//控制台绘图设备描述句柄 HDC
HPEN hPen, hPen2;//画笔变量
HPEN hPenOld;
TCHAR title[256];//控制台程序标题
int times = 0;//绘制次数变量
double datay[XDATALEN];//曲线纵坐标数组
//毫秒延时函数
void delay_ms(INT64 Ms)
{
LARGE_INTEGER CurrTicks, TicksCount;
QueryPerformanceFrequency(&TicksCount);
QueryPerformanceCounter(&CurrTicks);
TicksCount.QuadPart = TicksCount.QuadPart * Ms / (INT64)1000;
TicksCount.QuadPart += CurrTicks.QuadPart;
while (CurrTicks.QuadPart<TicksCount.QuadPart)
QueryPerformanceCounter(&CurrTicks);
}
//绘制清屏矩形
void ClearWind(HDC hdc)
{
HPEN hPen;
HBRUSH hBrush;
hBrush = CreateSolidBrush(RGB(0, 0, 0));
hPen = CreatePen(PS_SOLID, 0, RGB(0, 0, 0));
SelectObject(hdc, hBrush);
SelectObject(hdc, hPen);
//绘制黑色矩形,范围可根据需要自行更改
Rectangle(hdc, ORIGINX, 0, ORIGINX + LENGTHX + 1, ORIGINY + LENGTHY + 1);
}
int main(int argc, char* argv[])
{
//获取控制台标题
GetConsoleTitle(title, 256);
//先通过FindWindow函数借助标题获取窗口句柄HWND,之后再利用GetDC函数借助HWND获取HDC
hdc = GetDC(FindWindow(0, title));
hPen = CreatePen(PS_SOLID, 3, RGB(255, 0, 0));//设置曲线画笔,红色
hPen2 = CreatePen(PS_SOLID, 3, RGB(0, 0, 255));//设置X轴画笔,蓝色
hPenOld = (HPEN)SelectObject(hdc, hPen);
char sendDataGain[15] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x01 ,0x10, 0x00, 0x38, 0x00, 0x01, 0x02, 0x00, 0x00 };//1倍增益
char sendDataAD[12] = { 0x00,0x00,0x00,0x00,0x00,0x06,0x01,0x03,0x01,0x00,0x00,0x01 };//AD1查询命令
char sendDataRange[15] = { 0x00,0x00,0x00,0x00,0x00,0x09,0x01,0x10,0x00,0x0a,0x00,0x01,0x02,0x00,0x01 };//-5~+5V和跳线对应
char recData[255];//TCP接收缓冲区
UINT8 VH = 0, VL = 0;//16位二进制电压采集数据原码高8位、低8位
float V = 0.0;//转化后电压值
int ret;//接收数据长度
WORD sockVersion = MAKEWORD(2, 2);
WSADATA data;
if (WSAStartup(sockVersion, &data) != 0)//启动并检查可用Winsock API实现库
{
printf("无可用Winsock API实现库");
return 0;
}
SOCKET sclient = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);//创建socket套接字
if (sclient == INVALID_SOCKET)
{
printf("socket无效!");
return 0;
}
sockaddr_in serAddr;
serAddr.sin_family = AF_INET;
serAddr.sin_port = htons(8000);//设置通讯端口号
serAddr.sin_addr.S_un.S_addr = inet_addr("192.168.1.126");//设置目标IP地址
if (connect(sclient, (sockaddr *)&serAddr, sizeof(serAddr)) == SOCKET_ERROR)//建立TCP连接
{
printf("连接错误!");
closesocket(sclient);
return 0;
}
else
{
printf("连接成功!\n");
}
//设置AD增益1倍
send(sclient, sendDataGain, 15, 0);
if (recv(sclient, recData, 255, 0) != 0)
{
printf("设置AD增益1倍\n");
}
//设置模拟量采集范围-5~+5V
send(sclient, sendDataRange, 15, 0);
if (recv(sclient, recData, 255, 0) != 0)
{
printf("设置模拟量采集范围-5~5V\n");
}
while (1)
{
//发送AD1读取命令
send(sclient, sendDataAD, 12, 0);
//接收下位机应答数据
ret = recv(sclient, recData, 255, 0);
if(ret>0)
{
for (int i= 0;i<2000;i++)
{
VH = (UINT8)recData[9];//读取16位AD数据原码高8位
VL = (UINT8)recData[10];//读取16位AD数据原码低8位
V = 5.0*(float)(VH << 8 | VL) / 32767.0 - 5.0;//将AD数据原码转化为工程单位
if (i<=99)
datay[i]=V;
else
for(int K=0 ;K<99;K++)
datay[K]=datay[K+1];
datay[99]=V;
}
}
ClearWind(hdc);//清屏
hPenOld = (HPEN)SelectObject(hdc, hPen);//选择画笔
MoveToEx(hdc, ORIGINX, ORIGINY, NULL);//移动到起点
for (int m = 0; m < XDATALEN; m++)
{
//绘制线段,连接前一个点与下一个点,第二个参数为目标点x坐标,第三个参数为y坐标
LineTo(hdc, LENGTHX * m / XDATALEN + ORIGINX,datay[m] + ORIGINY);
}
//创建绘制x轴的pen并将其选入设备上下文
hPenOld = (HPEN)SelectObject(hdc, hPen2);//选择画笔
MoveToEx(hdc, ORIGINX, ORIGINY, NULL);//移动到起点
LineTo(hdc, ORIGINX + LENGTHX, ORIGINY);//绘制X轴直线
times++;
delay_ms(100);//延时100ms
if (kbhit())//检查是否有按键按下
{
if (_getch() == 0x1b)//若按下ESC键跳出循环
{
break;
}
}
}
DeleteObject(hPen);//删除画笔
DeleteObject(hPen2);//删除画笔
return 0;
}