北東北 LabVIEWユーザー会

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

Control of the line sensor ILX511 using MicroPython and display of spectroscopic data using LabVIEW

昨日からBing AIを使いだしたのでタイトルを考えてもらいました。

MicroPythonによるラインセンサILX511の制御とLabVIEWによる分光データの表示

 

main.png

 

ラインセンサの制御とADCのタイミングはほぼESP32 + Arduino IDEでのプログラミングと似たような感じでできました。MicroPythonではPWM出力のパルスのエッジで割り込みをかけることができなかったので、PWM出力を別のピンの入力にワイヤーで接続してそのピンの割り込みを使いました。一応動くようになりましたが、PCへのデータ出力が最大の難関で、2000個ぐらいのデータなのに1.5秒ぐらいかかっています。

ESP32 + Arduino IDEに対して優位性はありませんが、MicroPythonを使うときの備忘録としてアップします。

 

配線

ILX511の駆動はCLKが14ピン、ROGが27ピンとしました。Voutは28ピンのADCを使いました。CLK用のPWMは15ピンで生成しています。ADCの割り込みとして26ピンを使いました。15ピンのPWM信号を26ピンに結線しています。


M6140117.JPG     M6140119.JPG

下左のオシロスコープ画面はCLKがオレンジ、ROGが青です。下右のオシロスコープ画面はVoutがオレンジ、ROGが青です。

F0001TEK.BMPF0000TEK.BMP

 

MicroPythonプログラムはRP2040のUSBメモリ状態のエリアにmain.pyとしてコピーすれば自動的に起動してくれます。

スクリーンショット 2023-06-14 15.56.16.png

 

import utime
from machine import Pin, PWM, Timer, ADC

CLK_PIN = 14 #PWM 7A
TRIG_PWM_PIN = 15 #PWM 7B
TRIG_IRQ_PIN = 26 #INPUT Connected to TRIG_PWM_PIN
ROG_PIN = 27 #ROG
READ_VOUT_PIN = 28

CLK_PWM_FRQ = 10000
CLK_PWM_DUTY = int(65535*0.5)
TRIG_PWM_FREQ = CLK_PWM_FRQ
TRIG_PWM_DUTY = CLK_PWM_DUTY

ROG_WIDTH = 100 #100μsec
ROG_INTRVAL_MS = 1700 #500msec(reading:200msec, sending:1500msec)

pulse_CLK = Pin(CLK_PIN, Pin.OUT)
trig_irq = Pin(TRIG_IRQ_PIN, Pin.IN)
pulse_ROG = Pin(ROG_PIN, Pin.OUT)

PIXELS = 2086
data_count = 0
sensorValue = 0
rising_Edge=True

pixelArray = bytearray(PIXELS * 2)
HEADER = bytearray([0x00, 0x00, 0xFF, 0xFF])

def rising_CLK(pin):
    global rising_Edge
    rising_Edge = True

def read_vout(pin):
    global sensorValue, sensorValue12it,pixelArray, data_count
    sensorValue = ADC(READ_VOUT_PIN).read_u16()
    sensorValue12it = sensorValue >> 4
    pixelArray[data_count * 2] = (sensorValue12it >> 😎 & 0xFF
    pixelArray[data_count * 2 + 1] = sensorValue12it & 0xFF
    data_count += 1

def writeArrayData():
    for i in range(4):
        print('{:02X}'.format(HEADER[i]), end="")
    
    for i in range(PIXELS):
        print('{:02X}'.format(pixelArray[i*2]), end="")
        print('{:02X}'.format(pixelArray[2*i+1]), end="")
        

trig_pwm = PWM(Pin(TRIG_PWM_PIN))
trig_pwm.freq(TRIG_PWM_FREQ)
trig_pwm.duty_u16(TRIG_PWM_DUTY)

while True:
    start = utime.ticks_ms()
    data_count = 0
    
    pulse_CLK.low()
    utime.sleep_us(50)
    pulse_CLK.high()
    utime.sleep_us(50)
    
    pulse_ROG.high()
    pulse_CLK.low()
    utime.sleep_us(ROG_WIDTH)
    pulse_ROG.low()
    
    rising_Edge = False
    trig_irq.irq(rising_CLK,Pin.IRQ_RISING)
    while (rising_Edge == False):
        pass
    pulse_CLK.high()
    trig_irq.irq(handler=None)
    
    clk_pwm = PWM(Pin(CLK_PIN))
    clk_pwm.freq(CLK_PWM_FRQ)
    clk_pwm.duty_u16(CLK_PWM_DUTY)
    
    trig_irq.irq(read_vout,Pin.IRQ_FALLING)
    while (data_count < PIXELS):
        pass
    
    trig_irq.irq(handler=None)
    pulse_CLK = Pin(CLK_PIN, Pin.OUT)
    pulse_CLK.high()
    
    writeArrayData()
    
    while(utime.ticks_diff(utime.ticks_ms(), start) < ROG_INTRVAL_MS):
        pass

 

RP2040 + MicroPythonの(私にとっての)最大のネックはprint()関数がバイトデータをそのまま送り出してくれず、UTF-8に変換して0x80から0xFFまでが2バイトで送られることです。この辺りの対処法がわかる方はぜひ教えてください。今回は0からFまで英数字で送っていますので1.7秒間隔ですが、対応策があれば1秒間隔ぐらいで動作すると思います。

 

それともう一つ驚いたのがADCの出力で、12ビットADCなのにrp2040用MicroPythonでは16ビットに拡大して出力しています。他のマイコンに合わせたということです。

 

MicroPythonプログラムとLabVIEWプログラムを添付します。動作確認はMac版のLabVIEW Community2022で行っています。

 

スクリーンショット 2023-06-14 17.28.59.pngスクリーンショット 2023-06-14 17.26.52.png

 

 

0 件の賞賛
メッセージ1/1
1,140件の閲覧回数