RFID | ETHERNET | RTC

Olá,

Adquiri recentemente um 'real time clock' e um leitor rfid da GROVE, assim como uma arduino ethernet (modolulo completo e não o shield). Desenvolvi o código abaixo para fazer um "relogio de ponto" no entanto queria armazenar as horas de entrada e saida num cartao SD e poder mostralo em HTML ...
No entanto o código está proximo de exceder o limite (32K) do arduino ...

Alguém me consegue dar uma ajuda a optimizar este código ?

#include <SD.h>
File SDFileData;

//rfid
#include <SoftwareSerial.h>
SoftwareSerial rfid(2, 3);
unsigned char buffer[14];
int count=0;

//Ethernet
#include <SPI.h>
#include <Ethernet.h>
byte mac[] = {
  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};
IPAddress ip(192,168,28,150);
EthernetServer server(8080);

//clock
#include <Time.h>  
#include <Wire.h>  
#include <DS1307RTC.h>


void setup() {
  // start Serial:
  Serial.begin(9600);
  while (!Serial) {
    ;
  }

  // start the Ethernet:
  Ethernet.begin(mac, ip);
  server.begin();
  Serial.println("Server OK");

  // start rfid:
  rfid.begin(9600); 

  // start clock:
  setSyncProvider(RTC.get);   // get the time from the RTC
  if(timeStatus()!= timeSet) 
    Serial.println("RTC FAIL");
  else
    Serial.println("RTC OK");

  // buzz:
  pinMode(8, OUTPUT);
  //sd card
 pinMode(10,OUTPUT);
  if (!SD.begin(4)) {
    Serial.println("FAIL Reinsert SD");
    return;
  }

  /* Check if the text file already exists */
  while(SD.exists("test.txt"))
  {
   SD.remove("test.txt");
   if(!SD.exists("test.txt")){
     Serial.println("Delete OK");
   } 
  }

  /* Create a new text file on the SD card */
 
  SDFileData = SD.open("test.txt", FILE_WRITE);
  if(SD.exists("test.txt")){
   Serial.println("Create OK");}
  else{
  Serial.println("Error");
  }
  
  
}


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();
        //Serial.write(c);
        // 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) {
          // send a standard http response header
          client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: text/html");
          client.println("Connnection: close");
          client.println();
          client.println("<!DOCTYPE HTML>");
          client.println("<html>");
          // add a meta refresh tag, so the browser pulls again every 5 seconds:
          client.println("<meta http-equiv=\"refresh\" content=\"2\">");
          // output the value of each analog input pin

            client.println("CLOCK TEST");  

          client.println("
");  
          client.println(digitalClockDisplay());   
          client.println("
"); 
          //write RFID TAG:

          if(rfid.available()){
            while(rfid.available())          
            {
              buffer[count++]=rfid.read();     
              if(count == 14)break;
            }
            //print value:
            //client.write(buffer,count);  //default value
            client.print(GetInfo(buffer,count));        
            clearBufferArray();             
            count = 0;
            
            //buzz(8, 2500, 500); // buzz the buzzer on pin 8 at 2500Hz for 500 milliseconds
             WriteOnSD(); 
          }

          client.println("
");       

          client.println("</html>");
         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(2);
    // close the connection:
    client.stop();
    Serial.println("stop");
  }
  

}

// RFID functions:
void clearBufferArray()              // function to clear buffer array
{
  for (int i=0; i<count;i++)
  { 
    buffer[i]=NULL;
  }                  // clear all index of array with command NULL
}

String GetInfo(unsigned char buff[14], int count)
{
  // remove stx checksum and etx and get name;
  String value = GetString(buff).substring(1,11); 
  String temp = GetData(value);
  return temp;
  //sd_card_write(temp + " » " +digitalClockDisplay());
}

String GetString(unsigned char* inStrReference)
{
  // convert unsigned char to string
  unsigned char* bufPtr = inStrReference; 
  String newstring = (char*)bufPtr;
  return newstring;
}

String GetData(String id)
{                       
  String bd[5][2] = {
    {
      "0F000C9C0E","Joao Pereira"                 }
    ,
    {
      "0F00088CD2","Ricardo Lopes"                }
    ,
    {
      "0F00086052","Pedro Rosas"                  }
    ,
    {
      "0F00096159","Filipe Macedo"                }
    ,
    {
      "0F000CF1F5","Mariana Gomes"                }
  };

  String data = id;

  for(int i=0; i<5;i++){
    if(bd[i][0]==id){
      data = bd[i][1];
    }
  }

  return data;

}

// clock functions:
String digitalClockDisplay(){ 
  String clock = String(hour()) + ":" + String(minute()) + ":" + String(second()) + " | " + String(day())+ "/" + String(month())+ "/" + String(year());
  return clock;
}

//void buzz(int targetPin, long frequency, long length) {
//  long delayValue = 1000000/frequency/2; // calculate the delay value between transitions
//  long numCycles = frequency * length/ 1000; // calculate the number of cycles for proper timing
//
//  for (long i=0; i < numCycles; i++){ // for the calculated length of time...
//    digitalWrite(targetPin,HIGH); // write the buzzer pin high to push out the diaphram
//    delayMicroseconds(delayValue); // wait for the calculated delay value
//    digitalWrite(targetPin,LOW); // write the buzzer pin low to pull back the diaphram
//    delayMicroseconds(delayValue); // wait againf or the calculated delay value
//  }
//}

void WriteOnSD(){
  /* Initiliase the SD card */
  if (!SD.begin(4)) 
  {
    /* If there was an error output this to the serial port and go no further */
    Serial.println("card failed");
    delay(2);
  }
  else
  {
      SDFileData.println("OK");
      SDFileData.close();   

      Serial.println("done");
      delay(2);
  }

}

Não usar Strings costuma ser melhor de duas formas... menos código e menos erros.

Podes tentar tirar o código HTML do código C e em vez disso ler esse código HTML dum ficheiro no cartão SD. Vais precisar de ter cuidado ao aceder ao cartão e usar a Ethernet mas talvez funcione.

Podes arranjar um Arduino Mega.

Se o Arduino estiver numa rede com servidores NTP, podes ver-te livre do RTC e tentar sincronizar a hora por esse servidor. (Isto não sei até que ponto optimizará o código).

Podes ver-te livre do sistema de ficheiros no cartão e usares o cartão SD como uma memória normal e guardares lá os dados que pretendes. Isto invalidaria o uso do cartão num computador normal.

De todas estas, a mais eficaz creio ser livrares-te da String e fazeres as coisas com arrays. Dá um pouco mais de trabalho mas é bem mais eficiente.

bubulindo:
Não usar Strings costuma ser melhor de duas formas... menos código e menos erros.

Podes tentar tirar o código HTML do código C e em vez disso ler esse código HTML dum ficheiro no cartão SD. Vais precisar de ter cuidado ao aceder ao cartão e usar a Ethernet mas talvez funcione.

Podes arranjar um Arduino Mega.

Se o Arduino estiver numa rede com servidores NTP, podes ver-te livre do RTC e tentar sincronizar a hora por esse servidor. (Isto não sei até que ponto optimizará o código).

Podes ver-te livre do sistema de ficheiros no cartão e usares o cartão SD como uma memória normal e guardares lá os dados que pretendes. Isto invalidaria o uso do cartão num computador normal.

De todas estas, a mais eficaz creio ser livrares-te da String e fazeres as coisas com arrays. Dá um pouco mais de trabalho mas é bem mais eficiente.

Obrigado pelas respostas...
Podes-me dar um exemplo !?
Eu tenho obrigatoriamente de ter um relógio local devido as falhas de energia... estou a utilizar o arduino ethernet devido ao modulo de ligação à rede ... com o mega preciso de um shield :slight_smile:

Exemplo de? usar arrays e apontadores em vez de strings?

bubulindo:
Exemplo de? usar arrays e apontadores em vez de strings?

Sim... eu não estou a perceber muito bem o que está a referir!

char isto_e_um_array[5];

??

Que sabes de C?

bubulindo:

char isto_e_um_array[5];

??

Que sabes de C?

Sim eu percebo o array e percebo de C(#,++...)/java e mais um monte de línguas,
Não estou a perceber é a utilidade no código em anexo. Precisava de um exemplo no código para ver se percebo :slight_smile:

Não usar String... ou seja... não usar o objecto String e em vez disso usar strings (nota a letra minúscula) ou arrays e a string.h.

Estás agora a perceber? A classe String apenas adiciona overhead e espaço de código, mas não adiciona funcionalidade... apenas facilita escrever o código. O problema é que isto não é um computador, mas sim um microcontrolador de 8 bits e como tal fazer código com classes nem sempre é o ideal.

fala ai jot4p,

Ouça o bubulindo, eu programo para ambiente Windows (C# a maior parte do tempo) e tenho enraizado o uso de string rs

Quando usamos microcontroladores temos de contar bits/bytes, tanto em relação ao código do programa quanto ao uso da memória e usar o máximo de objetos nativos é a melhor alternativa, neste caso o char no lugar de string.

Uma coisa que também podes fazer é revisar as livrarias que estas a utilizar, podes encontrar métodos desnecessários, coisas a melhorar e/ou remover.

Eu uso um arduino mega, sem precisar economizar muito, mas quando peguei o atmega328p a coisa complicou rs

Mortis:
fala ai jot4p,

Ouça o bubulindo, eu programo para ambiente Windows (C# a maior parte do tempo) e tenho enraizado o uso de string rs

Quando usamos microcontroladores temos de contar bits/bytes, tanto em relação ao código do programa quanto ao uso da memória e usar o máximo de objetos nativos é a melhor alternativa, neste caso o char no lugar de string.

Uma coisa que também podes fazer é revisar as livrarias que estas a utilizar, podes encontrar métodos desnecessários, coisas a melhorar e/ou remover.

Eu uso um arduino mega, sem precisar economizar muito, mas quando peguei o atmega328p a coisa complicou rs

Olá,

Pois o meu problema é que estou muito habituado ao C# e a "string" é utilizada sem pensar nas consequências para a memoria :slight_smile:

Obrigado pela resposta, vou explorar...

O que estão a dizer é por exemplo substituir o codigo por isto:
char* GetInfo(unsigned char buff[14], int count)
{

// PARA string:
// remove stx checksum and etx and get name;
// String value = GetString(buff).substring(1,11);
// String temp = GetData(value);
// return temp;
//sd_card_write(temp + " » " +digitalClockDisplay());

// para char:
char buffer[10];
for(int i=0;i<9;i++){
buffer*= buff[i+1];*

  • }*
  • return buffer;*
    }

Você ganha uns 2K se programar seu arduino usando ICSP. Neste caso o espaço utilizado pelo bootloader passa a poder ser utilizado pelo seu sketch.

Para fazer a programação via ICSP, você vai precisar de um programador ISP, que pode ser outro Arduino (rodando o sketch ArduinoISP e uns cabos para ligar um ao outro) ou um AVR ISP ou um USBasp ou qqr coisa parecida. Isto tem a grande vantagem de:

  • ao ligar, o seu firmware entra em operação imediatamente, pois não tem o tempo de carregamento do bootloader
  • outra pessoa não conseguirá usar o chip como um arduino comum a não ser que também tenha algum programador ISP.
  • é reversível (vc pode a qualquer momento gravar o bootloader de volta)
  • te dá aproximadamente 2Kb a mais para seus programas na memória flash do Atmega328

Quanto a seu programa, vou dar uma olhada com mais calma, mas o que o pessoal aí em cima já disse é um bom começo, sobretudo a questão de abandonar o tipo String.

Cara, porque em vez de ficar usando bibliotecas furadas, mal implementadas, não vai direto à fonte?
http://www.nongnu.org/avr-libc/user-manual/group__avr__string.html

Eu fico pensando o quanto a falta de eficiência nos códigos gastam recursos(tempo,alimentação)... nos arduinos, nos PCs, nos celulares, nos pacotes de dados da internet...
-Arduino: usando digitalWrite gasta 5000ns, enquanto o acesso direto ao PORTx gasta 62,5 ns. Quase 20x diferença...
-android: já acessou o logcat de um android com meia duzia de apps instalados, são dezenas de acessos à arquivos, à rede e aplicativos que se corrompem e são recarregados novamente para a memória...
-PC: nem precisao falar nada né??!
-pacotes de internet:Antigamente não haviam "packet analyzers", wireshark... só o tal d tcpdump, então a comunicação tinha que ser bem explicativa, para que ao se observar os pacotes "crus" você pudesse diagnosticar problemas... só que hoje ainda não foi simplificada, imagina todo mundo acessando webpages e a cada uma delas um monte de texto que poderia ser compactado, imagina a sobrecarga do sistema:

requisição:

GET http://pt.kioskea.net HTTP/1.0  
Accept : text/html  
If-Modified-Since : Saturday, 15-January-2000 14:37:11 GMT  
User-Agent : Mozilla/4.0 (compatible; MSIE 5.0; Windows 95)

resposta:

HTTP/1.0 200 OK  
Date : Sat, 15 Jan 2000 14:37:12 GMT  
Server : Microsoft-IIS/2.0  
Content-Type : text/HTML  
Content-Length : 1245  
Last-Modified : Fri, 14 Jan 2000 08:25:13 GMT      
*conteudo da pagina*

fabiohbm007:
Cara, porque em vez de ficar usando bibliotecas furadas, mal implementadas, não vai direto à fonte?
avr-libc: <string.h>: Strings
Eu fico pensando o quanto a falta de eficiência nos códigos gastam recursos(tempo,alimentação)...

kkkk você esta certo! Mas a maioria fica contente com a coisa funcionando, sem se importar com o resto. Para hobbystas como eu, penso que seja admissível, para profissionais parece imperdoável :wink:

Como o arduino se propões a ser "fácil" a existência do digitalWrite é fundamental, mas para aqueles que querem tirar o máximo do microcontrolador acessos diretos são os mais viáveis, apesar de parecer difícil no início.

AlxDroidDev:
Você ganha uns 2K se programar seu arduino usando ICSP. Neste caso o espaço utilizado pelo bootloader passa a poder ser utilizado pelo seu sketch.

AlxDroidDev,

Verdade, tinha me esquecido do bootloader. Eu fiz uns testes com um atmega328 (arduino minimal :D). Sem dizer que você não tem o auto reset ao abrir serial.

jot4p:
Pois o meu problema é que estou muito habituado ao C# e a "string" é utilizada sem pensar nas consequências para a memoria :slight_smile:

Fui alertado sobre o uso de strings pelo HugoPT e Bubulindo faz pouco tempo.

Estou na mesma situação, mas sabe que estou curtindo apender sobre C e C++? Aos poucos nos livramos das amarras rs

Tenho tirado muitas dúvidas nesse site: http://www.cplusplus.com/reference/cstring/strcmp/ e sempre estou no google, ai vamos testando e vendo os resultados :wink:

A principal causa de gasto de memoria está aqui:

String digitalClockDisplay(){ 
  String clock = String(hour()) + ":" + String(minute()) + ":" + String(second()) + " | " + String(day())+ "/" + String(month())+ "/" + String(year());
  return clock;
}

O problema é que não consigo colocar isso num Char array...

A ideia era algo como:

char* digitalClockDisplay(){ 
 clock.getTime();
char date_time[] = {
    ((char)clock.hour,DEC),':',clock.minute,':',clock.second,'|',clock.dayOfMonth,'/',clock.month,'/',clock.year+2000,'\0'};  
    return date_time;

Pretendes transformar um numero em letras... Procura por itoa().

Em todo o caso será algo simples de escrever em C.

Também podes tentar sprintf, mas vai dar ao mesmo que tens.

fabiohbm007:
Cara, porque em vez de ficar usando bibliotecas furadas, mal implementadas, não vai direto à fonte?
avr-libc: <string.h>: Strings

Não é preciso ser assim. Arrisco dizer que a maioria das bibliotecas do Arduino têm uma boa implementação. A classe String a meu ver é um caso à parte porque tenta implementar algo que só funciona bem numa máquina com imensos recursos. E o AVR não tem imensos recursos... É esse a meu ver o problema aqui.
Eu quando (muito raramente) tenho de programar algo para um computador ainda tomo os cuidados que costumo ter com microcontroladores... apesar de ter muito mais recursos para utilizar, mas isso depende da experiência de cada um talvez.

fabiohbm007:
Eu fico pensando o quanto a falta de eficiência nos códigos gastam recursos(tempo,alimentação)... nos arduinos, nos PCs, nos celulares, nos pacotes de dados da internet...
-Arduino: usando digitalWrite gasta 5000ns, enquanto o acesso direto ao PORTx gasta 62,5 ns. Quase 20x diferença...
-android: já acessou o logcat de um android com meia duzia de apps instalados, são dezenas de acessos à arquivos, à rede e aplicativos que se corrompem e são recarregados novamente para a memória...
-PC: nem precisao falar nada né??!

Como o Mortis disse, o objectivo do digitalWrite read e afins é ser fail proof para os utilizadores que mal sabem de electrónica e programação. Nada te impede de usar o PORTx para aceder aos pinos de saída do microcontrolador. Mas para quem não sabe mais, são funções que cumprem o que é suposto fazerem.

Uma dúvida, no Android, isso são apps da Google ou de outros fabricantes?

fabiohbm007:
-pacotes de internet:Antigamente não haviam "packet analyzers", wireshark... só o tal d tcpdump, então a comunicação tinha que ser bem explicativa, para que ao se observar os pacotes "crus" você pudesse diagnosticar problemas... só que hoje ainda não foi simplificada, imagina todo mundo acessando webpages e a cada uma delas um monte de texto que poderia ser compactado, imagina a sobrecarga do sistema:

requisição:

GET http://pt.kioskea.net HTTP/1.0  

Accept : text/html 
If-Modified-Since : Saturday, 15-January-2000 14:37:11 GMT 
User-Agent : Mozilla/4.0 (compatible; MSIE 5.0; Windows 95)



resposta:


HTTP/1.0 200 OK 
Date : Sat, 15 Jan 2000 14:37:12 GMT 
Server : Microsoft-IIS/2.0 
Content-Type : text/HTML 
Content-Length : 1245 
Last-Modified : Fri, 14 Jan 2000 08:25:13 GMT     
conteudo da pagina

Se vamos falar nisto assim... porque não apontar o facto que a comunicação é feita em ASCII (ou UTF)? Os computadores não "falam" inglês... e no entanto a maior parte das nossas comunicações obriga os computadores a "falar" assim.

jot4p:
A principal causa de gasto de memoria está aqui:

String digitalClockDisplay(){ 

String clock = String(hour()) + ":" + String(minute()) + ":" + String(second()) + " | " + String(day())+ "/" + String(month())+ "/" + String(year());
  return clock;
}




O problema é que não consigo colocar isso num Char array...

A ideia era algo como:


char* digitalClockDisplay(){
clock.getTime();
char date_time[] = {
    ((char)clock.hour,DEC),':',clock.minute,':',clock.second,'|',clock.dayOfMonth,'/',clock.month,'/',clock.year+2000,'\0'}; 
    return date_time;

Procura pela palavra cast em C para perceberes o que estavas a fazer...

O que queres é algo assim:

void digitalClockDisplay(char * str){ 
char temp[5];   

clock.getTime(); //isto está errado... mas funciona e não é o propósito explicar porquê. 
//HH:mm:ss|DD/mm/YYYY\0  20 digitos no pior caso. 
    itoa(clock.hour, str, 10); //base 10 é o que queremos... 
    strcat(str, ":");    
    itoa(clock.minute, temp, 10);  
    strcat(str, temp);
    strcat(str, ":");
    itoa(clock.second, temp, 10);
    strcat(str, temp);
    strcat(str, "|");
    itoa(clock.dayOfMonth, temp, 10);
    strcat(str, temp);
    strcat(str, "/");
    itoa(clock.month, temp, 10);
    strcat(str, temp);
    strcat(str, "/");
    itoa((clock.year+2000), temp, 10);
    strcat(str, temp);
}

loop(){

char date_time[20]; 

digitalClockDisplay(date_time);
Serial.println(date_time);

O que queres é algo assim:

void digitalClockDisplay(char * str){ 

char temp[5];

clock.getTime(); //isto está errado... mas funciona e não é o propósito explicar porquê.
//HH:mm:ss|DD/mm/YYYY\0  20 digitos no pior caso.
   itoa(clock.hour, str, 10); //base 10 é o que queremos...
   strcat(str, ":");    
   itoa(clock.minute, temp, 10);  
   strcat(str, temp);
   strcat(str, ":");
   itoa(clock.second, temp, 10);
   strcat(str, temp);
   strcat(str, "|");
   itoa(clock.dayOfMonth, temp, 10);
   strcat(str, temp);
   strcat(str, "/");
   itoa(clock.month, temp, 10);
   strcat(str, temp);
   strcat(str, "/");
   itoa((clock.year+2000), temp, 10);
   strcat(str, temp);
}

loop(){

char date_time[20];

digitalClockDisplay(date_time);
Serial.println(date_time);

Muito Obrigado, Funciona mt bem.

Estava a fazer algo do tipo:

//char* digitalClockDisplay(){ 
//  clock.getTime();
//  
//char buf[24];
//
//char date_time[12];
//date_time[0] = *itoa(clock.hour,buf,10);
//date_time[1] = *":";
//date_time[2] = *itoa(clock.minute,buf,10);
//date_time[3] = *":";
//date_time[4] = *itoa(clock.second,buf,10);
//date_time[5] = *"|";
//date_time[6] = *itoa(clock.dayOfMonth,buf,10);
//date_time[7] = *"/";
//date_time[8] = *itoa(clock.month,buf,10);
//date_time[9] = *"/";
//date_time[10] = *itoa(clock.year+2000,buf,10);
//date_time[11] = '\0';
//
//
//Serial.println(date_time);
////return(date_time);
//
//}

mas estava-me a dar um problema... apenas aparece o primeiro digito de cada um :slight_smile:

tipo: 10:10:10 | 03/04/2013 --> aparece: 1:1:1|0/0/2

Claro... repara bem no que estavas a fazer... estavas apenas a passar o primeiro digito da conversão.
Percebes muito de ASCII? :\

bubulindo:
Não é preciso ser assim. Arrisco dizer que a maioria das bibliotecas do Arduino têm uma boa implementação. A classe String a meu ver é um caso à parte porque tenta implementar algo que só funciona bem numa máquina com imensos recursos. E o AVR não tem imensos recursos... É esse a meu ver o problema aqui.
Eu quando (muito raramente) tenho de programar algo para um computador ainda tomo os cuidados que costumo ter com microcontroladores... apesar de ter muito mais recursos para utilizar, mas isso depende da experiência de cada um talvez.

bubulindo:
Como o Mortis disse, o objectivo do digitalWrite read e afins é ser fail proof para os utilizadores que mal sabem de electrónica e programação. Nada te impede de usar o PORTx para aceder aos pinos de saída do microcontrolador. Mas para quem não sabe mais, são funções que cumprem o que é suposto fazerem.

Uma dúvida, no Android, isso são apps da Google ou de outros fabricantes?

Sou muito grato ao staff do arduino por ter disponibilizar a interface como um todo, iniciei quando a interface estava em 0015, mas EU não acho que o arduino seja um produto ready-to-market, não adianta digitalWrite ser fail proof se o cara não sabe que se colocar o pino como saida e high e na hora de fazer a conexão dos "fiozinhos" por engano tocar no GND é pino queimado na certa... cadê os resistores de >270 ohm para garantir que o erro não acabe com a brincadeira, quantos aqui no forum vem com codigo que funciona mas o chip ta com portas queimadas, o cara desiste porque não fez funcionar.
outro é o clock que foi comentado anteriormente... ainda se usa 16MHz porque o primeiro arduino idealizado usava os atmega8-16 cujo clock maximo é 16MHz, manteve-se na mesma frequencia por uma "retro-compatibilidade"?! mas como se existe o lillypad(8MHz)?
Na minha opinião o Ruggeduino é o ideal pra alguem que nunca mexeu, junto a programação...
Ninguem aqui usa só o computador com apenas produtos Microsoft, ou android com apenas softwares da google ou linux com programas desenvolvidos pelo staff responsavel pelo kernel.

bubulindo:
Se vamos falar nisto assim... porque não apontar o facto que a comunicação é feita em ASCII (ou UTF)? Os computadores não "falam" inglês... e no entanto a maior parte das nossas comunicações obriga os computadores a "falar" assim.

O problema não é comunicação em ASCII; que unifica o alfabeto americano junto a codigos de controle de dados/conexão/periféricos,
nem UTF creio eu é a abrangência em uma tabela de todos os simbolos e letras do mundo; é como a informação é trocada,
o cabeçalho do pacote de dados do protocolo TCP/IP é perfeito, feito para o computador entender... o cabeçalho do http não!
o javascript tambem segue a mesma linha, na definição de uma class, chamando a class pelo nome, gasta-pse muito recurso.

Começei a o hobby de programar com clipper, um dinossauro, mas na hora de compilar o programa,
eu tinha uma opção "verbose" que praticamente incluia o codigo fonte junto ao assembly gerado, na hora de debugar ele restaurava nomes de variaveis, etc...
ou podia compilar sem esses dados, que tornava o codigo mais leve...
Sabe quem faz isso de comprimir os pacotes de dados, o Opera mini, você navega por um proxy deles que comprime os dados, eu acho muito mais rapido...

como vão vender o arduino mega se tornarem o codigo muito eficiente à ponto de caber tudo no uno, todos tem que "comer".
veja esse link:http://arduino.cc/forum/index.php/topic,153160.0.html de 14k de flash para 1,5k?!?!
A facilidade da biblioteca com buffer incrostados consumindo memoria em dobro, e OOP eu não quero...
Se os criadores do arduino implementassem um array indicando quais pinos estão em uso pelas bibliotecas e na hora que elas fossem carregadas se desse "conflito" soltasse essa informação por serial, acabaria com grande parte dos posts desse forum, e supostamente quem usa o digitalWrite não teria que perder tempo pesquisando(qual era o objetivo do digitalWrite?) porque o codigo não funciona.

Peço desculpas ao criador do tópico pelo desvio...