2022年12月11日日曜日

2164VCA V2164を使用したVCA(Exp特性)の製作

 CoolAudio社のV2164を使ってVCA(Exponential特性)を製作しました。V2164については「V2164動作確認」で書きました。



回路図

ブレッドボードテスト用配線


工夫した点


  • ピン互換でLinera特性のAS3340も使えるようにフットプリントを追加。JP1、C15。
  • CV入力のオフセットを設定するトリムを追加。RV1。
  • CV入力状態を示すLEDを追加。LED1、LED2。

ALFA製のAS3364は2164とピン互換でLinear特性のVCAチップです。2164とはPin1の使用法が異なっており、2164と3364を切り替えて使用できるように半田ジャンパとコンデンサのフットプリントを追加しました。AS3364については未テストなので、現段階で動作するかは不明です。

V2164動作確認」で書きましたが、CVが0Vのときに出力も0Vにするためには、CVにバイアスを掛ける必要があります。トリム(RV1)で、U1周辺の反転増幅回路の非反転端子にバイアス電圧を入力するようにしました。CV入力が0Vのときに出力がぎりぎり無音になるようにRV1を設定します。U1、U2のPin5で電圧測定できるので、+1.3V~+1.4V程度で調整します。

CVに入力が来ているかどうかを示すLEDを付けました(LED1、LED2)。LEDはパネルに取り付け、カソード側をGNDにつなぎます。LEDドライバはバイポーラトランジスタを使用しており、単純に点滅するだけでなく、CVの電圧に追従してLEDのじんわりと明るくなったり暗くなったりします。D1、D2は逆電圧がかかった場合の保護用です。

入出力の測定


入出力波形


IN: 200Hz/±5Vp-pサイン波
CV: ArEGから入力

CH1

C1:OUT C2:CV

CH2

C1:OUT C2:CV

Exponential特性のためCVに入力したEGのカーブよりも振幅が急峻に変化します。とくにアタックはEGは上に膨らんだカーブですが、出力振幅は下に膨らんだカーブになっているのが特徴的です。

OTA_VCA

C1:OUT C2:CV

同じ信号を入力したLinear特性のOTA_VCAの出力波形です。包絡線はEGの波形そのままです。

周波数特性


CH1 入力=5V CV=5V


CH2 入力=5V CV=5V

実際に音出ししてみると、Linear特性のOTA_VCAがオルガン的なのに比べてExponential特性の2164VCAはピアノ的だと言えると思います。Exponential特性でもEGのADSRをそれぞれ大きめに設定すればオルガン的な音も出せます。

メモ


出力振幅が小さい。±5Vp-p入力でIN、CVのPOTをともに最大にしたが、出力振幅が最大±2Vp-p程度。ボード線図でも-16dB程度に。
→R2、R3の抵抗値を調整すればよい?

LEDの輝度が低い
→R9、R11の抵抗値を調整すればよい?

ボード線図を見ると出力の位相が反転。
→入力か出力に反転アンプを入れる?

5mmのLEDをは、アクリルパネルに5mm弱の穴を開け押し込んで固定できます。接着剤不要。穴径は小さめの穴をドリルで開けてリーマで調整します。

2022年12月3日土曜日

Raspberry Pi 覚書

Raspberry Piを使っていく上でのメモです。徐々に追加する予定です。

使用環境
  • Raspberry Pi 3 Model B V1.2
  • HDMIモニタ
  • USBキーボード(無線)
  • USBマウス(無線)


Raspberry Piを背面にマウントできるタイプのHDMIモニタを使用しています。

キーボードとマウスは中華製の安物ですが、USBドングル一つで無線接続できるのでUSBポートの節約になります。

ネットワークにWifiを使えば、必要なケーブルは電源用のUSBケーブル1本のみとなります。

Raspberry Pi 初期設定


OSインストール


Raspberry Pi Imagerを入手

SDカードを読み書きできるPCにRaspberry Pi Imagerをインストール。

Raspberry Pi Imagerを起動。
  • OS: Raspberry Pi OS (32-bit)
  • ストレージ: SDドライブを選択
  • 書き込む

Raspberry PiのSDカードドライブにOSを書き込んだSDカードを挿入して起動。

SSHの設定


「スタート」→「設定」→「Raspberry Piの設定」
「インターフェイス」→「SSH」: ON →「OK」


VNCの設定


VNCを使うとGUIでリモート操作が可能になる。

PCのVNC ViewerでRaspberry Piに接続しているようす

「スタート」→「設定」→「Raspberry Piの設定」
「インターフェイス」→「VNC」: ON →「OK」

VNC ViewerでPCから接続。

参考
Interface 2021年9月号 104p  「特設2 第2章 ラズベリー・パイ4/3B/3B+のセットアップ」

LAMPのインストール


以下の順にインストールします。
  • Apache2
  • PHP7
  • MySQL(MariaDB)
  • phpMyAdmin

Raspberry Pi OSのバージョン 

pi@raspberrypi:~ $ uname -a
Linux raspberrypi 5.15.76-v7+ #1597 SMP Fri Nov 4 12:13:17 GMT 2022 armv7l GNU/Linux

Apache2のインストール


パッケージのアップデート
sudo apt update
sudo apt upgrade

Apache2のインストール
sudo apt install apache2

Apache2が起動しているか確認
ps agx | grep apache

WebブラウザでApache2に接続。
http://127.0.0.1/

ユーザーpiがhtmlを編集できるようにwww-dataグループを作り所有権を変更。
sudo usermod -a -G www-data pi
sudo chown -R -f www-data:www-data /var/www/html
sudo chmod -R g+w /var/www/html

ログアウトしてログインし直す。

デフォルトWebページを編集
nano /var/www/html/index.html

PHP7のインストール

PHP7のインストール
sudo apt install php7.4 libapache2-mod-php7.4 php7.4-mbstring php7.4-mysql php7.4-curl php7.4-gd php7.4-zip

テスト用のPHPファイルを作成
nano /var/www/html/example.php

nanoでテキストを編集
<?php
phpinfo();
?>

動作確認
http://localhost/example.php

MySQLのインストール


参考「Pi My Life Up:  Setup a Raspberry Pi MYSQL 」

パッケージのアップデート
sudo apt update
sudo apt upgrade

MySQLのインストール
sudo apt install mariadb-server

MySQLのセキュリティ設定
sudo mysql_secure_installation
すべて「Y」を選択する。

mysql_secure_installationで表示されるメッセージ (DeepLで和訳)

NOTE: RUNNING ALL PARTS OF THIS SCRIPT IS RECOMMENDED FOR ALL MariaDB
      SERVERS IN PRODUCTION USE!  PLEASE READ EACH STEP CAREFULLY!

注:このスクリプトのすべての部分を実行することは、すべてのMariaDBサーバーに推奨されます。
      サーバで使用することを推奨します。 各ステップを注意深く読んでください!

In order to log into MariaDB to secure it, we'll need the current password for the root user. If you've just installed MariaDB, and haven't set the root password yet, you should just press enter here.

MariaDBにログインしてセキュリティを確保するためには、rootユーザーの現在のパスワードが必要です。MariaDBをインストールしたばかりで、まだrootパスワードを設定していない場合は、ここでEnterキーを押すだけでよいでしょう。

Enter current password for root (enter for none): 

OK, successfully used password, moving on...

Setting the root password or using the unix_socket ensures that nobody can log into the MariaDB root user without the proper authorisation.

You already have your root account protected, so you can safely answer 'n'.

rootのパスワードを設定するか、unix_socketを使用することで、誰も適切な権限なしにMariaDBのrootユーザーにログインすることができないようにすることができます。

あなたは既にrootアカウントを保護しているので、安全に'n'と答えることができます。

Switch to unix_socket authentication [Y/n] Y
Enabled successfully!
Reloading privilege tables..
 ... Success!


You already have your root account protected, so you can safely answer 'n'.

すでにrootアカウントは保護されていますので、安心して「n」とお答えください。

Change the root password? [Y/n] Y
New password: 
Re-enter new password: 
Password updated successfully!
Reloading privilege tables..
 ... Success!


By default, a MariaDB installation has an anonymous user, allowing anyone to log into MariaDB without having to have a user account created for them.  This is intended only for testing, and to make the installation go a bit smoother.  You should remove them before moving into a production environment.

デフォルトでは、MariaDBのインストールには匿名ユーザーがあり、誰でもユーザーアカウントを作成することなくMariaDBにログインすることができるようになっています。 これはテスト用で、インストールを少しスムーズにするためだけです。 本番環境に移行する前に削除しておく必要があります。

Remove anonymous users? [Y/n] Y
 ... Success!

Normally, root should only be allowed to connect from 'localhost'.  This ensures that someone cannot guess at the root password from the network.

通常、rootは「localhost」からの接続のみを許可されるべきです。 これにより、誰かがネットワークからrootのパスワードを推測することができないようにします。

Disallow root login remotely? [Y/n] Y
 ... Success!

By default, MariaDB comes with a database named 'test' that anyone can access.  This is also intended only for testing, and should be removed before moving into a production environment.

デフォルトでは、MariaDBには誰でもアクセスできる'test'という名前のデータベースが付属しています。 これもテスト用であり、本番環境に移行する前に削除してください。

Remove test database and access to it? [Y/n] Y
 - Dropping test database...
 ... Success!
 - Removing privileges on test database...
 ... Success!

Reloading the privilege tables will ensure that all changes made so far will take effect immediately.

権限テーブルを再ロードすることで、これまでに行ったすべての変更が直ちに有効になります。

Reload privilege tables now? [Y/n] Y
 ... Success!

Cleaning up...

All done!  If you've completed all of the above steps, your MariaDB installation should now be secure.

Thanks for using MariaDB!

すべて完了  上記の手順がすべて完了したら、MariaDBのインストールは安全なものになるはずです。

MariaDBを使用していただきありがとうございます。

MySQLサーバーへのアクセス
sudo mysql -u root -p

SQLのテスト
CREATE DATABASE exampledb;
CREATE USER 'pi'@'localhost' IDENTIFIED BY 'password';
GRANT ALL PRIVILEGES ON exampledb.* TO 'pi'@'localhost';
FLUSH PRIVILEGES;
quit;

PHP MySQLコネクタのインストール
sudo apt install php-mysql

phpMyAdminのインストール



パッケージのアップデート
sudo apt update
sudo apt upgrade

PHPMyAdminのインストール
sudo apt install phpmyadmin
webサーバ→apache2を選択
dbconfig-commonで設定しますか?→はい
phpmyadmin 用の MySQL アプリケーションパスワード:→パスワードを入力

rootはPHPMyAdminで禁止されているのでユーザーを作成しすべてのアクセスを許可する。
sudo mysql -u root -p
GRANT ALL PRIVILEGES ON *.* TO 'pi'@'localhost' IDENTIFIED BY 'password' WITH GRANT OPTION;
quit;

Apacheの設定
sudo nano /etc/apache2/apache2.conf

最下行に次の一行を追加
Include /etc/phpmyadmin/apache.conf

Apacheを再起動
sudo service apache2 restart

PHPMyAdminにアクセス
http://127.0.0.1/phpmyadmin

IPアドレスは次のコマンドで確認
hostname -I

Raspberry PiでphpMyAdminを実行しているようす

phpMyAdminのドキュメント

2022年11月10日木曜日

3320LPF V3320を使用したVCFの製作

CoolAudio社のV3320を使ってVCF(4次LPF)を製作しました。V3320については「4次VCF V3320(CEM3320互換)の動作確認」で書きました。



回路図

ブレッドボードテスト用配線

基本的にはV3320のデーターシートに掲載されているLPF回路です。

主に以下の点を変更しています。

  • カットオフ周波数のPOTによる設定とCVによる変調をミックスするための反転加算回路を追加。

  • レゾナンスの効きをよくするため出力にアンプを追加し、レゾナンス用の正帰還入力(IRES:PIN9)に入力。

  • CR類を入手容易な値のものに変更し、一部交換可能なようにピンソケットを使って実装。

「Electric Druid」さんの「CEM3320 Filter designs」の記事によると、出力にアンプを付加すると低い周波数でレゾナンスの効きが良くなるそうです。Sequencial Pro-Oneで採用されているテクニックです。

出力の測定


カットオフ周波数のバイアスを設定するCutoff Trim(RV4)は最大に設定して測定しました。カットオフ周波数が最も高くまで設定できるようになります。

INのPOTは最大、FCV1、FCV2、QCVのPOTは0に設定しています。

IN: 1kHz/Sawtooth 2Vp-p
Cutoff: 1時の位置 (+6.0V)
Resonance: 0 (0V)

C1:IN C2:OUT

IN: 1kHz/Sawtooth 2Vp-p
Cutoff: 1時の位置 (+6.0V)
Resonance: 1時の位置 (+6.0V)

C1:IN C2:OUT

IN: 1kHz/Sawtooth 2Vp-p
Cutoff: 1時の位置 (+6.0V)
Resonance: 最大(+12.1V)

C1:IN C2:OUT

※共振の様子を見るために横軸の縮尺を変えています。

IN: 1kHz/Sawtooth 2Vp-p
Cutoff: 最大 (+12.1V)
Resonance: 0 (0V)

C1:IN C2:OUT

IN: 1kHz/Sawtooth 2Vp-p
Cutoff: 最大 (+12.1V)
Resonance: 1時の位置 (6.0V)

C1:IN C2:OUT

IN: 1kHz/Sawtooth 2Vp-p
Cutoff: 最大 (+12.1V)
Resonance: 最大 (+12.1V)

C1:IN C2:OUT

レゾナンスを大きくすると発振します。発振周波数はカットオフ周波数になります。

レゾナンス(Q)は共振の意味で、LC回路の場合
ω = 1 / √(LC)
ですが、シンセなどRC低周波回路ではL(コイル)は使わず正帰還により共振を発生させます。共振が大きくなると自己発振してオシレーターとして振る舞います。この回路でも自己発振します。発振周波数はカットオフ周波数に追随します。

無入力でレゾナンスを上げた自己発振

C1:OUT

綺麗な正弦波の発振波形です。(その分あまり面白みはないかも?)

周波数特性


位相が180度回る位置が1kHz付近になるようにCutoff(RV3)を調整して測定しました。

Cutoff: +5.73V
Resonance: 0 (0V)

Cutoff: +5.73V
Resonance: 1時の位置 (+6.0V)

Cutoff: +5.73V
Resonance: 最大 (+12.1V)

C1:IN C2:OUT

メモ


カットオフ周波数がもう少し高い周波数まで設定できるようにピンソケットで実装している抵抗の値を調整したほうが良さそうです。

また出力アンプの増幅率によりレゾナンスがどのように変化するかも試してみる価値はありそうです。

トランジスタラダー・フィルターのTLF01と比較すると、フィルターとしての性能に優れています。カットオフ周波数を変化させても出力レベルがあまり変わらず、カットオフを絞っていくと正弦波に近い波形に落ち着いていきます。扱いやすく適用範囲の広いLPFだと言えると思います。
 

2022年10月27日木曜日

SSD1306 OLEDをSTM32で動かす。 afiskonライブラリ

afiskonライブラリafiskon/stm32-ssd1306はSSD1306は4iloライブラリからforkされたものの様で、SSD1306 OLEDのI2C版とSPI版に対応しています。

Nucleo-F446REとNucleo-G431KBで動作確認しました。

以下の記事を参考にさせていただきました。

「afiskon」さん(本家) https://github.com/afiskon/stm32-ssd1306
「hacksOnTable」さん 「STM32 OLED TUTORIAL(Youtube)

HALを使ったプログラミングはSTM32CubeIDEの登場でかなり便利になりましたが、MPUのシリーズによって特徴があり、設定やプログラミングが方法がそれぞれ少しずつ異なります。冗長になりますが、Nucleo-F446REとNucleo-G431GBで、SSD1306のI2C版とSPI版の使い方を説明します。

STM32CubeIDEのバージョン: 1.10.1

I2C版 Nucleo-F446RE


Board SelecotorでNuckeo-F446REを指定してDefult Modeで初期化。

MXの設定


Pinout & Configuration
  Connectivity
    I2C1
      Mode
        I2C: I2C
      Configuration
        Parameter Settings
          Master Features
            I2C Speed Mode: Standard Mode
        GPIO Settings
          PB8 I2C1_SCL
          PB9 I2C1_SDA

afiskonライブラリではデフォルトでI2C1を使う設定になっています。I2C2やI2C3などを使う場合は「ssd1306_conf_template.h」を適宜書き換えます。

ハードウェアの準備


SSD1306 F446RE Arduino Header
GND GND GND
VDD 3V3 3V3
SCK PB8 D15
SDA PB9 D14

ブレッドボード配線図

ライブラリの準備


GitHubのafiskon/stm32-ssd1306からZIPファイルをダウンロードします。
  • ssd1306.h
  • ssd1306_conf_templates.h
  • ssd1306_fonts.h
  • ssd1306_tests.h
を「<Projectフォルダ>\Core\Inc\」に
  • ssd1306.c
  • ssd1306_fonts.c
  • ssd1306_tests.c
を「<Projectフォルダ>\Core\Src\」にコピーします。IDEのProject ExplorerでProjectフォルダを右クリックし「Refresh」します。

「Core/Inc/ssd1306_conf_template.h」の内容を以下のように書き換えます。

// Choose a microcontroller family
//#define STM32F0
#define STM32F4

重要:「ssd1306_conf_template.h」を「ssd1306_conf.h」にRenameします。

ソースコード


MXでコード生成して、Core\Src\main.cに以下のコードを追加します。

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "ssd1306.h"
#include "ssd1306_fonts.h"
#include "ssd1306_tests.h"
/* USER CODE END Includes */

<>

  /* USER CODE BEGIN 2 */
  ssd1306_TestAll();
  /* USER CODE END 2 */

実行している様子

FPS表示値

Standard Mode 9
Fast Mode 34

F446REの駆動クロックはHSI/84MHz。

I2C信号波形

F446RE I2C Fast Mode 2.2kΩ Pullup


C1:SDA C2:SCL

I2C版 Nucleo-G431KB


Board SelecotorでNuckeo-G431KBを指定してDefult Modeで初期化。

MXの設定


Pinout & Configuration
  Connectivity
    I2C1
      Mode
        I2C: I2C
      Configuration
        Parameter Settings
          Master Features
            I2C Speed Mode: Standard Mode
        GPIO Settings
          PA15 I2C1_SCL
          PB7  I2C1_SDA

ブレッドボード配線図


SSD1306 G431KB Arduino Header
GND GND GND
VDD 3V3 3V3
SCK PA15 D5
SDA PB7 D4

ライブラリの準備


必要なファイルをコピーします。
  • Core/Inc/ssd1306.h
  • Core/Inc/ssd1306_conf_templates.h
  • Core/Inc/ssd1306_fonts.h
  • Core/Inc/ssd1306_tests.h
  • Core/Src/ssd1306.c
  • Core/Src/ssd1306_fonts.c
  • Core/Src/ssd1306_tests.c
「Core/Inc/ssd1306_conf_template.h」の内容を以下のように書き換えます。

// Choose a microcontroller family
//#define STM32F0
#define STM32G4

「#define STM32G4」はコメントアウトで用意されていないので書き加えます。「ssd1306.h」では

#elif defined(STM32G4)
#include "stm32g4xx_hal.h"

と、STM32G4を使用する場合の定義があります。

重要:「ssd1306_conf_template.h」を「ssd1306_conf.h」にRenameします。

ソースコード


MXでコード生成して、Core\Src\main.cに以下のコードを追加します。

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "ssd1306.h"
#include "ssd1306_fonts.h"
#include "ssd1306_tests.h"
/* USER CODE END Includes */

<>

  /* USER CODE BEGIN 2 */
  ssd1306_TestAll();
  /* USER CODE END 2 */

main.cへのソースコードの追加はI2C版 Nucleo-F446REと同じです。

実行している様子

FPS表示値

Standard Mode 9
Fast Mode 35
Fast Mode Plus 76

※Fast Mode Plusで使用する場合は2.2kΩ程度で外部Pullupする。

G431KBの駆動クロックはHSI/170MHz。

I2C信号波形

G431RB I2C Fast Mode Plus 2.2kΩ Pullup


C1:SDA C2:SCL

SPI版 Nucleo-F446RE


Board SelecotorでNuckeo-F446REを指定してDefult Modeで初期化。

MXの設定


Pinout & Configuration
  System Core
    Configuration
      GPIO
        PA10 : Output Push Pull : Very High : OLED_Res
        PB4  : Output Push Pull : Very High : OLED_CS
        PB5  : Output Push Pull : Very High : OLED_DC
  Connectivity
    SPI2
      Mode
        Mode: Half Duplex Master
      Configuration
        Parameter Settings
          Clock Parameters
            Prescaler(for Baud Rate): 64
            Clock Polarity(CPOL): High
            Clock Phase(CPHA): 2 Edge
        GPIO Settings
          PB10 SPI2_SCK
          PC1  SPI2_MOSI

Nucleo-F446REでは、SPI1はデフォルトでは使用不可になっているのでSPI2を使用します。MISOは使わないのでModeはHalf Duplex Masterにします。

動作確認のためClock Prescalerは大きめにしてクロック周波数を低く設定します。

重要:Clock Polarity(CPOL)、Clock Phase(CPHA)は上記の通り設定すると動作するようです。

またGPIOで制御信号線(CS、RES、DC)を割り当てます。右側のPinout図でPinをクリックしてGPIO_Outputを選択し、User Labelを設定します。User Labelはssd1306_conf_template.hで定義されているものを入力します。

ハードウェアの準備


SSD1306 F446RE Arduino Header 機能
GND GND GND GND
VDD 3V3 3V3 3.3V Power
D0 PB10 D6 SPI/SCK
D1 PC1 A4 SPI/MOSI
RES PA10 D2 Reset
DC PB5 D4 Data/Command
CS PB4 D5 SPI/CS

ブレッドボード配線図

ライブラリの準備


必要なファイルをコピーします。
  • Core/Inc/ssd1306.h
  • Core/Inc/ssd1306_conf_templates.h
  • Core/Inc/ssd1306_fonts.h
  • Core/Inc/ssd1306_tests.h
  • Core/Src/ssd1306.c
  • Core/Src/ssd1306_fonts.c
  • Core/Src/ssd1306_tests.c
Core\Inc\ssd1306_conf_template.hを以下のように変更します。

// Choose a microcontroller family
//#define STM32F0
//#define STM32F1
#define STM32F4
//#define STM32L0
//#define STM32L1
//#define STM32L4
//#define STM32F3
//#define STM32H7
//#define STM32F7
//#define STM32G0

// Choose a bus
//#define SSD1306_USE_I2C
#define SSD1306_USE_SPI

// I2C Configuration
//#define SSD1306_I2C_PORT        hi2c1
//#define SSD1306_I2C_ADDR        (0x3C << 1)

// SPI Configuration
#include "main.h"
#define SSD1306_SPI_PORT        hspi2
#define SSD1306_CS_Port         OLED_CS_GPIO_Port
#define SSD1306_CS_Pin          OLED_CS_Pin
#define SSD1306_DC_Port         OLED_DC_GPIO_Port
#define SSD1306_DC_Pin          OLED_DC_Pin
#define SSD1306_Reset_Port      OLED_Res_GPIO_Port
#define SSD1306_Reset_Pin       OLED_Res_Pin

SPI2を使うのでSSD_1306_SPI_PORTの定義をhspi2に変更します。

あまり感心できるものではありませんが、OLED_CS_GPIO_Portなどが定義されていないというエラーが出るので、直前に
#include "main.h"
という一行を追加して、定義されているヘッダーファイルをインポートします。

重要:「ssd1306_conf_template.h」を「ssd1306_conf.h」にRenameします。

ソースコード


MXでコード生成して、Core\Src\main.cに以下のコードを追加します。

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "ssd1306.h"
#include "ssd1306_fonts.h"
#include "ssd1306_tests.h"
/* USER CODE END Includes */

<>

  /* USER CODE BEGIN 2 */
  ssd1306_TestAll();
  /* USER CODE END 2 */

main.cのコード追加はI2C版と同じです。

実行している様子

FPS表示値

SPI Prescaler:64 (655.25KBits/s) 60
SPI Prescaler:16 (2.625MBits/s) 144
SPI Prescaler: 2 (21.0MBits/s) 217

F446REの駆動クロックはHSI/84MHz。

SPI信号波形

F446RE SPI Prescaler=16


C1:MOSI C2:SCK


SPI版 Nucleo-G431KB


Board SelecotorでNuckeo-G431KBを指定してDefult Modeで初期化。

MXの設定


Pinout & Configuration
  System Core
    Configuration
      GPIO
        PA11 : Output Push Pull : Very High : OLED_Res
        PB4  : Output Push Pull : Very High : OLED_CS
        PB5  : Output Push Pull : Very High : OLED_DC
  Connectivity
    SPI1
      Mode
        Mode: Half Duplex Master
      Configuration
        Parameter Settings
          Basic Parameters
            Data Size: 8bit
          Clock Parameters
            Prescaler(for Baud Rate): 256
            Clock Polarity(CPOL): High
            Clock Phase(CPHA): 2 Edge
        GPIO Settings
          PA5 SPI2_SCK
          PA7 SPI2_MOSI

Nucleo-G431KBではデフォルトでSPI1が使用できるのでSPI1を使います。MISOは使わないのでModeはHalf Duplex Masterにします。重要:Data Sizeがデフォルトでは4bitになっているので、8bitに変更します。

動作確認のためClock Prescalerは大きめにしてクロック周波数を低く設定します。

Clock Polarity(CPOL)、Clock Phase(CPHA)は上記の通り設定すると動作するようです。

またGPIOで制御信号線(CS、RES、DC)を割り当てます。右側のPinout図でPinをクリックしてGPIO_Outputを選択し、User Labelを設定します。User Labelはssd1306_conf_template.hで定義されているものを入力します。

ハードウェアの準備


SSD1306 G431KB Arduino Header 機能
GND GND GND GND
VDD 3V3 3V3 3.3V Power
D0 PA5 A4 SPI/SCK
D1 PA7 A6 SPI/MOSI
RES PA11 D10 Reset
DC PB5 D11 Data/Command
CS PB4 D12 SPI/CS

ブレッドボード配線図


ライブラリの準備


必要なファイルをコピーします。
  • Core/Inc/ssd1306.h
  • Core/Inc/ssd1306_conf_templates.h
  • Core/Inc/ssd1306_fonts.h
  • Core/Inc/ssd1306_tests.h
  • Core/Src/ssd1306.c
  • Core/Src/ssd1306_fonts.c
  • Core/Src/ssd1306_tests.c
Core\Inc\ssd1306_conf_template.hを以下のように変更します。

// Choose a microcontroller family
//#define STM32F0
//#define STM32F1
//#define STM32F4
//#define STM32L0
//#define STM32L1
//#define STM32L4
//#define STM32F3
//#define STM32H7
//#define STM32F7
//#define STM32G0
#define STM32G4

// Choose a bus
//#define SSD1306_USE_I2C
#define SSD1306_USE_SPI

// I2C Configuration
//#define SSD1306_I2C_PORT        hi2c1
//#define SSD1306_I2C_ADDR        (0x3C << 1)

// SPI Configuration
#include "main.h"
#define SSD1306_SPI_PORT        hspi1
#define SSD1306_CS_Port         OLED_CS_GPIO_Port
#define SSD1306_CS_Pin          OLED_CS_Pin
#define SSD1306_DC_Port         OLED_DC_GPIO_Port
#define SSD1306_DC_Pin          OLED_DC_Pin
#define SSD1306_Reset_Port      OLED_Res_GPIO_Port
#define SSD1306_Reset_Pin       OLED_Res_Pin

あまり感心できるものではありませんが、OLED_CS_GPIO_Portなどが定義されていないというエラーが出るので、直前に
#include "main.h"
という一行を追加して、定義されているヘッダーファイルをインポートします。

重要:「ssd1306_conf_template.h」を「ssd1306_conf.h」にRenameします。


ソースコード


MXでコード生成して、Core\Src\main.cに以下のコードを追加します。


/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "ssd1306.h"
#include "ssd1306_fonts.h"
#include "ssd1306_tests.h"
/* USER CODE END Includes */

<>

  /* USER CODE BEGIN 2 */
  ssd1306_TestAll();
  /* USER CODE END 2 */

main.cはいずれも同じコードです。

実行している様子

FPS表示値

SPI Prescaler:256 (654.062KBits/s) 69
SPI Prescaler: 64 (2.65625MBits/s) 199
SPI Prescaler: 8 (21.25MBits/s) 437
SPI Prescaler: 4 (42.5MBits/s) 動作せず

G431REの駆動クロックはHSI/170MHz。

SPI信号波形

G431KB SPI Prescaler=64


C1:MOSI C2:SCK


2022年10月24日月曜日

SSD1306 OLEDをSTM32で動かす。 4iloライブラリ

Nucleo-F446REとNucleo-G431KBで4lioライブラリを使ってみました。4iloライブラリはI2C版のみの対応です。SPI版のSSD1306 OLEDを使用するには派生ライブラリのafiskonライブラリafiskon/stm32-ssd1306を使います。(次回予定)

以下の記事を参考にさせていただきました。


使用したSTM32CubeIDEのバージョン: 1.10.1

なお、久しぶりにSTM32CubeIDEを立ち上げると延々とUpdateがかかるので事前に一度起動してUpdateを完了させると良いと思います。ST-LinkのファームウェアのアップデートもあるのでLチカなども走らせましょう。

Nucleo-F446RE


Board SelecotorでNuckeo-F446REを指定してDefult Modeで初期化。

MXの設定


STM32CubeIDEでは「Device Configuration Tool」と呼ばれるもので、「.ioc」ファイルを開くとIDE内で起動します。STM32CubeMXと機能的にはほぼ同等なので、このBlogではMXと呼んでいます。STM32CubeMXを別途立ち上げる必要はありません。

Pinout & Configuration
  Connectivity
    I2C1
      Mode
        I2C: I2C
      Configuration
        Parameter Settings
          Master Features
            I2C Speed Mode: Standard Mode
        GPIO Settings
          PB8 I2C1_SCL
          PB9 I2C1_SDA

Parameter Settingsはデフォルトのまま、Standard Mode (100kHz)でOKです。Fast Mode(400kHz)でも動作します。

GPIO Settingsは右側のPinout図で設定すると左下のConfigurationペインに反映されます。ピン割当はArduinoヘッダのD14(PB8)、D15(PB9)に変更しました。

ハードウェアの準備


ブレッドボード配線図
SSD1306 F446RE Arduino Header
GND GND GND
VDD 3V3 3V3
SCK PB8 D15
SDA PB9 D14

ライブラリの準備


4ilo/ssd1306-stm32HALからZIPファイルをダウンロード(右上の「Code」-「Download ZIP」をクリック)して展開しておきます。
  • ssd1306.h
  • fonts.h
を「<Projectフォルダ>\Core\Inc\」に
  • ssd1306.c
  • fonts.c
を「<Projectフォルダ>\Core\Src\」にコピーします。IDEのProject ExplorerでProjectフォルダを右クリックし「Refresh」します。

ソースコード


MXでコード生成して、Core\Src\main.cに以下のコードを追加します。

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "ssd1306.h"
#include "fonts.h"
/* USER CODE END Includes */

<>

  /* USER CODE BEGIN 2 */
  // Init lcd using one of the stm32HAL i2c typedefs
  ssd1306_Init(&hi2c1);

  // Write data to local screenbuffer
  ssd1306_SetCursor(0, 36);
  ssd1306_WriteString("4ilo", Font_11x18, White);

  // Copy all data from local screenbuffer to the screen
  ssd1306_UpdateScreen(&hi2c1);
  /* USER CODE END 2 */

実行している様子

I2C信号波形


外部Pullupなし Fast Mode(400kHz)

C1:SDA C2:SCL

I2CのSCLとSDAは、SSD1306モジュール上でPullupされているので、外部Pullupしなくても動作します。

外部Pullup 10kΩ  Fast Mode(400kHz)

C1:SDA C2:SCL

外部Pullupすると信号波形がきれいになります。

外部Pullup 2.2kΩ  Fast Mode(400kHz)

C1:SDA C2:SCL

外部Pullupの抵抗値を小さくしても400kHzクロックではあまり変わりませんね。

Nucleo-G431KB


Board SelecotorでNuckeo-G431KBを指定して「Defult Mode」で初期化。

MXの設定


Pinout & Configuration
  Connectivity
    I2C1
      Mode
        I2C: I2C
      Configuration
        Parameter Settings
          I2C Speed Mode: Standard Mode
        GPIO Settings
          PA15: I2C1_SCL
          PB7:  I2C1_SDA

I2C Speed ModeはまずStandard Modeで動作確認し、Fast Mode、Fast Plus Modeに変更して動作確認しました。

ハードウェアの準備


ブレッドボード配線図
SSD1306 G431KB Arduino Header
GND GND GND
VDD 3V3 3V3
SCK PA15 D4
SDA PB9 D5

ライブラリの準備


Nucleo-F446REと同様にファイルをコピーします。

Core/Inc/fonts.h
Core/Inc/ssd1306.h
Core/Src/fonts.c
Core/Src/fonts.h

重要: STMG431KBを使うので、Core/Inc/ssd1306.hを以下のように変更します。

//#include "stm32f4xx_hal.h"
#include "stm32g4xx_hal.h"

main.cへのソースコードの追加はNucleo-F446REの場合と同じです。

実行している様子

I2C Speed Mode


10kΩの外部Pullupした場合、Standard Mode、Fast Modeでは動作しましたが、Fast Mode Plusでは動作しませんでした。外部Pullupを2.2kΩに変更するとFast Mode Plusでも動作しました。

Standard Mode(100kHz) 外部Pullup 10kΩ 

C1:SDA C2:SCL

Fast Mode(400kHz) 外部Pullup 10kΩ 

C1:SDA C2:SCL

Fast Mode Plus(1000kHz) 外部Pullup 10kΩ 

C1:SDA C2:SCL

9bit目でACKされておらず(HIGHに引っ張りきれていない)、以降のI2C通信が失敗しています。

Fast Mode Plus(1000kHz) 外部Pullup 2.2kΩ 

C1:SDA C2:SCL

Pullup抵抗の抵抗値を小さくすると、ACKが認識されて正常に通信が行われています。

注)オシロ波形の下に周波数を表示させていますが、C1:SDAの値です。クロック周波数を知るためにはC2:SCLの値を表示させるべきでした。クロック周波数はC2(青色)の波形数と目盛りから概算できます。