Emoncms - Modbus Datalogger - EthernetServer/EthernetClient

Buongiorno a tutti,

Apro questo topic per avere aiuto riguardo un problema di programmazione, al tempo stesso farà da tutorial per altri.

Dopo aver tribolato non poco con i miei ricordi di C sono arrivato a recuperare i dati che il contatore elettrico mi fornisce in Modbus (ULYS MD80-M + ULYSCOM MODBUS). Per l'interfaccia in RS485 ho usato un driver come questo.

Gli esempi per il ModbusMaster e le librerie li ho trovati qui e qui.

Poi ho voluto dataloggare i dati su la SD che é alloggiata nella Shield Ethernet e li ho cercato di che mantenere la cronologia con un RTC come questo.

GLi esempi per la SD sono nell'API Arduino, per l'utilizzo di un RTC ne ho discusso qui.

Visto che poi riuscivo a fare il mio bel file CSV e a scriverlo sulla SD ho voluto visualizzare i valori più interessanti su una semplicissima paginetta web con un refresh di 5 sec come da esempio, Webserver, che ho trovato nell'API.

Contentissimo volevo qualcosa di più sofisticato, cercando ancora ho trovato questo progettino ben fatto dove si usa Pachube ma che poi ho scoperto essere diventata Xively ma niente Opensource...

Poi mi ricordo di aver visto un bellissimo progetto inglese OpenEnergyMonitor che usa Arduino come base per il conteggio dell'energia elettrica e cercando ancora ho visto questo Playground per Emoncms che mi ha aiutato per mettere in forma i dati da inviare al database.

Adesso i dati sono trasferiti al mio account di Emoncms che funziona egregiamente ma purtroppo il simpatico Webserver che mi dava i dati in tempo reale non funziona più... >:(
Far convivere la parte Server con la parte Client non mi é semplice.

Penso di aver fatto un bel casino con i while e if... e non solo, questo é la parte del Loop

void loop(){
 
 modbus_update();
 timer.run();
  
  // if there's incoming data from the net connection.
  // send it out the serial port.  This is for debugging
  // purposes only:
  if (client.available()) {
    char c = client.read();
    Serial.print(c);
  }

  // if there's no net connection, but there was one last time
  // through the loop, then stop the client:
  if (!client.connected() && lastConnected) {
    Serial.println();
    Serial.println("Disconnecting...");
    client.stop();
  }
  
  // if you're not connected, and at least <postingInterval> milliseconds have
  // passed sinceyour last connection, then connect again and
  // send data:
  if(!client.connected() && (millis() - lastConnectionTime > postingInterval)) {
   
    //Create Data to Emoncms.org
    
      Voltage = (Compact2Word(12,readRegs1))/1000.0;
      Current = (Compact2Word(22,readRegs1))/1000.0;
      PowerFactor = readRegs1[27]/1000.0;
      ActivePower = Compact3Word(6,readRegs2)/1000.0;
      Frequency = readRegs2[33]/1000.0;
      ActiveEnergy = (Compact3Word(9,readRegs3))/10000.0;
      
      
    //send values
    sendData();
    
    Serial.println(Voltage);
    Serial.println(Current);
    Serial.println(PowerFactor);
    Serial.println(ActivePower);
    Serial.println(Frequency);
    Serial.println(ActiveEnergy);
  }
  // store the state of the connection for next time through
  // the loop:
  lastConnected = client.connected();

    
   
   
 EthernetClient client = server.available();
  if (client) {
    Serial.println("new 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");
            // output the value of each analog input pin
            readTime(); 
            client.print("Date "); client.print(monthday); client.print("/"); client.print(month); client.print("/"); client.print(year);
            client.print("  Hour "); client.print(hour); client.print(":"); client.print(minute); client.print(":"); client.print(second); client.println("
");
            float a =0;
            client.print("Voltage "); client.print(Voltage, 2); client.println("V 
");
            client.print("Current "); client.print(Current, 2); client.println("A 
");  
            client.print("Power Factor "); client.print(PowerFactor, 2); client.println(" 
");
            client.print("Active Power "); client.print(ActivePower, 2); client.println("W 
");
            client.print("Apparent Power "); client.print((a = Compact3Word(18,readRegs2))/1000, 2); client.println("VA 
");
            client.print("Reactive Power "); client.print((a = Compact3Word(30,readRegs2))/1000, 2); client.println("VAR 
");
            client.print("Frequency "); client.print(Frequency, 2); client.println("Hz 
");
            client.print("Active Energy "); client.print(ActiveEnergy, 2); client.println("KWh 
");
            client.print("Inductive apparent Energy "); client.print((a = Compact3Word(33,readRegs3))/1000, 2); client.println("VAh 
");
            client.print("Capacitive apparent Energy "); client.print((a = Compact3Word(57,readRegs3))/1000, 2); client.println("VAh 
");
            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(1);
    // close the connection:
    client.stop();
    Serial.println("client disconnected");
  }
}

// this method makes a HTTP connection to the server:
void sendData() {
  // if there's a successful connection:
  if (client.connect(emoncms, 80)) {
    Serial.println("Connecting...");
    // send the HTTP GET request:
    client.print("GET /api/post?apikey="); // GET /api/post?apikey=Myapikey&node=0&json={Voltage:236548,Current:14785,Power-Factor:78548,Active-Power:485250} 
    client.print(apikey);
    if (node > 0) {
      client.print("&node=");
      client.print(node);
    }
    client.print("&json={Voltage:");
    client.print(Voltage, 2);    
    client.print(",Current:");
    client.print(Current, 2);
    client.print(",Power-Factor:");
    client.print(PowerFactor, 2);   
    client.print(",Active-Power:");
    client.print(ActivePower, 2); 
    client.print(",Frequency:");
    client.print(Frequency, 2);
    client.print(",Active-Energy:");
    client.print(ActiveEnergy, 2);  
    client.println("} HTTP/1.1");
    client.println("Host:emoncms.org");
    client.println("User-Agent: Arduino-ethernet");
    client.println("Connection: close");
    client.println();

    // note the time that the connection was made:
    lastConnectionTime = millis();
  } 
  else {
    // if you couldn't make a connection:
    Serial.println("Connection failed");
    Serial.println("Disconnecting...");
    client.stop();
  }
}

In allegato metto il file.ino tutt'intero per chi voglia eventualmente verificarlo e dirmi se l'ho scritto corettamente.

Grazie in antcipo,

Simone

Modbus_Energy_Counter_EthernetClient-Server.ino (17.2 KB)

Scusate ho dimenticato di mettere il link al topic di DanielaES dal quale ho cercato di mettere in pratica i consigli di Zoomkat... :confused:

Potresti aggiungere i link delle librerie utilizzate.

Certo eccole qui:

SimpleModbusMasterV10.h
SimpleTimer.h
EmonLib.h

Le restanti:
SPI.h
SD.h
Wire.h
Ethernet.h

fanno parte dell'API 1.5.8

Buongiorno a tutti,
qualcuno ha avuto modo di testare il codice che non mi funziona completamente? :confused:
Tanks..

Salve a tutti,
sto cercando di sistemare questo sketch da un pò ma non ci riesco...

Vorrei fare in modo che continui ad alimentare la base dati che è sul server Emon ed al contempo quando accedo da remoto sul IP dell'Arduino vorrei che continuasse ad inviare i dati ma che aggiornasse anche una paginetta leggera leggera dove visualizzare i dati più importanti...
Ho problemi per capire come usare il Server.Available
Fino ad ora ogni qualvolta che accedo all'indirizzo il non visualizzo un bel niente e resto senza dati...

Chi può darmi una mano?

Grazie,
Simone

Si è più volte discusso sul forum sulla possibilità di avere le funzionalità client e server contemporaneamente.
Ma è difficile ottenerle.
Cerca vecchie discussioni sull'argomento.