Notifications
Clear all

Sending data over the ethernet using server.write()

74 Posts
6 Users
7 Likes
1,997 Views
gameworn
(@gameworn)
Eminent Member
Joined: 2 years ago
Posts: 30
Topic starter  

Hello

I have an Arduino Mega with an ethernet shield. I have it connected to a laptop via an ethernet cable and into a software package called "Processing". Among other things, I want to monitor the battery voltage on the Mega. I am using server.write() to send the battery voltage from the Mega and Myclient.read() to read it on the Processing side. Server.write() allows data to be sent in bytes or char form. The battery voltage I want to send is 14.85 Volts for example. I can't send a float using server.write(), so I multiplied my battery voltage by 10 and sent 148 over to Processing. On the Processing end, and after some math, I see a voltage of 14.75 to 14.8. To get a more accurate voltage value,  I would like to send the whole 14.85 or 1485 to Processing, but I cannot pass such a high number using server.write(). I believe the byte type limits this. A value of 1485 passed from Mega is seen as 220 on the Processing end.

 How do I send a large number, or maybe a float number using server.write() from the Mega to Processing.

I have researched this over and over on different forums, but nothing makes sense,  as I was looking for the time, but saw how to build a time machine, if you know what I mean.

 Thank You


   
Quote
Ron
 Ron
(@zander)
Famed Member
Joined: 2 years ago
Posts: 3875
 

@gameworn Break the number into two chunks. If you can only send bytes, then get the number into a 16 bit variable, then use bit masks and shift to isolate the low order 8 bits and the high order 8 bits. Send two bytes then reverse the procedure on the other side.

Arduino says and I agree, in general, the const keyword is preferred for defining constants and should be used instead of #define
"Never wrestle with a pig....the pig loves it and you end up covered in mud..." anon
My experience hours are >75,000 and I stopped counting in 2004.
Major Languages - 360 Macro Assembler, Intel Assembler, PLI/1, Pascal, C plus numerous job control and scripting


   
ReplyQuote
Will
 Will
(@will)
Famed Member
Joined: 2 years ago
Posts: 2218
 

@gameworn

If you can send chars or string, why not just send over the text form of the number. You can then decode it back to float after the transfer if you need to.

Experience is what you get when you don't get what you want.


   
ReplyQuote
Inq
 Inq
(@inq)
Noble Member
Joined: 10 months ago
Posts: 980
 

@gameworn - I don't use most of the hardware or libraries you are using, but... I'm betting they are using the Stream libraries of the base Aduion code.  So, I bet server.write() is really Serial.write().

https://www.arduino.cc/reference/en/language/functions/communication/serial/write/

It says you can write a buffer.  This means you can send the binary form of any variable IF YOU PREFER and know how to handle it on the other end.  For instance if you wanted to send a float or double... you could use:

float pi = 3.14159265;
server.write((byte*) &pi, sizeof(float));

This will send out the binary version of the floating point structure.  Some things that may look odd:

  • The & before the variable says to pass the address of memory location.
  • The (byte*) is called type casting and its so the compiler doesn't complain.
  • sizeof() function knows how big a float is and will send 4 bytes.

This is very useful because it can be used for whole, arbitrary structures also.

struct Person
{
  char first[16];
  char last[16];
  u8 age;
  float weight;
  double netWorth;
};

Person who = { "Killroy", "Was Here", 42, 0.45666, 23.3466E19 };

void setup() 
{
     Server.write((byte*) &who, sizeof(Person));    
}

void loop()
{
}

3 lines of code = InqPortal = Complete IoT, App, Web Server w/ GUI Admin Client, Access Point Manager, Drag & Drop File Manager, OTA, Performance Metrics, Web Socket Comms, Easy App API, All running on ESP8266...
Even usable on ESP-01S - Quickest Start Guide


   
ReplyQuote
Ron
 Ron
(@zander)
Famed Member
Joined: 2 years ago
Posts: 3875
 

@inq Am I misunderstanding? How is his laptop going to access the memory of his arduino?

Arduino says and I agree, in general, the const keyword is preferred for defining constants and should be used instead of #define
"Never wrestle with a pig....the pig loves it and you end up covered in mud..." anon
My experience hours are >75,000 and I stopped counting in 2004.
Major Languages - 360 Macro Assembler, Intel Assembler, PLI/1, Pascal, C plus numerous job control and scripting


   
ReplyQuote
Will
 Will
(@will)
Famed Member
Joined: 2 years ago
Posts: 2218
 
Posted by: @inq

It says you can write a buffer.  This means you can send the binary form of any variable IF YOU PREFER and know how to handle it on the other end.  For instance if you wanted to send a float or double... you could use:

float pi = 3.14159265;
server.write((byte*) &pi, sizeof(float));

It would be better to write this as ...

server.write( (byte*) &pi, sizeof(pi) );

in case the datatype of variable pi is ever changed.

Experience is what you get when you don't get what you want.


   
ReplyQuote
Ron
 Ron
(@zander)
Famed Member
Joined: 2 years ago
Posts: 3875
 

@will Unless I have completely lost my marbles, &pi means the address of pi. You think the laptop can read a memory location in an arduino? I know I have been away from code for a while, but I think you mean pi.

Arduino says and I agree, in general, the const keyword is preferred for defining constants and should be used instead of #define
"Never wrestle with a pig....the pig loves it and you end up covered in mud..." anon
My experience hours are >75,000 and I stopped counting in 2004.
Major Languages - 360 Macro Assembler, Intel Assembler, PLI/1, Pascal, C plus numerous job control and scripting


   
ReplyQuote
Will
 Will
(@will)
Famed Member
Joined: 2 years ago
Posts: 2218
 

@zander 

Huh ? I assumed that this was the sample from Inq's post above where pi is declared, assigned a value and then transferred via the server.write() command. I'm assuming that the server.write command is issued from the same machine as the declaration and assignment are made.

The command is just saying "send sizeof(pi) (i.e. this many) bytes starting from this address (&pi, i.e. the location of the value pi) to an available receiver (if one exists and is listening)". I see the command as always working with local values only.

Experience is what you get when you don't get what you want.


   
ReplyQuote
Ron
 Ron
(@zander)
Famed Member
Joined: 2 years ago
Posts: 3875
 

@will I do see two ways of looking at this. I read it as I am sending you sizeof(pi) bytes that is the address(&) of the variable pi. I don't see a prototype for the call so I assumed normal pass by value syntax.

Arduino says and I agree, in general, the const keyword is preferred for defining constants and should be used instead of #define
"Never wrestle with a pig....the pig loves it and you end up covered in mud..." anon
My experience hours are >75,000 and I stopped counting in 2004.
Major Languages - 360 Macro Assembler, Intel Assembler, PLI/1, Pascal, C plus numerous job control and scripting


   
ReplyQuote
Will
 Will
(@will)
Famed Member
Joined: 2 years ago
Posts: 2218
 

@zander 

OK, but this command will pass down the four bytes (in this case) of the 32bit value for pi, NOT it's address. Is that where we differ ?

Experience is what you get when you don't get what you want.


   
ReplyQuote
Ron
 Ron
(@zander)
Famed Member
Joined: 2 years ago
Posts: 3875
 

@will It depends on the implementation of the server.write. We are both assuming facts not in evidence. I am not talking about @Inq's code, that's just a made up example, it's the OP's code we did NOT see. What he said is he can't send a float, this suggests the write statement expects a single byte. The OP said

I believe the byte type limits this.

Since he got correct data sending a 148 value and incorrect sending 1485 that strongly suggests the value is passed as value and not reference.

NOTE: I recognize you were only responding to Inq.

Arduino says and I agree, in general, the const keyword is preferred for defining constants and should be used instead of #define
"Never wrestle with a pig....the pig loves it and you end up covered in mud..." anon
My experience hours are >75,000 and I stopped counting in 2004.
Major Languages - 360 Macro Assembler, Intel Assembler, PLI/1, Pascal, C plus numerous job control and scripting


   
ReplyQuote
Ron
 Ron
(@zander)
Famed Member
Joined: 2 years ago
Posts: 3875
 

@will I went and found (I think) the api doc, if he specifies a size as the second argument, then indeed the buffer can be almost any size and the first argument is indeed an address, most often of the form buffer where buffer is char[size] and size is then the value passed as the 2nd argument Otherwise as he seems to be doing perhaps because he doesn't know about the 2nd form is just passing a single char/byte. YES that makes Inq's example correct, but I wanted to make sure the OP got the full message.

Arduino says and I agree, in general, the const keyword is preferred for defining constants and should be used instead of #define
"Never wrestle with a pig....the pig loves it and you end up covered in mud..." anon
My experience hours are >75,000 and I stopped counting in 2004.
Major Languages - 360 Macro Assembler, Intel Assembler, PLI/1, Pascal, C plus numerous job control and scripting


   
ReplyQuote
Will
 Will
(@will)
Famed Member
Joined: 2 years ago
Posts: 2218
 

@zander 

OK, to limit the confusion, I went back to the documentation at 

https://processing.org/reference/libraries/net/Server_write_.html

Setting aside Inq's supposition that this is equivalent to Serial.write(), it appears that the command will accept an int, a byte array or a String. Given that, I'll stand by my original suggestion that the value be sent as a string (with embedded decimal point) and converted back to a numeric type if/as required.

Experience is what you get when you don't get what you want.


   
Ron reacted
ReplyQuote
Ron
 Ron
(@zander)
Famed Member
Joined: 2 years ago
Posts: 3875
 

@will I think 3 of the 4 of us understand. Now if @gameworn would rejoin the conversation his problem would be solved. In this case a formatted string is good enough, performance is not an issue.

Arduino says and I agree, in general, the const keyword is preferred for defining constants and should be used instead of #define
"Never wrestle with a pig....the pig loves it and you end up covered in mud..." anon
My experience hours are >75,000 and I stopped counting in 2004.
Major Languages - 360 Macro Assembler, Intel Assembler, PLI/1, Pascal, C plus numerous job control and scripting


   
ReplyQuote
Inq
 Inq
(@inq)
Noble Member
Joined: 10 months ago
Posts: 980
 
Posted by: @zander

@inq Am I misunderstanding? How is his laptop going to access the memory of his arduino?

I believe so... 

Posted by: @gameworn

 How do I send a large number, or maybe a float number using server.write() from the Mega to Processing.

The laptop does not access the Arduino.  These server based libraries typically set up a TCP connection and inherit the Stream class to actually handle the lower level sending as if it is saving to a file (which also inherits the Stream class).   The code on the Arduino writes data to the stream and the laptop side pulls it off the stream and uses it.

Posted by: @gameworn

laptop via an ethernet cable and into a software package called "Processing".

I'm assuming that this "Processing" program can be configured to understand that the next four bytes coming in represents the float number @gameworm wants.   What it does from that point... I have no clue.

VBR,

Inq  

3 lines of code = InqPortal = Complete IoT, App, Web Server w/ GUI Admin Client, Access Point Manager, Drag & Drop File Manager, OTA, Performance Metrics, Web Socket Comms, Easy App API, All running on ESP8266...
Even usable on ESP-01S - Quickest Start Guide


   
ReplyQuote
Page 1 / 5