Bonjour à tous et toutes,
C'est mon premier post ici donc je tâcherai d'être le plus clair possible.
Pour un projet perso je souhaite interfacer un Arduino esp32 nano avec le capteur CCd toshiba TCD1304.
J'y suis arrivé, malgré la datasheet plutôt obscure j'obtiens mon signal de TCD1304.
Cependant mon signal capteur est évidemment analogique et au vue de la fréquence l'ADC intégrée à l'esp elle n'est pas suffisante
Avec le temps d'intégration le plus lent le capteurs envoie les signaux des pixels en 14ms. Compte tenu du nombre de pixel (~3700) cela me fais un fréquence de 264 000Hz minimum pour mon ADC.
J'ai donc dû utiliser un convertisseur externe, dans mon cas le ADS7818.
J'utilise le protocole SPI afin d'interfacer l'ADC, cependant les valeurs numérique ressemble plus à du bruit qu'autre chose. J'ai pourtant vérifier que la période de capture se déroule bien lorsque la barrette CCD envoie la valeurs des pixels.
(j'ai vérifier que mon signal analogique du CCD est bien en entré de broche +In)
Je ne sais plus où chercher si vous pourriez m'aider ou me donner des pistes cela m'aiderai grandement !
Questions:
-
Appeler les fonction ADC_setup ainsi que TCD_setup dans void setup(), ne donne pas le résultat attendu : mon signal SH ne se lance pas. Mais lorsque j'appelle les fonctions dans void loop() SH se lance correctement.
-
Mon signal ICG qui permet de "réinitialiser" la barette CCD est très irrégulier et se lance deux fois à 1.5 microseconde d'écarts (voire image 1).
Mais l'écart en plus de ces 2 impulsions sont irrégulier (voire image 2 signal jaune).
- Mon ADC convertie une sorte de bruit:
Je vérifie pourtant la période de conversion à l'aide du pin 20 dans la fonction ADC_converter qui reste à l'état HIGH du début jusqu'à la fin de la conversion.
Voici une image des signaux SCK en vert et CS en jaune:
- Afin d'avoir un réel délais entre chaque capture de 600ms nécessaire à l'envoie des données via le port série je dois mettre un délais de 200ms et non 600ms (lorsque je renseigne 600ms le délais entre chaque capture est >1s).
J'espère avoir été le plus clair possible ! Si des informations importantes manque n'hésitez pas à me le faire remarquer.
main.cpp
/* Problème capture de bruit par ADC environs 20% du temps
Peux aussi être problème de synchro TCD avec ICG
*/
#include "Arduino.h"
#include "ADC.h" //Inclus les fonctions concernant l'ADC
#include "TCD.h" //Inclus les fonctions concernant le TCD
#include "LED.h" //Inclus les fonctions de controle de LED
unsigned long currentTime = 0;
unsigned long previousTime = 0;
void setup() {
//Unique set-up de tous les sous-programmes
Serial.begin(115200); //Initialise la fréquence de communication série
delay(1);
LED_setup();//Initialise les pin et la config des LEDS
//ADC_setup();
//TCD_setup();//Ne fonctionne pas correctement dans setup
}
void loop() {
//LED_select(1); //Selection de la LED
//LED_power(250);// selection de l'intensité
currentTime= millis();
if (currentTime- previousTime >= 200){//L'affichage des valeurs via le port série prend environs 600ms
previousTime= currentTime;
ADC_setup();
TCD_setup();
ADC_converter();
TCD_clock();
}
delay(1);
}
TCD.cpp
//TCD13 04
#include "TCD.h"
const short pinSH = 2;
const short pinmasterclock = 3; // Pin de sortie
const short pinICG = 4;
const int frequency_SH = 20000; //Tint min 20kHz
const int frequency_master = 925926; // 1 MHz /925926
const short pwmmasterclock = 2;
const short pwmSH = 1;
const short resolution = 1; // Résolution en bits des signaux d'horloges utilisant le PWM
int currentTime_TCD;
int lastSampleTime_TCD = 0;
const short samplingInterval_TCD = 8;
void TCD_setup() {
pinMode(pinmasterclock, OUTPUT);
pinMode(pinSH, OUTPUT);
pinMode(pinICG, OUTPUT);
// Configurer les canaux PWM
ledcSetup(pwmmasterclock, frequency_master, resolution);
// Attacher le canal PWM au pin spécifié
ledcAttachPin(pinmasterclock, pwmmasterclock);
// En résolution 1 bit, 1 signifie 50%
ledcSetup(pwmSH, frequency_SH, resolution);
// Attacher le canal PWM au pin spécifié
ledcAttachPin(pinSH, pwmSH);
}
void TCD_clock() {
ledcWrite(pwmmasterclock, resolution);
digitalWrite(pinICG, LOW);
ledcWrite(pwmSH, resolution); // En résolution 1 bit, 1 signifie 50%
delayMicroseconds(6);
digitalWrite(pinICG, HIGH);
}
ADC.cpp
//ADC ADS7818
#include "ADC.h"
// Définir les broches SPI personnalisées
#define SCK_PIN 13
#define MISO_PIN 12 //ESP32 nano pin pour SPI définis
#define MOSI_PIN 11
#define CS_PIN 10
#define SPI_FREQUENCY 8000000
const unsigned long samplingInterval_ADC = 0.1; //intervalle échantillonage en microsecondes
const unsigned int numSamples = 4000; //nombre d'échantillons attendu
uint16_t samples[numSamples]; //Tableau stockage échantillons
short tempsTot;
float volt;
int sampleIndex;
//Défini les différents state de la machine à état
enum State { INI,
CAPTURE,
AFFICHAGE };
State adcState = INI; //Défini l'état initiale de la machine à état
//Sous-fonction d'initialisation de l'interfaçage avec l'ADC
void ADC_setup() {
pinMode(20, OUTPUT); //Permet le controle de la période de conversion
pinMode(CS_PIN, OUTPUT);// Initialisation de la broche CS
digitalWrite(CS_PIN, HIGH);
// Initialisation du SPI avec les broches définis
SPI.begin(SCK_PIN, MISO_PIN, MOSI_PIN, CS_PIN);
}
//Sous-fonction permettant le transfert des données via la liaison série
//On attends des données sur 16bits
void ADC_display(uint16_t* data) {
for (unsigned int i = 0; i < numSamples; i++) {
volt = samples[i];
Serial.print(volt);
Serial.print(" ");
}
Serial.println("end");
}
//Lance le protocole de communication ainsi que les signaux/horloges permettant la conversion des données
//Stock les données dans la matrice "samples[]" jusqu'à atteindre numSamples définie
void ADC_converter() {
switch (adcState) {
case INI:
SPI.beginTransaction(SPISettings(SPI_FREQUENCY, MSBFIRST, SPI_MODE2)); // Définir les paramètres SPI (fréquence, ordre des bits, mode SPI)
adcState = CAPTURE; //Une fois les settings effectués change d'état
break;
case CAPTURE:
digitalWrite(20, HIGH); //VERIFIE DECALLAGE ENTRE SH ET ADC
for (sampleIndex = 0; sampleIndex < numSamples; sampleIndex++) {
digitalWrite(CS_PIN, LOW);
//On attends un entier de 12bits mais 16bits est envoyé
//Décallage de 3 bits de poids faibles
samples[sampleIndex] = SPI.transfer16(0x0000) >> 3;
digitalWrite(CS_PIN, HIGH);
delayMicroseconds(samplingInterval_ADC);
}
SPI.endTransaction(); //Termine la communication via SPI une fois la matrice complété
digitalWrite(20, LOW); //VERIFIE DECALLAGE ENTRE SH ET ADC
//ADC_display(samples); //Appel la fonction d'envoie sur la liaison série les données
adcState = AFFICHAGE; //Une fois les données récupérées change d'état
break;
case AFFICHAGE:
ADC_display(samples); //l'affiche prend environs 600ms a être effectué ce cette manière
adcState = INI; //Reinitialise l'état afin de convertir des données
break;
}
}