How can send 16bit Data using TCPserver, with photon particle?


#1

I’m trying to send a data array but i need to send values between 0 and 4095 via TCP. im testing and only can send 0 to 255 Data values.


#2

Any given 16bit value is also comprised of 8bit bytes - just two of them one following the other :wink:
The transport layer is indifferent to the actual datatype it sends.


#3

So what should the receiver do to recover the signal?, in the server im using a for loop and the function server.write to send the data one by one, but in the receptor (MATLAB) the received data have values between o to 255.

If i see the send Data in the serial monitor the values are the reals, between 0 to 4096.


#4

With TCPServer you would rather use server.write(buffer, len) to send a chunk of data (but no more than 1024 byte at a time) in one go.
On the receiving side you should also place the data in a buffer and then recover it from there in whatever form you need it.


#5

Hi, i tried to solve teh issue, but i haven´t luck. i found a function that scale de 4095 values to 255 and next i send it via TCP, but the signal that MATLAB receives doesn´t have the resolution that i need. Im new using the Photon and Data sending protocols.

Here is the code that i use in Photon.

//TCP server

uint8_t ip[] = {192, 168, 0, 114};
TCPServer server = TCPServer(80);
TCPClient client;

//Variables

int PWM = D0;
int Led=D7;
int  ch1 = A0; // Pin de adquisicion de datos. Resolucion de 12bits
uint16_t Dat1[10000];

void setup()
{
  pinMode(PWM, OUTPUT);  
  pinMode(D7, OUTPUT);
  pinMode(ch1, INPUT);
  analogWrite(PWM,128,50);
  digitalWrite(Led,HIGH);

  server.begin(); // Server Start
  delay(3000);
}


void loop()
{
  client.connect(ip, 80); //Conection client.
  delay(1000);
  while (server.available()) {
   //Toma de muestras 
    for (int i=0;i<10000;i++){
        Dat1[i]=analogRead(A0);
        delay(2);
    }
    digitalWrite(Led,LOW);

    //Mapping of the values between 0 to 4095 converted to 0 to 255 values
    for (int i=0;i<10000;i++){
        Dat1[i]=map(Dat1[i], 0, 4095, 0, 255);
    }
    //TCP server, sending Data
    for (int i=0;i<10000;i++){
        server.write(Dat1[i]);
    }
  }
}


#6

That wouldn’t require a function but is a straight forward division by 16 (that’s what map() internally does due to the fact that both ranges start at 0).

Since both values are powers of two (4096 = 2^12 vs 256 = 2^8) it’s actually easier to use a binary shift

  Dat1[i] >>= 4; // shifting 4 bits left is the same as dividing by 16

This is much cheaper for the controler than calling a function with multiple parameters performing multiple arithmetic operations.
However, this operation (your version or mine) will inevitably discard the bottom bits and hence lose the resolution. If you need higher resolution than 8bit you cannot fit that in a single byte.

I also don’t see the point for running three for() loops iterating over the same array.

    for (int i=0;i<10000;i++){
        Dat1[i] = analogRead(A0) >> 4;
        delay(2);
    }

is much more straight forward.

And for the third loop I’ll repeat what I said a month ago


#7

I wold like to use server.write(buffer, len), i create a vector with Data example.

uint16_t Dat1[3]={4095,2095,305};

Next i used server.write(buffer, len).

server.write(Dat[1], 16);
//server.write(Dat[2], 16);
//server.write(Dat[3], 16);

The programs flash correct in the photon but in MATLAB im not receiving the two 8-bit data. for example if i send 260 im receiving 5, if i send 256 i receiving 1. what is the correct form to send the Data example using server.write(buf,len)? THANK YOU!!


#8

How do you catch the data on the MATLAB side?
Have you considered using the same datatype you are sending on the receiving side too?

https://uk.mathworks.com/help/matlab/ref/tcpclient.read.html#d117e1184536

read(t, 3, 'uint16')

#9

@Titin2205, you define your “vector” as uint16_t but server.write() is defined as:

server.write(buf, len);
  where buf = array of bytes to send
        len = length of the buffer "buf"

Also, the first index of an array is 0 (zero), not 1 (one).

So in your case, calling server.write(Dat[1], 16); will send 16 bytes starting with the byte at Dat[1]. This is NOT the integer you are expecting to send and Matlab will not know otherwise. On top of that, Matlab needs to know what the endianess of the data is (high or low byte of uint16_t first). To send a single int, you would need server.write(Dat[0], 2) for example. Or to send the whole vector, use server.write(Dat[0], 6).


#10

@peekay123, I totally missed that the example was using an individual field of the array and not the array itself :man_facepalming: :blush:

However, I think server.write(Dat[0], 6) isn’t doing the intended either.
If I’m not mistaken server.write(buf, len) expects the first parameter to be a *uint8_t.
So I think it should be server.write((const uint8_t*)Dat, sizeof(Dat))

Or for a particular field in the array server.write((const uint8_t*)&Dat[x], sizeof(Dat[x])).


#11

@ScruffR, yup, you are correct!! I wasn’t focusing on the pointer. :roll_eyes:


#12

THANKS A LOT! Now it works perfectly sending 10.000 Biometric Data from Photon to Matlab.