注釈

こんにちは、SunFounder Raspberry Pi & Arduino & ESP32 愛好者コミュニティ(Facebook)へようこそ!Raspberry Pi、Arduino、ESP32 をさらに深く学び、仲間と交流しましょう。

参加する理由

  • 専門的な支援: 購入後の問題や技術的な課題を、コミュニティやチームの助けで解決できます。

  • 学びと共有: 技術や工夫を交換し、知識を広げることができます。

  • 限定の先行情報: 新製品のお知らせや先行公開をいち早く入手できます。

  • 特別割引: 最新製品を会員限定の割引で入手できます。

  • 祭りや贈り物企画: 季節ごとの企画や贈り物イベントに参加できます。

👉 一緒に探求し、ものづくりを楽しみましょう!こちらから参加してください → [ここ]

2.2.1 フォトレジスタ (MCP3008)

注釈

_images/mcp3008_and_adc0834.jpg

キットの種類によって ADC0834 または MCP3008 が含まれています。必ず手元の部品を確認し、対応する章に進んでください。

はじめに

フォトレジスタは生活の中で周囲の明るさを検出するために広く使われる部品です。 昼夜を検知し、常夜灯のような光制御に利用されます。 この実験は可変抵抗器の実験とよく似ており、電圧の変化を利用して光を検知します。

必要な部品

_images/list2_2.2.1_photoresistor.png

原理

フォトレジスタ(光依存抵抗)は光で抵抗値が変化する素子です。 入射する光が強くなるほど抵抗値は低下し、光導電性を示します。 光検出回路や明暗によって切り替わる回路に広く利用されます。

_images/image1961.png

回路図

T-Board 名称

物理ピン

WiringPi

BCM

SPICE0

pin24

10

8

SPIMOSI

pin19

12

10

SPIMISO

pin21

13

9

SPISCLK

pin23

14

11

GPIO22

pin15

3

22

_images/schematic_2.2.1_photoresistor_mcp3008.png

実験手順

手順1: 回路を組みます。

_images/july24_2.2.1_photoresistor_mcp3008.png

C言語の場合

手順2: コードのあるフォルダに移動します。

cd ~/davinci-kit-for-raspberry-pi/c/2.2.1-2/

手順3: コンパイルします。

gcc 2.2.1_Photoresistor.c -o photoresistor -lwiringPi -lm

手順4: 実行します。

./photoresistor

実行すると、フォトレジスタが検知した光の強さに応じて LED の明るさが変化します。

注釈

「wiringPi.h が見つかりません」というエラーが出た場合は wiringPi のインストールと確認 を参照してください。

コード

#include <wiringPi.h>
#include <wiringPiSPI.h>
#include <stdio.h>
#include <softPwm.h>

#define SPI_CHANNEL 0
#define SPI_SPEED   1000000
#define LedPin      3

int readMCP3008(int channel) {
    if (channel < 0 || channel > 7) return -1;

    unsigned char buffer[3];
    buffer[0] = 1;
    buffer[1] = (8 + channel) << 4;
    buffer[2] = 0;

    wiringPiSPIDataRW(SPI_CHANNEL, buffer, 3);

    int result = ((buffer[1] & 3) << 8) | buffer[2];
    return result;
}

int main(void) {
    if (wiringPiSetup() == -1) {
        printf("wiringPi 初期化失敗!\n");
        return 1;
    }

    if (wiringPiSPISetup(SPI_CHANNEL, SPI_SPEED) == -1) {
        printf("SPI 初期化失敗!\n");
        return 1;
    }

    softPwmCreate(LedPin, 0, 100);

    while (1) {
        int analogVal = readMCP3008(0);
        printf("ADC 値: %d\n", analogVal);

        int pwmVal = analogVal * 100 / 1023;
        softPwmWrite(LedPin, pwmVal);

        delay(100);
    }

    return 0;
}

コード解説

このコードは 2.1.4 可変抵抗器 (MCP3008) で説明した内容と同じです。詳しくはそちらを参照してください。

Pythonの場合

手順2: SPI を設定し、 spidev をインストールしてください(詳細は SPI 設定 を参照)。

手順3: コードのあるフォルダに移動します。

cd ~/davinci-kit-for-raspberry-pi/python

手順4: 実行します。

sudo python3 2.2.1-2_photoresistor.py

実行すると、フォトレジスタが検知した光の強さに応じて LED の明るさが変化します。

警告

RuntimeError: Cannot determine SOC peripheral base address というエラーが出た場合は 「gpiozero」が動作しない場合。 を参照してください。

コード

#!/usr/bin/env python3

import RPi.GPIO as GPIO
import spidev
import time

PWM_PIN = 22

GPIO.setmode(GPIO.BCM)
GPIO.setup(PWM_PIN, GPIO.OUT)

pwm = GPIO.PWM(PWM_PIN, 1000)
pwm.start(0)

spi = spidev.SpiDev()
spi.open(0, 0)
spi.max_speed_hz = 1000000

def read_adc(channel):
    if channel < 0 or channel > 7:
        return -1
    r = spi.xfer2([1, (8 + channel) << 4, 0])
    value = ((r[1] & 3) << 8) | r[2]
    return value

try:
    while True:
        analogVal = read_adc(0)
        print(f"value = {analogVal}")

        duty_cycle = analogVal * 100 / 1023
        pwm.ChangeDutyCycle(duty_cycle)

        time.sleep(0.2)

except KeyboardInterrupt:
    pass

finally:
    pwm.stop()
    GPIO.cleanup()
    spi.close()

コード解説

  1. ライブラリを読み込みます。

    • RPi.GPIO : GPIO 制御と PWM 出力

    • spidev : MCP3008 と SPI 通信

    • time : 待機処理

    #!/usr/bin/env python3
    
    import RPi.GPIO as GPIO
    import spidev
    import time
    
  2. GPIO22 を PWM 出力として設定し、周波数 1000Hz で開始します。

    # GPIO pin for PWM LED
    PWM_PIN = 22
    
    # Setup GPIO
    GPIO.setmode(GPIO.BCM)
    GPIO.setup(PWM_PIN, GPIO.OUT)
    
    # Initialize PWM (frequency = 1000Hz)
    pwm = GPIO.PWM(PWM_PIN, 1000)
    pwm.start(0)  # Start with 0% duty cycle
    
  3. SPI をバス0、CE0 で初期化し、速度を 1MHz に設定します。

    # Initialize SPI (MCP3008 on Bus 0, CE0)
    spi = spidev.SpiDev()
    spi.open(0, 0)
    spi.max_speed_hz = 1000000  # 1 MHz
    
  4. read_adc() 関数で MCP3008 の指定チャンネルから 0–1023 の値を取得します。

    # Function to read MCP3008 ADC value
    def read_adc(channel):
        """
        Read analog value from MCP3008 (channel 0–7)
        Returns: 10-bit value (0–1023)
        """
        if channel < 0 or channel > 7:
            return -1
        r = spi.xfer2([1, (8 + channel) << 4, 0])
        value = ((r[1] & 3) << 8) | r[2]
        return value
    
  5. メインループでは CH0 の値を読み取り、PWM デューティ比に変換し LED の明るさを調整します。0.2秒ごとに更新します。

    # Main loop to read ADC and set PWM brightness
    try:
        while True:
            analogVal = read_adc(0)
            print(f"value = {analogVal}")
    
            # Scale ADC value (0–1023) to duty cycle (0–100)
            duty_cycle = analogVal * 100 / 1023
            pwm.ChangeDutyCycle(duty_cycle)
    
            time.sleep(0.2)
    
  6. Ctrl+C で終了すると PWM と GPIO を解放し、SPI を閉じます。

    except KeyboardInterrupt:
        pass
    
    finally:
        pwm.stop()
        GPIO.cleanup()
        spi.close()