Hi all,
I have an issue converting a java long to an uint64_t value to the Arduino platform.
Here is the code, both for the Arduino part and the java one.
Arduino code:
#include <SPI.h>
#include <Ethernet.h>
byte mac[] = { 0x90, 0xA2, 0xDA, 0x00, 0x20, 0x45 };
byte ip[] = { 192, 168, 33, 17 };
byte javaServer[] = { 192, 168, 33, 16 };
Server server(10001);
Client javaClient(javaServer, 10002);
void setup()
{
int i = 0;
uint64_t javaLong = 0;
byte buffer[16];
Serial.begin(57600);
Ethernet.begin(mac, ip);
server.begin();
delay(3000);
Client client = server.available();
if (client) {
Serial.println("Client available");
// read the input buffer
Serial.println("Receiving bytes...");
while (client.connected() && i < sizeof(buffer)) {
if (client.available()) {
buffer[i] = client.read();
i++;
}
}
Serial.println("Bytes received");
Serial.print("Num of bytes readed: ");
Serial.println(i);
Serial.print("Received bytes: ");
for (int i = 0; i < sizeof(buffer); i++) {
Serial.print(buffer[i], HEX);
Serial.print(" ");
}
Serial.println();
// copy the buffer value to the uint64_t variable
memcpy(&javaLong, buffer, sizeof(uint64_t));
Serial.print("Uint64_t value = ");
Serial.print((unsigned long) javaLong);
Serial.print(", binary: ");
Serial.println((unsigned long) javaLong, BIN);
client.stop();
}
else {
Serial.println("Client not available!");
return;
}
byte *longPtr = (byte *) &javaLong;
Serial.print("Number to send (hex format): ");
for (i = 0; i < sizeof(uint64_t); i++) {
Serial.print(* (longPtr + i), HEX);
Serial.print(" ");
}
Serial.println();
if (javaClient.connect()) {
// send
if (longPtr) {
Serial.println("Sending bytes...");
for (i = 0; i < 8; i++) {
javaClient.write(* (longPtr + i));
}
Serial.println("Sending finished");
}
delay(1);
javaClient.stop();
}
else {
Serial.println("NOT connected");
}
}
void loop() { }
Java code:
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.ByteBuffer;
public class SendReceiveUint64 {
public static final int SHIFT_ONE_BYTE = 8;
public static final int SHIFT_TWO_BYTES = 16;
public static final int SHIFT_THREE_BYTES = 24;
public static final int SHIFT_FOUR_BYTES = 32;
public static final int SHIFT_FIVE_BYTES = 40;
public static final int SHIFT_SIX_BYTES = 48;
public static final int SHIFT_SEVEN_BYTES = 56;
public static final int SHIFT_EIGHT_BYTES = 64;
public static final long FIRST_8_BITS_MASK_LONG = 0x000000FFL;
public static final long SECOND_8_BITS_MASK_LONG = 0x0000FF00L;
public static final long THIRD_8_BITS_MASK_LONG = 0x00FF0000L;
public static final long FOURTH_8_BITS_MASK_LONG = 0xFF000000L;
public static void main(String[] args) {
Socket socket = null, client = null;
ServerSocket server = null;
int serverPort = 10002;
OutputStream sockOutput = null;
InputStream sockInput = null;
byte[] b = null;
// long num = 2147483648L;
long num = 21474836489L;
System.out.println("Original long value: " + num);
System.out.println("Bytes in (java) memory: " + Long.toHexString(num));
System.out.println("Number in binary format: " + Long.toBinaryString(num));
try {
socket = new Socket("192.168.33.17", 10001);
sockOutput = socket.getOutputStream();
if (socket == null || sockOutput == null) {
System.out.println("Error while creating socket");
return;
}
b = longToByteArray(num);
System.out.print("Hex format: ");
for (int i = 0; i < b.length; i++) {
System.out.printf("%02X ", b[i]);
}
System.out.println();
sockOutput.write(b);
socket.close();
}
catch (IOException io) {
io.printStackTrace();
}
try {
server = new ServerSocket(serverPort);
if (server == null) {
System.out.println("Error while creating server socket");
return;
}
System.out.println("Server started");
client = server.accept();
if (client == null) {
System.out.println("No client connected");
return;
}
System.out.println("New socket accepted");
sockInput = client.getInputStream();
byte[] buf = new byte[256];
int bytesRead = 0;
try {
// delay needed to read all the input buffer
Thread.sleep(200);
bytesRead = sockInput.read(buf, 0, buf.length);
System.out.println("Input buffer received");
if (bytesRead < 0) {
System.out.println("Trying to read from socket, but failed");
return;
}
System.out.println("Readed " + bytesRead + " bytes");
byte[] uint64Bytes = new byte[8];
System.arraycopy(buf, 0, uint64Bytes, 0, uint64Bytes.length);
System.out.print("Bytes received from the net (hex): ");
for (int i = 0; i < uint64Bytes.length; i++) {
System.out.printf("%02X ", uint64Bytes[i]);
}
System.out.println();
long receivedNum = bytesToLong(uint64Bytes, (uint64Bytes.length - 1));
System.out.println("Received number = " + num);
System.out.print("Bytes in hex format: ");
System.out.println(Long.toHexString(receivedNum));
System.out.print("Bytes in binary format: ");
System.out.println(Long.toBinaryString(receivedNum));
System.out.print("Bytes in memory (hex): ");
for (int i = 0; i < uint64Bytes.length; i++) {
System.out.printf("%02X ", uint64Bytes[i]);
}
System.out.println();
}
catch (Exception e) {
System.err.println("Exception reading from/writing to socket, e = " + e);
e.printStackTrace(System.err);
return;
}
socket.close();
}
catch (IOException e) {
e.printStackTrace(System.err);
}
}
public static byte[] longToByteArray(long value) {
byte[] array = new byte[8];
array[0] = (byte) (value & FIRST_8_BITS_MASK_LONG);
array[1] = (byte) ((value & SECOND_8_BITS_MASK_LONG) >>> SHIFT_ONE_BYTE);
array[2] = (byte) ((value & THIRD_8_BITS_MASK_LONG) >>> SHIFT_TWO_BYTES);
array[3] = (byte) ((value & FOURTH_8_BITS_MASK_LONG) >>> SHIFT_THREE_BYTES);
array[4] = (byte) ((value & FIRST_8_BITS_MASK_LONG) >>> SHIFT_FOUR_BYTES);
array[5] = (byte) ((value & SECOND_8_BITS_MASK_LONG) >>> SHIFT_FIVE_BYTES);
array[6] = (byte) ((value & THIRD_8_BITS_MASK_LONG) >>> SHIFT_SIX_BYTES);
array[7] = (byte) ((value & FOURTH_8_BITS_MASK_LONG) >>> SHIFT_SEVEN_BYTES);
return array;
}
public static long bytesToLong(byte[] value, int end) {
byte[] b = new byte[8];
// storing bytes in little-endian form
for (int i = 0, pos = end; i < 8; i++) {
b[i] = value[pos - i];
}
return ByteBuffer.wrap(b).getLong();
}
}
I have no issue if the input number fits into 32 bits. Following is the output for the number 2147483648L.
Arduino side:
Num of bytes readed: 8
Received bytes: 0 0 0 80 0 0 0 0
Uint64_t value = 2147483648, binary: 10000000000000000000000000000000
Number to send (hex format): 0 0 0 80 0 0 0 0
Java side:
Original long value: 2147483648
Bytes in (java) memory: 80000000
Number in binary format: 10000000000000000000000000000000
Hex format: 00 00 00 80 00 00 00 00
Input buffer received
Readed 8 bytes
Bytes received from the net (hex): 00 00 00 80 00 00 00 00
Received number = 2147483648
Bytes in hex format: 80000000
Bytes in binary format: 10000000000000000000000000000000
Bytes in memory (hex): 00 00 00 80 00 00 00 00
Instead, if the input long number does not fit into 32 bits, the result is incorrect. This is the output for the number 21474836489L.
Arduino side:
Num of bytes readed: 8
Received bytes: 9 0 0 0 0 0 0 0
Uint64_t value = 9, binary: 1001
Number to send (hex format): 9 0 0 0 0 0 0 0
Java side:
Original long value: 21474836489
Bytes in (java) memory: 500000009
Number in binary format: 10100000000000000000000000000001001
Hex format: 09 00 00 00 00 00 00 00
Input buffer received
Readed 8 bytes
Bytes received from the net (hex): 09 00 00 00 00 00 00 00
Received number = 21474836489
Bytes in hex format: 9
Bytes in binary format: 1001
Bytes in memory (hex): 09 00 00 00 00 00 00 00
Does anyone have some suggestions?
Thanks in advance.