So far all I am seeing in example code for reading in information from an internet source is that client.read(); only reads in a char.
Is there a way to read in a string or at least a char array?
I'd like to somehow be able to send commands through a simple text-based interface like ssh or telnet that connects to an ethernet shield/arduino uno server.
Below is some server test code that captures the characters into the readString string.
//zoomkat 12-18-10
//routerbot code
//for use with IDE 0021
//open serial monitor to see what the arduino receives
//
#include <SPI.h>
#include <Ethernet.h>
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; //physical mac address
byte ip[] = { 192, 168, 1, 102 }; // ip in lan
byte gateway[] = { 192, 168, 1, 1 }; // internet access via router
byte subnet[] = { 255, 255, 255, 0 }; //subnet mask
Server server(84); //server port
String readString;
//////////////////////
void setup(){
//start Ethernet
Ethernet.begin(mac, ip, gateway, subnet);
server.begin();
//enable serial data print
Serial.begin(9600);
Serial.println("servertest1"); // so I can keep track of what is loaded
}
void loop(){
// Create a client connection
Client client = server.available();
if (client) {
while (client.connected()) {
if (client.available()) {
char c = client.read();
//read char by char HTTP request
if (readString.length() < 100) {
//store characters to string
readString += c;
Serial.print(c);
}
//if HTTP request has ended
if (c == '\n') {
///////////////
Serial.println(readString);
//now output HTML data header
client.println("HTTP/1.1 204 Zoomkat");
client.println();
client.println();
delay(1);
//stopping client
client.stop();
/////////////////////
//clearing string for next read
readString="";
}}}}}
With basically the exact same code except I commented out these lines:
//now output HTML data header
//client.println("HTTP/1.1 204 Zoomkat");
//client.println();
//client.println();
delay(1);
//stopping client
//client.stop();
/////////////////////
//clearing string for next read
//readString="";
Also, the server is set up on port 23 instead of 84 and baud rate of 9600 (same as in serial monitor)
I tested the chatServer code and it worked just fine for both the telnet and serial monitor but it only allows reading in one character. I'm not sure what would have changed because it seems roughly the same besides the added String stuff.
Is it perhaps not reading in the char properly or appending it incorrectly to the String?
I typed in single characters and hit enter and the output in the serial monitor was consistently the "ÿûÿû ÿû" - the blank box I think being the newline character or something.
Does the connection need to be closed (client.close() in order to complete a client.read();?
Well according to the code, each character read in should be printed to the serial monitor right then (Serial.print(c) but nothing shows up when typing each character.
After hitting return is when the jarble shows up on the serial monitor.
does the client.read(); function read the char in as it is typed or does it wait for a space or newline to complete the read?
I changed "if (readString.length() < 100) {" to be 11 instead of 100.
Also, according to http://arduino.cc/en/Tutorial/StringAdditionOperator, the String needs to be set to something before adding can be done. This might be what is going on since I commented out the "readString = "";" line and it isn't set anywhere else.
does the client.read(); function read the char in as it is typed
The client.read() function reads the next character in the buffer, when it is called, if there is one. Characters get added to the buffer at the sending application's discretion. I don't know if your sender is sending characters as they are entered (unlikely) or at some specific event (enter, a button press, etc.) or when an internal buffer gets full.
Not entirely correct. When the String object is created, it is set to something (a blank string, if nothing is defined).
Well according to the code, each character read in should be printed to the serial monitor right then
"Right then" being when it was read, which is independent of when it was typed. The question was really a hint that Serial.print() by itself tells you very little.
Serial.print("client.read() returned a [");
Serial.print(c);
Serial.println("]");
takes a little longer, but conveys a lot more information.
Serial.print("The complete string is: [");
Serial.print(readString);
Serial.println("]");
With this, you'd know exactly where the garbage was coming from.
I commented out the "readString = "";" line and it isn't set anywhere else.
void loop() {
// Create a client connection
Client client = server.available();
if (client) {
while (client.connected()) {
if (client.available()) {
char in = client.read();
//read char by char HTTP request
if (readString.length() < 100) {
//store characters to string
readString += in;
Serial.print("client.read() returned a [");
Serial.print(in);
Serial.println("]");
}
//if HTTP request has ended
if (in == '\n') {
// output
Serial.print("The complete string is: [");
Serial.print(readString);
Serial.println("]");
delay(1);
//clearing string for next read
readString="";
}
}
}
}
}
Serial output upon telnet session connection:
client.read() returned a [ÿ]
client.read() returned a [û]
client.read() returned a []
client.read() returned a [ÿ]
client.read() returned a [û]
client.read() returned a [ ]
client.read() returned a [ÿ]
client.read() returned a [û]
client.read() returned a []
client.read() returned a [ÿ]
client.read() returned a [û]
client.read() returned a [']
client.read() returned a [ÿ]
client.read() returned a [ý]
client.read() returned a []
client.read() returned a [ÿ]
client.read() returned a [û]
client.read() returned a []
client.read() returned a [ÿ]
client.read() returned a [ý]
client.read() returned a []
So it gets all of that nonsense right off the bat.
After typing "hello" and hitting enter the cumulative output is:
client.read() returned a [ÿ]
client.read() returned a [û]
client.read() returned a []
client.read() returned a [ÿ]
client.read() returned a [û]
client.read() returned a [ ]
client.read() returned a [ÿ]
client.read() returned a [û]
client.read() returned a []
client.read() returned a [ÿ]
client.read() returned a [û]
client.read() returned a [']
client.read() returned a [ÿ]
client.read() returned a [ý]
client.read() returned a []
client.read() returned a [ÿ]
client.read() returned a [û]
client.read() returned a []
client.read() returned a [ÿ]
client.read() returned a [ý]
client.read() returned a []
client.read() returned a [h]
client.read() returned a [e]
client.read() returned a [l]
client.read() returned a [l]
client.read() returned a [o]
client.read() returned a [
]
client.read() returned a [
]
The complete string is: [ÿûÿû ÿûÿû'ÿýÿûÿýhello
]
On the 2nd send of "hello" it gives just:
client.read() returned a [h]
client.read() returned a [e]
client.read() returned a [l]
client.read() returned a [l]
client.read() returned a [o]
client.read() returned a [
]
client.read() returned a [
]
The complete string is: [hello
]
How do you know what is actually sent when you are using telnet? There may be a lot more data being sent than just the characters you type. I think others in the forum have used an application called wire shark (or something similar) to see all the traffic.
Adding a client.flush(); after "if (client) {" seems to have fixed the issue. It probably was just some stuff left over in the buffer after the connection.
Serial output from connect to first command:
client.read() returned a [h]
client.read() returned a [e]
client.read() returned a [l]
client.read() returned a [l]
client.read() returned a [o]
client.read() returned a [
]
client.read() returned a [
]
The complete string of length(7) is: [hello
]
Edit: adding the below line resolved the extra spaces from the read and gives an easy to compare string:
readString = readString.trim();
Output:
client.read() returned a [h]
client.read() returned a [e]
client.read() returned a [l]
client.read() returned a [l]
client.read() returned a [o]
client.read() returned a [
]
client.read() returned a [
]
The complete string of length(5) is: [hello]
so, what's the proof? Hope you just didn't assume all applications automatically append a carrage return/line feed to data being being sent when the enter key is depressed.