Before commenting read Forum rules
Don't comment the topic if you have a new question.
You can create a new topic selecting correct category from Gurux Forum and then create a new topic selecting "New Topic" from the top left.
Before commenting read Forum rules
Don't comment the topic if you have a new question.
You can create a new topic selecting correct category from Gurux Forum and then create a new topic selecting "New Topic" from the top left.
Hello,
I am quite a newbie in windows coding and I am trying to make a sample code in C++ running using gurux but... got nothing working.
I installed everything that was said in the readme.txt, and every component does compile fine.
Could you give us a full sample code using GXNET and GXSerial in C++ like the one given in C# please?
The code in C# I am talking about:
using System;
using Gurux.Common;
using Gurux.Serial;
using Gurux.Net;
using Gurux.DLMS2;
namespace GuruxCOSEMSample
{
public class GXCOSEMSample
{
// Device reply wait time.
int WaitTime = 5000;
private CGXCOSEM m_Cosem;
//Constructor.
public GXCOSEMSample()
{
m_Cosem = new CGXCOSEM();
}
///
/// Walk through all device objects using serial port connection.
///
pubic Gurux.DLMS2.CDLMSObjectCollection GetAllObjects()
{
GXSerial serial = InitializeSerialConnection();
CDLMSObjectCollection objs = GetObjects(serial);
return objs;
}
///
/// Initialize serial port connection to COSEM/DLMS device.
///
GXSerial InitSerial()
{
GXSerial serial = new GXSerial();
serial.Port = "COM1"; //TODO: Change correct serial port.
object reply = null;
byte Terminator = (byte)0x0A;
// Bitrate must be 300 when connection is initialized.
serial.BitRate = 300;
serial.DataBits = ByteSize.Byte7Bits;
serial.Parity = Parity.Even;
serial.StopBits = StopBits.One;
serial.Open();
//Query device information.
if (!serial.SendSync("/?!\r\n", Gurux.Common.VariantType.String, Terminator, 0, WaitTime, false, Gurux.Common.VariantType.String, out reply))
{
object d = serial.GetReplyData(Gurux.Common.VariantType.HexString);
throw new Exception("Failed to receive reply from the device in given time.");
}
string answer = reply.ToString();
if (answer[0] != '/')
{
throw new Exception("Invalid responce.");
}
string manufactureID = answer.Substring(1, 3);
char baudrate = answer[4];
int bitrate = 0;
switch (baudrate)
{
case '0':
bitrate = 300;
break;
case '1':
bitrate = 600;
break;
case '2':
bitrate = 1200;
break;
case '3':
bitrate = 2400;
break;
case '4':
bitrate = 4800;
break;
case '5':
bitrate = 9600;
break;
case '6':
bitrate = 19200;
break;
default:
throw new Exception("Unknown baud rate.");
}
//Send ACK
//Send Protocol control character
byte controlCharacter = (byte)'2';// "2" HDLC protocol procedure (Mode E)
//Send Baudrate character
//Mode control character
byte ModeControlCharacter = (byte)'2';//"2" //(HDLC protocol procedure) (Binary mode)
//Set mode E.
serial.SendSync(new byte[] { 0x06, controlCharacter, (byte)baudrate, ModeControlCharacter, 13, 10 }, Gurux.Common.VariantType.None, Terminator, 0, 500, false, Gurux.Common.VariantType.Array | Gurux.Common.VariantType.UInt8, out reply);
serial.BitRate = bitrate;
serial.DataBits = ByteSize.Byte8Bits;
serial.Parity = Parity.None;
serial.StopBits = StopBits.One;
return serial;
}
///
/// Initialize network connection settings.
///
public GXNet InitNet()
{
GXNet net = new GXNet();
net.HostName = "TODO: Change correct IP address";
net.HostPort = 1000;
net.Protocol = NetworkType.Tcp;
net.Connect();
return net;
}
public GXSerial InitializeSerialConnection()
{
GXSerial serial = InitSerial();
object data, reply;
data = m_Cosem.SNRMRequest();
reply = ReadDLMSPacket(serial, data, WaitTime);
//Has server accepted client.
m_Cosem.ParseUAResponse(reply);
//Generate AARQ request.
data = m_Cosem.AARQRequest();
//Split regusts to multible packets if needed.
//This must be done because all data might not be fit in one packet if password is used.
Array arr = (Array) m_Cosem.SplitDataToPackets(data);
int len = arr.Length;
int pos = 0;
foreach (byte[] it in arr)
{
data = it;
data = m_Cosem.Read(data, ++pos, len, ObjectType.None, 0);
reply = ReadDLMSPacket(media, data, WaitTime);
}
//Parse reply.
m_Cosem.ParseAAREResponse(reply);
return serial;
}
public GXSerial InitializeNetConnection()
{
GXNet net = InitNet();
object data, reply;
data = m_Cosem.SNRMRequest();
reply = ReadDLMSPacket(net, data, WaitTime);
//Has server accepted client.
m_Cosem.ParseUAResponse(reply);
//Generate AARQ request.
data = m_Cosem.AARQRequest();
//Split regusts to multible packets if needed.
//This must be done because all data might not be fit in one packet if password is used.
Array arr = (Array)m_Cosem.SplitDataToPackets(data);
int len = arr.Length;
int pos = 0;
foreach (byte[] it in arr)
{
data = it;
data = m_Cosem.Read(data, ++pos, len, ObjectType.None, 0);
reply = ReadDLMSPacket(media, data, WaitTime);
}
//Parse reply.
m_Cosem.ParseAAREResponse(reply);
return net;
}
object ReadDLMSPacket(Gurux.Common.IGXMedia2 media, object data, int wt)
{
if (data == null)
{
return null;
}
object reply = null;
byte Terminator = 0x7E;
if (!media.SendSync(data, Gurux.Common.VariantType.None, null, Terminator, 5, wt, true, Gurux.Common.VariantType.Array | Gurux.Common.VariantType.UInt8, out reply))
{
throw new Exception("Failed to receive reply from the device in given time.");
}
//Loop until whole m_Cosem packet is received.
while (!m_Cosem.IsDLMSPacketComplete(reply))
{
if (!media.WaitMoreReplyData(Terminator, 0, wt, true, Gurux.Common.VariantType.Array | Gurux.Common.VariantType.UInt8, ref reply))
{
throw new Exception("Failed to receive reply from the device in given time.");
}
}
media.SendSyncComplete = true;
return reply;
}
private Gurux.DLMS2.CDLMSObjectCollection GetObjects(IGXMedia2 media)
{
object data, reply;
try
{
data = m_Cosem.GetObjects(RegisterObjectType.AssociationSn);
reply = ReadDLMSPacket(media, data, WaitTime);
object allData = null;
m_Cosem.GetDataFromPacket(reply, ref allData);
int maxProgress = m_Cosem.GetMaxProgressStatus(allData);
//Notify progress here if you want to.
try
{
while (m_Cosem.IsMoreDataAvailable(reply))
{
data = m_Cosem.ReceiverReady();
reply = ReadDLMSPacket(media, data, WaitTime);
m_Cosem.GetDataFromPacket(reply, ref allData);
//Notify progress here if you want to.
}
}
catch (Exception Ex)
{
throw new Exception("DLMS AARQRequest failed. " + Ex.Message);
}
Gurux.DLMS2.CDLMSObjectCollection objs = m_Cosem.ParseObjects(allData, ObjectType.None);
return objs;
}
catch
{
return null;
}
}
pubic object Readobject(object baseName, int interface, int attributeOrder)
{
return m_Cosem.Read(baseName, 1, 1, interface, attributeOrder);
}
}
}
since I am beginning to
since I am beginning to understand a little the code, I post something that compile and send a message:
_first create a windows form application
_add as reference the gurux COM products
_you will see in the general tab of the tool box the DLMS modules, add GXNet class to the form
in the form.h you should see this->axGXNet1 created, in the end of the file put:
Gurux::DLMS2::CGXCOSEMClass ^ mCosem = gcnew Gurux::DLMS2::CGXCOSEMClass();
this->axGXNet1->HostName="yourMachine";
this->axGXNet1->HostPort=9000;
this->axGXNet1->Protocol=GuruxNet::GX_NW_TYPE::GX_NW_TCPIP;
this->axGXNet1->Connect();
Object ^ c = gcnew String("hello world");
Gurux::Common::VariantType SendType;
Object ^ Terminator = (Byte) 0x7E;
Object ^ Reply;
Object ^ Replyterminator;
Object ^ ReplyData = gcnew Object;
Object ^% ReplyDataRef = ReplyData;
Object ^ Data;
// mCosem->ClientID
Data = mCosem->SNRMRequest()
this->axGXNet1->SendSync(c, GuruxNet::GX_VARTYPE::GX_VT_NONE, 0,
Replyterminator, 0, 2000, false,
GuruxNet::GX_VARTYPE::GX_VT_ARRAY |GuruxNet::GX_VARTYPE::GX_VT_UINT16,
ReplyDataRef);
If you remove the line "Data = mCosem->SNRMRequest()" you would see the "hello world" appearing in your echo server set port 9000, but since I have no meter nor test server this code gives an error: client id not found.
This code was created looking at the C# code sample.
Initial settings
Hello,
You received this error message because you have not set client and server IDs before calling SNRMRequest.
Try this.
mCosem->ClientID = (byte) 0x21;
mCosem->ServerID = (byte) 0x3;
Happy Coding,
Mikko
thanks for the answer :-) Nel
thanks for the answer :-)
Nel
Initial settings
Hi,
No problem. Let us know if you have anything else.
Happy coding,
Mikko
Sample VC++ Code
Is there any sample code showing the use of the DLMS Component with Visual C++?
DLMS and Visual C++
Hi,
At this moment we do not have any example code for Visual C++ and DLMS/COSEM component.
It almost same are you using Visual C++ or some other language. Component interfaces are the same. You can see example how to create Gurux Serial port component from here:
http://www.gurux.fi/gxdn/Serial/UseC.html
Using DLMS/COSEM component is almost same. First create the component and after that set correct parameters.
BR,
Mikko
I couldn't compile C# sample code. Please help
Hi,
Is there anyone who was able to compile the C# sample code and connect and read from the meter using that sample? I couldn't compile the sample C# code. It asks for some libraries and i don't know where i can find them (I added all the DLL files which come from Director and Editor installation but they are not enough they don't have DLMS DLL for example. ).
I also tried to read from using Gurux Director but it give errors like "object reference not set to an instance of object" when i try to define device. I think that I already downloaded the latest versions.
Thank you for your time.
Ferda Ozdemir Sonmez
C# Sample
Hi,
We do not have installer for the sample at this moment.
Best way to get started is if you install GXDLMSDirector.
It will install all nesessary files.
I have few questions to you:
1. What meter you are using?
2. When this "Object reference..." error occurred? When you created,
new device, import data from device, etc. I'm asking this because this
is a new issue to us.
3. What Windows version you are using?
4. What language you are using(English, Spanish, etc...)
BR,
Mikko
DLMS and Visual C++
Unfortunately the sample in C# is too far from the one should be in Visual C++ (MFC projects and not .NET)
for example when you want to create AARQ, the code in C# is this:
//Generate AARQ request.
data = m_Cosem.AARQRequest();
and what you must do in C++ is something like this:
if (FAILED(hr = m_Cosem->AARQRequest(pTag, &vRequest)))
AfxMessageBox(dlms.GetGXErrorMsg((IUnknown* )hr), MB_OK|MB_ICONSTOP);
I don't have any idea how to fill the pTag arqument and I can't find any USEFUL documentation about it!!!
the result is a frame without HDLC header and trailer.
Could anyone PLEASE help me?
MFC
Hi,
You are right about C++ documentation. We are generating helps with Sandcastle and it do not generate C++ helps. I know that this is excuse and we have lots to improve with helps. We try to do our best. :-)
At the meantime if you have anything to ask post your questions to this forum.
You do not need to fill tags. You can pass NULL pointer.
Happy coding,
Mikko