玩具功能
- 减速齿轮组,把电机速度降低。
- 齿轮比可以调。两档变速。
- 只能停转后才能换挡。想过做个离合器,貌似没法3D打印实现吧。如果哪位高手有办法,请赐教。
- LED彩灯,两个模式。
A. 随机颜色,过渡变换。
B. 手动模式,三个可调变阻器,分别控制RGB值。
经验总结
- 先说教训吧。烧掉一块arduino nano。实验成功后跟LP显摆,结果9v供电把VIN和GND接反了。一股青烟,换来LP大人的欢笑。
- 还烧掉一块电池充电保护板。教训时,焊电池的时候,最后一步再焊正负级。
- 设计建模时,多根电线绑在一起时,直径要打出富裕。
- 要充分考虑到沉积打印成品的受力特点。几件东西拼接的时候,不能用插头链接。一定要用的话,插头做到很粗。而且插孔要大,拔出时不能有阻力。这次折了粘,粘了折,用掉不少502。
- 意外发现,502粘完后,再用玻璃胶沾一下。还算比较结实。
制作过程记录
代码见本文末尾。SolidWorks模型最近几天发到thingiverse.com上。
一. 电路原型

原型测试成功后,画电路图。不赶紧画出来,三天后自己就搞不清楚一堆乱线怎么插出来的了。

先用arduino uno做设计。考虑到成品尺寸不能太大,最后改在nano dreamer上实现。
二. 电路板焊接

焊接工作台。焊接手艺有待提高,好在倒是一次成功。该连的都连上了,不该连的都还分着。





三. SolidWorks建模
这一步花的时间最长。建好了是这样。
才知道齿轮都有模数一说。模数一样的,才能咬合得上。





四. 3D打印

每天早上开始打,顺利的时候,晚上回来能出炉一批零件。

当然也有不顺的时候。。。回来需要打扫卫生。

都打出来,差不多是这样。
五. 最后组装调试



代码:
/*
version 2:
removed IC L293D
added color LED, auto / manual color change
added 3 pots
*/
//#include <string.h>
#define potPinR 0
#define potPinG 1
#define potPinB 2
#define transistorPin 4
#define bluePin 9
#define greenPin 10
#define redPin 11
int redValue=0;
int greenValue=0;
int blueValue=0;
int mButtonPin= 5; //motor button pin, digital
int lButtonPin= 6; // led button pin, digital
int buttonState[] = {
LOW, LOW}; //[0] > motor, [1] > led.
//int buttonState[1] = LOW;
int lastButtonState[] = {
LOW, LOW}; // 记录button前一个状态值
int reading[] = {
0,0};
long lastDebounceTime[] = {
0,0};
long debounceDelay = 50; //去除抖动时间
int mSwitchStatus = LOW;
int lSwitchStatus = LOW;
int ledMode = 1; // 0>turn off, 1 > auto color, 2 > manual color
float RGB1[3];
float RGB2[3];
float INC[3];
void setup(){
// pinMode(potPin,INPUT);
pinMode(transistorPin,OUTPUT);
pinMode(potPinR,INPUT);
pinMode(potPinG,INPUT);
pinMode(potPinB,INPUT);
pinMode(mButtonPin, INPUT); // motor on/off
pinMode(lButtonPin, INPUT); // led on/off
Serial.begin(9600);
digitalWrite(transistorPin,HIGH);
randomSeed(millis());
RGB1[0]=0;
RGB1[1]=0;
RGB1[2]=0;
RGB2[0]=random(256);
RGB2[1]=random(256);
RGB2[2]=random(256);
}
void loop(){
mSwitchStatus=digitalRead(transistorPin);
buttonDebounce(mButtonPin,0); //[0] > motor, [1] > led.
buttonDebounce(lButtonPin,1); //[0] > motor, [1] > led.
switch(ledMode){
case 0:
lSwitchStatus=LOW;
offRGB();
redValue=0;
greenValue=0;
blueValue=0;
analogWrite(redPin,redValue);
analogWrite(greenPin,greenValue);
analogWrite(bluePin,blueValue);
break;
case 1:
/* redValue=0;
greenValue=100;
blueValue=0;
analogWrite(redPin,redValue);
analogWrite(greenPin,greenValue);
analogWrite(bluePin,blueValue); */
for (int x=0;x<3;x++){ RGB2[x] = random(256); RGB2[x] = constrain(RGB2[x], 0, 255); //delay(20); } colorRGB(); break; case 2: redValue=analogRead(potPinR)/4; greenValue=analogRead(potPinG)/4; blueValue=analogRead(potPinB)/4; /* Serial.print("pot Red: "); Serial.print(redValue); Serial.print(". pot Green: "); Serial.print(greenValue); Serial.print(". pot Blue: "); Serial.println(blueValue); */ analogWrite(redPin,redValue); analogWrite(greenPin,greenValue); analogWrite(bluePin,blueValue); break; } Serial.print("mSwitchStatus: "); Serial.print(mSwitchStatus); Serial.print(". lSwitchStatus: "); Serial.println(lSwitchStatus); } boolean buttonDebounce(int buttonPin, int deviceID){ //deviceID [0] > motor, [1] > led.
// delay(800);
// Serial.println(strf);
reading[deviceID] = digitalRead(buttonPin); //reading用来存储buttonPin的数据
// 一旦检测到数据发生变化,记录当前时间
if (reading[deviceID] != lastButtonState[deviceID]) {
lastDebounceTime[deviceID] = millis();
}
/*
Serial.print("ButtonPin: ");
Serial.print(buttonPin);
Serial.print(". now: ");
Serial.print(millis());
Serial.print(". last: ");
Serial.print(lastDebounceTime[deviceID]);
Serial.print(". reading: ");
Serial.print(reading[deviceID]);
Serial.print(". buttonState: ");
Serial.println(buttonState[deviceID]);
*/
// 等待50ms,再进行一次判断,是否和当前button状态相同
// 如果和当前状态不相同,改变button状态
// 同时,如果button状态为高(也就是被按下),那么就改变继电器的状态
if ((millis() - lastDebounceTime[deviceID]) > debounceDelay) {
// Serial.println(">100ms");
if (reading[deviceID] != buttonState[deviceID]) {
buttonState[deviceID] = reading[deviceID];
Serial.println("StateDiff");
if (buttonState[deviceID] == HIGH) {
if(deviceID==0){ //motor
mSwitchStatus=!mSwitchStatus;
}
else if(deviceID==1){ //led
// Serial.print("ledMode: ");
// Serial.println(ledMode);
// lSwitchStatus=!lSwitchStatus;
if(ledMode==2){
ledMode=0;
}
else{
ledMode =ledMode+1;
}
}
}
}
}
digitalWrite(transistorPin,mSwitchStatus);
// Serial.print("Turn: ");
// Serial.println(lSwitchStatus);
// 改变button前一个状态值
lastButtonState[deviceID] = reading[deviceID];
}
void offRGB(){
RGB2[0]=0;
RGB2[1]=0;
RGB2[2]=0;
for (int x=0; x<3; x++){
INC[x] = ( RGB2[x] - RGB1[x] ) / 128;
}
for ( int x =0 ; x<128; x++) {
redValue = int(RGB1[0]);
greenValue = int(RGB1[1]);
blueValue = int(RGB1[2]);
analogWrite(redPin, redValue);
analogWrite(greenPin, greenValue);
analogWrite(bluePin, blueValue);
delay(3);
RGB1[0] += INC[0];
RGB1[1] += INC[1];
RGB1[2] += INC[2];
}
}
void colorRGB(){
/*
int potRed = analogRead(potRedPin); // potRed存储模拟口0读到的值
int potGreen = analogRead(potGreenPin); // potGreen存储模拟口1读到的值
int potBlue = analogRead(potBluePin); // potBlue存储模拟口2读到的值
int val1 = map(potRed,0,1023,0,255); //通过map函数转换为0~255的值
int val2 = map(potGreen,0,1023,0,255);
int val3 = map(potBlue,0,1023,0,255);
int val1 = random(255);
int val2 = random(255);
int val3 = random(255);
*/
randomSeed(millis());
for (int x=0; x<3; x++){
INC[x] = ( RGB2[x] - RGB1[x] ) / 128;
}
for ( int x =0 ; x<128; x++) { redValue = int(RGB1[0]); greenValue = int(RGB1[1]); blueValue = int(RGB1[2]); //串口依次输出Red,Green,Blue对应值 /* Serial.print(x); Serial.print(" Red:"); Serial.print(redValue); Serial.print(" Green:"); Serial.print(greenValue); Serial.print(" Blue:"); Serial.println(blueValue); */ analogWrite(redPin, redValue); analogWrite(greenPin, greenValue); analogWrite(bluePin, blueValue); delay(3); RGB1[0] += INC[0]; RGB1[1] += INC[1]; RGB1[2] += INC[2]; buttonDebounce(mButtonPin,0); //[0] > motor, [1] > led.
buttonDebounce(lButtonPin,1); //[0] > motor, [1] > led.
}
for (int x=0;x<3;x++){
RGB2[x] = random(256);
RGB2[x] = constrain(RGB2[x], 0, 255);
delay(20);
}
}
你真够牛的,厉害厉害!