回路を知る | |
---|---|
![]() |
4つあるうちの一つの回路。左側がLEDを点灯させる回路。右側が光の検出回路。RAS17とAD0に繋がっていることが分かります。 LEDのRAS17~20はP2コネクタのそれぞれ7,11,13,15に繋がっています。 |
![]() |
4つのセンサーからの信号はAD0~AD3に入力されます。このICを制御するのはSPI(Serial Peripheral InterfaceModule)というプロトコルで行います。GPIO11、MISO、MOSI、GPIO8の信号で制御されているのが分かります。 GPIO11は23pin、MISOは21pin、MOSIは19pin、GPIO8は24pinに繋がっています。 ここで用いているRaspberryPiDotNetライブラリにはmcp3208を制御するクラスはありませんが、mcp3008を制御するクラスがあります。この違いはmcs3208は12bit精度でmcs3008は10bit精度の違いだけですので、クラスはそのまま使えます。 |
メインプログラム | |
---|---|
public static void Main (string[] args) { GPIOMem[] LED = new GPIOMem[4]; LED[0] = new GPIOMem (GPIOPins.V2_Pin_P1_07); LED[1] = new GPIOMem (GPIOPins.V2_Pin_P1_11); LED[2] = new GPIOMem (GPIOPins.V2_Pin_P1_13); LED[3] = new GPIOMem (GPIOPins.V2_Pin_P1_15); for (int i = 0; i < LED.Length; i++) LED [i].PinDirection = GPIODirection.Out; GPIOMem SPICLK = new GPIOMem (GPIOPins.V2_Pin_P1_23); SPICLK.PinDirection = GPIODirection.Out; GPIOMem SPIMISO = new GPIOMem (GPIOPins.V2_Pin_P1_21); SPIMISO.PinDirection = GPIODirection.In; GPIOMem SPIMOSI = new GPIOMem (GPIOPins.V2_Pin_P1_19); SPIMOSI.PinDirection = GPIODirection.Out; GPIOMem SPICS = new GPIOMem (GPIOPins.V2_Pin_P1_24); SPICS.PinDirection = GPIODirection.Out; double read_adc = 0.0; MCP3008 mcp3208; while (true) { for (int adcnum = 0; adcnum < 4; adcnum++) { LED [adcnum].Write (true); Thread.Sleep (10); mcp3208 = new MCP3008 (adcnum, SPICLK, SPIMOSI, SPIMISO, SPICS); read_adc = mcp3208.AnalogToDigital; Thread.Sleep (300); LED [adcnum].Write (false); double millivolts = (Convert.ToDouble (read_adc) / 4096.0) * 3.3; Console.Write ("{0}ch{1,6:f3}, ", adcnum, millivolts); } Console.WriteLine (); } } |
1 2 3 GPIOMemの配列を作る 4 ピン制御のオブジェクトを作る 5 6 7 8 9 出力に設定する 10 11 クロックのオブジェクト 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 ADコンバータのオブジェクト 28 29 30 31 32 33 34 35 36 |
ADコンバータのクラス | |
---|---|
public class ADcon { static GPIOMem[] LED = new GPIOMem[4]; static GPIOMem SPICLK = new GPIOMem (GPIOPins.V2_Pin_P1_23); static GPIOMem SPIMISO = new GPIOMem (GPIOPins.V2_Pin_P1_21); static GPIOMem SPIMOSI = new GPIOMem (GPIOPins.V2_Pin_P1_19); static GPIOMem SPICS = new GPIOMem (GPIOPins.V2_Pin_P1_24); public static double[] distance = new double[4]; public ADcon() { LED[0] = new GPIOMem (GPIOPins.V2_Pin_P1_07); LED[1] = new GPIOMem (GPIOPins.V2_Pin_P1_11); LED[2] = new GPIOMem (GPIOPins.V2_Pin_P1_13); LED[3] = new GPIOMem (GPIOPins.V2_Pin_P1_15); for (int i = 0; i < LED.Length; i++) LED [i].PinDirection = GPIODirection.Out; SPICLK.PinDirection = GPIODirection.Out; SPIMISO.PinDirection = GPIODirection.In; SPIMOSI.PinDirection = GPIODirection.Out; SPICS.PinDirection = GPIODirection.Out; } public static void adGet(object state) { MCP3008 mcp3208; for (int adcnum = 0; adcnum < LED.Length; adcnum++) { LED [adcnum].Write (true); Thread.Sleep (10); mcp3208 = new MCP3008 (adcnum, SPICLK, SPIMOSI, SPIMISO, SPICS); distance[adcnum] = mcp3208.AnalogToDigital; LED [adcnum].Write (false); } } } |
1 2 3 LEDを入れる配列を作る 4 制御信号オブジェクトを作る 5 6 7 8 測定データを入れる配列 9 10 コンストラクタ 11 12 LEDのオブジェクトを作る 13 14 15 16 17 LEDを出力に設定 18 各制御信号の入出力の設定 19 20 21 22 23 24 各ADコンバータの値を読み取る 25 26 ADコンバータのクラス 27 28 29 30 31 32 33 34 35 36 |
距離測定メインプログラム | |
---|---|
public static void Main(string[] args) { new ADcon (); // 一定間隔ごとに呼び出すメソッドをTimerCallbackとして登録 TimerCallback timerCallback = new TimerCallback(ADcon.adGet); // 100milli秒ごとにtimerCallbackメソッドを呼び出す new Timer(timerCallback, null, 0, 100); while (true) { Thread.Sleep (500); for (int i = 0; i < ADcon.distance.Length; i++) { double millivolts = (ADcon.distance [i] / 4096.0) * 3.3 * 1000; Console.Write ("{0}ch{1,6:f1},{2} ", i, millivolts, ADcon.distance [i]); } Console.WriteLine (); } } |
1 2 3 ADコンバータのオブジェクトを作る 4 5 コールバックの登録 6 7 8 タイマーで定期的に測定する 9 10 11 測定結果を表示する 12 13 14 15 16 17 |