2022年11月27日日曜日

7セグメントLEDでカウンターの作成 その2

TPIC6C596がアノードコモン用のICなので、購入した7セグLEDも当然アノードコモンとなる。 ピン配列は購入したショップの説明欄に書かれていたので問題無かったのだけれど、セグメント毎のVf等のスペックが書かれていない。
で、色々と調べてみたら、共立電子に同じような商品が売られていたので、そちらを参考に実際に電圧を印加して確認した。結果A~Gは9V、DPは1.8Vだと思われる。今回DPを使う予定は無いけれど、TPIC6C596と接続するのであれば、リセット時等に電流が流れたりするので、それなりの制限抵抗を入れておかなければならない。
今回購入したTPIC6C596基板には最初から各セグメント毎に15Ωのチップ抵抗が実装されているが、もともと5インチ以上の7セグLEDでVf12V程度を想定している抵抗値なので、今回使用する4インチで使う場合は入力電圧自体を9V程度に収める必要があるし、そもそもDPには追加の制限抵抗が必須になる。
全部のセグメントに制限抵抗を追加するのは面倒くさいので入力電圧を調整する事で誤魔化す事にして、TPIC6C596基板を7セグLEDの背面に両面テープで張り付けてラッピングワイヤーで接続していく。

コンタクトピンが出ていてケーブルで接続する必要があり、行先がバラバラの場合という限られた条件では、ラッピングワイヤーは凄く便利だ。
半田付けすると故障時の部品の入替が面倒くさいし、ラッピングに比べて衝撃に案外弱い。まぁ、ラッピングも軸方向に引っ張れば抜けてしまったりするので、コンタクトピンが短すぎると使い難いところはある。
LEDの部分の作業はコレだけだ。配線距離が短いのは面倒が無くて助かる。 桁数を増やしたくなっても数百円のコントローラーボードとコントローラーボード間を繋ぐ為のケーブルを追加するだけで良いので、本当に有難い。
7セグLEDを保持する為のガワに関しては、3ユニットを収容できるような大きさの物を作れるような大きな3Dプリンターは持っていないし、持っていたとしても造形に失敗したら泣きそうなので、素直に1ユニット毎に作成する。

こうしておけば、後から桁数を増やしたくなった時に、中間ユニット用の保持部だけを作れば良い。
最初の造形物はLEDユニットの寸法通りに作成してしまって失敗。122mmの処を122mmで作れば当然入らない。印刷公差を考えて0.5~1.0mm程度は大きめに作る必要がある。ボタン取付用の穴も同様に0.5mm程度は大きくしておいた方が無難かもしれない。
まぁ、丸穴は最悪ドリルで拡張すれば良いので、0.2mm程度大きめの穴を開ければ使い物になるかも。
で、7セグLED保持部だが、内壁を0.5mm拡張しようとするとフライス盤で削るという方法が考えられるのだけれど、今回はインフィル充填率50%で作っているので、壁面を削ってしまうと強度的に問題が有りそうだ。
データを修正して作り直す方がフライス盤で修正するよりも面倒が無いし、その方が出来栄えも綺麗なので結局作り直すことにした。
しかし、所詮ホビー用の3Dプリンターなので1個作るのに9~12時間かかるのが辛い。
初回試作でボタン位置やケーブル通し溝に問題がある事が判明したので、無駄にはならなかったと思いたい。
こういう時にだけKP3Sぐらいの小さい3Dプリンターがもう一台欲しくなる。
総印刷時間に20時間以上かけて3桁分のケースを印刷しなおして7セグLEDを実装する。固定は全て両面テープ。

幅1mmのアクリル両面テープは携帯電話分解組み立ての際に裏蓋を固定する為に購入した物だが、ヒケの出ない接着剤として使用するのに便利で、今回の工作の際にもLEDの固定やケースとアクリル板を固定する際に大変役立っている。

アクリル板は元は普通のスモークの物だったが、それだとアクリル板を貼る前と大して見栄えが変わらなかったので、400番のペーパーを当てて摺ガラス調にする事でLEDの明かりがソフトになり、消灯しているセグメントやケース内の適当な配線や工作を見えにくくなった事で数字の視認性が良くなった。

電源に関しては10VのACアダプターを使用して、ATtiny88のVin及びTPIC6C596の12Vに入力する事で、7セグLEDのDP以外は制限抵抗の追加は無しとした。

5V系はATtiny88の5Vからの出力で全て賄う事ができている。
そんな感じのやっつけ電源なので、間違って12VのACアダプターを使ってしまうと、7セグLEDは壊れるかもしれない。
とりあえず半年程連続稼働させて問題なければ、そのまま継続使用しても大丈夫かなぁ…

 

 

 

 

 

 

2022年11月8日火曜日

7セグメントLEDでカウンターの作成 その1

4インチの7セグLEDを3つ使用してカウンター表示器を作成した。
といっても、昔の用にシフトレジスターを論理回路でゴチャゴチャする必要が無いので、作るのは非常に簡単だ。
今回作成したのは大型の7セグLEDを3つ並べて使用する物なのだけれど、将来的に4桁必要になるかもしれないという事から、1桁毎にTPIC6C596を取り付けて、このLEDドライバーをチェーン接続するという方式を取った。

この7セグLEDドライバー1つで制御できるのは一桁だけなのだが、これをディジーチェーンすると、いくらでも桁数を増やす事ができる。
カウンターの制御は当初Arduino nanoを使う予定だったのだが、既にヘッダピンを下向きに半田付けしてしまっていて、組み込みにくかった事と、最近Arduinoが互換品でもそれなりの値段になっていて(ヘタするとESP8266やEPS32のボードの方が安いぐらい)、使うのが勿体なかったので、

他に何か良いのが無いかと探してみた処、AtmelのATtiny88を見つけた。

このマイコンボード、実はnanoと勘違いして購入してしまった代物で、届いてからArduino nanoとは全く別物だと気づいて愕然としていたのだけれど、調べてみるとArduino IDEが使えるし、Vinや5Vout、EEPROM等、今回のカウンター作成で使いたい機能は一通り揃っていたので、試しに使ってみる事にした。
microUSB-Bのポートは付いているものの、USB制御チップが乗っていないので、シリアルで書き込みしないと駄目かなぁと思ったら、V-USBという仕組みを採用しているらしく、PCにドライバーを入れれば容易に認識した。
ArduinoIDEで使う際は、コンパイル後、ファームウェアを転送し始めたらPCとATtiny88をUSBケーブルで繋ぐ、もしくはATtiny88のリセットボタンを押してリブートするといった作法が必要になるけれど、慣れればCOMポートの設定も必要ないし便利といえば便利かもしれない。
カウンターのプログラムは多分に漏れず他人の書いたコードのコピペで、それを元にして実装したい機能に合わせてライブラリを追加したり、足りない部分や辻褄合わせの為のコードを追記していく。 Arduinoの良い処は既に安定して動作するライブラリを他人様が無料で提供してくれているところだろう。そして、ハードウェアレベルのロジックを考えなくても大抵の事ができてしまう。
何故そうなるのかといった理屈は知っておいた方が良いとは思うが、昔みたいにオシロを持ち出して波形なんて眺めなくても、電卓とスペックシートとプログラミング環境(とインターネットの集合知)があれば、ショボい電子工作なら素人でも手が出せるようになっているので、間口は無茶苦茶広くなっている。
凝った事をしたくなったら、基板の作成は安価に出せるようになってるし、機構や外装には3Dプリンターが使えるので、これもハードルが低い。
コードは以下の通り。


#include EEPROM.h
#include ButtonEvents.h

//GPIO declarations
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
byte segmentClock = 4;
byte segmentLatch = 5;
byte segmentData = 3;
const int up_pin    = 6; //カウントアップボタン
const int down_pin  = 7; //カウントダウンボタン
const int reset_pin = 1; //リセットボタン
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

ButtonEvents up_button; // create an instance of the ButtonEvents class to attach to our button
ButtonEvents down_button;
ButtonEvents reset_button;

int number   = 0;
int segnumber= 0;
int button_pt = 0;
char sp = ' ';

void setup()
{
  Serial.begin(9600);
  Serial.println(EEPROM.length());
  Serial.println("Large Digit Counter ver.1.0");

  pinMode(segmentClock, OUTPUT);
  pinMode(segmentData, OUTPUT);
  pinMode(segmentLatch, OUTPUT);
  pinMode(up_pin, INPUT_PULLUP);
  pinMode(down_pin, INPUT_PULLUP);
  pinMode(reset_pin, INPUT_PULLUP);

  digitalWrite(segmentClock, LOW);
  digitalWrite(segmentData, LOW);
  digitalWrite(segmentLatch, LOW);
  EEPROM.get(0x00,number);

  // attach our ButtonEvents instance to the button pin
  up_button.attach(up_pin);
  down_button.attach(down_pin);
  reset_button.attach(reset_pin);

  //ButtonParameter Setup
  //ダブルタップ制限時間(ms)
  up_button.doubleTapTime(200);
  down_button.doubleTapTime(200);
  reset_button.doubleTapTime(200);
  //長押し判定時間(ms)
  up_button.holdTime(5000);
  down_button.holdTime(5000);
  reset_button.holdTime(5000);
}

void loop()
{
  //アップボタン(シングルタップ +1, ダブルタップ +10)
  up_button.update();
  if(up_button.tapped() == true) 
  {
    EEPROM.put(0xf0,number); //カウンター数字バックアップ
    number++;
    number %= 1000; //Reset x after 999
    EEPROM.put(0x00,number);
  }
  if(up_button.doubleTapped() == true)
  {
    EEPROM.put(0xf0,number); //カウンター数字バックアップ
    number = number + 10;
    number %= 1000; //Reset x after 999
    EEPROM.put(0x00,number);
  }

  //ダウンボタン(シングルタップ -1, ダブルタップ -10)
  down_button.update();
  if(down_button.tapped() == true)
  {
    EEPROM.put(0xf0,number); //カウンター数字バックアップ
    number--;
    if(number < 0) 
    {
      number = number + 1000;
    }
    number %= 1000; //Reset x after 999
    EEPROM.put(0x00,number);
  }
  if(down_button.doubleTapped() == true)
  {
    EEPROM.put(0xf0,number); //カウンター数字バックアップ
    number = number - 10;
    if(number < 0) 
    {
      number = number + 1000;
    }
    number %= 1000; //Reset x after 999
  }

// リセットボタン(長押し リセット, ダブルタップ リストア)
  reset_button.update();
  if(reset_button.held() == true) //リセットボタン長押しでリセット
  {
    EEPROM.put(0xf0,number); //カウンター数字バックアップ
    number = 0;
    EEPROM.put(0x00,number);
  }
  if(reset_button.doubleTapped() == true) //リセットボタンダブルタップでリストア
  {
    EEPROM.get(0xf0,number); //カウンター数字リストア
    EEPROM.put(0x00,number);
  }

//  Serial.println(number);
  showNumber(number);
}

//Takes a number and displays 3 numbers. Displays absolute value (no negatives)
void showNumber(float value)
{
  segnumber = number ;
  int segnumber = abs(value); //Remove negative signs and any decimals
  Serial.print("number: ");
  Serial.println(segnumber);
  for (byte x = 0 ; x < 3 ; x++) //桁数決定
  {
    if ((x > 0) && (segnumber == 0)) //下2桁目以上が0の場合スペース
    {
      postNumber(sp, false);
    }
    else
    {
      int remainder = segnumber % 10; //各桁の数字を抽出
      postNumber(remainder, false); //1桁ずつ送信
      segnumber /= 10;
    }
  }

  //Latch the current segment data
  digitalWrite(segmentLatch, LOW);
  digitalWrite(segmentLatch, HIGH); //Register moves storage register on the rising edge of RCK
}

//Given a number, or '-', shifts it out to the display
void postNumber(byte segnumber, boolean decimal)
{
  //    -  A
  //   / / F/B
  //    -  G
  //   / / E/C
  //    -. D/DP

#define a  1<<0
#define b  1<<6
#define c  1<<5
#define d  1<<4
#define e  1<<3
#define f  1<<1
#define g  1<<2
#define dp 1<<7

  byte segments;

  switch (segnumber)
  {
    case 1: segments = b | c; break;
    case 2: segments = a | b | d | e | g; break;
    case 3: segments = a | b | c | d | g; break;
    case 4: segments = f | g | b | c; break;
    case 5: segments = a | f | g | c | d; break;
    case 6: segments = a | f | g | e | c | d; break;
    case 7: segments = a | b | c; break;
    case 8: segments = a | b | c | d | e | f | g; break;
    case 9: segments = a | b | c | d | f | g; break;
    case 0: segments = a | b | c | d | e | f; break;
    case ' ': segments = 0; break;
    case 'c': segments = g | e | d; break;
    case '-': segments = g; break;
  }

  if (decimal) segments |= dp;

  //Clock these bits out to the drivers
  for (byte x = 0 ; x < 8 ; x++)
  {
    digitalWrite(segmentClock, LOW);
    digitalWrite(segmentData, segments & 1 << (7 - x));
    digitalWrite(segmentClock, HIGH); //Data transfers to the register on the rising edge of SRCK
  }
}


参考というか、ほぼコピペさせて頂いたサンプルプログラムはsparkfunのLarge Digit Driver Hookup Guideにある「Example:Two Large Digits
使用させて頂いたライブラリは
ButtonEvents
とそれに付随する
Bounce2
というわけで、これらをとりあえずブレッドボードで接続して動作させた処、問題無く動作したので、実装を進めていく。

ちなみに、ATtiny88TPIC6C596はamazonで購入すると、安かったり高かったりとなかなか値段が安定しないので、aliexpressで売られている価格と比較すれば良いと思う。ATtiny88はAliexpressに近い値段で売られている事が多いが、TPIC6C596は値差が大きい気がする。

 

 

 

2022年11月5日土曜日

Cygnus-X パンク修理失敗とタイヤ交換 ODO 35557km

シグナスの前後輪共にスリップサインが出て久しいのだが、面倒くさくてタイヤ交換をしていなかった。
久々に後輪を眺めながら手でくるくると回していると釘を踏んでいたので、パンクしなければ良いなぁと思いながら引っこ抜いたところ、手で触れて分かるような空気漏れは無かったので大丈夫かなぁと思っていたら、3時間後には見事にパンクしていた。

で、前回のリベンジということで、スティックタイプのパンク修理キットを持ち出して、修理してみたのだが、あえなく惨敗。 リークテスターでは分からない程度のエアー漏れなんだけど、数時間したら空気が抜けてしまう。

うーん、ゴムスティックがベタベタになっているので、それが駄目なんだろうか? でも買った時からこんな感じだしなぁ。
まぁ、駄目元で修理してみただけなので、そもそもタイヤの交換時期だったという事もあって、素直に新しいタイヤに交換する事にした。
パンクで敢無くお役御免となったIRCのSCT-001は結局10300km程の寿命だった。スリップサインが出たのはもう少し前で9千キロぐらいかな。パンクさえしなければ、あと千キロぐらいは使っていたと思われる。前回のタイヤ交換が2019年12月なので、凡そ3年弱使用したにも関わらずサイドウォールのひび割れが見られない事を考えると、結構優秀なタイヤだと思う。
前輪で使用していたIRCのMB67の使用距離は20700km程。交換頻度としては、前輪1回につき後輪は2回といった感じなのかな。こちらもスリップサインは1.8万キロぐらいには露出していたと思うが、結局2万キロ超まで使用してしまった。たぶん今回のパンクがなければ、あと千キロぐらいは使っていたと思う。 このタイヤの交換は2016年12月なので、6年弱使用した。

流石にこれだけ長期間使用するとサイドウォールに微細なひび割れが見られるが、実家の屋外保管されているスクーターに比べれば微々たるものだ。 やはりタイヤを保管するのに直射日光は大敵という事なんだろう。

今回購入したタイヤはDUROのHF-912A(前輪)とDM-1017(後輪)。

DUROのタイヤは母親のスクーターで使用していた際には経年劣化によるひび割れが目立つタイヤだったが、屋内保管なので、アレ程酷くはならないと思いたい。まぁ安いタイヤなので、1万キロ弱もってくれれば御の字かな。
後輪のタイヤ交換はマフラーやスイングアームの取り外しが面倒臭いだけで、タイヤサイズ的には脱着しやすい。古いタイヤを外して、新しいタイヤを取り付け、エアー漏れが無いかリークチェッカーで確認したところ、ビードとリムの隙間から微妙に漏れているっぽい。
 
このタイヤ、送料を無料にする為の価格調整用に購入したから、長らく放置状態だったので、ビード部分の密着が悪くなっているのかもしれない。そんなことがあり得るのか分からないけど… ビードもリムも傷は無さそうなので、エアー漏れする原因がわからない。

全然エアー漏れしていないところにはリムに傷があったけれど。

とりあえずビードシーラーを塗り付けて誤魔化したところエアー漏れは無くなったので、しばらく様子を見る事にする。

後輪を交換するついでにドラムブレーキシューも交換しようとしたところ、シューとホイールが干渉してしまいホイールが挿入できなかったので、「この中華品質め」と愚痴りながら、元のシューに戻してホイールを取り付け。

で、今、写真をよくよく見てみたら中華シューの取り付けが裏表逆だった。これがホイールがハマらなかった原因なのかもしれないので、次回のタイヤ交換まで中華シューは捨てずに置いておこう。

次に前輪のタイヤ交換。 タイヤサイズの問題なのか、後輪に比べて脱着が非常にやりにくい。とにかく硬い。ブレーキディスクが邪魔で作業性が悪いのもあるが、とにかくタイヤが後輪よりも硬く感じる。
こちらのタイヤも後輪と同じく送料無料の価格調整用に購入した為、購入してからそれなりに時間が経過している。後輪と同じく新しいタイヤを装着し終わってからリークチェッカーで確認したところ、ビードとリムの間から微細なエアー漏れ。 同様にビードシーラー塗布で胡麻化してエアー漏れは止まったので、こちらもしばらく様子見。
前輪タイヤ交換のついでに、ブレーキディスクの摩耗が進んでいたので、こちらも交換しておく。

本来はディスクを固定するボルトも新品にすべきなのだけれど、今回は再使用する事にした。特に理由は無く単純に注文し忘れただけ。

中華の安物のディスクだが、そんなにブレーキを酷使するようなバイクではないので、問題は無いと思う。 耐摩耗性がどれぐらいあるのかは使ってみなければ分からない。純正のディスクとの値段差が大きすぎるので、多少問題があったとしても許容できるかな。
amazonの評価では平面が出ていないとか、止まらないとか書かれていたけれど、今回購入したものは特に問題は無かった。
まぁ平面が出ていなければ、止まらないだろう。 平面が出ているのに止まらないのは、ディスク取り付け前に脱脂するのを忘れてるか、パッドとの相性が悪いんじゃないかな。

タイヤ交換が終わって軽く試走してみた感想としては、前輪の動きが鈍重。やはりIRCのタイヤに履き替えた際の感想は正しかった。
直減りしたIRCのタイヤよりも軽快感が無いとは思わなかった。ちゃんと入力してやれば普通に曲がるし、グリップ感が無い訳ではないので、単純にタイヤ形状によるフィーリングの違いか。 こればかりは好みの問題だろうから、慣れれば問題無いだろう。
後輪に関しては、いつも通り違いが分からない。路面が濡れてたりすればグリップとか排水性が気になるのかもしれない。

ODO 35557km