3Dプリンター(13)2016年01月16日

skeleton3D

skeleton3Dプリンターのその後です。まだ完成はしていません。X・Y軸の駆動ベルトとプーリー、リニアベアリングと言った駆動系のパーツとホットエンドが届いていません。日本国内調達ならこんなに待たされることはないのですが中国から調達すると当たり前ですが待たされます。今回は不着でキャンセルになってしまった関係で再注文をしなければならなくなり、特に遅れています。そんなに待たされても調達コストを考えるとやむを得ないことでしょう。
現時点で調達済みの部分は少しづつ組み付けています。今回の製作目標が小型で運搬しやすい3Dプリンターを目指していす。skeleton3Dを採用することでどちらの目標もクリアするのですが、制御系の配線をぐるぐる巻きにしているとトラブルのもとになります。ケーブルを余らないように調整して切断し、コネクターを取り付けながらの作業ですから時間がかかリます。MKS Gen v1.2シングルコントロールボードは思ったとおりにすっきり配線が行えます。「運搬しやすい」とは言っても分解・組み立てを想定しているわけではありませんのでこの程度の配線です。パーツや仕様に合わせてACインレット、スイッチボックスやLCDパネルのケースも作成しています。写真は、駆動系以外が組み上がったところです。Z軸用のパーツは揃っているので動作確認まで行いました。Marlin Firmeareはskeleton3Dで配布されているものは少し古く、最終的には最新の安定版を入れる予定です。

3Dプリンター(12)2016年01月09日

ヒートベッド用ヒーター

skeleton3Dのベッド用のヒーターを検討しています。小型で効率良く温めることができる素材です。RepRap WiKiなどにもいろいろな方式が紹介されていますが、現在はPCBヒーターが主流です。しかし、電気を食うので大電流を流せる電源が必要になりとても高価です。そこでベッドヒーターはAC100Vを電源に使用するほうが効率的にもコスト的にも良いのではないかと思って探してみました。あまり聞き慣れない名前ですがPTCヒーターを見つけました。メタルクラッド抵抗やニクロム線と違い設計温度以上には上昇しません。また、温度が上がると消費電力が減るというエコな特徴があり、大変小型です。12Vや24VのPTCヒーターもありますが、AC100Vの場合、制御ボードからアイソレートされたONOFF制御が必要ですが高価な大電流電源が必要ありません。
110V 100WのPTCヒーターです。PTCヒーターは、半導体粒子と、電気をよく伝えるカーボン粒子(導体)などを配合し、温度によって電気の流れやすさが変わるように作られたヒーターです。AC100Vを使用するのでより効率的に温めができるのではないでしょうか。また、ニクロム線のように赤熱してしまうこともありません。ヒーターの大きさは52 x 21 x 6mmです。とりあえず250℃のものを1個注文しました。

制御ボード側の温度制御はPCB HeatedBedと同じなのですが、制御ボードのD8(ヒートベッド用)端子からは入力しているDC12Vが出力されます。それを利用して秋月のソリッドステートリレーでAC100VのONOFFを行います。
これでABS素材も印刷できることを期待しているのですが、実際に動かしてみないとわかりません。ネットを検索してもPTCヒーターを利用したケースが出てきません。最近の素材なのでしょうか。コスト的にも110V 100WPTCヒーターで約600円でしたのでPCBヒーターよりも安価です。3mm厚のアルミ板をベッドに使用していますがアルミ板への取付方法や、温度の上がり方、保温状態の安定度、サーミスタセンサの取り付け位置などわからないことがいっぱいありますが実験あるのみです。

3Dプリンター(3)2015年10月12日

エクストルーダーとホットエンド

エクストルーダーとホットエンドは3Dプリンターの中心になる部分です。3Dプリントの原料となるフィラメントをホットエンドに送り出す役割がエクストルーダーです。そのフィラメントをヒーターで溶かしてノズルから押し出すのがホットエンドです。押し出す圧力(量)はエクストルーダーから送られるフィラメントの圧力になります。RapRep Prusa i3オリジナルでは3Dプリントしたパーツで作成したエクストルーダーとJ-Headと呼ばれるホットエンドの組み合わせです。市販されている3DプリンターキットではMK8エクストルーダーがよく使用されています。
両者に違いはフィラメントの送りギアーとステッピングモーターとの間に変速ギアーを入れているかどうかです。MK8エクストルーダーはステッピングモーターのシャフトにフィラメントの送りギアーが取り付けられているダイレクトドライブ方式です。ステッピングモーターのトルクが要求される反面、構造がシンプルで作成が容易で小型化が可能です。MK8エクストルーダーはホットエンドと一緒にX軸のキャリアにのせることが可能です。
また、デルタ型の3Dプリンターではキャリアが宙吊り状態なので重量的にホットエンドとエクストルーダーを分離してキャリアにはホットエンドのみをのせ、フレーム上にエクストルーダーを固定する方法が取られます。Bowdenエクストルーダーです。エクストルーダーとホットエンド間はPTFEテフロンチューブで結合し、その中をフィラメントが通ります。エクストルーダーの押し出す力をしっかりとホットエンドに伝えるためにPTFEテフロンチューブ両端をしっかりと固定する必要があります。M4ナットで固定してもよいのですがハーフユニオンを使用すると脱着が可能になります。このBowdenエクストルーダーとホットエンドの組み合わせはPrusa i3でもキャリアにのせる質量が少なくなるので有効な方法です。
3Dプリントで作成したBowdenエクストルーダー

  • AirTripper's Extruder




  • 小型エクストルーダー Mini NEMA17 Extruder




  • 変わったエクストルーダー Saintflint Extruder





今回新しく購入したE3D V6タイプのホットエンドです。ホットエンドは3個のパーツとヒーター、冷却用のヒートシンクとファン、温度計測用のサーミスターで構成されています。エクストルーダーとホットエンドの一体型MK8エクストルーダーでも構成部品は同じです。
M6 x 26mmまたは30mm、内径2mmのバレルとヒートブロック、ノズルが構成部品です。ヒートブロックにノズル、ヒーターとサーミスターを取り付け、M6バレルにヒートブロックとヒートシンクを取り付けます。ヒートシンクの形状でいろいろなタイプがあります。ヒートブロックはABSフィラメント使用で230度以上に加熱します。その熱をバレルの上まで伝えてしまうとノズル詰まりを起こしてしまいますのでバレル上部の冷却は重要です。E3D V6タイプのホットエンドはバレルにヒートシンクが装着され、ファンで強制冷却すれば効率的にホットエンド上部が冷却できます。E3D V6タイプのホットエンドはバレルにヒートシンクが装着され、ファンで強制冷却すれば効率的にホットエンド上部が冷却できます。ファンは30mm角のファン程度十分に冷却できます。この辺りのパーツは国内でも入手できますが高いです。e-bayで中国から直接購入するほうが安価に入手できます。参考にリンクを張ってあります。
ホットエンドで冷却不足を起こすとホットエンド上部やエクストルーダーでフィラメントが柔らかくなり、フィラメント送りに障害が出てしまいます。

  • MK8の詳細な組み立て方です。
  • Bowden方式でよく使用するE3D V6ホットエンドの詳細な解説はGE techのサイトを参照してください。

  • Slim Bowden E3D v5 mount for Prusa i3
    マウントしているのはE3D V6 ホットエンドですがサイズは同じです。PLA樹脂よりも熱に強いABS樹脂で作成しました。30mm角DC12Vファン使用。

Arduino用のMPU2014年12月18日

Atmel 8-bit Microcontroller

秋月電子でArduino用のMPUを物色していたらATmega328P-AUを見つけました。ATmega328P-PUと性能は同じですがパッケージがTQFP 32ピンです。アナログピンが増えてMPUの価格は同じ、変換基板を使用する場合は100円アップということになります。変換基板はATmega32U2に使用したものと同じですので0.8mmピッチの表面実装ハンダ付けでブレッドボードで使用することができます。
Arduino UNO SMDやArduino Mini、Arduino Fioと同じMPUです。

aitendoのプロトタイプシールド基板を使ってオリジナルArduino UNO R1互換ボードを作りました。実験用に一台あると便利かもしれません。この基板はオリジナルと同様にICSP端子やリセットスイッチのレジストがあるので簡単に互換ボードが作れそうです。32ピンの変換基板はギリギリで入りました。MPUの32ピンICソケット下にクリスタルやパスコンを配置してなるべく基板スペースを開けるようにしたのでRGB 3色LED 2個と温度センサーLM35DZを一緒にのせました。
PCとの通信には秋月電子のFT231X USBシリアル変換モジュールが従来品のFT232RLより小型なので一緒に実装できます。後は電源ですね。USBバスパワーだけでは心もとないので5V1Aのレギュレターものせようかと思ったのですが5V以上の電源を使用することはないので取りやめにしました。FT231Xの5V出力は全体で350mA、3.3Vは50mAまでですので注意が必要です。
細かいことは気にせずArduinoクローンと同等ならOKと言うことでboot loaderはATmegaBOOT_168_atmega328.hexをArduino IDE 1.0.6とAVRISP MkII クローンで書き込み使用しています。

電源基板各種2014年11月22日

たまった電源基板

ネット通販や秋葉原で買い物をする時、必要なパーツ以外についつい電源基板を買ってしまいます。なぜでしょうか。12Vから5Vを作成する場合、7805などの三端子レギュレータ―でもいいのですが低効率のため結構発熱します。DCDCコンバーターならほとんど発熱しません。三端子レギュレータより値段は高いですが安いものを見つけた時に買っています。電源基板が貯まってきた(貯金じゃないよって)ので整理をしようと並べています。組み込んで使用したものもあります。取り扱いのあるショップにリンクを張っておきます。

  • 可変電圧LDOローノイズタイプ
    TPS7A4700 超ローノイズ・レギュレータ(正出力)
    この電源基板はハイレゾ対応DACのプラス電源に使用しました。

    TPS7A3301 超ローノイズ・レギュレータ(負出力)
    この電源基板はハイレゾ対応DACのマイナス電源に使用しました。

  • DCDC昇圧タイプ
    LM2577 入力:3~34V、、出力:4~35V、最大出力:2.5A


    CE8301 入力0.9〜5V、出力5V、電池昇圧
    AS1322A 昇圧型DC-DCコンバータモジュール(3.3V/5V)
    入力は0.85V~、電池駆動の電源に最適です。

    PFMステップアップDC/DCコンバータ HT7750A(5V)
    入力は0.7V~5V、電池駆動の電源に最適です。
    基板化されたものもあります。

  • DCDC降圧タイプ
    5V3A DC-DCコンバータ制御IC SI-8050S
    3Aと大出力なのでUSB充電用電源に使用しています。
    車や太陽光発電した12V電源からスマホやタブレットの充電に使用する5Vを作ります。
    LM2596 入力:4〜40V、出力:1.23〜35V、最大:2A
    AMS1117 入力電源:6~12V、出力:3.3V



    LC2319 入力電源:12V、出力:5V USB 2個口
    最大出力電流:2A


  • プラスマイナス2電源タイプ
    入力4.5V~18V、出力±5V、±300mA
    オペアンプやヘッドフォーンアンプのプラスマイナス電源に使用しています。

    入力9V~36V、出力±15V、±200mA
    オペアンプやヘッドフォーンアンプのプラスマイナス電源に使用しています。

  • LiPo電池充電器
    MAX1555リチウムイオンポリマー電池充電IC
    TP4056 USBパワー、4.2V/1A、充電指示LED
    seeedstudio.com Li-Po ライダー
    LiPo電池の充電とUSB 5V出力が一枚の基板できるすぐれものです。、Arduinoの実験用に最適です。LiPo電池側には電源スイッチが付いています。

Arduinoで音声合成2014年11月17日

音声合成LSI - AquesTalk pico LSI

AquesTalk pico LSIはATmega328を使用した音声合成エンジンLSIです。外部との接続インターフェースが柔軟で、UART(シリアル)、I2C、SPI接続に対応しています。Arduino Leonardo互換ボードで使用するとするとUARTまたはSPIになります。Felicaリーダーに残高を発声させようとすると残っているインターフェースはSPI接続になります。

  • コントローラ
    ATmega32U2 Arduino Leonardoクローン
     Caterina-Minimus.hex
  • AquesTalk pico LSI
    AquesTalk pico LSIは秋月で購入しました。28pin DIPパッケージのかわいい系の女声(ATP3011F4-PU)を選択しました。Arduino標準のSPIライブラリーを使用します。サンプルプログラムはここを参考にしました。

ArduinoでFelicaリーダー2014年11月14日

FelicaカードのIDmと残高表示

ArduinoボードにはATmega32U2を使用したArduino Leonardo互換ボードを使用しています。USB内蔵タイプはシリアルポートが空いているのでスケッチの更新のたびにRC-S620/Sを外さなくて済みますし、読み取ったIDmやカード・残高をキー入力としてPCに送ることも出来ます。

  • コントローラ
    ATmega32U2 Arduino Leonardoクローン
     Caterina-Minimus.hex
  • Felicaリーダー RC-S620/S
    ソニーのFelicaリーダー。Arduino向けRC-S620/S制御ライブラリを使用しました。
    USB内蔵タイプのMPUはシリアルポートが異なりますのでRCS620S.cppを直接修正しました。

【プログラム】
「FeliCa電子マネー残高照会機モドキ」のブログで紹介されています。残高照会の部分はそののまま使用させていただきました。FelicaカードのHackはこのサイトで紹介されています。IDmの読み出しの部分はRC-S620/Sライブラリーのサンプルプログラムを使用しました。
デジタルピン5、6にそれぞれスイッチを接続しています。ピン5はUSBキー出力のON/OFFスイッチで、ピン6はIDm読み出し/残高照会の切り替えスイッチです。

Felica reader
// Felica caed reader             2014/11/14
//  Read out the card history by RC-S620/S.
//  Corresponding to PASSNET, Edy, nanaco and waon.
//  MPU: ATmega32U2 + Caterina-Minimus.hex
// Sample program site.
// http://www.orsx.net/blog/archives/3835
// Felica card informations.
// http://sourceforge.jp/projects/felicalib/wiki/FrontPage
// 
#include <LiquidCrystal.h>
#include <RCS620S.h>
 
// RCS620S
#define COMMAND_TIMEOUT               400
#define POLLING_INTERVAL              500
#define RCS620S_MAX_CARD_RESPONSE_LEN 30
 
// FeliCa Service/System Code
#define CYBERNE_SYSTEM_CODE           0x0003
#define COMMON_SYSTEM_CODE            0xFE00
#define PASSNET_SERVICE_CODE          0x090F
#define EDY_SERVICE_CODE              0x170F
#define NANACO_SERVICE_CODE           0x564F
#define WAON_SERVICE_CODE             0x680B
 
RCS620S rcs620s;

// SW, LED and LCD pin assign.
#define LED_PIN 7
#define SEL_PIN 6
#define KEY_PIN 5
//   1602         RS R/W  E  D4  D5  D6  D7
LiquidCrystal LCD(0, 1, 2, 15, 16, 17, 18);

void setup(){
  pinMode(SEL_PIN, INPUT);    // for select SW
  pinMode(KEY_PIN, INPUT);    // for output keybord SW
  digitalWrite(SEL_PIN, HIGH);// Pullup 
  digitalWrite(KEY_PIN, HIGH);// Pullup 
  pinMode(LED_PIN, OUTPUT);   // for Polling Status
  digitalWrite(LED_PIN, LOW); 
  Keyboard.begin();

  LCD.begin(16, 2);
  LCD.clear();
  LCD.setCursor(0, 0);
  LCD.print("Felica reader");
  LCD.setCursor(0, 1);
  LCD.print("Start...");
  delay(3000);

  // Modified the library for ATmega32U2.
  //  Serial -> Serial1(RX:8, TX:9 pins)
  Serial1.begin(115200);  
  int ret = rcs620s.initDevice();
  while (!ret) {
    delay(POLLING_INTERVAL);
    ret = rcs620s.initDevice();
  }
}
 
void loop(){
  digitalWrite(LED_PIN, HIGH);
  if(digitalRead(SEL_PIN)){
    readhistory();
  } else {
    rcs620s.timeout = COMMAND_TIMEOUT;
    LCD.clear();
    if(rcs620s.polling()) {
      LCD.print("IDm:");
      LCD.setCursor(0, 1);
      for(int i = 0; i < 8; i++) {
        if(rcs620s.idm[i] / 0x10 == 0) LCD.print(0);
        LCD.print(rcs620s.idm[i], HEX);
        if(digitalRead(KEY_PIN)) {
          sprintf(result, "%02x", rcs620s.idm[i]);
          Keyboard.print(result); 
        }
      }
      if(digitalRead(KEY_PIN)) Keyboard.println(); 
    } else {
    LCD.setCursor(0, 0);
    LCD.print("Reading IDm.");
    if(digitalRead(KEY_PIN)) {
        LCD.setCursor(15, 0);
        LCD.write(0x7E);
    }
    LCD.setCursor(0, 1);
    LCD.print("Polling...");
    }
  } 
  rcs620s.rfOff();
  digitalWrite(LED_PIN, LOW);
  delay(POLLING_INTERVAL);
}

void readhistory() {
  uint32_t balance;
  uint8_t buf[RCS620S_MAX_CARD_RESPONSE_LEN];
   
  rcs620s.timeout = COMMAND_TIMEOUT;
   
  // サイバネ領域
  if(rcs620s.polling(CYBERNE_SYSTEM_CODE)){
    // Suica PASMO
    if(requestService(PASSNET_SERVICE_CODE)){
      if(readEncryption(PASSNET_SERVICE_CODE, 0, buf)){
        // Little Endianで入っているPASSNETの残高を取り出す
        balance = buf[23];                  // 11 byte目
        balance = (balance << 8) + buf[22]; // 10 byte目
        // 残高表示
        printBalanceLCD("PASSNET", &balance);
      }
    }
  }
   
  // 共通領域
  else if(rcs620s.polling(COMMON_SYSTEM_CODE)){
    // Edy
    if(requestService(EDY_SERVICE_CODE)){
      if(readEncryption(EDY_SERVICE_CODE, 0, buf)){
        // Big Endianで入っているEdyの残高を取り出す
        balance = buf[26];                  // 14 byte目
        balance = (balance << 8) + buf[27]; // 15 byte目
        // 残高表示
        printBalanceLCD("Edy", &balance);
      }
    }
     
    // nanaco
    if(requestService(NANACO_SERVICE_CODE)){
      if(readEncryption(NANACO_SERVICE_CODE, 0, buf)){
        // Big Endianで入っているNanacoの残高を取り出す
        balance = buf[17];                  // 5 byte目
        balance = (balance << 8) + buf[18]; // 6 byte目
        balance = (balance << 8) + buf[19]; // 7 byte目
        balance = (balance << 8) + buf[20]; // 8 byte目
        // 残高表示
        printBalanceLCD("nanaco", &balance);
      }
    }
     
    // waon
    if(requestService(WAON_SERVICE_CODE)){
        // Block number History1=1, History2=3, History3=5
      if(readEncryption(WAON_SERVICE_CODE, 5, buf)){
        // Big Endianで入っているWaonの残高を取り出す
        balance = buf[17];                  // 21 byte目
        balance = (balance << 8) + buf[18]; // 22 byte目
        balance = (balance << 8) + buf[19]; // 23 byte目
        balance = balance & 0x7FFFE0;       // 残高18bit分のみ論理積で取り出す
        balance = balance >> 5;             // 5bit分ビットシフト
        // 残高表示
        printBalanceLCD("waon", &balance);
      }
    }
  } else {
    LCD.clear();
    LCD.setCursor(0, 0);
    LCD.print("Reading History");
    if(digitalRead(KEY_PIN)) {
        LCD.setCursor(15, 0);
        LCD.write(0x7E);
    }
    LCD.setCursor(0, 1);
    LCD.print("Polling...");
  }
}
 
// request service
int requestService(uint16_t serviceCode){
  int ret;
  uint8_t buf[RCS620S_MAX_CARD_RESPONSE_LEN];
  uint8_t responseLen = 0;
   
  buf[0] = 0x02;
  memcpy(buf + 1, rcs620s.idm, 8);
  buf[9] = 0x01;
  buf[10] = (uint8_t)((serviceCode >> 0) & 0xff);
  buf[11] = (uint8_t)((serviceCode >> 8) & 0xff);
 
  ret = rcs620s.cardCommand(buf, 12, buf, &responseLen);
   
  if(!ret || (responseLen != 12) || (buf[0] != 0x03) ||
      (memcmp(buf + 1, rcs620s.idm, 8) != 0) || ((buf[10] == 0xff) && (buf[11] == 0xff))) {
    return 0;
  }
 
  return 1;
}
 
int readEncryption(uint16_t serviceCode, uint8_t blockNumber, uint8_t *buf){
  int ret;
  uint8_t responseLen = 0;
   
  buf[0] = 0x06;
  memcpy(buf + 1, rcs620s.idm, 8);
  buf[9] = 0x01; // サービス数
  buf[10] = (uint8_t)((serviceCode >> 0) & 0xff);
  buf[11] = (uint8_t)((serviceCode >> 8) & 0xff);
  buf[12] = 0x01; // ブロック数
  buf[13] = 0x80;
  buf[14] = blockNumber;
 
  ret = rcs620s.cardCommand(buf, 15, buf, &responseLen);
 
  if (!ret || (responseLen != 28) || (buf[0] != 0x07) ||
      (memcmp(buf + 1, rcs620s.idm, 8) != 0)) {
    return 0;
  }
 
  return 1;
}
 
void printBalanceLCD(char *card_name, uint32_t *balance){
  char result[17];
  sprintf(result, "Result = \\%u", *balance);
  LCD.clear();
  LCD.setCursor(0, 0);
  LCD.print(card_name);
  LCD.setCursor(0, 1);
  LCD.print(result);

  sprintf(result, "%s - %u", card_name, *balance);
  if(digitalRead(KEY_PIN)) Keyboard.println(result); 
  return;
}

使用したArduino IDEのバージョンは1.0.2 ATmega32U2対応版です。
ソースプログラム中のカギ括弧にご注意ください。HTMLのタグとの区別ため一部に全角文字を使用しています。Arduino IDEの置換え機能で半角に変換してからコンパルしてください。

コントローラ基盤 Vol.2-22014年11月01日

MAX7219と8x8matrix LED

aitendoで見つけた8x8マトリックスモジュールです。税別495円です。パーツを買うより安かったので買ってしまいました。
外部との接続インターフェースはSPI接続です。Arduino ライブラリーではMatrix LEDのライブラリーが多数掲載されています。使いやすいものを使用すると良いでしょう。

このあたりのライブラリーが使用できます。

コントローラ基盤 Vol.2-12014年11月01日

HT16K33と8x8matrix LED 2個

aitendoで見つけたI2C接続のLEDコントローラドライバ[HT16K33-28W] を使って8x8matrix LED 2個の表示モジュールを作製しました。

  • コントローラ
    aitendo I2C接続LEDコントローラドライバ[HT16K33-28W] と専用基板
  • 8x8 matrix LED
    TOM-15888H-B ちょと前のBタイプマトリックスLEDです。

コントローラ基盤 Vol.22014年11月01日

ちょっと、光もので遊んでいます。

aitendoで見つけたI2C接続のLEDコントローラドライバ[HT16K33-28W] を使ったモジュールを作成するためのICと基板の2点セットです。
アノード側(ROW0~ROW15)16ビット、カソード側(COM0~COM7)8ビットのLEDコントローラーです。8x8matrixLEDなら2個までコントロールできます。7セグLEDや14セグLEDもコントロール可能(カソードコモン)です。使用しているコントローラーICはHOLTEK社のHT16K33というICです。このコントローラは16x8ビットRAMデータストレージを持っていますのでI2Cへはアドレスデータ(通常00H)、16ビット表示データ(通常8行分)、表示コマンドの順にデータを送信することで表示を行います。adafruitからはHT16K33を使用した8x8 matrix LEDや7セグLED、Dual Alphanumeric Displayを表示させる基板がいくつか発売されています。国内ではスイッチサイエンスで取り扱いがあります。コントローラー基板は秋月でも扱っいます。


MPUとはI2C接続です。ArduinoやRaspberry PiとI2Cバス接続して使用することができます。Arduinoライブラリーも公開されています。
  Adafruit-LED-Backpack-Library
  Adafruit-GFX-Library