shonen.hateblo.jp

やったこと,しらべたことを書く.

Windowsアプリケーションから Arduino の OLED ディスプレイを操作する(HSP - テキスト送信編)

目標

  • シリアル通信を介してUSBで接続された ArduinoMicro+OLED にテキストを表示する.

f:id:m_buyoh:20180130003243j:plain:w400

環境

前提

  • "Adafruit SSD1306" と "Adafruit GFX Library" を使用したサンプルが動作すること.

次の記事を参考にしてください.

qiita.com

特にI2Cアドレスのトラップは注意.

PC上で入力した文字列をArduino上で表示

文字列の表示

  • 画面にHello, world!と表示するArduinoのコードは次のようになる.
  • 要はdisplay.println関数がAdafruitのライブラリに用意されているので,これを使うだけ.
  • 必要に応じて display.begin(SSD1306_SWITCHCAPVCC, 0x3C); を書き換えてください.
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define OLED_RESET 4
Adafruit_SSD1306 display(OLED_RESET);

#if (SSD1306_LCDHEIGHT != 64)
#error("Height incorrect, please fix Adafruit_SSD1306.h!");
#endif


void setup() {
  Serial.begin(9600);

  // by default, we'll generate the high voltage from the 3.3v line internally! (neat!)
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);  // initialize with the I2C addr 0x3D (for the 128x64)
  // init done
  
  // Show image buffer on the display hardware.
  // Since the buffer is intialized with an Adafruit splashscreen
  // internally, this will display the splashscreen.
  // display.display();
  // delay(2000);

  // Clear the buffer.
  display.clearDisplay();

  display.setTextSize(1);
  display.setTextColor(WHITE);

  // print "Hello, world!"
  display.setCursor(0,0);
  display.println("Hello, world!");
  
  // redraw
  display.display();
}

void loop() {
  // put your main code here, to run repeatedly:
}

シリアルモニタから入力した文字列を画面に表示する.

  • シリアル通信によって届いたデータを確認する方法は,次のリファレンスが役に立つ.
  • https://www.arduino.cc/reference/en/language/functions/communication/serial/read/
  • 以下のコードをArduinoに書き込もう.
  • 「メニューバー」→「ツール」→「シリアルモニタ」を開き,右下の改行コードを「LFのみ」に変える.
  • 文字列を入力して送信ボタンを押すと,OLEDに入力した文字列が表示されるはず.
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define OLED_RESET 4
Adafruit_SSD1306 display(OLED_RESET);

#if (SSD1306_LCDHEIGHT != 64)
#error("Height incorrect, please fix Adafruit_SSD1306.h!");
#endif


void setup() {
  Serial.begin(9600);

  // by default, we'll generate the high voltage from the 3.3v line internally! (neat!)
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);  // initialize with the I2C addr 0x3D (for the 128x64)
  // init done

  display.setTextSize(1);
  display.setTextColor(WHITE);
  
  display.clearDisplay();
  display.display();
  delay(2000);
}


#define BUFFSIZE 250
char buff[BUFFSIZE+1];
int buffptr = 0;

void loop() {

  while (Serial.available() > 0){
    int c = Serial.read();
    if (c == '\n'){
      buff[buffptr] = 0;
      display.clearDisplay();
      display.setCursor(0,0);
      display.println(buff);
      display.display();
      buffptr = 0;
    }
    else if (buffptr < BUFFSIZE){
      buff[buffptr++] = c;
    }
  }
}
  • シリアルから届いた文字が\n(改行)ならば,配列buffに貯めていた文字列をprintする.
  • buff[buffptr]=0の意味については Google検索

シリアルモニタを自分で作ろう

#include "hspext.as"

#const COMPORT 3

    buff = ""
    
    onexit *exit
    comopen COMPORT, "baud=9600 parity=N data=8 stop=1"
    if stat : dialog "error" : end

    screen 0, 320, 240
    objmode 2
    mesbox buff, 320, 200
    
    button gosub "submit", *submit
    
    stop
    
*submit
    comput buff+"\n"
    return
    
*exit
    comclose
    end

改行が効かない!!

  • 試してみると分かる通り,実は改行が効かない.
  • 理由は簡単で,今Arduino用に書いたコードは改行を文字列の末端としているから.
  • そこで,文字列の末端とする文字コードを改行以外の何かに割り当てれば良い.
  • 例えば\0がある.

以上を実装すると,Arduino側のコード,HSP側のコードは次のようになる.

完成品

#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define OLED_RESET 4
Adafruit_SSD1306 display(OLED_RESET);

#if (SSD1306_LCDHEIGHT != 64)
#error("Height incorrect, please fix Adafruit_SSD1306.h!");
#endif


void setup() {
  Serial.begin(9600);

  // by default, we'll generate the high voltage from the 3.3v line internally! (neat!)
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);  // initialize with the I2C addr 0x3D (for the 128x64)
  // init done
  
  // Show image buffer on the display hardware.
  // Since the buffer is intialized with an Adafruit splashscreen
  // internally, this will display the splashscreen.
  display.display();
  delay(2000);

  display.setTextSize(1);
  display.setTextColor(WHITE);
  
  display.clearDisplay();
  display.display();
}


#define BUFFSIZE 250
char buff[BUFFSIZE+1];
int buffptr = 0;

void loop() {

  while (Serial.available() > 0){
    int c = Serial.read();
    if (c == 0){
      buff[buffptr] = 0;
      display.clearDisplay();
      display.setCursor(0,0);
      display.println(buff);
      display.display();
      buffptr = 0;
    }
    else if (buffptr < BUFFSIZE){
      buff[buffptr++] = c;
    }
  }
}
#include "hspext.as"

#const COMPORT 3

    buff = ""
    
    onexit *exit
    comopen COMPORT, "baud=9600 parity=N data=8 stop=1"
    if stat : dialog "error" : end

    screen 0, 320, 240
    objmode 2
    mesbox buff, 320, 200
    
    button gosub "submit", *submit
    
    stop
    
*submit
    comput buff
    computc 0
    return
    
*exit
    comclose
    end