Show Posts
|
|
Pages: [1]
|
|
1
|
Using Arduino / Programming Questions / Re: What does the F() do exactly?
|
on: May 02, 2012, 08:08:55 am
|
Hi everybody, I'm trying to copy a string from the flash memory to a char[] variable. But because of the __FlashStringHelper * type I don't know how to do it. Any idea? I'm working on a Web Server with a table which I have to construct on each iteration (see code below). But I don't want to send the string and numerical information separately because of the TCP overhead. So instead, I would like to store and concatenate the info in a fixed size buffer and when full, send it. I already posted a thread about it (without flash memory) http://arduino.cc/forum/index.php/topic,103110.0.html and I have good performance for a buffer of 60 bytes. But because I'm running out of memory I need to store the HTML code in the flash memory. I'm having error because of the different types. I need a way to copy the flash values to RAM values. Tnx!! const int Buffer_length = 90; char buffer[Buffer_length]; int TempTable[5][5];
void SecondTable(EthernetClient client) { for (int i = 1; i < 5; i++) { int i=1; printI(i,client); printC(F("</td><td align='center'><input type='text' name='Block"),client); printI(i,client); printC(F("1' value='"),client); printI(TempTable[i-1][0],client); printC(F("' size='2' maxlength='2'/>: <input type='text' name='Block"),client); printI(i,client); printC(F("2' value='"),client); printI(TempTable[i-1][1],client); printC(F("' size='2' maxlength='2'/></td><td align='center'><input type='text' name='Block"),client); printI(i,client); printC(F("3' value='"),client); printI(TempTable[i-1][2],client); printC(F("' size='2' maxlength='2'/>: <input type='text' name='Block"),client); printI(i,client); printC(F("4' value='"),client); printI(TempTable[i-1][3],client); printC(F("' size='2' maxlength='2'/></td><td align='center'><input type='text' name='Block"),client); printI(i,client); printC(F("5' value='"),client); printI(TempTable[i-1][4],client); printC(F("' size='2' maxlength='2'/></td></tr>"),client); }
void printI(int num, EthernetClient client){ if (strlen(buffer)<Buffer_length-6) //we add the int value only if we have enough space! { sprintf(buffer,"%s%d",buffer,num); //we add the int value to the buffer } else { client.println(buffer); //we send the buffer though the net buffer[0]='\0'; //we reset the buffer sprintf(buffer,"%s%d",buffer,num); } } void printC(const __FlashStringHelper * info, EthernetClient client){ int length_array1=strlen(buffer); int length_array2=strlen(info); if (Buffer_length-1>length_array1+length_array2) { strcat(buffer,info); } else { client.println(buffer); buffer[0]='\0'; strcat(buffer,info); } }
|
|
|
|
|
2
|
Topics / Home Automation and Networked Objects / Re: Ethernet Web Thermostat: more efficient TCP packages.
|
on: April 30, 2012, 11:52:50 am
|
Ok, So I finally came up with something interesting. As I said before, each time we call client.print(blabla); we are sending 1 TCP packet. So if I want to make an HTML table like the web server example included in the compiler, we are going to send a lot of small packets. Specially each time we send an int number (just 2 bytes). The header of the TCP packet is about 20 bytes so it's a lot of overhead for sending small amounts of info. By implementing the functions I wrote before on the web server example, I reduced the time in a 33% (I changed the table from 5 to 150 entries). Take care about the buffer size because of 2 reasons: 1) It has to be bigger than the info we want to put inside. 2) For reducing the time of refreshing the web page, I found an optimum buffer of 60 Bytes. I though that a bigger buffer will be even better, but it's not. Maybe the time of writing/reading the data in the buffer takes more time than the overhead of the TCP protocol. Any way, here is the example with the implemented functions. Try to change the buffer size and refresh many time the web page and you will see the effect. Hope it will be useful for someone! #include <SPI.h> #include <Ethernet.h>
// Enter a MAC address and IP address for your controller below. // The IP address will be dependent on your local network: byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; IPAddress ip(192,168,1, 177);
const int Buffer_length = 60; //Optimum buffer size char buffer[Buffer_length]; //buffer for TCP packets
// Initialize the Ethernet server library // with the IP address and port you want to use // (port 80 is default for HTTP): EthernetServer server(80);
void setup() { // start the Ethernet connection and the server: Ethernet.begin(mac, ip); server.begin(); Serial.begin(9600); }
void loop() { // listen for incoming clients EthernetClient client = server.available(); if (client) { // an http request ends with a blank line boolean currentLineIsBlank = true; while (client.connected()) { if (client.available()) { char c = client.read(); // if you've gotten to the end of the line (received a newline // character) and the line is blank, the http request has ended, // so you can send a reply if (c == '\n' && currentLineIsBlank) { int inicio=millis(); // send a standard http response header printC("HTTP/1.1 200 OK\n",client); printC("Content-Type: text/html\n",client); printC("\n",client);
// output the value of each analog input pin for (int analogChannel = 0; analogChannel < 150; analogChannel++) { printC("analog input ",client); printI(analogChannel,client); printC(" is ",client); printI(analogChannel*100,client); printC("<br />",client); } printflush(client); int fin=millis(); Serial.print("Elapsed time= "); Serial.println(fin-inicio); break; } if (c == '\n') { // you're starting a new line currentLineIsBlank = true; } else if (c != '\r') { // you've gotten a character on the current line currentLineIsBlank = false; } } } // give the web browser time to receive the data delay(1); // close the connection: client.stop(); } }
void printI(int num, EthernetClient client){ if (strlen(buffer)<Buffer_length-6) //we add the int value only if we have enough space! { sprintf(buffer,"%s%d",buffer,num); //we add the int value to the buffer // Serial.print("agrege int a buffer= "); Serial.println(num); } else { client.println(buffer); //we send the buffer though the net // Serial.println(buffer); buffer[0]='\0'; //we reset the buffer sprintf(buffer,"%s%d",buffer,num); // Serial.println("mande el buffer"); } } void printC(char info[], EthernetClient client){ int length_array1=strlen(buffer); int length_array2=strlen(info); if (Buffer_length-1>length_array1+length_array2) { strcat(buffer,info); // Serial.println("agrege char a buffer"); } else { client.println(buffer); // Serial.println("mande el buffer"); // Serial.println(buffer); buffer[0]='\0'; strcat(buffer,info); } }
void printime(int h, int m, int s, EthernetClient client) { //size 8 bytes if (strlen(buffer)<Buffer_length-9) { sprintf(buffer,"%s%02d:%02d:%02d",buffer,h,m,s); } else { client.println(buffer); buffer[0]='\0'; sprintf(buffer,"%s%02d:%02d:%02d",buffer,h,m,s); } }
void printdate (int d, int m, int y, EthernetClient client) { //size 10 bytes if (strlen(buffer)<Buffer_length-11) { sprintf(buffer,"%s%02d:%02d:%02d",buffer,d,m,y); } else { client.println(buffer); buffer[0]='\0'; sprintf(buffer,"%s%02d:%02d:%02d",buffer,d,m,y); } }
void printflush(EthernetClient client){ //we send any information left client.println(buffer); // Serial.println("flushed el buffer"); // Serial.println(buffer); buffer[0]='\0'; }
|
|
|
|
|
3
|
Topics / Home Automation and Networked Objects / Re: Ethernet Web Thermostat: more efficient TCP packages.
|
on: April 27, 2012, 08:38:00 am
|
Hi draythomp! Tnx for your answer. It was very useful! But I decided to take another approach. Your solutions works because you know exactly what you are sending, so you can conform your packets before. But in my cas it will take me a really long time doing so. Then I decided to make some print functions that will be in charge of creating a buffer of maximum 200 bytes and when almost full, sending it through the net. Just for making it easier I'm using Serial.println() instead of client.print(), but if someone wants to use it, you just have to change them (and maybe also pass the client to each of the functions). Anyway, I would like to create a unique function to send ints or chars, but I don't know if there is an upper class common to both. Any idea? Here is the code with one example. const int Buffer_length = 200; char buffer[Buffer_length]; //public variables
void setup() { Serial.begin(9600); buffer[0]='\0'; //reset the buffer Serial.println(); }
void loop() { //information to be send printI(12547); //Note that we are using int, no longs, take care with the size of the number!!! printC("mi amol"); printdate(12,3,2012); printC("hhhhhhhhsdfvzdjjjjjjjjxhzgdbashxb"); //try making it bigger (if more than 200 bytes will not work printime(6,3,59); printflush(); //This function is used at the end of the program. //if some info was left in the buffer we have to send it.
}
void printI(int num){ if (strlen(buffer)<Buffer_length-6) //we add the int value only if we have enough space! { sprintf(buffer,"%s%d",buffer,num); //we add the int value to the buffer } else { Serial.println(buffer); //we send the buffer though the net buffer[0]='\0'; //we reset the buffer } } void printC(char info[]){ int length_array1=strlen(buffer); int length_array2=strlen(info); if (Buffer_length-1>length_array1+length_array2) { strcat(buffer,info); } else { Serial.println(buffer); buffer[0]='\0'; } }
void printime(int h, int m, int s) { //size 8 bytes if (strlen(buffer)<Buffer_length-9) { sprintf(buffer,"%s%02d:%02d:%02d",buffer,h,m,s); } else { Serial.println(buffer); buffer[0]='\0'; } }
void printdate (int d, int m, int y) { //size 10 bytes if (strlen(buffer)<Buffer_length-11) { sprintf(buffer,"%s%02d:%02d:%02d",buffer,d,m,y); } else { Serial.println(buffer); buffer[0]='\0'; } }
void printflush(){ //we send any information left Serial.println(buffer); buffer[0]='\0'; }
|
|
|
|
|
4
|
Topics / Home Automation and Networked Objects / Ethernet Web Thermostat: more efficient TCP packages.
|
on: April 26, 2012, 08:16:22 am
|
Hi everybody, I'm new on the Arduino community, but till now I have read a lot about all the amazing projects done and now I'm working on my own. Like a lot of you I have decided to construct a heating controller based on the Arduino 1.0 But I found some problems. Some sketch using HTML web server are sending INT values to the client just by typing Client.print(int value). So if I would like to display the hour on a web page, I should do something like: client.print(" </td><td>"); client.print(hour()); client.print(":"); if (minute()<10){client.print("0");} client.print(minute()); client.print(":"); if (second()<10){client.print("0");} client.print(second()); client.print(" </td><td>"); which is not efficient in the point of view of the TCP protocol. I mean, each time I'm sending a package of just some bytes (like hour() or minute() ) I have to send the hole header (20 bytes if I'm right). So I want to make a longer string (maybe of 200-500 bytes) before sending the package. My question is, has somebody done something similar or tried to handle this problem? Of course what I what to send is not just the hour but some data stored in a matrix. So when sending 100 values (for a 10x10 matrix) I don't need to send 100 TCP packages plus the one of the HTML code, but just few of them. I'm working on the following code that will conform my string, but I have some weird results. If I make the buffer bigger than 10 bytes (20 for example) I will have a strange output. The same will happen if I uncomment the last "If" case and "strcat" function (with a buffer of size 10 bytes). Any Idea to proceed? Tnx you all! Nico. void setup() { Serial.begin(9600); delay(1);
char buffer[10]; int h=10; int m=5; int s=33;
bufer[0]='\0'; char Hora[]="La hora es: "; //Formamos la hora con min y sec
itoa(h,buffer,10); Serial.println(buffer); if (h<10) {strcat(Hora,"0");} strcat(Hora,buffer); strcat(Hora,":"); bufer[0]='\0'; itoa(m,buffer,10); Serial.println(buffer); if (m<10) {strcat(Hora,"0");} strcat(Hora,buffer); strcat(Hora,":"); bufer[0]='\0'; itoa(s,buffer,10); Serial.println(buffer); // if (s<10) {strcat(Hora,"0");} // strcat(Hora,buffer); Serial.println(Hora);
}
void loop() {}
|
|
|
|
|
5
|
Using Arduino / Installation & Troubleshooting / Re: Arduino 1: Problem with Alarm.delay ?
|
on: March 06, 2012, 09:45:27 am
|
|
I got the same problem but this solution didn't worked for me.
So instead of creating the file WProgram.h, I edited the file TimeAlarms.cpp (you can find it in the library directory) and then changed the following
#include <WProgram.h> by #include <Arduino.h>
So I finally got (extract of the file)
<<extern "C" { #include <string.h> // for memset }
#include <Arduino.h> #include "TimeAlarms.h" #include "Time.h"
#define IS_ONESHOT true // constants used in arguments to create method #define IS_REPEAT false
//************************************************************** //* Alarm Class Constructor >>
|
|
|
|
|