SevenPlumBar(7PlumBar)

カタカナでマーサ(となりの芝生)

ポン菓子屋店頭用電光掲示板


電光掲示板(LED 64×16)

 

f:id:SevenPlumBar:20190105230013j:plain

スクロール中でブレていますが…

SODIALのLEDモジュール(8×8×4連)を4個連結して、64×16にしてArduinoDUEでコントロールさせています
「たま吉さん」のスケッチ等を参考にさせていただき(感謝!)、SODIALのモジュールはLEDユニットの並びが左右逆のようなので、少し変更して動かしています

64×16での表示は出来たので、時計と温度・湿度表示をできるようにしたら(夏の屋外営業では必須?)ケースに入れようかと思っています

ちなみに、この表示で5V入力での消費電流は約200mAなので、6000mAh程度のモバイルバッテリーで、1日はもちそうです

 

変更箇所1 SDカード接続ピンアサイ

//#define MOSI_SD 11 // SDカードのMOISへ接続
//#define MISO_SD 12 // SDカードのMISOへ接続
//#define CLK_SD 13 // SDカードのCLKへ接続

#define MOSI_SD 75 // SDカードのMOSIへ接続@DUE
#define MISO_SD 74 // SDカードのMISOへ接続@DUE
#define CLK_SD 76 // SDカードのCLKへ接続@DUE

 

変更箇所2 MAX7219接続数、表示エリアの横ドット数指定

// #define SCREENS 8 // MAX7219カスケード接続数
#define SCREENS 16 // MAX7219カスケード接続数

// #define SC_WIDTH 32 // マトリック表示横ドット数
#define SC_WIDTH 64 // マトリック表示横ドット数

 

変更箇所3 フレームバッファからMAX7219バッファへの変換部

// for (uint8_t i=0; i < 8; i++) {
// memcpy(&ptr[i*8],&fbuf[i*4+32], 4);
// memcpy(&ptr[i*8+4],&fbuf[i*4], 4);
// }

for (uint8_t i=0; i < 8; i++) { // each MAX7219 has 8 rows
memcpy(&ptr[i*SCREENS],&fbuf[i*SC_WIDTH/8+SC_WIDTH+7], 1);
memcpy(&ptr[i*SCREENS+1],&fbuf[i*SC_WIDTH/8+SC_WIDTH+6], 1);
memcpy(&ptr[i*SCREENS+2],&fbuf[i*SC_WIDTH/8+SC_WIDTH+5], 1);
memcpy(&ptr[i*SCREENS+3],&fbuf[i*SC_WIDTH/8+SC_WIDTH+4], 1);
memcpy(&ptr[i*SCREENS+4],&fbuf[i*SC_WIDTH/8+SC_WIDTH+3], 1);
memcpy(&ptr[i*SCREENS+5],&fbuf[i*SC_WIDTH/8+SC_WIDTH+2], 1);
memcpy(&ptr[i*SCREENS+6],&fbuf[i*SC_WIDTH/8+SC_WIDTH+1], 1);
memcpy(&ptr[i*SCREENS+7],&fbuf[i*SC_WIDTH/8+SC_WIDTH], 1);
memcpy(&ptr[i*SCREENS+8],&fbuf[i*SC_WIDTH/8+7], 1);
memcpy(&ptr[i*SCREENS+9],&fbuf[i*SC_WIDTH/8+6], 1);
memcpy(&ptr[i*SCREENS+10],&fbuf[i*SC_WIDTH/8+5], 1);
memcpy(&ptr[i*SCREENS+11],&fbuf[i*SC_WIDTH/8+4], 1);
memcpy(&ptr[i*SCREENS+12],&fbuf[i*SC_WIDTH/8+3], 1);
memcpy(&ptr[i*SCREENS+13],&fbuf[i*SC_WIDTH/8+2], 1);
memcpy(&ptr[i*SCREENS+14],&fbuf[i*SC_WIDTH/8+1], 1);
memcpy(&ptr[i*SCREENS+15],&fbuf[i*SC_WIDTH/8], 1);
}

 

変更箇所4 max7219_matrix.hの中の

//#define MAXSCREENS 8 // 最大接続数

#define MAXSCREENS 16 // 最大接続数

 

nuneno.cocolog-nifty.com

カットしたアクリル材(2セット分)到着(1/9)・・・穴あけ加工前

f:id:SevenPlumBar:20190109213950j:plain

アクリル材入手

完成(1/17)  ArduinoDUE + SODIAL LED ディスプレイモジュール×4

f:id:SevenPlumBar:20190117223041j:plain

Arduinoシールド基板部品表(DUEの背中に乗せた基板)

①I2C接続のRTC:秋月電子 RTC-8564NB をLi電池でバックアップ(275nA)

②I2C接続のOLED:秋月電子 0.96インチ 128×64ドット OLED

③I2C接続の温湿度センサ:秋月電子 AM2322

④プッシュスイッチ×4:秋月電子

Arduinoシールド基板:秋月電子 Arduino用ユニバーサルプロトシールド

⑥3.3V出力 → 5.0V入力 レベル変換IC実装(SN74LS07)

 

メッセージ部分は完成したので、ポン菓子屋に引き渡した

2/24(日)が「今年の初ポン=デビュー日」らしい

行ってらっしゃ~い

 

 

C++ (Arduino)

 継承

 

class U8G2_MAX7219_64X8_1_4W_HW_SPI : public U8G2 {
 public: U8G2_MAX7219_64X8_1_4W_HW_SPI(const u8g2_cb_t *rotation, uint8_t cs,   uint8_t dc, uint8_t reset = U8X8_PIN_NONE) : U8G2() {
  u8g2_Setup_max7219_64x8_1(&u8g2, rotation, u8x8_byte_arduino_hw_spi,  u8x8_gpio_and_delay_arduino);
  u8x8_SetPin_4Wire_HW_SPI(getU8x8(), cs, dc, reset);
  }
};

解釈:

U8G2_MAX7219_64X8_1_4W_HW_SPI が派生クラス

U8G2 が基底クラス (: public がキーワード)

その後ろの {・・・} の部分が派生クラスの定義

関数 U8G2_MAX7219_64X8_1_4W_HW_SPI(・・・)はコンストラクタ(関数が生成(実体化)されたときに自動的に実行される初期化関数)
「U8G2_MAX7219_64X8_1_4W_HW_SPI」のコンストラクタとして

U8G2()(基底クラスのコンストラクタ)を実行した後に
u8g2_Setup_max7219_64x8_1(・・・)と u8x8_SetPin_4Wire_HW_SPI(・・・)の関数が実行されることになる

OLEDモジュール

 

0.9インチ128x64

  • SSD1306 I2Cインターフェース 秋月電子
  • u8g2ライブラリ使用(M0では「***_HW_I2C」を選択)

1.3インチ128x128

  • SSD1327 I2Cインターフェース amazon
    SSD1306に比べると画素の数以上に遅い(SSD1327にはディレイが必要らしい)
  • u8g2ライブラリ使用(DUEでは「***_2ND_HW_I2C」を選択)
  • 「MSP1503」というのがモジュールの名前らしい

    f:id:SevenPlumBar:20190102101205j:plain

    やぁ!(©chobihige/LINE stamp 「ちょっと理系なうさたろう2」)



Arduino(忘備録)

 

 共通

  • Arduino」はワンチップマイコンに、ドライバ(ブートローダ)を書き込み
    統合化開発環境「Arduino IDE」経由で、コンパイラ・リンカ「gcc toolchain」を使用している
    (AVR、SAM、ESP32、STM32、ルネサス(旧日立系)など)
  • Arduino IDE」の代わりに、「Visual Micro (Arduino IDE for Visual Studio)」を使用すると、関数定義の参照ブレークポイントの使用、などの機能が使えて便利
    (最初に、「Arduino IDE」でビルド後に使用しないと、ライブラリの参照とかがうまくいかない、二つの環境を適宜使い分けてデバッグしている)
  • 「setup()」,「loop()」:実は「main.cpp」の中から、以下のように呼ばれている
    int main(void) {
      init();       //CPUの初期化
      initVariant();              //システムの初期化(差分?)
      setup();                    //ユーザープログラム(.ino)の初期化プロセス
      for(;;) {
         loop();                    //ユーザープログラム(.ino)のプログラム
         if(serialEventRun)
            serialEventRun(); //シリアル通信は別プロセスとして動作
       }
         retun(0);
    }
  • 環境設定file  C:\Users\<アカウント名>\AppData\Local\Arduino15\ の中の                                         「preferences.txt」 に設定情報が格納される
  • 追加ライブラリー  C:\Users\<アカウント名>\Documents\Arduino\libraries
  • ピンと信号名の対応
    C:\Users\*yourName\AppData\Local\Arduino15\packages\arduino\hardware\sam\1.6.11\variants\arduino_due_x\variant.h とか variant.cpp の中で定義されている(*yourNameは各PCごと)

  ArduinoM0(Atmel SAMD:ARM Cortex-M0+)

  • "serial"は無くって、"serialUSB"を使用
  • "serial5"が使えるようになった  0,1ピン(RX、TXと書いてあるピン)を使用
  • SPIはICSP (SCK,MISO,MOSI,SS)=(24,22,23,SS)(DMA付)
  • SERCOM4で SPI.begin(13,12,11,10); を追加可能(UNOと同じ)
  • SD:HardSSを使用しないときでもHardSSピンを出力に設定
  • ArduinoZERO が M0 に名前を変えたらしい…が同じではなさそう

ArduinoDUE(Atmel SAM:ARM Cortex-M3

  • SPIはICSP (SCK,MISO,MOSI,SS)=(76,74,75,SS)(DMA付)
    SPI_CONTINUE(SSをアクティブのままにしておく)が使えるのはDUEのみ
  • setup()内でSS信号ピンを設定 : SPI.begin(*SS);       *SS=4(CS1),10(CS0),52(CS2) のみ設定可
  • I2C  wire  :SDA,SCL=20,21(MEGAタイプのArduinoにしか存在しないピン)
              wire1:SDA,SCL=70,71 (他のArduino のI2Cのピン) 
  • A/D 10bit(default)/12bit(analogReadResolution(12);で指定)
    SPANはdefaultでは3.3Vになっているが「AREF」というジャンパ(ICSPコネクタのCPU寄り)で「EXT」側にジャンパすると「AREFピン」に変更できる
    「AREFピン」入力は10bit動作時は2.0V~VDD、12bit動作時は2.4V~VDD
    入力電流は250μAmax(14kΩtyp)…フィルタなしだとノイズで9bit程度

    f:id:SevenPlumBar:20190102212544p:plain

ESP32(Tensilica Xtensa LX6)

  • IO12を”H"にして、serialへ”Enter"を入力すると「BASIC」が起動する
    これがHSPIのMOSI信号になっているので「プルアップ」すると
    このモードになってしまい、プログラムの書き込みができなくなる
  • GPIO6,7,8,9,10,11はGPIOとしては使えない(らしいがSPIとしては使えるみたい、内蔵FLASHとSSを分ける)
  • SPIは"SPI.begin(SCK,MISO,MOSI,SS);"で宣言(DMA付)
    VSPI(標準SPI):  SPI.begin(18,19,23,5);
    HSPI(SPI2になる): SPI.begin(14,12,13,15);
    *HSPIにmicroSDを割り付けるとなぜだかうまくいかない→VSPIに割り付けた
    SPI(内蔵FLASH用): SPI.begin(6,7,8,SS);  (SS≠11)
  • freeRTOS with LwIPの下で走っている
  • ピンマップ

    #define EXTERNAL_NUM_INTERRUPTS 16 //外部割込み
    #define NUM_DIGITAL_PINS 40   //デジタル入出力ピン
    #define NUM_ANALOG_INPUTS 16     //アナログ入力ピン

    #define analogInputToDigitalPin(p) (((p)<20)?(esp32_adc2gpio[(p)]):-1)
    #define digitalPinToInterrupt(p) (((p)<40)?(p):-1)
    #define digitalPinHasPWM(p) (p < 34)

    static const uint8_t TX = 1;          // Serialピンアサイ
    static const uint8_t RX = 3;

    static const uint8_t SDA = 21;     // Wire(I2C)ピンアサイ
    static const uint8_t SCL = 22;

    static const uint8_t SS = 5;          // SPIピンアサイン(VSPI)
    static const uint8_t MOSI = 23;
    static const uint8_t MISO = 19;
    static const uint8_t SCK = 18;

    static const uint8_t A0 = 36;        // A1,A2が無い!!
    static const uint8_t A3 = 39;
    static const uint8_t A4 = 32;
    static const uint8_t A5 = 33;
    static const uint8_t A6 = 34;
    static const uint8_t A7 = 35;       // A8,A9も無い…
    static const uint8_t A10 = 4;
    static const uint8_t A11 = 0;
    static const uint8_t A12 = 2;
    static const uint8_t A13 = 15;
    static const uint8_t A14 = 13;
    static const uint8_t A15 = 12;
    static const uint8_t A16 = 14;
    static const uint8_t A17 = 27;
    static const uint8_t A18 = 25;
    static const uint8_t A19 = 26;

    static const uint8_t T0 = 4;            // Timer出力(PWM)
    static const uint8_t T1 = 0;
    static const uint8_t T2 = 2;
    static const uint8_t T3 = 15;
    static const uint8_t T4 = 13;
    static const uint8_t T5 = 12;
    static const uint8_t T6 = 14;
    static const uint8_t T7 = 27;
    static const uint8_t T8 = 33;
    static const uint8_t T9 = 32;

    static const uint8_t DAC1 = 25;       // DAC出力
    static const uint8_t DAC2 = 26;

f:id:SevenPlumBar:20190102213030j:plain

STM32の自作ボード用のコンフィグファイルの作成方法

  • C:\Users\<user_name>\AppData\Local\Arduino15\packages\STM32\hardware
    \stm32\1.7.0\variants\ の下のboard_templateフォルダから、元になりそうなものをコピーしてくる
  • それにピンマップを追加
    C:\Users\<user_name>\AppData\Local\Arduino15\packages\STM32
     \tools\STM32Tools\1.3.1\tools\src\genpinmap\Arduino\ の下の
    PeripheralPins.c と PinNamesVar.h を元に変更
  • システムクロックの設定方法
    CubeMXを使って初期化ファイルを出力させて、それを
    C:\Users\<user_name>\AppData\Local\Arduino15\packages\STM32
    \hardware\stm32\1.7.0\variants\NUCLEO_F303K8 の下の
    variant.cppに反映させる

 マイクロSD

  • マイクロSDによっては、NSS(CS)が 「inactive」になっても、”MISO"のライン(マイクロSDの出力ライン)を開放しない(Hi-Zにしてくれない)ものがあるらしい(トランセンド8Gと東芝16G共に”H"のままだった…)

    →マイクロSDとCPUの、MISOの信号間を直接つなぐのではなく、470Ωの抵抗を介して接続する(複数のSPIデバイスがMISOラインを共有しているとき)