北東北 LabVIEWユーザー会

キャンセル
次の結果を表示 
次の代わりに検索 
もしかして: 

2048ピクセルのCCDラインセンサILX511(SONY)をESP32で制御してLabVIEWで分光データを受け取る

ILX511はTCD1304に比べて画素幅が8μmから14μmに大きくなって画素数が3648から2048に少なくなっています。

 

TCD1304を使った記事は https://forums.ni.com/t5/北東北-LabVIEWユーザー会/分光器のラインセンサー-TCD1304-をESP32で制御して分光データをLabVIEW-Communityで受け取... です。

センサー変更で感度を幾らかでも上げたいというマツラボさんの希望でILX511を試してみることにしました。

分光器への取り付け基板です。74HC04を介していますのでESP32からの信号は反転させています。データを受け取るLabVIEWプログラムは基本的にTCD1304用と同じですので、ESP32のプログラムがこの記事での新しい部分です。今回はArduino IDE 1.8.19を使用して、500msec間隔で動作させています。

 

ILX511LIS.JPG

 

 

//Koji Ohashi MaDA Lab@Morioka 230507
//ILX511_Esp32230507
//Software:  Arduino IDE 1.8.19
//Software:  Arduino core for the ESP32 2.0.6

//パルス生成:Special thanks to 
//https://www.mgo-tec.com/blog-entry-ledc-pwm-arduino-esp32.html/2
//https://logikara.blog/pwm/
//割り込み処理:Special thanks to
//https://lang-ship.com/blog/work/esp32-freertos-l04-interrupt/

//for SONY ILX511
//バッファ用反転ICが入るのでプログラムのIOは反転
//CLK IO5
//ROG IO18
//Trig_RO IO26 //internal use
//VOUT IO27(Analog In) Trig_ROがFallのタイミングで読む

//ROG
#define ROG_PIN 18
#define ROG_WIDTH 100 //100μsec
#define ROG_INTRVAL_MS 500 //500msec(reading:210msec, sending:180msec)
//CLK
#define CLK_PIN 5 //GPIO #36~#39 は設定不可
#define LEDC_CHANNEL_CLK 0 //CHANNEL_0 (CHANNEL_0とCHANNEL_1は周波数とタイマービットを同一値)
#define LEDC_TIMER_BIT_CLK 6 //6bit--64(0-63)
#define LEDC_BASE_FREQ_CLK 10000.0 //AnalogReadに時間がかかって13kHzが上限
#define DUTY_CLK 32//50% 0x20 = 32

//TrigRO
#define GPIO_PIN_TrigRO 26 //GPIO #36~#39 は設定不可
#define LEDC_CHANNEL_TrigRO 1 //CHANNEL_1 (CHANNEL_0とCHANNEL_1は周波数とタイマービットを同一値)
#define LEDC_TIMER_BIT_TrigRO 6 //6bit--64(0-63)
#define LEDC_BASE_FREQ_TrigRO 10000.0 //AnalogReadに時間がかかって13kHzが上限
#define DUTY_TrigRO 32//50% 0x20 = 32


#define PIXELS 2086
#define ReadRO_PIN 27

int16_t pixelArray[PIXELS];
volatile int read_count=0;
volatile int16_t sensorValue=0;
volatile boolean risingEdge=false;

byte HEADER[]={0x00,0x00,0xFF,0xFF};
byte SendBytes[2];

//割り込み関数***************
//ARDUINO_ISR_ATTRに変更になった

void ARDUINO_ISR_ATTR readRO(){
  sensorValue = analogRead(ReadRO_PIN);
  pixelArray[read_count]=sensorValue;
  read_count++;
}

void ARDUINO_ISR_ATTR risingCLK(){
  risingEdge=true;
}

//割り込み関数***************

void setup() {
  Serial.begin(230400);
  pinMode(ROG_PIN,OUTPUT);
  pinMode(CLK_PIN,OUTPUT);
  pinMode(ReadRO_PIN,ANALOG);
  //CLK 必要な時だけ出力する
  ledcSetup(LEDC_CHANNEL_CLK, LEDC_BASE_FREQ_CLK, LEDC_TIMER_BIT_CLK);

  //TrigRO 割り込みに使用するため常に出力する
  ledcSetup(LEDC_CHANNEL_TrigRO, LEDC_BASE_FREQ_TrigRO, LEDC_TIMER_BIT_TrigRO);
  ledcAttachPin(GPIO_PIN_TrigRO, LEDC_CHANNEL_TrigRO);
  ledcWrite(LEDC_CHANNEL_TrigRO, DUTY_TrigRO);
}
 
void loop() {
  unsigned long startCLK = millis();
  
  digitalWrite(CLK_PIN,LOW);
  delayMicroseconds(50); //10kHzの周期の1/2
  digitalWrite(CLK_PIN,HIGH);
  delayMicroseconds(50); //10kHzの周期の1/2
  
  digitalWrite(ROG_PIN,HIGH);
  digitalWrite(CLK_PIN,LOW);
  delayMicroseconds(ROG_WIDTH);//100μSec
  digitalWrite(ROG_PIN,LOW);
  // CLKに使うパルスがHIGHになるまで待つ
  risingEdge=false;
  attachInterrupt(GPIO_PIN_TrigRO, risingCLK, RISING); //割り込み開始
  while(risingEdge==false){ //wait rising edge
  }
  digitalWrite(CLK_PIN,HIGH); //CLKをHIGHにする
  detachInterrupt(GPIO_PIN_TrigRO);//割り込み解除
  ledcAttachPin(CLK_PIN, LEDC_CHANNEL_CLK);//CLKパルスを出力
  ledcWrite(LEDC_CHANNEL_CLK, DUTY_CLK);//CLKパルスを出力
  
  read_count=0;
  attachInterrupt(GPIO_PIN_TrigRO, readRO, FALLING);
  //Reading CCD data
  while(read_count < PIXELS){
    //全てのPIXELを読み込むまで待つ
  }
  detachInterrupt(GPIO_PIN_TrigRO);
  ledcDetachPin(CLK_PIN); //CLKパルスを停止
  digitalWrite(CLK_PIN,HIGH); //CLKをHIGHにする
  //Serial.println(read_count);
  //Serial.println(millis()-startCLK);
  
  writeArrayData();
  //Serial.println(millis()-startCLK);
  
  while((millis()-startCLK) < ROG_INTRVAL_MS){
    //wait ROG Interval
  }
  //Serial.println(millis()-startCLK);
}

void writeArrayData(){
  Serial.write(HEADER,4);
  for(int i=0;i<PIXELS;i++){
    sensorValue = pixelArray[i];
    SendBytes[0] = byte(sensorValue);
    SendBytes[1] = byte(sensorValue >> 8);
    Serial.write(SendBytes,2);
  }
}

 

ROG信号(オレンジ)とCLK信号(青)のオシロスコープ画面(左)

ROG信号(オレンジ)とVout(青)のオシロスコープ画面(右)

F0003TEK.BMPF0001TEK.BMP

 

blueData.png

 

ILX511の方が扱いやすいような印象を持ちました。

時間を作って、ラズパイPico互換ボードとMicroPythonで動かしてみたいなと思っています。

 

プログラム一式を添付しました。LabVIEWはCommunity 2023で作ってしまったのでお手数ですがLabVIEW Community 2023をお使いください。

 

メッセージ1/1
1,630件の閲覧回数