Aide pour mon programme capteur CCD

Bonjour,

Je suis actuellement en terminale SSI et ai pour projet un réfractomètre numérique, je travaille sur la programmation d’un capteur CCD (ILX551A http://home.fnal.gov/~maeshima/align...ip/ILX551A.pdf). En gros, je dois comparer la tension de sortie entre les différents pixels, et trouver le pic lumineux qui correspond au pic de tension en y associant la position du pixel. Le capteur est linéaire, il associe 33 premiers pixels inutiles, 2048 utilisables et 6 à la fin inutiles. Voici mon programme, pourriez vous s’il vous plaît me dire ce qui cloche ? Merci d’avance pour votre aide.
Je l’ai fait sur Arduino.
Rog et Clock sont les deux signaux à générer.

#include <Wire.h> //inclusion de la libraire Wire (protocole I2C / TWI)
#include <LiquidCrystal_I2C.h> //inclusion librairie écran LCD
?LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); //definir adresse LCD ) 0x27 pour un affichage de 
#define Vout A0 // Vout sur broche A0
boolean rog = 3; //Rog sur broche 3
boolean clock =2; //Clock sur broche 2
float n, D, B; //n,D,B en float
int i, Ntemp; //déclarer i et Ntemp
int posmin = 1; //position minimum du pixel à 1 ?
int lum; //lum est la tension sur Vout (sortie)
int pic_lum =2047; //position du pixel le plus lumineux
int poslum //position du pixel
int poslum1 //position du pixel
int lum1 //lum1 est la tension sur Vout

void setup(){
  lcd.begin(20,4);  // init lcd 20 caractères 4 lignes
  lcd.backlight(); //  retro éclairage on  
  Serial.begin(9600); //Conexon série 9600 bauds
}

void loop(){  
  mesure();
  lcd.setCursor(1,0); //postion curseur
  ?lcd.print(i); //écrire i 
  calcul_taux();
}



// *****************************mesure*****************************
 void mesure(){
   depart_mesure();
  i = 1; //on se place au pixel 1
  while(i<34){      // 33 premiers clock inutiles (voir doc ilx551a)
       digitalWrite(clock,LOW); //Niveau logique bas sur clock
       delayMicroseconds (0,001); 
       digitalWrite(clock,HIGH); //niveau logique haut
       delayMicroseconds (0,001);
       i=i+1; //incrémentation (on change de pixel)
       
    
  }
  i = 34; //on se place au pixel 34 (33 inutiles)
 while(i<2049){     // mesure des 2048 pixels utiles
       digitalWrite(clock,LOW); //niveau logique bas sur clock
       delayMicroseconds (0,001); 
       digitalWrite(clock,HIGH);
       delayMicroseconds (0,001); //REVOIR HERTZ
       lum = analogRead(Vout); //acquérir tension de Vout
       delayMicroseconds (100);
       poslum= i //position du pixel duquel on prélève la tension
       i=i+1 //on avance d'un pixel
       lum1 = analogRead(Vout); //on releve la tension de ce pixel
       poslum1 = i //on garde la position du pixel
       if (lum > lum1){ //Comparer les deux tensions
         pic-lum = i; //prendre position avec plus haute tension
        else pic-lum= poslum //sinon l'autre
        pic-lum= i-1;

Bonjour,

  • le programme n'est pas entier
  • il y a un ? avant LiquidCrystal_I2c
  • il manque des ';'
    ....

bonjour,
restif pour I2C
ca devrait être
adrese, nb colones, nb lignes

LiquidCrystal_I2C lcd(0x27,16,2);

tu as mélangé un I2C et un lcd normal

je regarde pas le reste

Bonjour, je n’ai pas mit le programme en entier parce que la partie sur laquelle je bloque est sur la recherche de la position du pixel lumineux, en fait j’aimerais juste obtenir ce pixel et donc en connaître la position et je voulais savoir si ma comparaison était correcte.
je rectifie le programme :

#include <Wire.h> //inclusion de la libraire Wire (protocole I2C / TWI)
#include <LiquidCrystal_I2C.h> //inclusion librairie écran LCD
LiquidCrystal_I2C lcd(0x27,20,4); //definir adresse LCD ) 0x27 pour un affichage de 
#define Vout A0 // Vout sur broche A0
boolean rog = 3; //Rog sur broche 3
boolean clock =2; //Clock sur broche 2
float n, D, B; //n,D,B en float
int i, Ntemp; //déclarer i et Ntemp
int posmin = 1; //position minimum du pixel à 1 ?
int lum; //lum est la tension sur Vout (sortie)
int pic_lum =2047; //position du pixel le plus lumineux
int poslum; //position du pixel
int poslum1; //position du pixel
int lum1; //lum1 est la tension sur Vout

void setup(){
  lcd.begin(20,4);  // init lcd 20 caractères 4 lignes
  lcd.backlight(); //  retro éclairage on  
  Serial.begin(9600); //Conexon série 9600 bauds
}

void loop(){  
  mesure();
  lcd.setCursor(1,0); //position curseur
  lcd.print(i); //écrire i 
}

// *****************************mesure*****************************
 void mesure(){
  i = 1; //on se place au pixel 1
  while(i<34){      // 33 premiers clock inutiles (voir doc ilx551a)
       digitalWrite(clock,LOW); //Niveau logique bas sur clock
       delay(10); 
       digitalWrite(clock,HIGH); //niveau logique haut
       delay(10);
       i=i+1; //incrémentation (on change de pixel)
    
  }
  i = 34; //on se place au pixel 34 (33 inutiles)
 while(i<2049){     // mesure des 2048 pixels utiles
       digitalWrite(clock,LOW); //niveau logique bas sur clock
       delay(10); 
       digitalWrite(clock,HIGH);
       delay(10); //REVOIR HERTZ
       lum = analogRead(Vout); //acquérir tension de Vout
       delay(10);
       poslum= i; //position du pixel duquel on prélève la tension
       i=i+1; //on avance d'un pixel
       lum1 = analogRead(Vout); //on releve la tension de ce pixel
       poslum1 = i; //on garde la position du pixel
       if (lum > lum1) //Comparer les deux tensions
       pic_lum = i; //prendre position avec plus haute tension
       else pic_lum = poslum; //si infèrieur prendre l'autre pixel
       pic_lum = i-1; //position du pixel précédent (si plus tension plus élevée)
}
}

//*************depart mesure**********************
 
void depart_mesure(){ 
  pic_lum =2047;
  posmin = 0;
   digitalWrite(rog,HIGH);
   digitalWrite(clock,HIGH);
   delay (10);
   digitalWrite(rog,LOW);
   delay (10);
   digitalWrite(rog,HIGH);
   delay (10);
}

//************************************************

void calcul_taux(){ 
    n= i*4265990;
    n= n/1000000;
    D= 6852*n-9153;
    lcd.setCursor(2,2);
    lcd.print(D);
    lcd.setCursor(7,2);
    lcd.print("g/L   ");
    B = 13345*D;
    B = B/10000;
    lcd.setCursor(3,3);
    lcd.print(B);
    lcd.setCursor(8,3);
    lcd.print("degre B   ");
  }

Merci de votre attention, excusez mes erreurs c’est la première fois que je programme.

marilenaf:
Merci de votre attention, excusez mes erreurs c’est la première fois que je programme.

Excuses moi aussi d’en remettre une couche, ton programme ne se compile même pas, comment veux tu qu’il soit correct ?

Je viens de tout revoir et il se compile sans aucune erreur.
Le voici:

#include <Wire.h> //inclusion de la libraire Wire (protocole I2C / TWI)
#include <LiquidCrystal_I2C.h> //inclusion librairie écran LCD
LiquidCrystal_I2C lcd(0x27,20,4); //definir adresse LCD ) 0x27 pour un affichage de 
#define Vout A0 // Vout sur broche A0
boolean rog = 3; //Rog sur broche 3
boolean clock =2; //Clock sur broche 2
float n, D, B; //n,D,B en float
int i, Ntemp; //déclarer i et Ntemp
int posmin = 1; //position minimum du pixel à 1 ?
int lum; //lum est la tension sur Vout (sortie)
int pic_lum =2047; //position du pixel le plus lumineux
int poslum; //position du pixel
int poslum1; //position du pixel
int lum1; //lum1 est la tension sur Vout

void setup(){
  lcd.begin(20,4);  // init lcd 20 caractères 4 lignes
  lcd.backlight(); //  retro éclairage on  
  Serial.begin(9600); //Conexon série 9600 bauds
}

void loop(){  
  mesure();
  lcd.setCursor(1,0); //position curseur
  lcd.print(i); //écrire i 
}

// *****************************mesure*****************************
 void mesure(){
  i = 1; //on se place au pixel 1
  while(i<34){      // 33 premiers clock inutiles (voir doc ilx551a)
       digitalWrite(clock,LOW); //Niveau logique bas sur clock
       delay(10); 
       digitalWrite(clock,HIGH); //niveau logique haut
       delay(10);
       i=i+1; //incrémentation (on change de pixel)
    
  }
  i = 34; //on se place au pixel 34 (33 inutiles)
 while(i<2049){     // mesure des 2048 pixels utiles
       digitalWrite(clock,LOW); //niveau logique bas sur clock
       delay(10); 
       digitalWrite(clock,HIGH);
       delay(10); //REVOIR HERTZ
       lum = analogRead(Vout); //acquérir tension de Vout
       delay(10);
       poslum= i; //position du pixel duquel on prélève la tension
       i=i+1; //on avance d'un pixel
       lum1 = analogRead(Vout); //on releve la tension de ce pixel
       poslum1 = i; //on garde la position du pixel
       if (lum > lum1) //Comparer les deux tensions
       pic_lum = i; //prendre position avec plus haute tension
       else pic_lum = poslum; //si infèrieur prendre l'autre pixel
       pic_lum = i-1; //position du pixel précédent (si plus tension plus élevée)
}
}

//*************depart mesure**********************
 
void depart_mesure(){ 
  pic_lum =2047;
  posmin = 0;
   digitalWrite(rog,HIGH);
   digitalWrite(clock,HIGH);
   delay (10);
   digitalWrite(rog,LOW);
   delay (10);
   digitalWrite(rog,HIGH);
   delay (10);
}

//************************************************

void calcul_taux(){ 
    n= i*4265990;
    n= n/1000000;
    D= 6852*n-9153;
    lcd.setCursor(2,2);
    lcd.print(D);
    lcd.setCursor(7,2);
    lcd.print("g/L   ");
    B = 13345*D;
    B = B/10000;
    lcd.setCursor(3,3);
    lcd.print(B);
    lcd.setCursor(8,3);
    lcd.print("degre B   ");
  }

Le lien de la datasheet : http://home.fnal.gov/~maeshima/alignment/zip/ILX551A.pdf

Les critique sont constructives et aident à apprendre alors n’hésitez pas et encore merci.

Ton algorithme me semble compliqué et erroné. Il suffit à chaque pixel de comparer avec la plus grande valeur précédemment trouvée.

// *****************************mesure*****************************
void mesure() {
  i = 1; //on se place au pixel 1
  while (i < 34) {  // 33 premiers clock inutiles (voir doc ilx551a)
    digitalWrite(clock, LOW); //Niveau logique bas sur clock
    delay(10);
    digitalWrite(clock, HIGH); //niveau logique haut
    delay(10);
    i = i + 1; //incrémentation (on change de pixel)

  }
  i = 34; //on se place au pixel 34 (33 inutiles)

  int lumMax=0;
  for (;i < 2049; i++) { // mesure des 2048 pixels utiles
    digitalWrite(clock, LOW); //niveau logique bas sur clock
    delay(10);
    digitalWrite(clock, HIGH);
    delay(10); //REVOIR HERTZ
    lum = analogRead(Vout); //acquérir tension de Vout
    if (lum>lumMax)
    {
      // on a trouvé un pixel plus lumineux que le dernier qu'on avait trouvé
      poslum=i;
      lumMax=lum;
    }
  }
}

deux conseils:
Utilises des boucles for quand tu dois faire varier un index entre 2 bornes (au lieu de while)
Numérote plutôt à partir de 0 (de 0 à 2047 plutôt que de 1 à 2048) car en C les indices commencent à 0.

J’ai fait les modifications que tu m’as dit, seulement je ne sais pas trop comment simplifier ce programme pour assimiler la position au pixel avec la plus haute tension…

/ *****************************mesure*****************************
 void mesure(){
  i = 0; //on se place au pixel 1
  for (0=<i=<33){      // 33 premiers clock inutiles (voir doc ilx551a)
       digitalWrite(clock,LOW); //Niveau logique bas sur clock
       delay(10); 
       digitalWrite(clock,HIGH); //niveau logique haut
       delay(10);
       i=i+1; //incrémentation (on change de pixel)
    
  }
  i = 34; //on se place au pixel 34 (33 inutiles)
for(34=<i=<2049){     // mesure des 2048 pixels utiles
       digitalWrite(clock,LOW); //niveau logique bas sur clock
       delay(10); 
       digitalWrite(clock,HIGH);
       delay(10); //REVOIR HERTZ
       lum = analogRead(Vout); //acquérir tension de Vout
       delay(10);
       poslum= i; //position du pixel duquel on prélève la tension
       i=i+1; //on avance d'un pixel
       lum1 = analogRead(Vout); //on releve la tension de ce pixel
       poslum1 = i; //on garde la position du pixel
       if (lum > lum1) //Comparer les deux tensions
       pic_lum = i; //prendre position avec plus haute tension
       else pic_lum = poslum; //si infèrieur prendre l'autre pixel
       pic_lum = i-1; //position du pixel précédent (si plus tension plus élevée)

Ca n'a rien à voir avec le programme que je t'ai suggéré.

Et est-ce que je ne pourrais pas plutôt faire un relevé de l'ensemble des tensions pour chaque pixel en ne gardant que la plus grande ? comment puis-je écrire cela? Je ne sais pas comment faire

J’ai réessayé en corrigeant la boucle for, pardon pour ma nullité :

void mesure(){
  i = 0; //on se place au pixel 1
  for(int i = 0;i < 33;i++){      // 33 premiers clock inutiles (voir doc ilx551a)
       digitalWrite(clock,LOW); //Niveau logique bas sur clock
       delay(10); 
       digitalWrite(clock,HIGH); //niveau logique haut
       delay(10);
    
  }
  i = 33; //on se place au pixel 33 (33 inutiles)
 for(int i=33; i<2047; i++){     // mesure des 2048 pixels utiles
       digitalWrite(clock,LOW); //niveau logique bas sur clock
       delay(10); 
       digitalWrite(clock,HIGH);
       delay(10); 
       lum = analogRead(Vout); //acquérir tension de Vout
 if (lum > lum) ; 
       pic_lum=i;
       
}
}

Tu as vu ce que tu mets là: if (lum > lum) ; Relis le pprogramme que je propose et essaie de le comprendre.
Tu dois comparer à la plus grande valeur (obtenue précédemment).

// *****************************mesure*****************************
 void mesure(){
  i = 0; //on se place au pixel 1
  for(int i = 0;i < 33;i++){      // 33 premiers clock inutiles (voir doc ilx551a)
       digitalWrite(clock,LOW); //Niveau logique bas sur clock
       delay(10); 
       digitalWrite(clock,HIGH); //niveau logique haut
       delay(10);
    
  }
  i = 33; //on se place au pixel 34 (33 inutiles)
 for(int i=33; i<2047; i++){     // mesure des 2048 pixels utiles
       digitalWrite(clock,LOW); //niveau logique bas sur clock
       delay(10); 
       digitalWrite(clock,HIGH);
       delay(10); //REVOIR HERTZ
       lum = analogRead(Vout); //acquérir tension de Vout
       if(lum>lummax);
       lummax= lum;
}

J’ai introduit int lumax = 0 en init, est-ce que c’est mieux ?

non

Je ne sais plus rien faire de plus franchement...Je ne vois pas l'erreur

J'ai l'impression que tu ne comprends pas ce que tu programmes, fais un copié/collé de ce que je t'ai proposé.

Si j'ai compris le fonctionnement mais du mal à le traduire, la différence n'était pas énorme entre les deux programmes et je ne l'ai pas regardé au début pour essayer de comprendre seule.
En tout cas merci de ton aide, j'ai donc copié collé ce que tu disais.

Après il te faudra accélerer la clock que tu génères car la suivant la datasheet la valeur typique est 1µs donc avec test 10ms tu perds beaucoup de temps pour lire le capteur.

Je l’ai modifié sur le programme, je l’avais remarqué :

#include <Wire.h> //inclusion de la libraire Wire (protocole I2C / TWI)
#include <LiquidCrystal_I2C.h> //inclusion librairie écran LCD
LiquidCrystal_I2C lcd(0x27,20,4); //definir adresse LCD ) 0x27 pour un affichage de 
#define Vout A0 // Vout sur broche A0
boolean rog = 3; //Rog sur broche 3
boolean clock =2; //Clock sur broche 2
float n, D, B; //n,D,B en float
int i, Ntemp; //déclarer i et Ntemp
int lum; //lum est la tension sur Vout (sortie)
int poslum; //position du pixel le plus luminneux
int lummax; //lummax est la plus grande tension en sortie

void setup(){
  lcd.begin(20,4);  // init lcd 20 caractères 4 lignes
  lcd.backlight(); //  retro éclairage on  
  Serial.begin(9600); //Conexon série 9600 bauds
}

void loop(){  
  lcd.setCursor(1,0); //position curseur
}
//****************depart mesure**********************************
void depart_mesure(){ 
   digitalWrite(rog,HIGH);
   digitalWrite(clock,HIGH);
   delay (10);
   digitalWrite(rog,LOW);
   delay (10);
   digitalWrite(rog,HIGH);
   delay (10);

}
// *****************************mesure*****************************
void mesure() {
  i = 1; //on se place au pixel 1
  while (i < 34) {  // 33 premiers clock inutiles (voir doc ilx551a)
    digitalWrite(clock, LOW); //Niveau logique bas sur clock
    delayMicroseconds(1);
    digitalWrite(clock, HIGH); //niveau logique haut
    delayMicroseconds(1);
    i = i + 1; //incrémentation (on change de pixel)

  }
  i = 34; //on se place au pixel 34 (33 inutiles)

  int lumMax=0;
  for (;i < 2049; i++) { // mesure des 2048 pixels utiles
    digitalWrite(clock, LOW); //niveau logique bas sur clock
    delayMicroseconds(1);
    digitalWrite(clock, HIGH);
    delayMicroseconds(1); 
    lum = analogRead(Vout); //acquérir tension de Vout
    if (lum>lumMax)
    {
      // on a trouvé un pixel plus lumineux que le dernier qu'on avait trouvé
      poslum=i;
      lumMax=lum;
      lcd.print(i);
      delay(1000);
    }

L’ensemble te paraît correct ?
J’ai mis un gros délai pour l’affichage de i histoire de voir s’il détecte bien la position.

Oui, pour la recherche du max, ça semble correct, maintenant pour la lecture du CCD je n'ai pas regardé, mais à mon avis tu peux réduire fortement les delais c'est à dire remplacer delay(10) par delayMicroseconds(10) ce qui diminue le temps par 1000.