map/das-dn/hostadsbf/example.cpp
2024-12-03 10:36:06 +08:00

144 lines
4.5 KiB
C++

// SPDX-License-Identifier: MIT
/**
Copyright (c) 2015 - 2021 Beckhoff Automation GmbH & Co. KG
*/
#include "AdsLib.h"
#include "AdsNotificationOOI.h"
#include "AdsVariable.h"
#include <array>
#include <cstring>
#include <iostream>
#include <iomanip>
using ExampleDatatype = uint8_t;
static void NotifyCallback(const AmsAddr* pAddr, const AdsNotificationHeader* pNotification, uint32_t hUser)
{
ExampleDatatype data{};
std::memcpy(&data, pNotification + 1, std::min<size_t>(sizeof(data), pNotification->cbSampleSize));
std::cout << std::setfill('0') <<
"NetId: " << pAddr->netId <<
" hUser 0x" << std::hex << hUser <<
" sample time: " << std::dec << pNotification->nTimeStamp <<
" sample size: " << std::dec << pNotification->cbSampleSize <<
" value:" << " 0x" << std::hex << +data <<
'\n';
}
static void notificationExample(std::ostream& out, const AdsDevice& route)
{
const AdsNotificationAttrib attrib = {
sizeof(ExampleDatatype),
ADSTRANS_SERVERCYCLE,
0,
{4000000}
};
AdsNotification notification { route, 0x4020, 4, attrib, &NotifyCallback, 0xDEADBEEF };
out << "Hit ENTER to stop notifications\n";
std::cin.ignore();
}
static void notificationByNameExample(std::ostream& out, const AdsDevice& route)
{
const AdsNotificationAttrib attrib = {
sizeof(ExampleDatatype),
ADSTRANS_SERVERCYCLE,
0,
{4000000}
};
out << __FUNCTION__ << "():\n";
AdsNotification notification { route, "MAIN.byByte[4]", attrib, &NotifyCallback, 0xBEEFDEAD };
out << "Hit ENTER to stop by name notifications\n";
std::cin.ignore();
}
static void readExample(std::ostream& out, const AdsDevice& route)
{
AdsVariable<uint8_t> readVar {route, 0x4020, 0};
out << __FUNCTION__ << "():\n";
for (size_t i = 0; i < 8; ++i) {
out << "ADS read " << std::hex << (uint32_t)readVar << '\n';
}
}
static void readByNameExample(std::ostream& out, const AdsDevice& route)
{
AdsVariable<uint8_t> readVar {route, "MAIN.byByte[4]"};
out << __FUNCTION__ << "():\n";
for (size_t i = 0; i < 8; ++i) {
out << "ADS read " << std::hex << (uint32_t)readVar << '\n';
}
}
static void readWriteExample(std::ostream& out, const AdsDevice& route)
{
AdsVariable<uint8_t> simpleVar {route, "MAIN.byByte[0]"};
AdsVariable<uint8_t> validation {route, "MAIN.byByte[0]"};
out << __FUNCTION__ << "():\n";
simpleVar = 0xA5;
out << "Wrote " << 0xA5 << " to MAIN.byByte and read " << (uint32_t)validation << " back\n";
simpleVar = 0x5A;
out << "Wrote " << (uint32_t)simpleVar << " to MAIN.byByte and read " << (uint32_t)validation << " back\n";
}
static void readWriteArrayExample(std::ostream& out, const AdsDevice& route)
{
static const std::array<uint8_t, 4> arrayToWrite = { 1, 2, 3, 4 };
AdsVariable<std::array<uint8_t, 4> > arrayVar {route, "MAIN.byByte"};
arrayVar = arrayToWrite;
std::array<uint8_t, 4> readArray = arrayVar;
out << "Wrote array with first value " << (uint32_t)arrayToWrite[0] << " and last value " <<
(uint32_t)arrayToWrite[3] << "\n";
out << "Read back array with first value " << (uint32_t)readArray[0] << " and last value " <<
(uint32_t)readArray[3] << "\n";
}
static void readStateExample(std::ostream& out, const AdsDevice& route)
{
const auto state = route.GetState();
out << "ADS state: " << std::dec << (uint16_t)state.ads << " devState: " << std::dec << (uint16_t)state.device <<
'\n';
}
static void runExample(std::ostream& out)
{
static const AmsNetId remoteNetId { 192, 168, 129, 26, 1, 1 };
// static const char remoteIpV4[] = "ads-server";
static const char remoteIpV4[] = "192.168.129.26";
// uncomment and adjust if automatic AmsNetId deduction is not working as expected
bhf::ads::SetLocalAddress({192, 168, 112, 34, 1, 1});
AdsDevice route {remoteIpV4, remoteNetId, AMSPORT_R0_PLC_TC3};
notificationExample(out, route);
notificationByNameExample(out, route);
readExample(out, route);
readByNameExample(out, route);
readWriteExample(out, route);
readWriteArrayExample(out, route);
readStateExample(out, route);
}
int main()
{
try {
runExample(std::cout);
} catch (const AdsException& ex) {
std::cout << "Error: " << ex.errorCode << "\n";
std::cout << "AdsException message: " << ex.what() << "\n";
} catch (const std::runtime_error& ex) {
std::cout << ex.what() << '\n';
}
std::cout << "Hit ENTER to continue\n";
std::cin.ignore();
}