工業製造
産業用モノのインターネット | 工業材料 | 機器のメンテナンスと修理 | 産業プログラミング |
home  MfgRobots >> 工業製造 >  >> Manufacturing Technology >> 製造プロセス

Arduino Nanoで自作オシロスコープ(10Hz〜50kHz)128×64 LCD搭載

必要な部品と用品

Arduino Nano R3×1
電解コンデンサ 100µF×1
ST7920 LCD 128×64ドット×1
ロータリーポテンショメーター×2
タクトスイッチ(モーメンタリ)×3

必要な工具

使用アプリ

プロジェクト概要

外部DACチップを使わず、Arduino単体で10Hz〜50kHzという広帯域を実現したシンプルなオシロスコープです。表示は128×64ドットのST7920 LCDで、波形表示エリア96×64、情報表示エリア32×64に周波数、Vppなどを表示します。

構成部品は極めて少なく、以下のみです。

主な機能:

元コードはWu Hanqing氏のブログで公開されており、筆者は過去のプロジェクトのハードウェアに合わせて最小限の修正を加えました。大画面で視認性が高く、オートトリガーの性能も驚くほど良好です。垂直位置は50kΩ、コントラストは10kΩのポテンショメーターで調整。正弦波・矩形波発生器で動作確認済み。

プロ仕様ではありませんが、教育用途や低周波信号の簡易チェックに十分使え、極めて安価かつ簡単に製作可能です。

スケッチ(コード)

U8glibライブラリを使用します。

#include <U8glib.h>
U8GLIB_ST7920_128X64_4X u8g(6, 5, 4); // SCK, MOSI, CS

int Input = A0;
int Key_add = 8;
int Key_sub = 9;
int Key_hold = 10;
int x, y;
int i, i1, i2, V_min, V_max, V_mid, t, t0, t1, sta, Key = 1, hold = 0;
long Freq;
float Vpp;
int Y[96];
int Buffer[192];

// 起動画面用ビットマップデータ(省略:元コード参照)
const uint8_t L[] PROGMEM = { ... };

void setup() {
  pinMode(Key_add, INPUT); digitalWrite(Key_add, HIGH);
  pinMode(Key_sub, INPUT); digitalWrite(Key_sub, HIGH);
  pinMode(Key_hold, INPUT); digitalWrite(Key_hold, HIGH);
  ADMUX = 0x60;  // ADC設定
  ADCSRA = 0xe2; // ADC設定
  u8g.setFont(u8g_font_5x7);
  u8g.firstPage();
  do { u8g.drawBitmapP(0, 0, 16, 64, L); } while (u8g.nextPage());
  delay(2000);
}

void loop() {
  sample();
  Measure();
  Transform();
  Key_scan();
  if (hold == 0) {
    u8g.firstPage();
    do { draw(); } while (u8g.nextPage());
  }
}

void sample() {
  for (i = 0; i < 192; i++) {
    Buffer[i] = ADCH;
    switch (Key) {
      case 1: break;
      case 2: delayMicroseconds(4); break;
      case 3: delayMicroseconds(10); break;
      case 4: delayMicroseconds(23); break;
      case 5: delayMicroseconds(60); break;
      case 6: delayMicroseconds(123); break;
      case 7: delayMicroseconds(248); break;
      case 8: delayMicroseconds(623); break;
      case 9: delayMicroseconds(1247); break;
    }
  }
}

void Measure() {
  V_max = Buffer[0]; V_min = Buffer[0];
  for (i = 0; i < 192; i++) {
    if (Buffer[i] > V_max) V_max = Buffer[i];
    if (Buffer[i] < V_min) V_min = Buffer[i];
  }
  V_mid = (V_max + V_min) / 2;
  Vpp = (V_max - V_min) * 5.0 / 255.0;

  for (i = 0; i < 97; i++) {
    if (Buffer[i] < V_mid && Buffer[i+1] >= V_mid) { i1 = i; break; }
  }
  for (i = i1 + 1; i < 98 + i1; i++) {
    if (Buffer[i] < V_mid && Buffer[i+1] >= V_mid) { i2 = i; break; }
  }
  t = i2 - i1;
  if (t > 0) Freq = 8000 / t; else Freq = 0;
}

void Transform() {
  for (sta = 0; sta < 96; sta++) {
    if (Buffer[sta] < 128 && Buffer[sta+2] > 128) break;
  }
  for (i = 0; i < 96; i++) Y[i] = 63 - (Buffer[i+sta] >> 2);
}

void draw() {
  for (x = 0; x < 95; x++) u8g.drawLine(x, Y[x], x, Y[x+1]);
  u8g.drawFrame(0, 0, 97, 64);
  u8g.drawLine(48, 0, 48, 63);
  u8g.drawLine(0, 32, 96, 32);
  for (x = 0; x < 96; x += 8) u8g.drawLine(x, 31, x, 33);
  for (y = 0; y < 64; y += 8) u8g.drawLine(47, y, 49, y);
  for (x = 8; x < 96; x += 8) for (y = 8; y < 64; y += 8) u8g.drawPixel(x, y);

  u8g.drawStr(98, 7, "MS/div");
  u8g.drawStr(98, 23, "V/div");
  u8g.drawStr(98, 30, "0.324");
  u8g.drawStr(98, 40, "Vpp");
  u8g.setPrintPos(98, 47); u8g.print(Vpp); u8g.drawStr(118, 47, "V");
  u8g.drawStr(98, 55, "F(HZ)");

  switch (Key) {
    case 1: u8g.drawStr(98, 14, "0.02"); u8g.setPrintPos(98, 62); u8g.print(Freq * 50); break;
    case 2: u8g.drawStr(98, 14, "0.05"); u8g.setPrintPos(98, 62); u8g.print(Freq * 20); break;
    case 3: u8g.drawStr(98, 14, " 0.1"); u8g.setPrintPos(98, 62); u8g.print(Freq * 10); break;
    case 4: u8g.drawStr(98, 14, " 0.2"); u8g.setPrintPos(98, 62); u8g.print(Freq * 5); break;
    case 5: u8g.drawStr(98, 14, " 0.5"); u8g.setPrintPos(98, 62); u8g.print(Freq * 2); break;
    case 6: u8g.drawStr(98, 14, " 1");   u8g.setPrintPos(98, 62); u8g.print(Freq); break;
    case 7: u8g.drawStr(98, 14, " 2");   u8g.setPrintPos(98, 62); u8g.print(Freq / 2); break;
    case 8: u8g.drawStr(98, 14, " 5");   u8g.setPrintPos(98, 62); u8g.print(Freq / 5); break;
    case 9: u8g.drawStr(98, 14, " 10");  u8g.setPrintPos(98, 62); u8g.print(Freq / 10); break;
  }
}

void Key_scan() {
  if (digitalRead(Key_add) == LOW) { while (digitalRead(Key_add) == LOW); Key++; if (Key == 10) Key = 9; delay(10); }
  if (digitalRead(Key_sub) == LOW) { while (digitalRead(Key_sub) == LOW); Key--; if (Key == 0) Key = 1; delay(10); }
  if (digitalRead(Key_hold) == LOW) { while (digitalRead(Key_hold) == LOW); hold = ~hold; delay(10); }
}

回路図

Arduino Nanoで自作オシロスコープ(10Hz〜50kHz)128×64 LCD搭載

製造プロセス

  1. 自作LUMAZOID:Arduino音楽ビジュアライザーDIYガイド
  2. Arduino Nanoで20kHzオシロスコープを自作:Nokia 5110 LCD搭載・簡易DIYガイド
  3. Arduinoでアイアンマンを自作:部品・センサー・手順ガイド
  4. ArduinoとBluetoothで作るスマート紛失防止タグ「Find Me」
  5. PIRセンサー連動 インタラクティブLEDマトリクスドアディスプレイ - ホリデーグリーティング
  6. DIY Arduino加湿器コントローラー:リレーを用いた安全な高電圧制御
  7. ArduinoとNokia 5110ディスプレイで自作電圧計:ステップバイステップガイド
  8. Arduino超音波センサーとProcessingで作るリアルタイム距離測定ソナー
  9. MobBob:Arduino製ロボットをAndroidスマホでシームレスに制御
  10. Arduino Nanoで自作オシロスコープ(10Hz〜50kHz)128×64 LCD搭載
  11. ゲーム用カスタムArduinoジョイスティックハンドルの製作