(RISOLTO) Stazione meteo, ethernet shield e FTP NAS

Ciao a tutti, grazie ai vostri consigli ed al vostro aiuto sono riuscito a realizzare una stazione meteo con pagina html accessibile da Internet e salvataggio dati su SD.

Quello che vorrei fare adesso é accedere da Internet ai dati salvati su file nella SD della Ethernet shield. Ho cercato molto in rete ma non ho trovato nulla che fosse effettivamente quello che mi servirebbe realizzare.

Io avrei in mente 2 strade da percorrere ma non so come realizzarle.

1) Accedo tramite http alla pagina html che ho creato con Arduino ed in qualche modo, che non conosco ancora, prelevo il file salvato sull'SD.

2) Implemento un comando periodico nello sketch o comando tramite la pagina html creata da Arduino, l'invio del file salvato su SD al mio NAS incorporato al router e che é raggiungibile con questo comando "ftp:://User:passswd@fritz.nas/Folder meteo/file.txt"

Non so realizzare nessuna delle 2 e quindi mi servirebbe il vostro aiuto per capire come procedere.

Premetto che non so realizzare script php e che mi piacerebbe una soluzione semplice semplice.

Grazie

. http://forum.arduino.cc/index.php/topic,179084.0.html

Priva a vedere se qui trovi quelli che cerchi, come. Ftp non penso troverai nulla, ma un download da pagina html mi sembra più fattibile.

Ciao vic

Per l'FTP credo ti occorra una scheda che lo implementa già on board ...

... ad esempio, utilizzando WiFi, QUESTO modulino (... che per altro è molto comodo dato che parla attraverso la seriale e non impegna troppi pin di Arduino, contrariamente ai classici shield) implementa già : DHCP, UDP, DNS, ARP, ICMP, HTTP client, FTP client e lo stack TCP.

Capisco che tu attualmente usi una connessione Ethernet, mentre questo è WiFi ... ... ma non so se per Ethernet riuscirai a trovare qualche cosa ... :roll_eyes:

Guglielmo

Grazie per le risposte.

@ Vic : ci daró un occhiata sperando di capire se fa al caso mio

@Guglielmo: vorrei continuare utilizzare lo shield Ethernet ma terró comunque in mente il tuo suggerimento

Alberto

http://playground.arduino.cc/Code/FTP

/*
   FTP passive client for IDE v1.0.1 and w5100/w5200
   Posted October 2012 by SurferTim
*/

#include <SD.h>
#include <SPI.h>
#include <Ethernet.h>
// comment out next line to write to SD from FTP server
#define FTPWRITE

// this must be unique
byte mac[] = { 0x90, 0xA2, 0xDA, 0x00, 0x59, 0x67 };  

// change to your network settings
IPAddress ip( 192, 168, 2, 2 );    
IPAddress gateway( 192, 168, 2, 1 );
IPAddress subnet( 255, 255, 255, 0 );

// change to your server
IPAddress server( 1, 2, 3, 4 );

EthernetClient client;
EthernetClient dclient;

char outBuf[128];
char outCount;

// change fileName to your file (8.3 format!)
char fileName[13] = "test.txt";

void setup()
{
  Serial.begin(9600);

  pinMode(10,OUTPUT);
  digitalWrite(10,HIGH);

  if(SD.begin(4) == 0)
  {
    Serial.println(F("SD init fail"));          
  }

  Ethernet.begin(mac, ip, gateway, gateway, subnet); 
  digitalWrite(10,HIGH);
  delay(2000);
  Serial.println(F("Ready. Press f or r"));
}

void loop()
{
  byte inChar;

  inChar = Serial.read();

  if(inChar == 'f')
  {
    if(doFTP()) Serial.println(F("FTP OK"));
    else Serial.println(F("FTP FAIL"));
  }

  if(inChar == 'r')
  {
    readSD();    
  }

}

File fh;

byte doFTP()
{
#ifdef FTPWRITE
  fh = SD.open(fileName,FILE_READ);
#else
  SD.remove(fileName);
  fh = SD.open(fileName,FILE_WRITE);
#endif

  if(!fh)
  {
    Serial.println(F("SD open fail"));
    return 0;    
  }

#ifndef FTPWRITE  
  if(!fh.seek(0))
  {
    Serial.println(F("Rewind fail"));
    fh.close();
    return 0;    
  }
#endif

  Serial.println(F("SD opened"));

  if (client.connect(server,21)) {
    Serial.println(F("Command connected"));
  } 
  else {
    fh.close();
    Serial.println(F("Command connection failed"));
    return 0;
  }

  if(!eRcv()) return 0;

  client.println(F("USER myuser"));

  if(!eRcv()) return 0;

  client.println(F("PASS mypassword"));

  if(!eRcv()) return 0;

  client.println(F("SYST"));

  if(!eRcv()) return 0;

  client.println(F("PASV"));

  if(!eRcv()) return 0;

  char *tStr = strtok(outBuf,"(,");
  int array_pasv[6];
  for ( int i = 0; i < 6; i++) {
    tStr = strtok(NULL,"(,");
    array_pasv[i] = atoi(tStr);
    if(tStr == NULL)
    {
      Serial.println(F("Bad PASV Answer"));    

    }
  }

  unsigned int hiPort,loPort;

  hiPort = array_pasv[4] << 8;
  loPort = array_pasv[5] & 255;

  Serial.print(F("Data port: "));
  hiPort = hiPort | loPort;
  Serial.println(hiPort);

  if (dclient.connect(server,hiPort)) {
    Serial.println(F("Data connected"));
  } 
  else {
    Serial.println(F("Data connection failed"));
    client.stop();
    fh.close();
    return 0;
  }

#ifdef FTPWRITE 
  client.print(F("STOR "));
  client.println(fileName);
#else
  client.print(F("RETR "));
  client.println(fileName);
#endif

  if(!eRcv())
  {
    dclient.stop();
    return 0;
  }

#ifdef FTPWRITE
  Serial.println(F("Writing"));

  byte clientBuf[64];
  int clientCount = 0;

  while(fh.available())
  {
    clientBuf[clientCount] = fh.read();
    clientCount++;

    if(clientCount > 63)
    {
      dclient.write(clientBuf,64);
      clientCount = 0;
    }
  }

  if(clientCount > 0) dclient.write(clientBuf,clientCount);

#else
  while(dclient.connected())
  {
    while(dclient.available())
    {
      char c = dclient.read();
      fh.write(c);      
      Serial.write(c); 
    }
  }
#endif

  dclient.stop();
  Serial.println(F("Data disconnected"));

  if(!eRcv()) return 0;

  client.println(F("QUIT"));

  if(!eRcv()) return 0;

  client.stop();
  Serial.println(F("Command disconnected"));

  fh.close();
  Serial.println(F("SD closed"));
  return 1;
}

byte eRcv()
{
  byte respCode;
  byte thisByte;

  while(!client.available()) delay(1);

  respCode = client.peek();

  outCount = 0;

  while(client.available())
  {  
    thisByte = client.read();    
    Serial.write(thisByte);

    if(outCount < 127)
    {
      outBuf[outCount] = thisByte;
      outCount++;      
      outBuf[outCount] = 0;
    }
  }

  if(respCode >= '4')
  {
    efail();
    return 0;  
  }

  return 1;
}


void efail()
{
  byte thisByte = 0;

  client.println(F("QUIT"));

  while(!client.available()) delay(1);

  while(client.available())
  {  
    thisByte = client.read();    
    Serial.write(thisByte);
  }

  client.stop();
  Serial.println(F("Command disconnected"));
  fh.close();
  Serial.println(F("SD closed"));
}

void readSD()
{
  fh = SD.open(fileName,FILE_READ);

  if(!fh)
  {
    Serial.println(F("SD open fail"));
    return;    
  }

  while(fh.available())
  {
    Serial.write(fh.read());
  }

  fh.close();
}

Bertu65: 1) Accedo tramite http alla pagina html che ho creato con Arduino ed in qualche modo, che non conosco ancora, prelevo il file salvato sull'SD.

se invece di visualizzare la pagina vuoi fare il download di un file da SD tramite browser la procedura è questa, non accedi a nesuna pagina html, appena metti l'IP di arduino sul browser appare il popup di download

client.println("HTTP/1.1 200 OK");    
 client.println("Content-Type: application/octet-stream"); 
 client.println("Content-Description: File Transfer");
 client.println("Content-Disposition: attachment; filename=MYFILE.HTM");
 client.println("Content-Transfer-Encoding: binary");
 client.println("Cache-Control: must-revalidate, post-check=0, pre-check=0");
 //client.println("Content-Length: " + size(webFile )); //questo mostra quanto è grande il file nel popup di download       
 client.println("Connection: close");
 client.println();
                                            
                    webFile = SD.open("MYFILE.HTM");       
                    if (webFile) {
                        while(webFile.available()) {
                            client.write(webFile.read()); 
                        }
                        webFile.close();
                    }
                    break;

per il size del file non ho guardato come ottenerlo, comunque è un parametro opzionale che ti permette di avere la percentuale di avanzamento e il tempo stimato per il 100%

ciao

Ciao, non molto tempo fa ho dato una mano ad un amico per relizzare una stazione meteo che salvasse i dati online, dai un occhiata: http://it.emcelettronica.com/stazione-meteo-online-con-arduino Saluti, Ivan

Grazie anche a Pablos ed Ivan ma siete andati un pochino fuori tema.

Pablos, se implemento la tua soluzione é vero che posso prelevare il file ma poi non posso vedere la pagina meteo che ho creato con Arduino. Forse si possono fare entrambe le cose ma ci devo studiare un po' su.

Ivan, la pubblicazione su database non mi interessa. I dati devono essere salvati sulla SD card dell'Ethernet shiield e se possibile, pubblicati sul mio NAS Intranet oppure prelevati "on demand" quando accedo da fuori.

si puoi fare entrambe le cose, visualizzazione, download e upload

Alla fine, con mia immensa soddisfazione, ce l'ho fatta.

Ho modificato la pagina HTTP aggiungendo un bottone per il download del file da SD. Ho utilizzato il codice suggerito da Pablos e devo dire che funziona a meraviglia.

Il codice e le funzioni continuano a crescere (circa 50K) cosí come cresce anche il mio godimento :D

Alberto

Il codice e le funzioni continuano a crescere (circa 50K)

Su quale arduino lavori? Con questa IDE non riuscirai a compilare più di 120k di sketch (8k sono già impegnati) anche se hai 256k totali Occhio a non esagerare :)

Uso Arduino Mega.

Da qui a 120K c'é ancora tanta strada e comunque potrei sempre lavorare sull'ottimizzazione del SW. (al momento é un po' macchinoso perché é stato scritto aggiungendo sempre qualche cosa alla parte giá esistene e siccome io non sono un esperto di SW, sono sicuro che lo si potrebbe sicuramente riscrivere meglio)

Possima modifica potrebbe essere quella di sostituire il display 20x4 LCD + tastiera capacitiva con LCD touch da 3,2" .......................ma il tempo per farlo scarseggia. :~ e devo trovare il modo di far coesistere l'Ethernet shield a lo schield del touch.