t49's blog

電子工作初心者のブログ

BadUSBを自作した話

概要

t49.hatenablog.jp

先日製作したスクリーンセーバーキラーはPCにHID(Human Interface Device)のマウスとして認識させています。
今回はキーボードと認識させて、任意のキー入力を行い、管理者権限でコマンドプロンプトを起動後、メモ帳を開いて文字を入力するという実験を行いました。

管理者権限を取得しキー入力ができれば、様々な悪さができてしまいます。
そのような悪意あるプログラムが仕込まれているUSBのことをBadUSBと呼びます。

実験内容

作成した実験用のプログラムは、下記のようにしました。

  1. 「Win」 + 「r」(「ファイル名を指定して実行」を開く )
  2. "cmd.exe"と入力
  3. 「Ctrl」+ 「Shift」+ 「Enter」(管理者権限で実行)
  4. 「このアプリがデバイスに変更を加えることを許可しますか?」に対して「←」で「はい」を選択
  5. 管理者権限で「cmd.exe」が開く
  6. "notepad.exe"と入力
  7. 「Ctrl」+ 「;」(画面録画した際文字が見えづらいので、文字を最大限まで拡大)
  8. 任意の文字を入力(helllo, worldとASCII文字列)

実験結果

実際にUSBポートに差し込むと以下のGIF動画のようにコマンドプロンプトが開き、「notepad.exe」を実行し文字列を入力し始めました。
※GIF動画では見えませんが、管理者権限で実行されています。

実行結果(GIF)

このようにUSBフラッシュメモリの形状に化けたキーボードは普段我々がしているように自由にPCを操作することが可能です。

特にWindowsの管理者アカウントでログインしている場合、管理者権限が必要な時、「このアプリがデバイスに変更を加えることを許可しますか?」に対して「←」で「はい」を選択するだけでいいので、BadUSBは簡単に管理者権限を取得してしまいます。

逆に標準アカウントから管理者権限を得ようと思うと管理者のパスワードを入力しなければならないので、上記の実験用のプログラムは途中で失敗します。
なぜなら今回製作したBadUSBの実態はUSBフラッシュメモリの形状をしたキーボードに過ぎず、プログラムした決まったキー入力しか行えないからです。
英数記号で総当りを行うことができれば理論上、管理者権限の取得は可能ですが、余程簡単なパスワードでない限り現実的ではありません。

まとめ

  • BadUSBは攻撃が成立するとユーザが行うキーボード・マウスの操作を全て行うことができるため非常に危険。
  • アウトプットはできるがインプットはできないため、単純な操作しかできない。
  • 攻撃を行うにはBadUSBを対象のPCに挿し込む必要がある。

以上のことから、下記のような対策が有効と考えました。

  • 不審なUSBデバイスは接続しない。
  • 標準アカウントを使用し管理者権限をパスワードで保護する。
  • 信頼できない場所では、下記のような製品でUSBポートをロックする。

スクリーンセーバーキラーを自作した話

コピー中やインストール中などの作業進行中はなるべく画面をつけておきたい、しかし席は離れたい時があります。
今回はそんな時のためにスクリーンセーバキラーを製作しました。
基板のままでは使い辛いので、3Dプリンタでケースも製作しました。

基板とケース

このスクリーンセーバーキラーをUSBポートに挿すと、PCはHID(Human Interface Device)のマウスと認識し、下記GIF画像のようにカーソルは正方形状に移動し続けます。

実行結果(GIF)

なお、カーソルの動作はプログラムで自由に制御することができます。
今回は絶対に画面を消したくないので、派手な動きにしてみました。

今回はマウスとして振る舞いますが、キーボードとして振る舞うことも可能です。

https://t49.jp/entry/badusb_experimentt49.jp

【ADT7310】ArduinoでLCDに気温を表示する

実行結果

概要

Arduinoを使用して、温度センサの値をキャラクLCDに表示させました。

部品

  • マイコンボード: Arduino Uno
  • I2C接続小型キャラクLCDモジュール: AQM0802A-FLW-GBW
  • 温度センサモジュール: AE-ADT7310

回路図

arduino-adt7310-lcd

プログラム

ライブラリ「FaBo 213 LCD mini AQM0802A」を使用しているため、Arduino IDEのライブラリマネージャーからインストールします。

ライブラリを事前にインストール

#include <FaBoLCDmini_AQM0802A.h>
#include<SPI.h>
#define SS 10
#define MOSI 11
#define MISO 12
#define SCLK 13

// short: 2byte
short raw_data;
double temperature;

FaBoLCDmini_AQM0802A lcd;

void setup(){
  // シリアル通信を開始
  Serial.begin(9600);
  Serial.println("Serial start");
  
  // 通信を無効
  digitalWrite(SS,HIGH);
  
  delay(300);

  // SPI通信を開始
  SPI.begin();
  Serial.println("SPI start");
  
  // 通信を有効
  digitalWrite(SS,LOW);

  // 連続読み取りモードを終了
  SPI.transfer(0x50);
  
  delay(300);

  // コマンドバイト: 設定レジスタに書き込み
  SPI.transfer(0x0C);
  // 設定レジスタ: 16bit分解能
  SPI.transfer(0x80);
  
  delay(300);
  
  // 温度レジスタに対して連続読み込み
  SPI.transfer(0x54);

  delay(300);

   // set up the LCD:
   lcd.begin();
   lcd.command(0x38);
   lcd.command(0x39);
   lcd.command(0x14);
   lcd.command(0x73);
   lcd.command(0x51);
   lcd.command(0x6c);
   lcd.command(0x38);
   lcd.command(0x01);
   lcd.command(0x0c);
   // Print a message to the LCD.
   lcd.print("hello!");
   
   delay(5000);
}
  
void loop(){
  // 16bitで温度データを取得
  raw_data = SPI.transfer16("");

  Serial.print("BIN DATA: ");
  Serial.println(raw_data,BIN);

  lcd.clear();
  
  // 符号ありの為、32768 = 0b1000_0000_0000_0000からマイナス
  if(raw_data >= 32768){
    // 65535 = 0b1111_1111_1111_1111 = -1と表現
    // 65536を引くことで、65535から-1と表現する
    // 16bit分解能: 0.0078°C ≒ 1/128
    temperature = (double)raw_data-65536/128;
  } else {
    temperature = (double)raw_data/128; 
  }
  
  lcd.print(temperature);
  Serial.print(temperature,4);
  Serial.println("[°C]");
  
  delay(500);
}

【AE-AQM1248A】ArduinoでグラフィックLCDを使う

実行結果

概要

Arduino Unoを使って、自作した32*32フォントの数字をグラフィックLCDに表示するデモを行いました。

部品

マイコンボード: Arduino Uno
・グラフィックLCD : AE-AQM1248A
・レベルシフタ: BSS138使用 4ビット双方向ロジックレベル変換モジュール(AE-LCNV4-MOSFET)

Arduino Unoの動力及び信号の電圧は5V、グラフィックLCDは3.3Vで動作するため、レベルシフタを使用しています。

回路図

arduino-AE-AQM1248A

プログラム

1ms毎にカウントした値をグラフィックLCDに表示しています。

#include<SPI.h>
// SPI Write = LOW,SPI not Write = HIGH
#define CS 10

// cmd = LOW, data = HIGH
#define RS 9

#define SCLK 13
#define SDI 11

#define PAGE_MAX 6
#define COL_MAX 128

// 32×32 bitmap fonts 0-9
char zero[][32] = {
  {0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0xFE,0xFE,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0xFE,0xFE,0xFE,0x00,0x00,0x00,0x00,0x00,0x00},
  {0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00},
  {0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00},
  {0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x7F,0x7F,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x7F,0x7F,0x7F,0x00,0x00,0x00,0x00,0x00,0x00}
};

char one[][32] = {
  {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0xFE,0xFE,0x00,0x00,0x00,0x00,0x00,0x00},
  {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00},
  {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00},
  {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x7F,0x7F,0x00,0x00,0x00,0x00,0x00,0x00}
};

char two[][32] = {
  {0x00,0x00,0x00,0x00,0x00,0x00,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0xFE,0xFE,0xFE,0x00,0x00,0x00,0x00,0x00,0x00},
  {0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00},
  {0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00},
  {0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x7F,0x7F,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x00,0x00,0x00,0x00,0x00,0x00}
};

char three[][32] {
  {0x00,0x00,0x00,0x00,0x00,0x00,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0xFE,0xFE,0xFE,0x00,0x00,0x00,0x00,0x00,0x00},
  {0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00},
  {0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00},
  {0x00,0x00,0x00,0x00,0x00,0x00,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x7F,0x7F,0x7F,0x00,0x00,0x00,0x00,0x00,0x00}
};

char four[][32] {
  {0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0xFE,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0xFE,0xFE,0x00,0x00,0x00,0x00,0x00,0x00},
  {0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00},
  {0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00},
  {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x7F,0x7F,0x00,0x00,0x00,0x00,0x00,0x00},
};

char five[][32] {
  {0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0xFE,0xFE,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x00,0x00,0x00,0x00,0x00,0x00},
  {0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0x00,0x00,0x00,0x00,0x00,0x00},
  {0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00},
  {0x00,0x00,0x00,0x00,0x00,0x00,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x7F,0x7F,0x7F,0x00,0x00,0x00,0x00,0x00,0x00}
};

char six[][32] {
  {0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0xFE,0xFE,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x00,0x00,0x00,0x00,0x00,0x00},
  {0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0x00,0x00,0x00,0x00,0x00,0x00},
  {0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00},
  {0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x7F,0x7F,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x7F,0x7F,0x7F,0x00,0x00,0x00,0x00,0x00,0x00}
};

char seven[][32]{
  {0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0xFE,0xFE,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0xFE,0xFE,0xFE,0x00,0x00,0x00,0x00,0x00,0x00},
  {0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00},
  {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00},
  {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x7F,0x7F,0x00,0x00,0x00,0x00,0x00,0x00}
};

char eight[][32] {
  {0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0xFE,0xFE,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0xFE,0xFE,0xFE,0x00,0x00,0x00,0x00,0x00,0x00},
  {0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00},
  {0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00},
  {0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x7F,0x7F,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x7F,0x7F,0x7F,0x00,0x00,0x00,0x00,0x00,0x00}
};

char nine[][32] {
  {0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0xFE,0xFE,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0xFE,0xFE,0xFE,0x00,0x00,0x00,0x00,0x00,0x00},
  {0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00},
  {0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00},
  {0x00,0x00,0x00,0x00,0x00,0x00,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x7F,0x7F,0x7F,0x00,0x00,0x00,0x00,0x00,0x00}
};

void sendCmd(char cmd) {
  // SPI connection enable
  digitalWrite(CS,LOW);
  digitalWrite(RS,LOW);
  
  // send data
  SPI.transfer(cmd);

  // SPI connection disable
  digitalWrite(CS,HIGH);
  digitalWrite(RS,HIGH);
}

void sendData(char data){
  digitalWrite(CS,LOW);
  digitalWrite(RS,HIGH);
  SPI.transfer(data);
  digitalWrite(CS,HIGH);
}

int dec2array(unsigned int num,unsigned int* nums){
  unsigned int shou = num;
  unsigned int cnt = 0;
  
  while(shou != 0){
    nums[cnt++] = shou%10;
    shou = shou/10;
  }

  return cnt;
}

void printNum(int num){
  unsigned int nums[64];
  int page,col;
  int cmd_msb,cmd_lsb;

  int cnt = dec2array(num,nums);
  
  for(int i=0;i<cnt;i++){
    for(page=0;page<4;page++){
      sendCmd(0xB1+page);
      for(col=i*32;col<i*32+32;col++){
        cmd_msb = 0x10 | col >> 4;
        sendCmd(cmd_msb);
        cmd_lsb = 0x00 | col & 0x0F;
        sendCmd(cmd_lsb);

        switch(nums[cnt-1-i]){
          case 0:
            sendData(zero[page][col-i*32]); break;
          case 1:
            sendData(one[page][col-i*32]); break;
          case 2:
            sendData(two[page][col-i*32]); break;
          case 3:
            sendData(three[page][col-i*32]); break;
          case 4:
            sendData(four[page][col-i*32]); break;
          case 5:
            sendData(five[page][col-i*32]); break;
          case 6:
            sendData(six[page][col-i*32]); break;
          case 7:
            sendData(seven[page][col-i*32]); break;
          case 8:
            sendData(eight[page][col-i*32]); break;
          case 9:
            sendData(nine[page][col-i*32]); break;
          default:
            sendData(eight[page][col-i*32]); Serial.println(nums[cnt-1-i]); break;
        }
      }
    }
  }
}

/*
 * 1011 0000 (0xB0) = Page 0
 * 1011 0001 (0xB1) = Page 1
 * 1011 0010 (0xB2) = Page 2
 * 1011 0011 (0xB3) = Page 3
 * 1011 0100 (0xB4) = Page 4
 * 1011 0101 (0xB5) = Page 5
 */
void lcd_clear(){
  int page,col;
  int col_address = 0;
  int cmd_msb,cmd_lsb;
  
  for(page=0;page<PAGE_MAX;page++){
    // ページアドレスを指定
    sendCmd(0xB0+page);
    for(col=0;col<COL_MAX;col+=8){
      cmd_msb = 0x10 | col >> 4;
      sendCmd(cmd_msb);
      cmd_lsb = 0x00 | col & 0x0F;
      sendCmd(cmd_lsb);

      for(int i=0;i<8;i++){
        sendData(0);
      }
    }
  } 
}

void lcd_all_on(){
  int page,col;
  int col_address = 0;
  int cmd_msb,cmd_lsb;
  
  for(page=0;page<PAGE_MAX;page++){
    // ページアドレスを指定
    sendCmd(0xB0+page);
    for(col=0;col<COL_MAX;col+=8){
      cmd_msb = 0x10 | col >> 4;
      sendCmd(cmd_msb);
      cmd_lsb = 0x00 | col & 0x0F;
      sendCmd(cmd_lsb);

      for(int i=0;i<8;i++){
        sendData(0xFF);
      }
    }
  } 
}

void setup() {
  pinMode(CS,OUTPUT);
  pinMode(RS,OUTPUT);
  pinMode(SCLK,OUTPUT);
  pinMode(SDI,OUTPUT);
  
  Serial.begin(9600);

  SPI.setBitOrder(MSBFIRST);
  
  // SPI function enable
  SPI.begin();
  
  // Display = OFF
  sendCmd(0xAE);
  // ADC = normal
  sendCmd(0xA0);
  // Common output = revers
  sendCmd(0xC8);
  // bias = 1/7
  sendCmd(0xA3);

  // regulator on
  sendCmd(0x2C);
  delay(2);
  sendCmd(0x2E);
  delay(2);
  sendCmd(0x2F);

  // contrast
  sendCmd(0x23);
  sendCmd(0x81);
  sendCmd(0x1C);

  // display setting
  sendCmd(0xA4);
  sendCmd(0x40);
  sendCmd(0xA6);
  sendCmd(0xAF);

  lcd_all_on();
  delay(3000);
  lcd_clear();
}

unsigned int test = 0;
void loop() {
  printNum(test++);
  delay(1);
}

【ADT7310】Arduinoで温度センサを使う

ADT7310の使い方を紹介します。
今回は、温度センサ「ADT7310」から温度を読み取り、シリアル通信でPCに値を表示します。
使用するマイコンボードはArduino Unoで、C言語を使用しています。

続きを読む

【レビュー】アイリスオーヤマ ラミネータ HSL-A34-W

家に一台あると便利かなと思いラミネータを購入しました。
ラミネータとは、印刷物を保護するために特殊なフィルムを貼る装置です。
お店のPOPなどで見るあれです。
大は小を兼ねるので、下記のA3サイズと、尖った角を丸くする「かどまる」を購入しました。

続きを読む

【レビュー】アイロボット(iRobot) ルンバi2

筆者はリビング、ダイニング用にルンバ870を所有いるのですが、 自室を掃除する時は、ルンバをリビングから自室に持ち運んでいました。
ルンバの価格も安くなってきましたので、ルンバi2を自室用に購入しました。

続きを読む

【レビュー】Ryzen 9 5950X, GTX 1660Ti搭載PCのベンチマークテスト

先代のPCがIntel i7 2700Kで組んだPCで、ここ最近までいわゆるSandy Bridgeおじさんでした。
現在も事務用途では全く問題なく使用することができますので、 先代はサブPCとして使用することにして、今年の初めに新たにPCを組みました。

今更ですが、今後の参考の為に構成や性能を記録していきたいと思います。

続きを読む

【TCP/IP】ソケットプログラミング

IoT全盛期(?)で低レイヤーから通信をすることが多くなったと思います。

ArduinoやRaspberryPiなどは先人達が作ってくれたありがたいライブラリが使えるので特に意識することなく使用していましたが、 その裏で何が起こっているのか、通信の概念の一例としてソケット通信を勉強しようと思いました。

続きを読む

【nc(netcat)】TCPクライアント・サーバとして使う

[サーバ側] 指定したPortでTCP/IPアクセスをListenする

nc -l [Port]

[クライアント側] IP,Portを指定してアクセスする

nc [IP] [Port]

結果

9999ポートで待ち受け、localhostで接続する。

サーバ、クライアント双方からテキストを送信できました。