文章目录
- 一、硬件连接与SOPAS连接测距仪
- 二、从SOPAS读取数据
- 三、通过JSON获取数据
- 1. 使用Postman测试接口
- 2. 通过代码实现
一、硬件连接与SOPAS连接测距仪
首先硬件设备连接如下:
电源厂家应该是不提供,需要自行解决。
安装完成后需要使用sick的SOPAS软件进行配置:
1、通过软件更改设备IP
2、从设备导入
3、读取数据
4、点击“离线”按钮,切换为在线状态
具体请按照这篇文章来连接
二、从SOPAS读取数据
连接成功后如下图:
双击设备进入设备页面,如下:
这两位就是十六进制的距离信息,可以自行转换为十进制数,与测距仪表面显示屏上的十进制数字进行对比。
三、通过JSON获取数据
分别使用Python和C++来实现了:
1. 使用Postman测试接口
其中:
{"header": {"portNumber": 0},"data": {"processData":"in"}}
获取到如下内容表示成功
{"header": {"status": 0,"message": "ok"},"data": {"processDataIn": [0,0,123,212,252,1],"isValid": true}
}
2. 通过代码实现
1、C++代码如下:
#include <windows.h>
#include <winhttp.h>
#include <iostream>
#include <string>
#include <vector>
#include "nlohmann/json.hpp"#pragma comment(lib, "winhttp.lib")using json = nlohmann::json;HINTERNET OpenSession(const wchar_t* userAgent) {HINTERNET hSession = WinHttpOpen(userAgent,WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,WINHTTP_NO_PROXY_NAME,WINHTTP_NO_PROXY_BYPASS, 0);if (!hSession) {std::cerr << "Failed to open WinHTTP session." << std::endl;}return hSession;
}std::string SendPostRequest(HINTERNET hSession, const wchar_t* serverName, const wchar_t* path, const std::string& postData) {HINTERNET hConnect = WinHttpConnect(hSession, serverName, INTERNET_DEFAULT_HTTP_PORT, 0);if (!hConnect) {std::cerr << "Failed to connect to server." << std::endl;return "";}HINTERNET hRequest = WinHttpOpenRequest(hConnect, L"POST", path, NULL, WINHTTP_NO_REFERER,WINHTTP_DEFAULT_ACCEPT_TYPES, 0);if (!hRequest) {std::cerr << "Failed to open request." << std::endl;WinHttpCloseHandle(hConnect);return "";}const wchar_t* headers = L"Content-Type: application/json";DWORD dwBytesSent = 0;if (!WinHttpSendRequest(hRequest, headers, -1L, (LPVOID)postData.c_str(), postData.size(), postData.size(), 0)) {std::cerr << "Failed to send request." << std::endl;WinHttpCloseHandle(hRequest);WinHttpCloseHandle(hConnect);return "";}if (!WinHttpReceiveResponse(hRequest, NULL)) {std::cerr << "Failed to receive response." << std::endl;WinHttpCloseHandle(hRequest);WinHttpCloseHandle(hConnect);return "";}std::string response;DWORD dwSize = 0;DWORD dwDownloaded = 0;LPSTR pszOutBuffer;do {dwSize = 0;if (!WinHttpQueryDataAvailable(hRequest, &dwSize)) {std::cerr << "Failed to query data available." << std::endl;break;}pszOutBuffer = new char[dwSize + 1];if (!pszOutBuffer) {std::cerr << "Memory allocation failed." << std::endl;break;}ZeroMemory(pszOutBuffer, dwSize + 1);if (!WinHttpReadData(hRequest, (LPVOID)pszOutBuffer, dwSize, &dwDownloaded)) {std::cerr << "Failed to read data." << std::endl;}else {response.append(pszOutBuffer, dwDownloaded);}delete[] pszOutBuffer;} while (dwSize > 0);WinHttpCloseHandle(hRequest);WinHttpCloseHandle(hConnect);return response;
}int main() {HINTERNET hSession = OpenSession(L"MyAppName/1.0");if (!hSession) {return 1;}const wchar_t* serverName = L"169.254.102.101";const wchar_t* path = L"/iolink/sickv1/readPort";json payload = {{"header", {{"portNumber", 0}}},{"data", {{"processData", "in"}}}};std::string postData = payload.dump();std::string response = SendPostRequest(hSession, serverName, path, postData);if (!response.empty()) {try {json data = json::parse(response);const json processDataIn = data.at("data").at("processDataIn");if (processDataIn.size() >= 4) {int thirdData = processDataIn[2].get<int>();int fourthData = processDataIn[3].get<int>();std::cout << "Third data: " << thirdData << std::endl;std::cout << "Fourth data: " << fourthData << std::endl;}else {std::cout << "Response does not contain enough data." << std::endl;}}catch (const std::exception& e) {std::cerr << "Failed to parse JSON response: " << e.what() << std::endl;}}else {std::cerr << "Request failed." << std::endl;}WinHttpCloseHandle(hSession);return 0;
}
注意,nlohmann/json.hpp需要自行去github上把nlohmann下载下来,然后去包含目录导入。
python比较简单:
python">import requests# 定义请求的URL和请求体
url = "http://192.168.0.20/iolink/sickv1/readPort"
payload = {"header": {"portNumber": 0},"data": {"processData": "in"}
}# 发送POST请求
response = requests.post(url, json=payload)# 检查请求是否成功
if response.status_code == 200:# 解析返回的JSON数据data = response.json()# 获取processDataIn列表process_data_in = data.get('data', {}).get('processDataIn', [])# 检查列表长度是否足够if len(process_data_in) >= 4:# 获取第3和第4个数据(索引为2和3)third_data = process_data_in[2]fourth_data = process_data_in[3]print(f"Third data: {third_data}")print(f"Fourth data: {fourth_data}")else:print("Response does not contain enough data.")
else:print(f"Request failed with status code: {response.status_code}")
运行结果:
即为所求