FORUM CTRLX AUTOMATION
ctrlX World Partner Apps for ctrlX AUTOMATION
07-27-2022 08:14 AM
Dear Community,
we got an issue with a read from the Datalayer.
/**
* MIT License
*
* Copyright (c) 2020-2021 Bosch Rexroth AG
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include "comm/datalayer/datalayer.h"
#include "comm/datalayer/datalayer_system.h"
#include "comm/datalayer/memory_map_generated.h"
#include <stdio.h>
#include <signal.h>
#include <thread>
#include <iostream>
bool endProcess = false;
static void hdl(int sig, siginfo_t *siginfo, void *context)
{
endProcess = true;
}
void cleanup(comm::datalayer::DatalayerSystem *datalayer,
comm::datalayer::IClient *client,
std::shared_ptr<comm::datalayer::IMemoryUser> input)
{
comm::datalayer::DlResult result;
std::cout << "finish my work" << std::endl;
result = datalayer->factory()->closeMemory(input);
if (comm::datalayer::STATUS_FAILED(result))
std::cout << "Closing input memory failed with: " << result.toString() << std::endl;
delete client;
datalayer->stop();
printf("\n");
exit(0);
}
static constexpr const char *EthercatInputNode_ = "fieldbuses/ethercat/master/instances/ethercatmaster/realtime_data/input";
static constexpr const char *EthercatInputNodeMap_ = "fieldbuses/ethercat/master/instances/ethercatmaster/realtime_data/input/map";
int main(int ac, char *av[])
{
comm::datalayer::DlResult result;
comm::datalayer::Variant data;
comm::datalayer::DatalayerSystem datalayer;
uint8_t *inData;
uint8_t *outData;
// Start datalayer without a broker - a broker already exists in automation snap
datalayer.start(false);
// Local
// comm::datalayer::IClient *client = datalayer.factory()->createClient("tcp://boschrexroth:Boschrexroth1@192.168.1.12:2069");
// Snap
comm::datalayer::IClient *client = datalayer.factory()->createClient(DL_IPC_AUTO);
if (!client->isConnected())
{
std::cout << "could not connect to datalayer, check ip and login data" << std::endl;
datalayer.stop();
return 1;
}
// Read the Memory Map to take the revision number, the revision number is necessary to work with the memory
result = client->readSync(EthercatInputNodeMap_, &data);
if (STATUS_FAILED(result))
{
std::cout << "Reading Memory Map failed with " << result.toString() << std::endl;
delete client;
datalayer.stop();
return 2;
}
auto memMap = comm::datalayer::GetMemoryMap(data.getData());
auto revision = memMap->revision();
std::cout << "Revision Number of Memory Map: " << revision << std::endl;
std::cout << "Opening some realtime memory: " << EthercatInputNode_ << std::endl;
std::shared_ptr<comm::datalayer::IMemoryUser> input;
result = datalayer.factory()->openMemory(input, EthercatInputNode_);
if (comm::datalayer::STATUS_FAILED(result))
{
std::cout << "creation of input failed with: " << result.toString() << std::endl;
delete client;
datalayer.stop();
return 3;
}
// Structure to interrupt the do while loop with SIGINT
struct sigaction act;
memset(&act, '\0', sizeof(act));
act.sa_sigaction = &hdl;
act.sa_flags = SA_SIGINFO;
sigaction(SIGINT, &act, NULL);
std::cout << "start producing some output data" << std::endl;
do
{
std::this_thread::sleep_for(std::chrono::seconds(1));
result = input->beginAccess(inData, revision);
if (STATUS_SUCCEEDED(result))
{
std::cout << "first byte of input: " << inData[0] << std::endl;
input->endAccess();
}
else
{
std::cout << "input memory not present at the moment: " << result.toString() << std::endl;
};
} while (!endProcess);
// Cleanup closes the memory and stop the datalayersystem
cleanup(&datalayer, client, input);
}
Output:
2022-07-25T15:24:35Z systemd[1]: Started Service for snap application sdk-cpp-realtime.datalayerRealtimeUser.
2022-07-25T15:24:35Z sdk-cpp-realtime.datalayerRealtimeUser[5312]: Revision Number of Memory Map: 3985439437
2022-07-25T15:24:35Z sdk-cpp-realtime.datalayerRealtimeUser[5312]: Opening some realtime memory: fieldbuses/ethercat/master/instances/ethercatmaster/realtime_data/output
2022-07-25T15:24:35Z sdk-cpp-realtime.datalayerRealtimeUser[5312]: start producing some output data
2022-07-25T15:24:36Z sdk-cpp-realtime.datalayerRealtimeUser[5312]: input memory not present at the moment: DL_RT_INVALIDOBJECT
2022-07-25T15:24:37Z sdk-cpp-realtime.datalayerRealtimeUser[5312]: input memory not present at the moment: DL_RT_INVALIDOBJECT
2022-07-25T15:24:38Z sdk-cpp-realtime.datalayerRealtimeUser[5312]: input memory not present at the moment: DL_RT_INVALIDOBJECT
2022-07-25T15:24:39Z sdk-cpp-realtime.datalayerRealtimeUser[5312]: input memory not present at the moment: DL_RT_INVALIDOBJECT
2022-07-25T15:24:40Z sdk-cpp-realtime.datalayerRealtimeUser[5312]: input memory not present at the moment: DL_RT_INVALIDOBJECT
2022-07-25T15:24:41Z sdk-cpp-realtime.datalayerRealtimeUser[5312]: input memory not present at the moment: DL_RT_INVALIDOBJECT
2022-07-25T15:24:42Z sdk-cpp-realtime.datalayerRealtimeUser[5312]: input memory not present at the moment: DL_RT_INVALIDOBJECT
2022-07-25T15:24:43Z sdk-cpp-realtime.datalayerRealtimeUser[5312]: input memory not present at the moment: DL_RT_INVALIDOBJECT
2022-07-25T15:24:44Z sdk-cpp-realtime.datalayerRealtimeUser[5312]: input memory not present at the moment: DL_RT_INVALIDOBJECT
Any suggestions how this can occur?
Actual we are using SDK version 1.14.
Our path to the datalayer-node is: fieldbuses/ethercat/master/instances/ethercatmaster/realtime_data/output
The communication over the web-ui is working fine.
Sincerely Elleshar
Solved! Go to Solution.
07-29-2022 10:15 AM
Hello Elleshar,
I tested your code and it works like expected. So I can read the input values and can not reproduce your error. I would recommed to look at your fieldbus configuration.
I tested it also with ctrlX CORE V1.14. As EtherCAT Slaves I used a ctrlX IO bus coupler and two DI16 modules.
One side hint:
To print out your uint8_t value in C++ correctly, you can use unsingned() to convert it.
result = input->beginAccess(inData, revision);
if (STATUS_SUCCEEDED(result))
{
std::cout << "first byte of input: " << unsigned(inData[0]) << std::endl;
input->endAccess();
}
Best regards,
Nick