@BDub than i need to change buffer limit 512 byte to 128 byte ? Isnt it ?
Flip that, reverse it. 128 to 512. You could do that if you are building locally.
The better way would be to handle it in your code. Letās see if we can do that here:
#define DEBUG_SERIAL false
String http_get(char const* hostname, String path) {
int i = 0;
int k = 0;
bool printOnce = false;
if (client.connect(hostname, 80)) {
client.print("GET ");
client.print(path);
client.println(" HTTP/1.1");
client.print("HOST: ");
client.println(hostname);
client.println("Connection: close");
client.println();
client.flush();
} else {
if(DEBUG_SERIAL) Serial.println("\r\n\r\nConnection Failed!");
client.flush();
client.stop();
return NULL;
}
// wait 5 seconds or less for the host to respond
uint32_t startTime = millis();
while(!client.available() && (millis() - startTime) < 5000);
if(DEBUG_SERIAL) Serial.println("\r\n\r\nREADING HOST DATA......");
uint32_t lastRead = millis();
// If the host doesn't close it's connection, we'll timeout in 10 seconds.
while (client.connected() && (millis() - lastRead) < 10000) {
while (client.available()) {
char c = client.read();
/*
if(DEBUG_SERIAL) {
Serial.print(c);
if(i++ > 100) {
delay(5);
i = 0;
}
}
*/
if(c == -1) {
Serial.print("\r\n\r\nERROR......\r\n\r\n");
client.flush();
client.stop();
}
if(DEBUG_SERIAL && !printOnce) {
Serial.print("\r\n\r\nSAVING......\r\n\r\n");
printOnce = true;
}
buffer[k++] = c; // save character to buffer
//Serial.print(c);
//delayMicroseconds(100);
if(k >= BUFFER_SIZE_MAX) { // if we reach the end of our buffer, just bail.
Serial.print("\r\n\r\nOUT OF BUFFER SPACE......\r\n\r\n");
client.flush();
client.stop();
}
// as long as we're reading data, reset the lastRead time.
lastRead = millis();
} // END while(client.available())
} // END while(client.connected())
client.flush();
client.stop();
// At this point the entire response with header is in 'buffer'
// Let's strip off just the response, we don't care about the header.
String response(buffer);
int bodyPos = response.indexOf("\r\n\r\n");
if (bodyPos == -1) {
if(DEBUG_SERIAL)Serial.println("\r\n\r\nCannot find http reponse body!\r\n\r\n");
return NULL;
}
return response.substring(bodyPos + 4);
}
You should be able to drop this right into your codeā¦ replacing that function. Be warned, I have not compiled this exact version which I modified from my Facebook Likes Alert code.
I changed my code with your code but making little changes (BUFFER_SIZE_MAX to TCPCLIENT_BUF_MAX_SIZE) and have been successfully compiled.
And my result is below.. I think the problem still continues.
millis(): 300001
OUT OF BUFFER SPACE......
Any update ? Someone can help me?
Hey Yasin,
I think you might want to try the HttpClient library thatās currently under development, I put your URL in the example app, and Iām getting responses back from your server, I copied all the code into a GIST here:
I hope that helps!
Thanks,
David
Looks good Dave! Thanks for stepping in
I would only suggest changing the millis() math to use subtraction to prevent weirdness when millis() overflows (probably doesnāt matter much for this app, but good practice anyway). Also renamed nextTime to lastTime.
void loop() {
if ( (millis() - lastTime) > 10000UL ) {
lastTime = millis();
Serial.println();
Serial.println("Application>\tStart of Loop.");
// Request path and body can be set at runtime or at setup.
request.port = 80;
request.hostname = "roman-mueller.ch";
request.path = "/api/weather";
// The library also supports sending a body with your request:
//request.body = "{\"key\":\"value\"}";
// Get request
http.get(request, response, headers);
Serial.print("Application>\tResponse status: ");
Serial.println(response.status);
Serial.print("Application>\tHTTP Response Body: ");
Serial.println(response.body);
}
}
@Dave yes , now your app is working. I am getting responses from server. By the way this is not my own code . This project @kwyjib0 weather lamp project. I wanted to create my own weather lamp. So i tried replace with @kwyjib0 code with HttpClient library but failed.
Could you help me a little more? Can you edit this with your codes?
Iāll try to take a try at this later today if I can, but it might take me a while before Iāll have some time to work on it.
Thanks,
David
@Dave i did that :)) but i want to know how can i remove server headers.?
I want see only that.
W-[255,255,000][000,128,000]-Temp:20,9Ā°C;Yellow-Condition:SkyIsClear;Green
Hello all,
Maybe a solution, itās work for me.
Before v0.2.3 my program worked perfectly and since 0.2.3 lot of BDubās similar error :
../inc/spark_wiring_ipaddress.h:54:105: warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]
bool operator==(const IPAddress& addr) { return (*((uint32_t*)_address)) == (*((uint32_t*)addr._address)); };
The error was in my pin definition :
int STARTPIN = D7;
int BUTTONPIN = D0;
int RELAY1 = D5;
int RELAY2 = D6;
int LIGHTPIN = A0;Ā //LIGHT PIN, photoresistanceĀ Ā Ā
int TEMPPIN = A1;Ā //MCP9700A temperature sensor
int REDLED = A6;
int MOISTURE_VCC = D4;//MOISTURE VSS POWER SUPPLY
int MOISTURE1_ANA = A2; //MOISTUREĀ analog in 1
int MOISTURE2_ANA = A3; //MOISTUREĀ analog in 2
int WATER_ANA = A4; //waterĀ analog in 1
int 12VTEST_ANA = A5; //measure 12V
==> Ā Ā Ā int 12VTEST_ANA = A5;
remplaced by int TEST12V_ANA = A5;
Start variable with number is forbidden with new firmware for me.
Hi @Yasin,
If you just want the response body and not the headers, I think thatās parsed out and exposed with the response.body variable I think:
Serial.print("Application>\tHTTP Response Body: ");
Serial.println(response.body);
Thanks,
David
@Dave My code uses a TCP Client along with UDP Server & Client. Iāve been able to make a decently sized application and Iāve managed to not overflow on RAM usage most of the time. I overflow on the RAM majorly when I have to send a message both using the TCP Client and UDP Client.
TCPClient seems to accept āuint8_tā buffer and UDPClient seems to accept a ācharā buffer. So I find myself allocating double the memory for a single message because of the datatype difference.
Example:
TCPClient tcpClient;
UDP udpClient;
void sendMessage(){
char udpMessage[12] = "Hello World"; // UDP Message Buffer
udpClient.beginPacket(IP, PORT);
udpClient.write(udpMessage);
udpClient.endPacket();
uint8_t tcpMessage[13]; // TCP Message Buffer
memcpy(tcpMessage, udpMessage, 12);
tcpClient.write(tcpMessage);
}
Any changes made for this or could you give me some notes as to how to optimize or do this better?
Edit: I mixed up the datatypes in the code. Corrected and re-arranged it.
Hi @nitred,
Oh interesting! Iām noticing that the write functions both support uint8_t:
https://github.com/spark/core-firmware/blob/master/inc/spark_wiring_udp.h#L56
https://github.com/spark/core-firmware/blob/master/inc/spark_wiring_tcpclient.h#L45
But the read operations are different, so I added an issue for you here:
Thanks,
David
@Dave Thank you for the additional comment as well to add ācharā into the write array. I prefer using ācharā arrays since they offer me additional functions such as āstrcatā and āstrcpyā when I have some string manipulation to do.
I was having issues before with using uint8_t with udpClient. I just figured out that I have to mention the size of the uint8_t array as one of the parameters.
uint8_t udpMessage[] = "Hello World";
udpClient.write(udpMessage, 12); <---- Have to add array length as parameter
So thatās solved as well
Thanks!
That seems like something that the function should take care of itself. When are you going to call udpClient.write() without using the whole array youāve passed in?
Hi @NanoAkron,
Good question! I think the limitation there is that itās hard for C/C++ programs to know the length of native arrays without providing the length or using a terminating character which doesnāt necessarily apply to raw buffers.
Thanks!
David
But isnāt this array defined at compile time and not dynamically changing? Surely you could use something like strlen() or sizeof() in the function, or scan to the next unoccupied space in the array.
@NanoAkron I donāt think having to add the array size is such a bad thing. If I were using a global buffer and only wanted to use the first three bytes of the buffer, then mentioning the buffer size would come in handy.
but,
@Dave tcpClient.write() doesnāt seem to need array length passed to it, but udpClient.write() needs it. It would be nice if both of them have a standard way of doing things.
Hi Guys,
C++ array length can be a bit contentious, I might be wrong on this, but hereās a stack overflow article to back me up - http://stackoverflow.com/questions/874169/how-to-get-the-size-of-an-array
@nitred - I think you are looking at the single-byte write function versus the array write functions:
from TCPClient:
virtual size_t write(uint8_t);
virtual size_t write(const uint8_t *buffer, size_t size);
from UDP:
virtual size_t write(uint8_t);
virtual size_t write(const uint8_t *buffer, size_t size);
Thanks!
David