玩具功能
- 减速齿轮组,把电机速度降低。
- 齿轮比可以调。两档变速。
- 只能停转后才能换挡。想过做个离合器,貌似没法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); } }
你真够牛的,厉害厉害!