見出し画像

ArduinoとSTM32マイコンをつないでマイコンシステム開発をしてみる その19 ~検証実験⑪~

 マイコンシステム開発の要件定義から総合テストまでの工程をたどってみます。
 題材としては、空調管理システムにします。
 機材はいま手元にあるArduino1台とSTM32マイコン1台を使います。

Arduino UNO
STM32

実装に入る前に検証実験をおこないます


以下の3点をおこないます。
① STM32で計測した気温データをSPI通信でArduinoに送信。
 1)STM32単体で、計測した気温データをUSB経由で端末エミュレータに出力。(完了)
 2)SPI通信でSTM32からArduinoにテストデータを送信。(完了
② Arduinoは気温データを受信し、LCDに表示。
 1)LCDに文字を出力するテスト(完了)
 2)受信した気温データをLCDに表示(今回行います)
③ ArduinoからSTM32に制御データを送信し、LEDを点灯。


前回はLCDをブレットボードに配線し、文字を出力するテストをおこないました

今回、Arduinoは気温データを受信し、LCDに表示します。

1.プログラムを作成します

① 気温データを送信するSTM32側のプログラム

  while (1)
  {
		/* 温度測定モードを設定 */
		i2cbuf[0] = 0x11; // CTRL_REG2 レジスタアドレス
		HAL_I2C_Mem_Write(&hi2c1, I2C_ADDR_W, 0x11, I2C_MEMADD_SIZE_8BIT, i2cbuf, 1, 1000);

	    /* 測定が完了するまで待機 */
	    while (1) {
	        i2cbuf[0] = 0;
	        HAL_I2C_Mem_Read(&hi2c1, I2C_ADDR_R, 0x27, I2C_MEMADD_SIZE_8BIT, i2cbuf, 1, 1000);
	        if ((i2cbuf[0] & 0x03) == 0x03) {
	            break; // 測定完了
	        }
	        HAL_Delay(10);
	    }
	    /* 温度データを取得 */
	    HAL_I2C_Mem_Read(&hi2c1, I2C_ADDR_R, 0x2B, I2C_MEMADD_SIZE_8BIT, i2cbuf, 2, 1000);
	    int16_t raw_temp = (int16_t)((i2cbuf[1] << 8) | i2cbuf[0]); // 2の補数形式のデータを取得

	    /* 温度を°Cに変換 */
	    float temperature_celsius = raw_temp / 100.0f;
	    /* 今回は整数部だけを送信 */
	    data = (uint8_t)temperature_celsius;

	    /* SSピンをLOWに設定して通信を開始 */
	    HAL_GPIO_WritePin(SS_PORT, SS_PIN, GPIO_PIN_RESET);

	    /* SPIデータ送信 */
	    if (HAL_SPI_Transmit(&hspi1, &data, 1, HAL_MAX_DELAY) != HAL_OK) {
	        /* エラー処理 */
	        Error_Handler();
	    }else{
	        snprintf(msgbuf, sizeof(msgbuf), "temperature=%.1f°C\r\n", temperature_celsius);
	    	CDC_Transmit_FS((uint8_t *)msgbuf, strlen(msgbuf));
	    }

	    /* SSピンをHIGHに設定して通信を終了 */
	    HAL_GPIO_WritePin(SS_PORT, SS_PIN, GPIO_PIN_SET);

	    /* 1秒待機 */
	    HAL_Delay(1000);
  }

今回は、センサーで検知した気温データの整数部分のみを送信します。

② 気温データを受信するArduino側のプログラム

#include <SPI.h>
#include <LiquidCrystal.h>

volatile byte receivedData;
volatile bool dataAvailable = false;

// LiquidCrystalオブジェクトの作成(ピン指定)
LiquidCrystal lcd(8, 9, 7, 6, 5, 4);

void setup() {
    Serial.begin(9600);
    Serial.println("SPI Slave Initialized");

    // SPIスレーブの初期化
    pinMode(MISO, OUTPUT);
    SPCR |= _BV(SPE); // SPI Enable
    SPCR &= ~_BV(MSTR); // スレーブモード

    // 割り込みでデータ受信
    SPCR |= _BV(SPIE);

    lcd.begin(16, 2); // LCDを16x2モードで初期化
}

ISR(SPI_STC_vect) {
    receivedData = SPDR; // 受信データを取得
    dataAvailable = true;
}

void loop() {
    if (dataAvailable) {
        // シリアルモニタに出力
        Serial.print("Received Data: ");
        Serial.println(receivedData);
        dataAvailable = false;
        // LCDに出力
        lcd.clear();
        lcd.print(receivedData); 
    }
}

2.実行

送信も受信も問題ありません。
シリアルモニタに出力されてます。

 23℃がシリアルモニタに表示

LCDの表示も問題ありません。

 23が表示

検証実験、成功です。

次の検証実験へ進みます。


いいなと思ったら応援しよう!