Go Down

Topic: Autodiagnosi per Arduino? (Read 3660 times) previous topic - next topic

frog

io mi riferivo al nome diagnuino che hai coniato tu

BrainBooster

#46
Jun 06, 2010, 08:11 pm Last Edit: Jun 06, 2010, 08:26 pm by brainbooster Reason: 1
@frog il tuo ragionamento non fà una piega, però, abbiamo dei valori attesi, potremmo anche ipotizzare che qualsiasi valore diverso da quelli attesi è da considerarsi un "problema" ? o vuoi che venga "analizzato" anche il tipo di problema?
pensavo che il test a 3v si potrebbe fare solo in caso di anomalie nei test a 0 e / o  a 5v.

frog

direi di partire con "il pin x ha dei problemi" se poi non ci sono troppe difficoltà si può passare a "il pin x è inchiodato a alto/basso/mezza_via".
in questo modo se uno sta utilizzando solo 4 uscite digitale e una gli si rompe, può cambiare semplicemente connessione e proseguire con il suo lavoro.
se vi va possiamo sviluppare a più mani creando un porgetto su http://code.google.com/intl/it-IT/projecthosting/ in questo modo gli allineamenti dei vari sviluppi verebbero gestiti in automatico da subversion.


Quote
pensavo che il test a 3v si potrebbe fare solo in caso di anomalie nei test a 0 e / o  a 5v
intendi una PWM per generare i 3V?

BrainBooster

@frog si, intendevo pwm. (qualora serva)

frog

probabilmente le prove a valori intermedi non sono necessarie, come diceva kokiua se un ingresso/uscita si brucia si perdono tutte le funzionalità. una volta sviluppato il progetto sarebbe interessante riuscire a fare qualche prova con delle schede che si sono rotte sul campo. se qualcuno ne ha le tenga da parte

BrainBooster

ok, eliminiamo un grado di complessità, infondo, è meglio avere solo 2 stati, (si ritorna nel "binario")

frog

#51
Jun 08, 2010, 10:49 pm Last Edit: Jun 09, 2010, 12:05 am by furgorsin Reason: 1
prima versione in gardo (si spera) di riconoscere gli ingressi analogici guasti. esempi di risultati:
tutto ok: http://img208.imageshack.us/img208/5258/tuttook.png
due analogiche bloccate a GND: http://img35.imageshack.us/img35/6043/dueagnd.png
due analogiche bloccate a VCC: http://img413.imageshack.us/img413/4717/dueavcc.png
una analogica a VCC e una a GND: http://img41.imageshack.us/img41/8766/unavccunagnd.png
la riga dopo la varianza segnala con un "1" gli ingressi analogici riconosciuti come danneggiati (da sinistra l'analogica 0)
dimenticavo, per far partire l'autodiagnosi si deve mandare "s" via seriale

Code: [Select]
char  inByte;
int   val = 0;
int   analogPin = 0;
int   analogValues[] = {0, 0, 0, 0, 0, 0};
int   analogSorted[] = {0, 0, 0, 0, 0, 0};
int   analogWrong[]  = {0, 0, 0, 0, 0, 0};
float analogMean     = 0;
float analogMean_min = 0;
float analogMean_max = 0;
float analogVar      = 0;
float analogVar_max  = 0;
float analogVar_min  = 0;
#define VAR_THRESHOLD  10

int  digitalPin;
byte digitalWrong[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};

#define MAX_ANALOG_PIN  5
#define MAX_DIGITAL_PIN  13

int num_value = MAX_ANALOG_PIN + 1;

void sortAnalog()
{
 byte i, j;
 int tmp = 0;
 for(i = 0; i < 6; i++)
   analogSorted[i] = analogValues[i];
 for(i = 0; i < 6; i++)
 {
   for(j = 0; j < 5 - i; j++)
   {
     if(analogSorted[j] > analogSorted[j + 1])
     {
       tmp = analogSorted[j];
       analogSorted[j] = analogSorted[j + 1];
       analogSorted[j + 1] = tmp;
     }
   }
 }
 return;
}

void setup()
{                
 Serial.begin(9600);
 for(digitalPin = 2; digitalPin < (MAX_DIGITAL_PIN + 1); digitalPin++)
 {
   pinMode(digitalPin, OUTPUT);
   digitalWrite(digitalPin, LOW);
 }
}

void loop()                    
{
 while(!Serial.available())
   ;
 inByte = Serial.read();
 if(inByte == 's')
 {
   // variable initialization
   analogMean = 0;
   analogVar  = 0;
   num_value = MAX_ANALOG_PIN + 1;
   Serial.println("parto");
   // all digital pins HIGH
   for(digitalPin = 2; digitalPin < (MAX_DIGITAL_PIN + 1); digitalPin++)
   {
     digitalWrite(digitalPin, HIGH);
   }
   delay(200);
   Serial.print("tutto alto");
   Serial.print('\t');
   for(analogPin = 0; analogPin < (MAX_ANALOG_PIN + 1); analogPin++)
   {
     val = analogRead(analogPin);
     analogValues[analogPin] = val;
     analogMean += val;
     Serial.print(val);
     Serial.print('\t');
   }
   analogMean /= 6.0;
   Serial.print('\n');
   Serial.print("valori ordinati\t");
   sortAnalog();
   for(analogPin = 0; analogPin < (MAX_ANALOG_PIN + 1); analogPin++)
   {
     Serial.print(analogSorted[analogPin]);
     Serial.print('\t');
   }
   Serial.print('\n');
   // variance
   for(analogPin = 0; analogPin < (MAX_ANALOG_PIN + 1); analogPin++)
   {
     analogVar += abs(analogValues[analogPin] - analogMean);
   }
   analogVar /= 6.0;
   while(analogVar > VAR_THRESHOLD)
   {
     // measure variance with max value
     analogMean_max = analogSorted[1];
     for(analogPin = 2; analogPin < num_value; analogPin++)
     {
       analogMean_max += analogSorted[analogPin];
     }
     analogMean_max /= (float)(num_value);
     analogVar_max = abs(analogSorted[1] - analogMean_max);
     for(analogPin = 2; analogPin < num_value; analogPin++)
     {
       analogVar_max += abs((analogSorted[analogPin] - analogMean_max));
     }
     
     // measure variance with min value
     analogMean_min = analogSorted[0];
     for(analogPin = 1; analogPin < num_value - 1; analogPin++)
     {
       analogMean_min += analogSorted[analogPin];
     }
     analogMean_min /= (float)(num_value);
     analogVar_min = abs(analogSorted[0] - analogMean_min);
     for(analogPin = 1; analogPin < num_value - 1; analogPin++)
     {
       analogVar_min += abs((analogSorted[analogPin] - analogMean_min));
     }
     
     if(analogVar_min > analogVar_max)
     {
       // delete min value
       for(analogPin = 0; analogPin < num_value - 1; analogPin++)
         analogSorted[analogPin] = analogSorted[analogPin + 1];
       analogVar = analogVar_max;
       analogMean = analogMean_max;
     }
     else
     {
       // delete max value
       analogVar  = analogVar_min;
       analogMean = analogMean_min;
     }
     num_value--;
     analogVar /= (float)(num_value);
   }
   // print results
   Serial.print("media = \t");
   Serial.print(analogMean);
   Serial.print('\n');
   Serial.print("varianza = \t");
   Serial.print(analogVar);
   Serial.print('\n');
   // check analogIn integrity on everything low
   Serial.print("\t\t");
   for(analogPin = 0; analogPin < (MAX_ANALOG_PIN + 1); analogPin++)
   {
     if(abs(analogMean - analogValues[analogPin]) > 10)
     {
       analogWrong[analogPin] = 1;
     }
     else
     {
       analogWrong[analogPin] = 0;
     }
     Serial.print(analogWrong[analogPin]);
     Serial.print('\t');
   }
   Serial.print('\n');
   Serial.print("\t\t");
   for(analogPin = 0; analogPin < (MAX_ANALOG_PIN + 1); analogPin++)
   {
     Serial.print(abs(analogMean - analogValues[analogPin]));
     Serial.print('\t');
   }
   Serial.print('\n');
   // all digital pins LOW
   for(digitalPin = 2; digitalPin < (MAX_DIGITAL_PIN + 1); digitalPin++)
   {
     digitalWrite(digitalPin, LOW);
   }
   delay(200);
   Serial.print("tutto basso");
   Serial.print('\t');
   analogMean = 0;
   for(analogPin = 0; analogPin < (MAX_ANALOG_PIN + 1); analogPin++)
   {
     val = analogRead(analogPin);
     analogMean += val;
     Serial.print(val);
     Serial.print('\t');
   }
   Serial.print('\n');
   // check analogIn integrity on everything high
   for(analogPin = 0; analogPin < (MAX_ANALOG_PIN + 1); analogPin++)
   {
     if(abs(analogMean - analogValues[analogPin]) > 10)
     {
       analogWrong[analogPin] = 1;
     }
   }
   // find out the first analog pin ok
   analogPin = 0;
   while(analogWrong[analogPin])
     analogPin++;
   // check digitalOut integrity whit the first analog ok
   for(digitalPin = 2; digitalPin < (MAX_DIGITAL_PIN + 1); digitalPin++)
   {
     Serial.print("digitale ");
     Serial.println(digitalPin);
     Serial.print("\tbasso\t");
     delay(200);
     for(analogPin = 0; analogPin < (MAX_ANALOG_PIN + 1); analogPin++)
     {
       val = analogRead(analogPin);
       Serial.print(val);
       Serial.print('\t');
     }
     Serial.print('\n');
     digitalWrite(digitalPin, HIGH);
     Serial.print("\talto\t");
     delay(200);
     for(analogPin = 0; analogPin < (MAX_ANALOG_PIN + 1); analogPin++)
     {
       val = analogRead(analogPin);
       Serial.print(val);
       Serial.print('\t');
     }
     Serial.print('\n');
     digitalWrite(digitalPin, LOW);
     delay(200);
   }
   Serial.println("fine");
 }
 else
 {
   Serial.println("comando errato, riprova");
 }
 Serial.flush();
}


cose da fare:
- riconoscere la condizione di "nessuna analogica buona rilevata"
- valutare il corretto funzionamenti dei singoli ingressi digitali



edit: ingressi analogici nella prima riga, avevo scritto digitali

BrainBooster

scusami frog, ma quale schema stai utilizzando per le prove?

frog

lo schema che utilizzo è questo http://img139.imageshack.us/img139/2560/diagnuinoschema.png
R13 è da 1kOhm. chiedo scusa per le dimensioni, potevo effettivamente farlo un po' più grande

BrainBooster

per gli ingressi digitali, pensavo che si potrebbe mettere High un pin e leggere gli altri e così via...

frog

con il circuito che ho realizzato non è possibile fare una cosa del genere.
avevo pensato, dopo l'analisi degli ingressi analogici, di fare una predizione di quello che dovrebbe essere il valore di tensione agli ingressi analogici con un solo pin digitale alto e utilizzare tale valore per capire se l'uscita digitale è bruciata

BrainBooster

magari mi sono espresso in manniera pedestre, :-[ ma, (se non ho capito male) è più o meno quello che dicevo nel mio post precedente

frog

fraintendimento mio, avevo capito che che intendevi impostare un'uscita digitale alta e poi leggere il valore con gli altri ingressi digitali.

BrainBooster

ma ci hai già provato?
quali sono i valori di "tutto ok"?

frog

non ho ancora avuto tempo di analizzare come prevedere il valore che discrimina i valori buoni delle singole uscite digitali alte.
un esempio di tutto ok è questo http://img822.imageshack.us/img822/5258/tuttook.png

Go Up