KiCadの起動がスムーズに

macOS 11 Big SurでArduino IDEがちゃんと起動しない件でJavaを更新したら、KiCadの起動がスムーズになった。それまでは起動にかなり時間がかかって、最初のうちはフリーズしたんじゃないかと強制終了してたくらいに時間がかかっていた。

カテゴリー: KiCad, ソフトウェア | タグ: , | コメントする

macOS 11 Big SurでArduino IDEがうまく起動しない

macOS 11 Big SurでArduino IDEが起動しない(3回に1回くらいは起動する)現象があって、さすがにググったらあった。

Javaを更新すればいいみたい。

https://wolfpaulus.com/java-on-macos-big-sur/
ここを参考にJavaをインストール

https://adoptopenjdk.net/archive.html?variant=openjdk11&jvmVariant=hotspot

ここから選択されているOpenJDK11, Hotspotのインストーラーをダウンロードしてインストール。

コレでArduino IDEがちゃんと起動するようになった。
と、思ったけどダメ。「再度開く」で起動はする。

カテゴリー: Arduino, ソフトウェア | タグ: | コメントする

リードスイッチ

Amazonでリードスイッチという磁石に反応するスイッチを見つけたので、試しに買ってみた。

リードスイッチ
リードスイッチ

大きさ的にホールICの方が小さいし、反応範囲(最大で約5mm。3mmくらいだと確実。)的にもホールICと大差ないのであまり利用価値はないかと思う。後、真ん中より両端の方がより反応するので長さ方向に磁石が動く場合、2回反応する可能性がある。

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

コンデンサによってLEDが消えるのを遅延させる

以前の記事で車両の位置表示を作成したが、レイアウトを変更するたびにプログラムを書き換えないといけないので、センサーと表示器を1:1でモジュール化しようと考えた。

しかし、車両がホールIC上を通過する時に意外に短いので単純にホールICのVoutでLEDをON/OFFさせるとLEDの点灯時間が短すぎる。実際にプログラム内で0.2秒消灯を遅らせていた。それで、コンデンサでLEDが消えるのを遅延させるテストをする事にした。

回路図は次のようにした。
(2021/06/23にYouTube動画のコメントにて、650 gx_xperia さんより指摘を受け修正しました。)

回路図(修正板)
回路図(修正板)

回路図を実際に回路を組んで試したら、16V 47μFでも充分長い感じ。

動画の中の回路図には誤りがありました。上記の「回路図(修正板)」を参照してください。

カテゴリー: 作ったモノ, 回路, 部品 | タグ: , , , , , , | コメントする

Nゲージ ホールICによる位置表示

ホールICは単純なので数を増やすのが簡単という事で、ホールIC6つにケーブルをつけてレイアウト上に配置して、車両の位置を表示してみた。

レイアウト上に6つのホールICを配置
レイアウト上に6つのホールICを配置

実際に動かした様子。

回路図はこちら。

回路図

スケッチはこちら。

#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 LEN_124 28
#define HALF_124  (LEN_124/2)
#define LEN_117 24
#define HALF_117  (LEN_117/2)
#define SIZE_SENSOR 6
#define MARK_SENSOR 3

#define CENTER_X  (SCREEN_WIDTH/2)
#define CENTER_Y  (SCREEN_HEIGHT/2)

#define NUM_SENSORS 6

typedef struct {
  int x, y;
} Point;
Point pts[NUM_SENSORS] = {
  {CENTER_X-HALF_124, CENTER_Y+LEN_117},
  {CENTER_X+HALF_124, CENTER_Y+LEN_117},
  {CENTER_X+HALF_124+LEN_117, CENTER_Y},
  {CENTER_X+HALF_124, CENTER_Y-LEN_117},
  {CENTER_X-HALF_124, CENTER_Y-LEN_117},
  {CENTER_X-HALF_124-LEN_117, CENTER_Y}};

typedef struct {
  int pin;
  int prev;
  int state;
  unsigned long msec;
} Sensor;
Sensor sensors[NUM_SENSORS] = {
  {2, LOW, LOW, 0}, {3, LOW, LOW, 0}, {4, LOW, LOW, 0}, {5, LOW, LOW, 0}, {6, LOW, LOW, 0}, {7, LOW, LOW, 0}
};

int needUpdate = 0;

void drawRail() {
  // Rail line
  display.drawFastHLine(CENTER_X-HALF_124, CENTER_Y-LEN_117, LEN_124, SSD1306_WHITE);
  display.drawFastHLine(CENTER_X-HALF_124, CENTER_Y+LEN_117, LEN_124, SSD1306_WHITE);
  display.drawCircleHelper(CENTER_X-HALF_124, CENTER_Y, LEN_117, 1, SSD1306_WHITE);
  display.drawCircleHelper(CENTER_X-HALF_124, CENTER_Y, LEN_117, 8, SSD1306_WHITE);
  display.drawCircleHelper(CENTER_X+HALF_124, CENTER_Y, LEN_117, 2, SSD1306_WHITE);
  display.drawCircleHelper(CENTER_X+HALF_124, CENTER_Y, LEN_117, 4, SSD1306_WHITE);
  // sensor points
  display.fillCircle(CENTER_X-HALF_124, CENTER_Y-LEN_117, SIZE_SENSOR, SSD1306_BLACK);
  display.drawCircle(CENTER_X-HALF_124, CENTER_Y-LEN_117, SIZE_SENSOR, SSD1306_WHITE);
  display.fillCircle(CENTER_X+HALF_124, CENTER_Y-LEN_117, SIZE_SENSOR, SSD1306_BLACK);
  display.drawCircle(CENTER_X+HALF_124, CENTER_Y-LEN_117, SIZE_SENSOR, SSD1306_WHITE);
  display.fillCircle(CENTER_X+HALF_124+LEN_117, CENTER_Y, SIZE_SENSOR, SSD1306_BLACK);
  display.drawCircle(CENTER_X+HALF_124+LEN_117, CENTER_Y, SIZE_SENSOR, SSD1306_WHITE);
  display.fillCircle(CENTER_X+HALF_124, CENTER_Y+LEN_117, SIZE_SENSOR, SSD1306_BLACK);
  display.drawCircle(CENTER_X+HALF_124, CENTER_Y+LEN_117, SIZE_SENSOR, SSD1306_WHITE);
  display.fillCircle(CENTER_X-HALF_124, CENTER_Y+LEN_117, SIZE_SENSOR, SSD1306_BLACK);
  display.drawCircle(CENTER_X-HALF_124, CENTER_Y+LEN_117, SIZE_SENSOR, SSD1306_WHITE);
  display.fillCircle(CENTER_X-HALF_124-LEN_117, CENTER_Y, SIZE_SENSOR, SSD1306_BLACK);
  display.drawCircle(CENTER_X-HALF_124-LEN_117, CENTER_Y, SIZE_SENSOR, SSD1306_WHITE);
  // sensor marker
  /*
  display.fillCircle(CENTER_X-HALF_124, CENTER_Y-LEN_117, MARK_SENSOR, SSD1306_WHITE);  // 0->4
  display.fillCircle(CENTER_X+HALF_124, CENTER_Y-LEN_117, MARK_SENSOR, SSD1306_WHITE);  // 1->3
  display.fillCircle(CENTER_X+HALF_124+LEN_117, CENTER_Y, MARK_SENSOR, SSD1306_WHITE);  // 2->2
  display.fillCircle(CENTER_X+HALF_124, CENTER_Y+LEN_117, MARK_SENSOR, SSD1306_WHITE);  // 3->1
  display.fillCircle(CENTER_X-HALF_124, CENTER_Y+LEN_117, MARK_SENSOR, SSD1306_WHITE);  // 4->0
  display.fillCircle(CENTER_X-HALF_124-LEN_117, CENTER_Y, MARK_SENSOR, SSD1306_WHITE);  // 5->5
  */
  for (int i=0; i<NUM_SENSORS; i++) {
    if (sensors[i].state == HIGH) {
      display.fillCircle(pts[i].x, pts[i].y, MARK_SENSOR, SSD1306_WHITE);
    }
  }
}

void initSensors() {
  for (int i=0; i<NUM_SENSORS; i++) {
    pinMode(sensors[i].pin, INPUT);
  }
}

void updateSensors() {
  needUpdate = 0;
  unsigned long msec = millis();
  for (int i=0; i<NUM_SENSORS; i++) {
    sensors[i].prev = sensors[i].state;
    int curr = digitalRead(sensors[i].pin);
    if (curr == HIGH) {
      sensors[i].msec = msec;
    }
    unsigned long delta = msec - sensors[i].msec;
    if (delta < 200) {
      sensors[i].state = HIGH;
    } else {
      sensors[i].state = LOW;
    }
    if (sensors[i].prev != sensors[i].state) {
      needUpdate++;
    }
  }
}

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  Serial.println("multi-hall-sensor-system");

  // 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
  }
  display.display();
  delay(2000); // Pause for 2 seconds

  initSensors();
  // Clear the buffer
  //display.clearDisplay();
  //display.display();
  display.clearDisplay();
  drawRail();
  display.display();
}

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

  if (needUpdate > 0) {
    display.clearDisplay();
    drawRail();
    display.display();
  }

  //delay(1);
}
カテゴリー: Arduino, Nゲージ, センサー, 作ったモノ | タグ: , , , , | コメントする

モータードライバー TA7291P

以前、ブレッドボード上に組んだTA7291Pが発掘された。

発掘されたPIC16F1938とTA7291Pの載ったブレッドボード
発掘されたPIC16F1938とTA7291Pの載ったブレッドボード
配線を上から撮影したもの
配線を上から撮影したもの

以前、自分で撮った配線(多分、PICチップも)が違う動作動画があったが、あまりに短く何も説明がないので全然わからない…自分で撮っておいて情けない…反省。

自分の記事があった。
https://physicom.ossantube.com/?p=2633

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

Nゲージ 旧チビ凸セットの動力ユニット換装

KATO チビ凸用動力ユニット (11-109)を買ったので、旧チビ凸セットの動力ユニットを換装してみた。

チビ凸用動力ユニットのパッケージ
チビ凸用動力ユニットのパッケージ
チビ凸用動力ユニット本体
チビ凸用動力ユニット本体
チビ凸を分解
チビ凸を分解

チビ凸の上ガワを外す時に前後方向のツメを1つ折ってしまった。本来は前後を指で押せば左右の部分が膨らんで左右のツメが外れて、さらに前後のツメも外れる仕組みだと思うんだけど、前後方向の1つがどうしても外れなくて、力を入れ過ぎて折れてしまった。
でも、上ガワの固定には左右のツメが重要らしく、前後のツメが1つ無くても特に問題なかった。

新動力ユニットを装着したチビ凸
新動力ユニットを装着したチビ凸

また、新動力ユニットに上ガワをはめる際にカプラーが1つ飛び出して分解してしまい、元に戻す際に小さなスプリングが飛んで行って紛失してしまった…(進行方向前側のカプラーで良かった…)おかげで前のカプラーがぷらぷらになってしまった。

古い動力ユニットの性能が悪いせいもあるけど、だいぶ走行性能が改善した。低速での走り出しとかもスムーズだし、R117での安定性も向上した。

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

Nゲージ(新車両編)旧チビロコセット、旧チビ凸セット

「そろそろ普通に数両編成で走らせられる車両が欲しいなぁ~」と思っていて、物色していた矢先、ヤフオクにてチビロコセットとチビ凸セットの2つセットで出品されているのを見つけて、思わず飛びついてしまいました…しかし、走らせてみたら「なんか今までの車両と違う…」と思って調べてみたら、動力ユニットが改良前のモデルでした…どうしたもんかと思いましたが、古い車両は今は普通に買えないと思って、とりあえず記録しておく事にしました。
※ヤフオクでよく調べもしないで飛びついたのは自分の責任でして、別に出品者を非難したりするつもりはありません。

落札した2つのセット
パッケージの写真2つとも

型番が古いです。

旧チビロコセット動作記録
旧チビ凸セット動作記録

どちらも低速域での走行が不安定です。普通に走らせるには新動力ユニットとかと比べて速めの設定で走らせる必要があります。
また、カーブで引っかかるような感じです。(これはR117のせいかも知れませんが)

カテゴリー: Nゲージ | タグ: , , , , , | コメントする

Nゲージ(ホールICでスピード計測)

以前作った赤外線LEDとフォトトランジスターによるスピード計測はセンサー部が大きくて邪魔なのでホールICを使ったスピード計測を作ってみました。

ホールICを使うので、車両に磁石を付ける必要があります。

回路図は次のようになります。
赤外線LEDが無くなったので、さらにシンプルになってます。

回路図

ホールIC(SK8552G-G03-K)は線路の継ぎ目に挟み込む事にします。

線路の繋ぎ目のホールIC(表)
線路の繋ぎ目のホールIC(裏)
ホールICの足の形
ホールICにケーブルを接続

車両の下に付ける磁石はセリアで見つけた「超強力マグネット ミニ 8P」を使いました。

磁石を車両の下にセロテープで固定した

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

#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 digitalPin1 = 2;
int digitalPin2 = 3;

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(digitalPin1, INPUT);
  pinMode(digitalPin2, INPUT);
  
  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 == HIGH) {
    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 == HIGH) {
    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:
  val1 = digitalRead(digitalPin1);
  val2 = digitalRead(digitalPin2);

  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 == HIGH) {
    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 == HIGH) {
    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 * 124.0 / delta_t;
      }
    }
  } else {
    chng_flag2 = 0;
  }

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

ホールIC(SK8552G-G03-K)

S極だけでなく、N極も検知するホールIC(SK8552G-G03-K)を秋月電子通商で入手した。

DN6851と違って、磁気を検知するとVOUTがHIになる。

特性(データシートより)

回路図はDN6851と同じ形。

回路図

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