3Dプリンタのヘッドを入手したので、動かしてみる。
ステッピングモータはバイポーラで動作電圧12Vになっている様子。黒と緑、青と赤がコイルの両端になっている様子。
巻線抵抗は確か7Ω程度で最大電流は1.5A程度になると推定している。
ヒータも12Vで動作し、抵抗は4Ωくらいだった気がする。
センサはサーミスタNTC3950 100K相当と推測される。
当初、センサの出力がおかしかったが、センサを固定するボルトが線を挟んでいて、ショートしていた様子。
注意書きで、280℃以上にしてはいけないとなっているが間違って、それより上げても、なんとか動作している。
制御方法によりそうだが、センサだけであれば、300℃程度までなら上げても良いようにも感じる。
ステッピングモータはHブリッジモータドライバ、TB6643を2個使い、ヒータもFETで制御する。
マイコンはArduino nano相当品を利用した。ボードにレギュレータが搭載されているが、12Vから5Vに一度に
落とすと電流によっては破損する可能性があるので、手元にあった7808にて8Vに落とす。
(Arduinoは入力電圧は12Vとはなっていたはず。具体的なレギュレータの仕様は未確認。)
フィラメントにもよるが、1kgで2000円くらいのPLAを購入したのでセンサに測定用の抵抗を付け、
ArduinoのADCで測定を行った。210℃で470Ω、230℃で330Ω、300℃で115Ω程度とのことで、330Ωの抵抗を接続した。
センサの電源はArduinoから取る。
Arduinoのプログラムは以下の通り。
#include<Wire.h>
//PIN ASSIGN
//D0 : NC(RXD)
//D1 : NC(TXD)
//RST: NC
//GND: NC
//D2 : NC
//D3 : HEATER(OC2B)
//D4 : IN1(DRIVER LEFT)
//D5 : IN2(DRIVER LEFT, OC0B)
//D6 : IN2(DRIVER RIGHT, OC0A)
//D7 : IN1(DRIVER RIGHT)
//D8 : IN (CONNECTOR 1, PIN64, P9.17, command2)
//D9 : IN (CONNECTOR 2, PIN62, P9.15, command1, OC1A)
//D10: IN (CONNECTOR 3, PIN60, P9.13, command0, OC1B)
//D11: OUT(CONNECTOR 4, PIN58, P9.11, printerReady, OC2A)
//D12: POWER SUPPLY TO LCD
//
//D13: LED(5V, ON BOARD LED(GROUND))
//3V3: (POWER SUPPLY TO THIS BOARD)
//AREF: connected to only capacitor
//A0 : NC
//A1 : NC
//A2 : NC
//A3 : AD623 OUTPUT(HEATER TEMPERATURE)
//A4 : LCD SDA
//A5 : LCD SCL
//A6 : 2.5V(LM36)
//A7 : TEMPERATURE SENSOR(LM35, Vout = 0.01 * T)
//+5V: (POWER SUPPLY TO THIS BOARD)
//RST: NC
//GND: (POWER SUPPLY)
//VIN: (POWER SUPPLY TO ARDUINO)
//TB6643KQ FUNCTION
//IN1 IN2 OUT1 OUT2
// H H L L BRAKE
// L H L H
// H L H L
// L L Hi-z Hi-z OFF
//Connector on this board
//1 :
//2 :
//3 :
//4 :
//5 : 3.3V (should not connect to 3.3V on this board)
//6 : GND
#define I2Cadr 0x3e
#define MOTOR_DUTY 100
#define MOTOR_DUTY_MAX 255
byte contrast = 35; // コントラスト(0~63)
void lcd_contdata(byte x) {
Wire.write(0b11000000); // CO = 1, RS = 1
Wire.write(x);
}
void lcd_lastdata(byte x) {
Wire.write(0b01000000); // CO = 0, RS = 1
Wire.write(x);
}
// 文字の表示
void lcd_printStr(const char *s) {
Wire.beginTransmission(I2Cadr);
while (*s) {
if (*(s + 1)) {
lcd_contdata(*s);
} else {
lcd_lastdata(*s);
}
s++;
}
Wire.endTransmission();
}
// 表示位置の指定
void lcd_setCursor(byte x, byte y) {
lcd_cmd(0x80 | (y * 0x40 + x));
}
void lcd_cmd(byte x) {
Wire.beginTransmission(I2Cadr);
Wire.write(0b00000000); // CO = 0,RS = 0
Wire.write(x);
Wire.endTransmission();
//Serial.write(Wire.endTransmission() + '0');
}
void setup() {
// put your setup code here, to run once:
pinMode(13, OUTPUT);
pinMode(12, OUTPUT);
pinMode(4, OUTPUT);
pinMode(7, OUTPUT);
//5, 6 can be PWM output
pinMode(5, OUTPUT);
pinMode(6, OUTPUT);
digitalWrite(12, HIGH);
delay(1000);
Wire.begin();
Serial.begin(115200);
delay(500);
lcd_cmd(0b00111000); // function set
lcd_cmd(0b00111001); // function set
lcd_cmd(0b00000100); // EntryModeSet
lcd_cmd(0b00010100); // interval osc
lcd_cmd(0b01110000 | (contrast & 0xF)); // contrast Low
lcd_cmd(0b01011100 | ((contrast >> 4) & 0x3)); // contast High/icon/power
lcd_cmd(0b01101100); // follower control
delay(200);
lcd_cmd(0b00111000); // function set
lcd_cmd(0b00001100); // Display On
lcd_cmd(0b00000001); // Clear Display
delay(2);
lcd_setCursor(0, 0);
lcd_printStr("HEAT");
lcd_setCursor(0, 1);
lcd_printStr("SENS");
}
void int2Str(int level, char *levelChar){
*(levelChar + 3) = level % 10 + '0';
level /= 10;
*(levelChar + 2) = level % 10 + '0';
level /= 10;
*(levelChar + 1) = level % 10 + '0';
level /= 10;
*levelChar = level + '0';
}
void motorRotate(){
static int status = 0;
switch(status){
case 0:
digitalWrite(4, HIGH);
analogWrite(5, MOTOR_DUTY_MAX - MOTOR_DUTY);
digitalWrite(6, LOW);
digitalWrite(7, LOW);
status = 1;
break;
case 1:
digitalWrite(4, HIGH);
analogWrite(5, MOTOR_DUTY_MAX - MOTOR_DUTY);
analogWrite(6, MOTOR_DUTY);
digitalWrite(7, LOW);
status = 2;
break;
case 2:
digitalWrite(4, LOW);
digitalWrite(5, LOW);
analogWrite(6, MOTOR_DUTY);
digitalWrite(7, LOW);
status = 3;
break;
case 3:
digitalWrite(4, LOW);
analogWrite(5, MOTOR_DUTY);
analogWrite(6, MOTOR_DUTY);
digitalWrite(7, LOW);
status = 4;
break;
case 4:
digitalWrite(4, LOW);
analogWrite(5, MOTOR_DUTY);
digitalWrite(6, LOW);
digitalWrite(7, LOW);
status = 5;
break;
case 5:
digitalWrite(4, LOW);
analogWrite(5, MOTOR_DUTY);
analogWrite(6, MOTOR_DUTY_MAX - MOTOR_DUTY);
digitalWrite(7, HIGH);
status = 6;
break;
case 6:
digitalWrite(4, LOW);
digitalWrite(5, LOW);
analogWrite(6, MOTOR_DUTY_MAX - MOTOR_DUTY);
digitalWrite(7, HIGH);
status = 7;
break;
case 7:
digitalWrite(4, HIGH);
analogWrite(5, MOTOR_DUTY_MAX - MOTOR_DUTY);
analogWrite(6, MOTOR_DUTY_MAX - MOTOR_DUTY);
digitalWrite(7, HIGH);
status = 0;
break;
default:
break;
}
}
void displayValue(){
int level;
int temp;
double tmpTemp;
char levelChar[4];
char tempChar[4];
level = analogRead(A6);
temp = analogRead(A7);
tmpTemp = 2.5 / level * temp * 100;
temp = (int)tmpTemp;
int2Str(level, levelChar);
int2Str(temp, tempChar);
lcd_setCursor(0, 0);
lcd_printStr("LEV");
// lcd_setCursor(4, 0);
// lcd_printStr(levelChar);
lcd_setCursor(0, 1);
lcd_printStr("TEMP");
lcd_printStr(tempChar);
}
void loop() {
int incomingByte;
int sensor;
char levelChar[4];
char heaterChar[4];
char sensorChar[4];
static int heaterDuty = 0;
sensor = analogRead(A3);
motorRotate();
if(Serial.available() > 0){
incomingByte = Serial.read();
if(incomingByte == 'u'){
heaterDuty += 10;
if(heaterDuty > 250){
heaterDuty = 250;
}
}else if(incomingByte == 'd'){
heaterDuty -= 10;
if(heaterDuty < 0){
heaterDuty = 0;
}
}
analogWrite(3, heaterDuty);
Serial.write(incomingByte+1);
}
int2Str(heaterDuty, heaterChar);
lcd_setCursor(4, 0);
lcd_printStr(heaterChar);
int2Str(sensor, sensorChar);
lcd_setCursor(4, 1);
lcd_printStr(sensorChar);
delay(1000);
/*
digitalWrite(13, HIGH);
delay(2000);
digitalWrite(13, LOW);
delay(2000);
*/
}
現状、センサの値を見て、手動でヒータの出力を変更している。
モータの回転数が遅いためか、温度をあげないと、ノズルから出てこない。