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 Select Authentication System). 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, 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.
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 ");
}
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)
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 ?
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.