Domanda su Pachube/Cosm

Ciao Cyberths,
lo sketch ha come base quello fornito da Cosm, nel loop ho inserito il mio Sketch (o meglio diversi sketch presi dalla rete, una brodaglia insomma).
Se non creo troppo stress posto qui sotto il codice....
Secondo me Cosm dovrebbe farmi vedere una segnale lineare e non con sbalzi da 0 a x, lo sketch si collega ogni 10 secondi a Cosm, mentre lo sketch stesso misura 5000 volte prima di passare il tutto a Cosm (almeno credo).
Ho tagliato la prima parte dello sketch altrimenti nn potevo postarlo tutto

Saluti Remo
------------------------------Snip--------------------------------------------

void setup() {
// start serial port:
Serial.begin(115200);
analogReference (EXTERNAL);
// start the Ethernet connection:
if (Ethernet.begin(mac) == 0) {
Serial.println("Failed to configure Ethernet using DHCP");
// DHCP failed, so use a fixed IP address:
Ethernet.begin(mac, ip);
}
}

void loop() {

analogReference (EXTERNAL);

// massimo delle sinus positive
analogReference (EXTERNAL);

ValA0 = analogRead(A0) ;
ValA1 = analogRead(A1) ;
ValA2 = analogRead(A2) ;

Vpartitore = analogRead(A3);

// record the maximum sensor value
if (ValA0 > sensorMax1) {
sensorMax1 = ValA0;
}

// record the minimum sensor value
if (ValA0 < sensorMin1) {
sensorMin1 = ValA0;
}

// record the maximum sensor value
if (ValA1 > sensorMax2) {
sensorMax2 = ValA1;
}

// record the minimum sensor value
if (ValA1 < sensorMin2) {
sensorMin2 = ValA1;
}

// record the maximum sensor value
if (ValA2 > sensorMax3) {
sensorMax3 = ValA2;
}

// record the minimum sensor value
if (ValA2 < sensorMin3) {
sensorMin3 = ValA2;
}

// Serial.println(ValA0);

// if (ValA0 < 510.72 ){ValA0 = 512 + (510.72 - ValA0); }
// if (ValA1 < 510.72 ){ValA1 = 512 + (510.72 - ValA1); }
// if (ValA2 < 510.72 ){ValA2 = 512 + (510.72 - ValA2); }

L1 = L1 + sensorMax1 ;
L2 = L2 + sensorMax2 ;
L3 = L3 + sensorMax3 ;

Cicli++ ;

// VIENE FATTA LA MEDIA SU 5000 Letture

if (Cicli == 5000){

L1 = (L1 / 5000.000)-510.000 ;
L2 = (L2 / 5000.000)-510.000 ;
L3 = (L3 / 5000.000)-510.000 ;

Serial.println(L1,4);
Serial.println(L2,4);
Serial.println(L3,4);

Vpartitore = analogRead(A3)*0.0032265625;

Voltaggio1 = (((L1 * 0.0032265625)-0));
Voltaggio2 = (((L2 * 0.0032265625)-0));
Voltaggio3 = (((L3 * 0.0032265625)-0));

Corrente1 = sqrt(((Voltaggio1*30)/3.3)0.9);
Corrente2 = sqrt(((Voltaggio2
30)/3.3)0.9);
Corrente3 = sqrt(((Voltaggio3
30)/3.3)*0.9);

Potenza1 = Corrente12400.9;
Potenza2 = Corrente22400.9;
Potenza3 = Corrente32400.9;
Ptot = (Potenza1+Potenza2+Potenza3);

Vpartitore = analogRead(A3)*0.0032265625;

Serial.println();
Serial.print( " Voltaggio 1 --> ");
Serial.print(Voltaggio1,4);
Serial.print( " Ampere --> ");
Serial.print(Corrente1,4);
Serial.print( " Potenza --> ");
Serial.println(Potenza1,4);

Serial.print( " Voltaggio 2 --> ");
Serial.print(Voltaggio2,4);
Serial.print( " Ampere --> ");
Serial.print(Corrente2,4);
Serial.print( " Potenza --> ");
Serial.print(Potenza2,4);
Serial.print( " Potenta Totale --> ");
Serial.println(Ptot,4);

Serial.print( " Voltaggio 3 --> ");
Serial.print(Voltaggio3,4);
Serial.print( " Ampere --> ");
Serial.print(Corrente3,4);
Serial.print( " Potenza --> ");
Serial.println(Potenza3,4);
Serial.println();
Serial.print( " Tensione sul Partitore --> ");
Serial.println(Vpartitore,4);

L1 = 0 ;
L2 = 0 ;
L3 = 0 ;
sensorMax1 = 0;
sensorMax2 = 0;
sensorMax3 = 0;
sensorMin1 = 0;
sensorMin2 = 0;
sensorMin3 = 0;

Cicli = 0 ;}

// 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 ten seconds have passed since
// your last connection, then connect again and send data:
if(!client.connected() && (millis() - lastConnectionTime > postingInterval)) {
sendData(Ptot,Potenza1,Potenza2,Potenza3);
}
// store the state of the connection for next time through
// the loop:
lastConnected = client.connected();
}

// this method makes a HTTP connection to the server:
void sendData(float thisData,float thisData1,float thisData2,float thisData3) {
// if there's a successful connection:
if (client.connect(server, 80)) {
Serial.println("connecting...");
// send the HTTP PUT request:
client.print("PUT /v2/feeds/");
client.print(FEEDID);
client.println(".csv HTTP/1.1");
client.println("Host: api.cosm.com");
client.print("X-ApiKey: ");
client.println(APIKEY);
client.print("User-Agent: ");
client.println(USERAGENT);
client.print("Content-Length: ");

// calculate the length of the sensor reading in bytes:
// 8 bytes for "sensor1," + number of digits of the data:
int thisLength = 8 + getLength(thisData);
client.println(thisLength);

// last pieces of the HTTP PUT request:
client.println("Content-Type: text/csv");
client.println("Connection: close");
client.println();

// here's the actual content of the PUT request:
client.print("A_MaxPower,");
client.println(thisData);
client.print("B_Power_L1,");
client.println(thisData1);
client.print("C_Power_L2,");
client.println(thisData2);
client.print("D_Power_L3,");
client.println(thisData3);

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

// This method calculates the number of digits in the
// sensor reading. Since each digit of the ASCII decimal
// representation is a byte, the number of digits equals
// the number of bytes:

int getLength(int someValue) {
// there's at least one byte:
int digits = 1;
// continually divide the value by ten,
// adding one to the digit count for each
// time you divide, until you're at 0:
int dividend = someValue /10;
while (dividend > 0) {
dividend = dividend /10;
digits++;
}
// return the number of digits:
return digits;
}
--------------snip-----------------------------

i sorgenti postali dentro i tag [code ] e [/ code] (sensa spazi), li trovi cliccando l'icona # nell'editor dei messaggi

Non hai inserito le dichiarazioni delle variabili, comunque credo di aver capito dov'è il problema.
La precisione delle variabili Float è di 5/6 digit complessivi, come recita la guida:

...
Floats have only 6-7 decimal digits of precision. That means the total number of digits, not the number to the right of the decimal point.
...

Questo vuol dire che se inserisci 0.0032265625 in realtà hai inserito 0.00323 (troncamento ed arrotondamento).
Se a questo aggiungi che durante i calcoli i valori possono diventare molto piccoli, ecco una possibile risposta al tuo problema.
Ti conviene lavorare con i numeri interi e solo alla fine effettuare il calcolo float (o double che per Arduino è la stessa cosa).
Qualche altro consiglio:
1 - inserisci l'struzione analogreference nel setup e non nel loop;
2 - riduci il ciclo allo stretto indispensabile per ridurre il solo "rumore" (basta un ciclo di una decina di letture), ma ricordati di distanziare nel tempo ciascuna istruzione analogread tramite un delayMicroseconds(100);
3 - per effettuare la conversione da int, anzi unsigned int (0-1023) puoi usare la comoda istruzione map().

Grazie Cyberhs,
provero ad attuare i tuoi consigli.

Saluti

Remo

Ho provato il consiglio di cyber ma il risultato rimane invariato, ogni tanto ho dei valori "0" nonostante il segnale sia continuo.

Esistono altenrative a COSM ? Che offrono servizi del genere ?

Saluti

Remo

Posta il codice completo, per favore.

Non so se esista un'alternativa a COSM.

Eccolo il Codice, non fare caso al subbuglio.

Saluti
Remo

Pachube_Ok_A07.ino (7.99 KB)

Mi puoi mandare lo schema del collegamento tra le sonde di corrente ed Arduino?

Spiegami questi passaggi:

    Corrente1 = (sensorMax1 - 510) * 0.00323;
    Corrente1 = sqrt(Corrente1);
    Corrente1 = (Corrente1 * 30) / 3.3;

Ciao Cyberhs,

come accennato nei precedenti post, queste sono formule di sola prova, queste che chiedi tu sono le formule per il calcolo della corrente.

sensorMax : Lettura massima rilevata su 5000 letture
510 : il valore del mio partitore che ammonta a 1.645 Volt (ho settato arduino con un Aref di 3.3 Volt esterni)

Sulla prima linea calcolo la tensione effettiva.
sulla seconda linea la Radice della prima
sulla terza faccio una proporzione del mio sensore di corrente : il mio sensore ha queste proprietà 0--30A in entrata (Ac) e in uscita 0..1 Volt Ac.
Allora ho usato la proporzione : 30A : 3.3v = x : voltaggio letto

So che non è la via giusta, ma ci sto lavorando.

Per quanto riguarda lo schema non esiste disegno, in pratica un polo del sensore viene alimentato direttamente dal partitore (1.645v) mentre l'altro polo entra direttamente sull'arduino.
Avro cosi un'offset di ca. 1.65V --> punto "0"---> e da li vado a ricavarmi i massimi valori di lettura.

I sensori sono del tipo Hall.

Saluti
Remo

Comincia a mettere mano al saldatore perché se vuoi precisione nella misura devi farti un circuito raddrizzatore.

Lo schema che ti posto usa un operazionale come raddrizzatore ideale ad una semionda e fornisce in uscita una tensione max di 3.3 Vp, ideale per una Aref di 3.3V, così non perdi neanche un bit di precisione.

Nota che ho usato un LM324 a 14 pin perché così con un solo IC puoi assemblare i tre raddrizzatori che ti sono necessari (il quarto è in più). Se non hai dimestichezza con i circuiti stampato o con la millefori ti posso preparare un layout (tempo permettendo).

Poi affronteremo il problema del software che, vedrai, sarà notevolmente più semplice.

Raddrizzatore Ideale.emf (23.8 KB)

Raddrizzatore Ideale.wmf (11.8 KB)

Buongiorno,
grazie dei file, se gentilmente potresti convertirli in PDF te ne sarei grato, non riesco ad aprirli.

Io ho comunque già provato con degli operazionali, appunto LM324 (vedi allegato), ma il risultato non è stato soddisfacente.
Usai questi Opamp in modalità non invertente, come vedi dalla foto ho usato una R ed un potenziometro per regolarne l'uscita a 3,3V.

Non so come sia concepito il tuo schema, gli daro un'occhiata non appena mi manderai una versione PDF.

Intanto grazie

Saluti
Remo

Sono riuscito ad aprire il tuo schema, a parte i 2 diodi, ho fatto la stessa cosa.

Potresti spiegarmene il motivo dei diodi ?

Avevo escluso questa possibilità poiché il segnale in uscita risultava molto disturbato.

Per la calibrazione del mio print ho utilizzazo un generatore di frequenza, impostato a 2V e 50 Hz, regolandone l'uscita a 3,3 Volt.

Saluti
Remo

I due diodi servono a filtrare l'onda in ingresso: quello in serie alla resistenza determina quale semionda amplificare, mentre l'altro blocca l'altra.
L'amplificazione, essendo invertente, è determinata dal rapporto R2/R1 ed essendo l'alimentazione a 5V (prelevata da Arduino) non può superare il valore 3,5 per evitare il clipping.
I calcoli devono tener conto della caduta di tensione dei diodi, quindi ho scelto A = 2,7 che sommata alla caduta di tensione 0,7 fornisce circa 3,4. Naturalmente bisogna tarare il circuito inserendo un trimmer da 10k in serie con la resistenza d'ingresso in modo da ottenere esattamente i 3,3V con un ingresso di 1 Vp.
Importante: un condensatore da 100n in parallelo e più vicino possibile al pin di alimentazione del IC e cortocircuitare ingresso ed uscita del 4° operazionale non utilizzato (vedi schema allegato).

Grazie Cyberhs,
provero oggi stesso a farmi il circuito, pensi che le mie sonde siano adatte al tuo schema ?
Io utilizzo sct-030-13 --> http://roysoala.files.wordpress.com/2012/04/sct-013_datasheet.jpg

per la taratura dai 1vp a 50 hz ? o 2vpp a 50 hz ? (ho detto la stessa cosa ??)

Saluti

Remo

comunque anche se siamo saltati su altro argomento, rispetto all'inizio.

Giusto per informazione, gli sbalzi dei valori a "0" su Cosm, sono dovuti a un bug interno del sito, e verrà corretto a breve.

Ecco la risposta di un addetto al sito

Ah, I see what's happening - this is a bug in our code I believe.

Sometimes your Arduino is sending a value like this: '209.' and we have a guard in our code to prevent trying to render a graph point for a num numeric value which incorrectly views that value as non numeric (it's currently looking for values that either look like '209' or '209.0').

It's quite an easy fix though, so I'll try and get it pushed out within the next hour or two.

Apologies for the inconvenience.

Best regards

Sam


Saluti
Remo

Ah, I see what's happening - this is a bug in our code I believe...

Beh questa è proprio il colmo!

Comunque il circuito che ti ho inviato dovrebbe risolvere i tuoi problemi di precisione (taratura 1 Vp = 2 Vpp @ 50Hz).

Sì, lo schema l'ho preparato per essere collegato ai tuoi sensori con uscita in tensione che credo siano blu, a differnza di quelli rossi che hanno un'uscita in corrente (o viceversa?).

Il circuito dovrebbe essere schermato (inserendolo in un contenitore metallico) per evitare che capti i disturbi dell'alternata.

Sto per terminare anche la revisione del software, ma necessito di un po' di tempo.

Grazie Cyberht,
molto gentile, apprezzo molto quello che stai facendo !!
Non saprei come sdebitarmi ....

Cosa intendi per contenitore metallico ?
Al momento lo sto montando sulla Breakboard, laborplate,..... o come si dice in italiano ?

Intanto grazie....

saluti

Remo

Per fare le prove va benissimo la millefori, ma poi se non vuoi captare disturbi dovrai inserire il tutto in una scatola metallica (alluminio va benissimo) che funga da gabbia di Faraday e collegata alla massa del circuito: le tensioni con cui la lavori sono molto basse (dell'ordine dei mV) ed è la stessa precauzione che viene usata per gli amplificatori audio (hai mai sentito il ronzio dei 50 Hz?).

Nel nostro caso il "ronzio" lo vedresti con l'oscilloscopio e sovrapposto al segnale utile!

Dovresti aver notato che il cavetto dei sensori è schermato (non a caso!).

il cavo in se stesso è schermato, ma non collegato, il miniJack l'ho dovuto tagliare per saldarlo poi sul print, ed ho notato che la schermatura del cavo nn è nemmeno collegata.

Solo i 2 cavi portatori del segnale e nient'altro.

Al momento le estrmita del sensore li collego a una "leuchterklemme" non so come si pronuncia in italiano.

Quella barretta dove fai passare i cavi da ambo le parti e poi avviti al centro.

Pensi dovrei spellare il cavo dei sensori e collegare anche la schermatura ? (appunto su di un contenitore metallico).

Saluti
Remo

Quello di collegare tutto a massa è uno dei primi errori che si commette quando si lavora con le basse tensioni.

Non si considera che lo stesso collegamento della calza dei fili schermati è un ottima antenna capta disturbi!

Apparentemente può sembrare complicato, ma non lo è più di tanto.

In pratica si deve evitare di fare i cosidetti "anelli di massa" (cerca su Google e troverai un sacco di siti che ne parlano), ma alle volte è difficle capire che ci sono!

Il mio consiglio è questo: collega i sensori alla scheda senza la calza collegata (non avendo riferimenti di massa non dovrebbe averne bisogno), ma se ricevi disturbi prova a collegarla per vedere se si riducono.

L'importante è schermare gli operazionali (forse potrebbe non essere indispensabile, ma tanto in una scatola li dovrai pure mettere, tanto vale che sia di metallo!

Ricordati che il collegamento della massa con la scatola metallica deve essere unico!