[Risolto] Codice che non restituisce nulla a Serial Monitor

Ciao a tutti
sono nuovo alla programmazione di arduino.
sto realizzando un dispositivo e relativo codice per leggere la corrente tramite una pinza amperometrica.
dopo vari tentativi, e aver valutato varie soluzioni in rete (openenergymonitor, e alcuni post in questo forum), ho scritto il seguente codice.
Il problema è che il serial monitor non mi stampa nulla, vorrei invece vedere i risultati dell’elaborazione, nell’ultima riga con serialprintln.
In altre versioni dello stesso sketch ottenevo la lista delle letture analogread su serial monitor, ma con questo skecth non appare nulla a schermo…non vorrei essermi incasinato con i vari cicli for.
probabilmente la soluzione è banale, ma per ora non ci arrivo!
Potete darmi qualche suggerimento sul codice in basso? Come mai non non vedo nulla a serial monitor dopo aver fatto upload su arduino?
grazie in anticipo

const int voltmax=5; // i millivolt massimi leggibili sono 5 (o 3.3V)
const int pin=0; //il sensore è collegato al pin 0
int n_samples=400;//campioni nel periodo
int mis;
int K=5; //mV/A
int bitI[400];
float I[400];
float IQ[400];
float Irms[50]; //array per fare la media di 50 valori rms (1 valore al secondo)
float Iave;

void setup()
{
  Serial.begin(9600);
  }
  
void loop()  //array valori nel periodo
{ 
 
  for (int k=0;k<50; k++) //media di 50 valori per avere un valore ogni secodo a schermo
  {
    for (int i=0; i<n_samples; i++)
    {
     mis=analogRead(pin);
     bitI[i]=mis;
     I[i]=(((mis*voltmax)/1024)*1000/K); //array delle correnti
    delayMicroseconds(50); //ogni  periodo (20ms) voglio 400 campioni quindi campiono a intervalli di 50us
    //Serial.println(I[i]); //anche aggiungendo questa riga non vedo nulla a serial monitor
     }
     
 
 float IQsum=0;//Calcolo valore efficacie
    for (int i=0; i<n_samples; i++)
    {
     IQ[i]=I[i]*I[i]; //array dei quadrati della corrente
     IQsum=IQsum+IQ[i];  //somma dell'array dei quadrati della corrente
      }  
       
    Irms[k]=sqrt((IQsum*2)/n_samples); //rms corrente nel periodo, metà del quale ha valori pari a zero
  }
    
 
 // media degli rms
 Iave=0;
 for (int j=0; j<50; j++)
 {
    Iave=Iave+Irms[j];
    }

float IaveRMS= Iave/50; //media dei 50 valori
Serial.println(IaveRMS);


}

Hai provato con Serial.write(); ?

Servirebbe solo per controllare se ce comunicazione tra Arduino e la seriale..

int bitI[400];
float I[400];
float IQ[400];
float Irms[50];

non so che arduino possiedi, ma hai la minima idea di quanta RAM stai usando in questi array? è arduino che non funziona proprio, non la seriale.

http://arduino.cc/en/Reference/Float http://arduino.cc/en/Reference/Int

ciao

Sono 800 Byte 1600 Byte 1600 Byte 200 Byte in tutto 4200 Byte contro un 2048 esistenti nel Arduino UNO che non puoi usufluire interamente. Ciao Uwe

grazie mille intanto. in effetti non avevo considerato il limite di RAM di arduino (parliamo della RAM in questo caso corretto? ), come vi dicevo sono davvero agli inizi. bene, ho scoperto allora quanto presto si fa a riempirla! tra domande: 1) come hai fatto ad assegnare il valore di memoria ad ogni mio array? cosi imparo per la prossima volta 2) avete qualche soluzione da consigliarmi per snellire il codice e la gestione delle variabili? 3) se la 2) è una domanda troppo pretenziosa, avete qualche link da suggerirmi per migliorare il mio sketch?

grazie in anticipo

Consultando la reference di Arduino puoi vedere che un valore di tipo int pesa 2 byte e quindi una "lista" di 400 numeri interi peserà 800 byte.. stesso discorso per i float che pesano 4 byte e quindi 4 x 400 fa 1600!

Tutte queste informazioni comunque le trovi qui: http://arduino.cc/en/Reference/HomePage.

Per quanto riguarda snellire il codice, devi ponderare esattamente se quel valore avrà bisogno di essere un int piuttosto che un byte e quant'altro, penso che con il tempo e che con l'esperienza riusciremo a migliorare al gestione del codice.

Anche io sono alle prime armi!

Quindi, correggetemi (e bastonatemi) se sbaglio !

1) come hai fatto ad assegnare il valore di memoria ad ogni mio array? cosi imparo per la prossima volta

leggendo le risposte che ti danno gli altri utenti... reply n°3

http://arduino.cc/en/Reference/Float http://arduino.cc/en/Reference/Int

Floating-point numbers can be as large as 3.4028235E+38 and as low as -3.4028235E+38. They are stored as 32 bits (4 bytes) of information.

On the Arduino Uno (and other ATMega based boards) an int stores a 16-bit (2-byte) value. This yields a range of -32,768 to 32,767 (minimum value of -2^15 and a maximum value of (2^15) - 1).

int : 2*400 = 800 byte float : 4*400 = 1600 byte

A volte si partecipa anche rispondendo, ti è stato praticamente chiesto che arduino hai, ma non l'hai ancora detto

Ciao ho un Arduino UNO rev3, quindi i riferimenti fatti sopra tornano, grazie Per la mia applicazione ho quindi raggiunto il limite delle possibilità di arduino,vedro cosa posso fare per migliorarla, non credo che questo forum sia il posto giusto per chiedere come migliorare il codice.

posto la richiesta come risolta. saluti e grazie

Ho proprio recentemente affrontato il tuo stesso problema e noto che parti da un presupposto errato.

Tu campioni inserendo un ritardo di 50 microsec tra una lettura e l'altra dimenticando che il convertitore ADC ha una velocità massima di 9600 campioni al secondo, che divisi per 50 Hz corrispondono ad un massimo di 192 campioni/periodo (teorici perché c'è da considerare il tempo speso dalle istruzioni tra un read e l'altro).

Poiché il calcolo RMS richiede un numero intero di periodi per ridurre l'errore, ti conviene campionare senza ritardo alcuno entro una finestra temporale di 1-n periodi (20, 40, 60 ... ms).

Inoltre non è necessario caricare tutto in un vettore, ma effettuare una semplice sommatoria dei quadrati e solo alla fine della finestra temporale calcolare la radice.

Un filtro passa basso a 4,8 kHz aiuta a ridurre il rumore.

in effetti stavo per domandare se quegli array servivano per poi farne una media, in tal caso fare una somma istantanea ecc … (sei arrivato prima), però questo non è il forum giusto per chiedere come migliorare il codice. :slight_smile:

@cyberhs: perchè fai il quadrato e poi radice? non puoi contare ad ogni ciclo loop sommando ogni volta e quando arrivi a 399 dividere ? poi ripartire da zero …

ciao

pablos: @cyberhs: perchè fai il quadrato e poi radice? non puoi contare ad ogni ciclo loop sommando ogni volta e quando arrivi a 399 dividere ? poi ripartire da zero ....

2 cause: 1. elimini i valori negativi e 2 cosí si calcola il valore effettivo di un segnale sinusoidale. Ciao Uwe

valori negativi su un input di arduino non credo ce ne saranno :) comunque interessante ... si tratta di ricavare il valore efficace quindi.

Campionamento almeno lungo un periodo. Elevazione al quadrato che comporta la perdita di segno dei valori negativi; Calcolo della media dei precedenti dati; Estrazione della sua radice quadrata.

Il risultato in base al teorema del campionamento di Nyquist-Shannon è corretto entro la banda passante in cui le armoniche superiori non superano la frequenza di campionamento. grazie

La corrente ha un segnale di onda sinusoidale che ha una semionda positiva e una negativa. Con un offset di 2,5V a cui colleghi la pinza amperometrica ottieni un segnale sempre positivo per poter usare l’ entrata analogica di Arduino per la misura.
Per il calcolo del valore della corrnete devi sotrarre l’ offset e ottieni dei valori positivi e negativi di corrente.

Ciao Uwe

pablos: @cyberhs: perchè fai il quadrato e poi radice? non puoi contare ad ogni ciclo loop sommando ogni volta e quando arrivi a 399 dividere ? poi ripartire da zero ....

Perché RMS sta per Root Mean Square, ovvero la radice della media dei quadrati, rappresenta il valore efficace, da non confondere con quello medio, di una tensione, o una corrente, AC.