ホールICについて

ホールIC(DN6851)を使ってみて、S極だけに反応すると知って改めて調べてみたら、いろいろなタイプがあることがわかった。
秋月電子通商で「ホールセンサー」で検索しても「ホールラッチ」、「ホールセンサー」、「ホールIC」の3つの名前が出てくるし…

はじめての人でも分かるホールセンサーの原理と種類

ホールICとは?

カテゴリー: Bookmark, センサー, 基礎知識, 部品 | タグ: , , , | コメントする

ホールIC(DN6851)

昔買ったホールIC(DN6851)を掘り返して動かしてみた。

注文した当時はホールICの事をよく知らなくて単純に磁気を検知するセンサーだと思っていたので、DN6851が磁石のS極しか反応しない事を知らなかった。

データシートを検索してディスコンになっているのを知った。

ホールICのDN6851の動作を確認するため、LEDをつけた回路図です。
回路図
カテゴリー: 部品 | タグ: , , | コメントする

Nゲージ(スピード計測編)

先日YouTubeの動画にコメントをいただいた、Petit Labさんのチャンネルに車両のスピードを計測する動画があった。

実は先日試していたフォトリフレクタで物体の検出をやっていて、これを活かせる方法としてスピード計測はぼんやりと考えていた。実際にやっている人がいるのを知って自分もやってみようと思った。

ついでにOLEDディスプレイもあるので、これでスピードを表示しようと思った。

で、出来たのが次の動画。

フォトリフレクタは赤外線の反射で検出するので、もっとダイレクトに「赤外線の遮蔽で検出した方がいいかな?」と赤外線LEDとフォトトランジスタで検出することにした。
回路は簡単で、次のようにした。

回路図

D1, Q1が先に検出する左側のセンサーになり、D2, Q2が右側のセンサーとなります。
あと、KiCadに部品が無かったので代わりに使った部品に0.96インチのOLEDディスプレイのU1に使わない端子(VLCD, V0)や”3 Lines 12 Character”の文字列がありますが、無視して下さい。

赤外線LEDとフォトトランジスタを別々に設置する必要があり、しかも正確に対峙するように設置したかったので、LEGOテクニックのビームの穴を利用することにした。

センサーフレーム

赤外線LEDとフォトトランジスタは4つの5×3のL字型ビームそれぞれに5つ穴の方の端から2番目に刺した。5mmのサイズだと全部は入らないので、適当に。
それを13穴の直線ビームの端に付けて、それらのビームを9穴のビームでつないだ。
これがセンサーフレームで、中央に線路の直線部分をはめ込んで使用する。
ただし、若干、線路より狭いのでちょっと強めに線路を押し込んだ。

左右のセンサー間の距離

左右のセンサー間の距離は95mmでした。

線路の高さを合わせるために、次のようなものをLEGOテクニックで作った。

線路の下に敷いたもの

上の方の大きなものはセンサーと逆側の直線部分に。その下の2つは各コーナーの頂点部分に。5つ穴のビーム4つはそれらの間に入れた。5つ穴のビームの両端には黒いピンが刺さっています。

Arduinoのスケッチは次のようになります。

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

#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels

// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
#define OLED_RESET     4 // Reset pin # (or -1 if sharing Arduino reset pin)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

#define LOGO_HEIGHT   16
#define LOGO_WIDTH    16
static const unsigned char PROGMEM logo_off[] =
{ B00000000, B00000000,
  B00000000, B00000000,
  B00000000, B00000000,
  B00000000, B00000000,
  B00000000, B00000000,
  B11111111, B11111110,
  B00000001, B11111110,
  B00000001, B11111110,
  B00000001, B11111110,
  B00000001, B11111110,
  B00000001, B11111110,
  B00000001, B11111110,
  B00000001, B11111110,
  B00000000, B00000000,
  B00000000, B00000000,
  B00000000, B00000000 };

static const unsigned char PROGMEM logo_on[] =
{ B00000000, B00000000,
  B11111111, B00000000,
  B11111111, B00000000,
  B11111111, B00000000,
  B11111111, B00000000,
  B11111111, B00000000,
  B11111111, B00000000,
  B11111111, B00000000,
  B11111111, B00000000,
  B10000000, B00000000,
  B10000000, B00000000,
  B10000000, B00000000,
  B10000000, B00000000,
  B10000000, B00000000,
  B10000000, B00000000,
  B10000000, B00000000 };

#define FLAG_ON_VALUE (900)

int analogPin1 = 0;
int analogPin2 = 1;
int ledPin1 = 8;
int ledPin2 = 9;

int val1 = 0;
int val2 = 0;

unsigned char prev_flag1 = 0;
unsigned char curr_flag1 = 0;
unsigned char chng_flag1 = 0;
unsigned char prev_flag2 = 0;
unsigned char curr_flag2 = 0;
unsigned char chng_flag2 = 0;
unsigned char need_draw  = 0;

unsigned long time0 = 0;
unsigned long time1 = 0;
unsigned long time2 = 0;
float val_speed = 0.0;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  Serial.println("SSD1306 OLED 128x64 i2c");

  // SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3D for 128x64
    Serial.println(F("SSD1306 allocation failed"));
    for(;;); // Don't proceed, loop forever
  }

  // Show initial display buffer contents on the screen --
  // the library initializes this with an Adafruit splash screen.
  display.display();
  delay(2000); // Pause for 2 seconds

  // Clear the buffer
  display.clearDisplay();

  pinMode(ledPin1, OUTPUT);
  pinMode(ledPin2, OUTPUT);
  
  drawflags();
  delay(1000);
}

void drawbitmap_off(int x, int y) {
  display.drawBitmap(
    x, y,
    logo_off, LOGO_WIDTH, LOGO_HEIGHT, 1);
}

void drawbitmap_on(int x, int y) {
  display.drawBitmap(
    x, y,
    logo_on, LOGO_WIDTH, LOGO_HEIGHT, 1);
}

void drawflags() {
  int x, y;
  y = LOGO_HEIGHT / 2;
  //y = (display.height() - LOGO_HEIGHT) / 4;
  display.clearDisplay();

  x = display.width() / 4  - LOGO_WIDTH / 2;
  if (val1 > FLAG_ON_VALUE) {
    drawbitmap_on(x, y);    // Draw a small bitmap image
  } else {
    drawbitmap_off(x, y);    // Draw a small bitmap image
  }

  x = display.width() * 3 / 4  - LOGO_WIDTH / 2;
  if (val2 > FLAG_ON_VALUE) {
    drawbitmap_on(x, y);    // Draw a small bitmap image
  } else {
    drawbitmap_off(x, y);    // Draw a small bitmap image
  }

  display.setTextSize(2); // Draw 2X-scale text
  display.setTextColor(SSD1306_WHITE);
  display.setCursor(25, display.height() / 2);
  int speed_int = (int)(val_speed * 3.6 + 0.5);
  if (speed_int < 100) {
    display.print(F(" "));
  }
  if (speed_int < 10) {
    display.print(F(" "));
  }
  display.print(speed_int);
  display.print(F(" km/h"));
  
  display.display();
}

void loop() {
  // put your main code here, to run repeatedly:
  digitalWrite(ledPin1, HIGH);
  digitalWrite(ledPin2, HIGH);
  delay(3);
  val1 = analogRead(analogPin1);
  val2 = analogRead(analogPin2);
  digitalWrite(ledPin1, LOW);
  digitalWrite(ledPin2, LOW);

  need_draw = 0;
  time0 = millis();
  if (time0 - time1 > 15000) {
    val_speed = 0;
    time1 = time2 = time0;
    need_draw = 1;
  }
  if (time0 - time2 > 15000) {
    val_speed = 0;
    time1 = time2 = time0;
    need_draw = 1;
  }
  if (val1 > FLAG_ON_VALUE) {
    curr_flag1 = 1;
  } else {
    curr_flag1 = 0;
  }
  if (prev_flag1 != curr_flag1) {
    chng_flag1 = 1;
    if (curr_flag1 > 0) {
      time1 = millis();
    }
  } else {
    chng_flag1 = 0;
  }
  
  if (val2 > FLAG_ON_VALUE) {
    curr_flag2 = 1;
  } else {
    curr_flag2 = 0;
  }
  if (prev_flag2 != curr_flag2) {
    chng_flag2 = 1;
    if (curr_flag2 > 0) {
      time2 = millis();
      if (time2 > time1) {
        float delta_t = time2 - time1;
        val_speed = 150.0 * 95.0 / delta_t;
      }
    }
  } else {
    chng_flag2 = 0;
  }

  if (chng_flag1 + chng_flag2 + need_draw > 0) {
    drawflags();
  }
  delay(7);
  prev_flag1 = curr_flag1;
  prev_flag2 = curr_flag2;
}
カテゴリー: Arduino, Nゲージ, センサー, 作ったモノ | タグ: , , , , | コメントする

安い中華製ブレッドボード

最近というか数年前から、Amazonで入手可能な安い中華製ブレッドボード。「安くていいな」と何枚か持っているけど、ワイヤーが差しにくかったりしてちょっと使いにくいと思っていた。
で、さらに数年経つと反ってくる現象が出てきた。

反ったブレッドボード(全体)
反ったブレッドボード(前から)
反ったブレッドボード(横から)

こんな感じで、もう一つも反っていてそっちを剥がしてみた。

底の台紙を剥がしてみた

底の両面テープになっている台紙を剥がすと、そのまま内部の金属が剥き出しになる。

ブレッドボードの仕組みがわかりやすい

ブレッドボードの仕組みがわかりやすい。

さらに数年前に秋月電子通商で買った同じ形のブレッドボード(サンハヤト製ではなくても)はワイヤーの刺さり具合もいいし、全然反ってないので、イライラしたくなければちゃんとしたのを買った方がいい。

剥がしたブレッドボードの台紙の上に、ちゃんとしたブレッドボードを貼っておいた。

Arduinoとブレッドボードを1枚のアクリル板に貼ったプラットフォームはとても使い勝手がいいけど、Amazonで売ってるやつに付属のブレッドボードがこの反るブレッドボードだった。

まさかブレッドボードみたいな簡単なものでもダメなものは作れるんだなぁ…

カテゴリー: 作業, 部品 | タグ: , , , , | コメントする

0.96インチ OLEDディスプレイモジュール I2C 128×64 SSD1306 ブルー

部品箱を漁っていたら出てきた小さなディスプレイモジュール。

0.96インチ OLEDディスプレイモジュール 表面
0.96インチ OLEDディスプレイモジュール 裏面

裏面を見るとIIC ADDRESS SELECTとか書いてあって、0x78と0x7Aが選択できるようになっていて、これに騙された…(ここ注意!0x78は0x3Cになるらしい。)

型番とかわからないので、「1インチ i2c 液晶」で検索したらAmazonで違う商品が出たが、関連商品に4ピンのものを発見したので、それと思って「0.96インチ oled i2c」で検索しなおしたら、このページを発見。
https://programresource.net/2015/05/09/2616.html

早速、Arduino IDEでAdafruit SSD1306のライブラリをインストール。

Arduuino IDEでライブラリをインストール(その1)

まずはArduino IDEの「ツール」メニューから「ライブラリを管理…」を選択。

Arduino IDEでライブラリをインストール(その2)

ライブラリマネージャで「adafruit ssd1306」を検索というかフィルタリング。(この図は既にインストールしちゃった後の図なので、インストールボタンの位置とか違っています。)
そして、インストール。

Adafruit SSD1306のサンプルからSSD1306_128x64_i2cを選択
Arduinoと接続

Arduinoの5V, GND, A4, A5にそれぞれ赤, 茶, 黄, オレンジをつないで、OLED側のGND, VCC, SCL, SDAに茶, 赤, オレンジ, 黄をつないだ。

I2Cアドレスが最初は0x3C(これで正しかった)になっていたのを0x78に書き換えて走らせるけど動かない…Adafruit SSD1305のライブラリとかインストールしたりしたけど、動かない…困って検索していたらこのページを見つけた。
https://programresource.net/2020/02/20/2891.html

早速、i2c_scannerをコピペして実行すると、0x3Cに見つかった…

最初のサンプルのI2Cアドレスを0x3Cに戻して実行すると、すんなりと動いた…

動いた時の記録

追記
Amazonの商品説明のところに、「I2Cアドレスが変更可能:0x78に接続すると、0x3Cになります:0x7Aに接続すると、0x3Dになります」って書いてあった…

追記2
3年近く前に記事を書いていた。当時もAdafruit SSD1306ライブラリで動かせなかったようで、この時もI2Cアドレスを間違えていたのかも知れない。
https://physicom.ossantube.com/?p=6135

カテゴリー: Arduino, 部品 | タグ: , , , , | コメントする

Nゲージ(LEGO実験編)

Nゲージでケーブルを線路の下にはわせたりしたい時のためにLEGOで線路を浮かせたい。
別の目的で持っていた、LEGOクラシック11005を使って試してみる。

LEGO CLASSIC 11005
カテゴリー: Nゲージ, 作ったモノ | タグ: , | コメントする

Nゲージ(Lチカ、電車と一緒に編)

最後にLチカと電車(使ったのは小形車両用動力ユニットです)を一緒に動かしてみました。

電車が映らない範囲が大きいので、ちょっとしか動かせませんが、一緒に動かすことが出来ました。

カテゴリー: Nゲージ, 作ったモノ | タグ: , , | コメントする

Nゲージ(Lチカ コントローラー下でのテスト編)

単体での動作確認できたので、レイアウトを組んだNゲージの線路に載せてテストしました。

カテゴリー: Nゲージ, 作ったモノ | タグ: , | コメントする

Nゲージ(Lチカ動作確認編)

Nゲージは線路から電車に電気を供給しているという事で、線路の極性とか知りたいと思って、まずはLチカをやってみる。

まずは最終イメージ。

線路に赤と緑のLEDと抵抗で作ったものを乗せてあります。
最終イメージ

最初は以前に投稿した小形車両用動力ユニットか台車に乗せたかったんですが、あまりに小さくて線路に乗せるのを作るのが精一杯な感じでした。

回路は次のように簡単なものです。バランスを取るために抵抗を2つに分けて左右に配置してあります。

回路図

最初、5mmのLEDをイメージしていましたが、3mmのLEDにしました。
また、最初から最終イメージがあったわけじゃなくて、作りながら最終的な形になりました。安定して組める形を探ってははんだ付けして、最終的に余計な部分を切り取って成形しました。

作っていく過程の写真です。

LEDを背中合わせに、しかし極性は逆になるようにつなぎます。
LEDを背中合わせに、しかし極性は逆になるようにつなぎます。
はんだ付けしたところ。
はんだ付けしたところ。
垂直に抵抗をはんだ付け(反対側も付けます)。
垂直に抵抗をはんだ付け(反対側も付けます)。
サイズを測って幅が9mm以下になるように余分な部分を切除します。
サイズを測って幅が9mm以下になるように余分な部分を切除します。
なんとか8mmにまで短く出来ました。
なんとか8mmにまで短く出来ました。
抵抗のワイヤーを成形して完成。
抵抗のワイヤーを成形して完成。
線路に乗せてみて確認。
線路に乗せてみて確認。

動作確認の動画です。

カテゴリー: Nゲージ, 作ったモノ | タグ: , | コメントする

Nゲージ(収納編)

今のところ、3リットルのパックにACアダプター以外は入ってます。

3リットルの食品用シール容器に入ったNゲージ部品。
カテゴリー: Nゲージ | タグ: , | コメントする