I have to do an application for a GPRS modem JAVA (J2ME) programmable that must interface with an electromedical device (glucometer).
I have an input buffer and an output buffer on the serial port of the device.
When the application starts, I listen on the serial port and I receive from the glucometer one byte with the decimal code "5" which corresponds, to the ASCII table, the symbol of Enquiry and after 15 seconds I get the bytes "4" that corresponds to the End of Transmission.
To receive data from the glucometer I need to send an ACK signal (acknowledge) which corresponds to the byte "6".
I tried the following forms:
outBuffer.write("ACK\r\n".getBytes()); //first without setting the charset and after I trying to set all the charset.
I tried to send a byte buffer like this:
byte[] bSend = new byte[] { 6 };
outBuffer.write(bSend); //(I tried also with the byte 10 (LF) and 13 (CR)).
The result is that I can not receive data but I get cyclically but only the values 5 and 4.
With all the software that can comunicate with serial port (like Serial Monitor) if I send an ACK message I receive data from glucometer correctly.
I think my problem is due to the value of the ACK coding in Java, someone can indicate any solution?
As this seems to be a pretty low-level interface that uses ASCII control characters to do its communication I think you need to send these byte values verbatim, and without extra stuff like newlines or whatever. This means that
byte[] bSend = new byte[] { 6 };
outBuffer.write(bSend);
Is the correct approach. Now, this protocol looks a lot like ASTM E1381, so I checked here and paragraph 6.1.2 might be related to your problem:
When the meter initiates the Establishment Phase, the meter determines
if the computer is connected by initially sending an <ENQ> character.
If the computer responds within 15 seconds by sending an <ACK>
character, the meter proceeds with Data Transfer Mode. If the computer
responds within 15 seconds with a <NAK> character, the meter sends an
<EOT> then attempts to enter Remote Command Mode, by looking for an
<ENQ> character from the computer. Also see "Section 6.2 Remote
Command Mode Protocol". Any response within 15 seconds to the meter’s
<ENQ> other than an <ACK> or <NAK> character causes the meter to send
an <EOT>, delay one second, then send another <ENQ>. If the computer
does not respond within 15 seconds, then the meter sends an <EOT>,
delays one second, then sends another <ENQ> and waits again for a
response from the computer. Note: One second after sending an <ENQ>,
the meter may enter a low power mode. Thus, there is a possibility
that the first <ACK> sent by the computer is not read correctly. In
this case, the meter responds with an <EOT>, delays one second, then
sends another <ENQ>.
Emphasis mine, I guess that that's what's happening. So, you should repeat sending another ENQ to get it into data transfer mode, assuming that that's what you want.
it should be
byte bSend=(byte)0x6;
outBuffer.write(bSend);
Related
I have a serial data read question.
I have a serial device that responds to commands with an ack (0x06) or error (0x21)
To start data flow, I need to send a certain command, wait for the ACK, then send the data request command... And collect the 18 byte, non-terminated data. Then resend the data request after a couple of seconds.
Currently, I am using the 'on read' signal from the port. This works...however, the read event mostly fires for each byte read and sometimes if fires and reads two bytes of data.
So... Question is... How can I ensure the after I send the data request that I collect JUST the 18 bytes of the response message?
Will this require checking the size of each data read from the port and splitting it up into aingle-byte chunks?
From what I could tell, a parser might work, but I could not tell how to kick off the parser read after the ACK, and then stop after reading 18 bytes, the start again after then next ACK.
Any help or thoughts would be appreciated.
I am currently working on a graduation project where I want to transmit a sessiontoken using BLE. On the server side I am using Node.js and Bleno to create the connection. After the client subscribes to the notification, the server will push the token.
A small part of the code is:
const buf1 = Buffer.from(info, 'utf8');
updateValueCallback(buf1);
At this step, I am using nRF Connect to check if everything is working. My intention works, except I see that only the first 20 characters are transferred. (As much as the packet size)
My question concerns the buffer size. Will, when I finally connect to an Android app, the whole string be transmitted? In this case the underlying protocols will cut the string and reassemble it on the other side. In this case the buffer size doesn't matter. Or must I negotiate the MTU to be the size of the string. In other words must the buffersize be the size of the transmitted package?
In the case the buffer is smaller than the whole string, can the whole string still be transmitted with it?
GATT requires that a notification is maximum MTU - 3 bytes long. The default MTU is 23 so hence the maximum modification value length is 20 bytes by default. By negotiating a larger MTU you can send longer notifications (if your BLE stack supports that).
I haven't used Bleno but all the stack that I have used I needed to slice the data myself 20 bytes at the time. And on receiver side collect them and put them together again.
The stacks have been good to buffer the data and transmit it one chunk at the time. So I have looped the function (as your updateValueCallback()) until all the slices of my data was done.
Hope it works for you.
I am currently attempting to communicate with an external application over TCP/IP based socket. I have successfully established a connection with the client and received some data. This manual here states that
After this command is received, the client must read an acknowledgement
octet from the daemon. A positive acknowledgement is an octet of zero bits. A negative acknowledgement is an octet of any other pattern.
I would like to send a positive acknowledgment and I am sending it this way
My server listening code was obtained from here
void WriteData(std::string content)
{
send(newsockfd,content.c_str(),content.length(),0);
}
WriteData("00000000");
My question is if I am sending this data corectly (octet of zero bits) ?
Update:
I have read this post here
which states that send only allows to send a char* array. So I am not sure how I can send a byte over a socket. I know i could do something like this
std::bitset<8> b1 ; // [0,0,0,0,0,0,0,0]
but i am not sure how i would send that over a socket.
Try
WriteData(std::string("\0",1));
using your function or even:
const char null_data(0);
send(newsockfd,&null_data,1,0);
to send it directly.
WriteData("00000000");
Will actually sends 8 octets of 48 [decimal] (assuming your platform is ASCII which all modern systems are compatible with).
However \0 is the escape sequence used in string literals to represent the null character (that is the zero octet).
There's a conflation (mixing together) in C++ between the notions of characters and bytes that dates back to the earliest days of C and is pretty much baked in.
I've never worked with bluetooth before. I have to sends data via BLE and I've found the limit of 20 bytes per chunk.
The sender is an Arduino and the receiver could be both an Android or a Node.js app on a pc.
I have to send 9 values, stored in float values, so 4 bytes * 9 = 36 bytes. I need 2 chunks for all my data via BLE. The receiving part needs both chunks to process them. If some data are lost, I don't care.
I'm not expert in network protocols and I think I have to give each message an incremental timestamp so that the receiver can glue the two chunks with the same timestamp or discard the last one if the new timestamp is higher. But I'm not sure how to do a checksum, if I really need it or not, if I really have to care about it, or if - for a simple beta version of my system - I can ignore all those problems..
Does anyone can give me some advice? Like examples of similar situations handled with BLE communication?
You can get around the size limitation using the "Read Blob Request" of ATT. It allows you to read an attribute and also give an offset. So, you can use it to read the attribute with an offset of 0, if there's more than ATT_MTU bytes than you can request again with the offset at ATT_MTU*1, if there's still more ATT_MTU*2, etc... (You can read it in 3.4.4.5 of the Bluetooth v4.1 specifications; it's in the 4.0 spec too but I don't have that in front of me right now)
If the value changes between request, I'm not sure how you could go about detecting such a change. You could have the attribute send notifications when there's a change to interrupt the process in case the value changes in the middle of reading it.
I am writing a serial port application using VC++, in which I can open a port on a switch device, send some commands and display their output. I am running a thread which always read open port for output of given command. My main thread waits until read completes, but problem is how do I recognize that command output ends, and I should signal main thread.
Almost any serial port communication requires a protocol. Some way for the receiver to discover that a response has been received in full. A very simple one is using a unique byte or character that can never appear in the rest of the data. A linefeed is standard, used by any modem for example.
This needs to get more elaborate when you need to transfer arbitrary binary data. A common solution for that is to send the length of the response first. The receiver can then count down the received bytes to know when it is complete. This often needs to be embellished with a specific start byte value so that the receiver has some chance to re-synchronize with the transmitter. And often includes a checksum or CRC so that the receiver can detect transmission errors. Further embellishments then is to make errors recoverable with ACK/NAK responses from the receiver. You'd be then well on your way in re-inventing TCP. The RATP protocol in RFC-916 is a good example, albeit widely ignored.