MAKER: ReinKTH/译:趣无尽 Cherry(转载请注明出处)
这是一只会撒娇求安抚的绯红狐狸。用萌动得让你难以忽视的姿势撩你,提醒你给它安抚。
在它的央求下,你暂时放下手上的枯燥工作,和它来个互动、小憩一下,你原本机械的工作状态也平添了几分乐趣和安慰……(有创造力的朋友当然可以发挥一下,直接做个小姐姐也没有什么不可以。)
咳……进入正题。这只可爱的小狐狸会像动物一样呼吸。当你开始工作时,轻轻地抚摸它,表示你开始工作了。当你工作许久后,小狐狸就会躁动起来,呼吸好像会变得沉重。发生这种情况,你得再次抚摸它,可以让它恢复平静。你也会马上意识到自己也需要休息调剂一下,喝个茶、吃点东西亦或是起身做个瑜伽。
经过短暂休憩,你可以再次轻轻地抚摸狐狸,告诉它你将继续工作。当你再次忽略它的时候,它会再次来讨你的宠爱,十分乖巧!
先看一段视频吧!
材料清单
Arduino pro micro ×1
micro USB转USB电缆×1
步进电机×1
电机驱动器×1
小面包板×2
彩色LED灯带×2
电线×若干
10M电阻×1
100M电阻×2
9伏电池×1
9伏电极夹×1
人造革×1
胶合板×1
纸板×1
铝箔纸×1
胶水×1
针和线×若干
操作预警:使用的人造革确保它不含任何PVC成分。人造皮将经过激光切割,如果含有PVC,切割时会释放氯化物的有毒气体。如你不能确定所用皮革是否含有PVC,可用剪刀来切割线条。
切割原材料
根据模板用激光切割机切割所有材料。如图所示,所有红线都需要切割,所有黑线需要雕刻。根据自己的要求设置好激光切割机。我建议,可先用一张人造革测试一下,以测定雕刻部件的深度是否足够。
如果没有激光切割机,也可以在纸上打印模板并手动切割所有模板,只是会花费更长的时间。
切割文件可在本项目文件库中下载。
http://make.quwj.com/project/81
将皮革粘贴到纸板上
纸板用作皮革的支撑材料,方便弯曲。除六边形外,皮革的每个表面都有匹配的纸板。根据皮革的形状将它们粘在皮革上。边缘处的纸板之间应该预留大约3mm的空间向外折叠,在向内折叠的纸板之间几乎没有空间。
同时,向内折叠的地方用工具刀稍微切割一下皮革,使皮革更容易折叠。确保你没有彻底切断它!
将铝箔纸粘合到内面
创建一个触摸传感器,感应是否有人正在触摸或抚摸狐狸。将4层铝箔纸粘贴在里面以便制作成电容式传感器。对于 Arduino 电容式触控开关原理可以参考这里。
将长边缝合在一起然后将铝箔纸粘在纸板上。确保内部折叠部分留出一些空间,以便铝箔纸不会破裂。预留一个地方连接到 Arduino 的接线处。
搭建电路并上传代码
代码可在本项目文件库中下载。
http://make.quwj.com/project/81
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 | /** capacitive sensing code with servo motor for Crimson Fox */ #include <Servo.h> #include <CapacitiveSensor.h> #include <HampelFilter.h> #include <Filters.h> #define dir 5 #define stp 6 #define capin 8 #define capout 9 #define ledWork 14 #define ledPanic 15 //Initializing touch sensor CapacitiveSensor cap_sense = CapacitiveSensor(capin, capout); // 10 megohm resistor between pins capin & capout //Initialiying Filters HampelFilter dataBuffer = HampelFilter(0.00, 3, 3.50); FilterOnePole lowpassFilter( LOWPASS, 5); //Initialiying threasholding for touch int upperThreashold = 8000; int lowerThreashold = 8000; int baseline = 100; int summedThreashold = 16000; int csSum = 0; long dynThreasholdCount = 0; long dynThreasholdTimeout = 6000; //Initializing Motor int pos = 0; // variable to store the servo position bool exhale = false ; // false for inhale, true for exhale int breathDepthTop; int breathDepthBottom; int breathDelay; //Initializing session and fox status enum WorkingStatus { pause, work, panic, standby }; WorkingStatus foxStatus; bool touched = false ; // status if touch was detected //Initialize Timing long sessionStart; //time at session start long sessionLength = 30000; //180000ms = 3min, time after which fox panics, one hour would be 3600000, 30 min would be 1800000 long REACTIVITYDELAY = 2000; long lastTouchTime; long breathStepStart; void setup() { cap_sense.set_CS_AutocaL_Millis(0xFFFFFFFF); // turn off autocalibrate on channel 1 - just as an example Serial.begin(9600); pinMode(stp, OUTPUT); pinMode(dir, OUTPUT); pinMode(ledWork, OUTPUT); pinMode(ledPanic, OUTPUT); enterPauseStatus(); breathStepStart = millis(); lastTouchTime = millis(); } void loop() { //read and filter touch sensor signal long total1 = lowpassFilter.input(cap_sense.capacitiveSensor(30)); //30 dataBuffer.write(total1); /* if(!(foxStatus == standby)){ Serial.print(lastTouchTime); Serial.print(", "); Serial.print(millis()); Serial.print(", "); Serial.println(lastTouchTime + REACTIVITYDELAY - millis()); }*/ if ((lastTouchTime + REACTIVITYDELAY - millis()) > 4294000000) { //Serial.println("checking status"); // state machine if (foxStatus == pause) { //enter work status if touched if (detectTouch(total1)) { enterWorkStatus(); } } else if (foxStatus == work) { //inter pause status if touched if (detectTouch(total1)) { enterPauseStatus(); } //check if it is time to panic if ((millis() - sessionStart) > sessionLength) { enterPanicStatus(); } } else if (foxStatus == panic) { //panic //enter work status if touched if (detectTouch(total1)) { enterWorkStatus(); } } } if (foxStatus != standby){ breathing(); } if (Serial.available() > 0){ String userInput = Serial.readString(); Serial.print(userInput); userInput.trim(); if (userInput.equals( "q" ) || userInput == "quit" ){ exhaleAndDie(); foxStatus = standby; } else { Serial.println(userInput + " could not be recogninzed use 'q' or 'quit' to shut down the fox." ); } } } bool detectTouch( int cs) { bool touchTriggered = false ; if (!dataBuffer.checkIfOutlier(cs)) { Serial.print(cs); Serial.print( "\t" ); if (cs > upperThreashold) { csSum += cs; Serial.print(cs); Serial.print( "\t" ); if (csSum >= summedThreashold) //c: This value is the threshold, a High value means it takes longer to trigger { Serial.print( "Trigger: " ); Serial.print(csSum); touchTriggered = true ; if (csSum > 0) { csSum = 0; //Reset } //cs_7_8.reset_CS_AutoCal(); //Stops readings } } else if (cs < lowerThreashold) { csSum = 0; //Timeout caused by bad readings } Serial.println( "" ); } return touchTriggered; } void breathing() { //Serial.println(millis()-breathStepStart); /*if(!(foxStatus == standby)){ Serial.print(breathStepStart); Serial.print(", "); Serial.print(millis()); Serial.print(", "); Serial.println(millis()-breathStepStart); }*/ //if(breathDelay < (millis()-breathStepStart)){ breathStepStart = millis(); if (pos > breathDepthTop) { exhale = true ; } else if (pos <= breathDepthBottom) { exhale = false ; } //set motor direction if (exhale) { pos = pos - breathDelay; digitalWrite(dir, LOW); } else { pos = pos + breathDelay; //Serial.println(pos); digitalWrite(dir, HIGH); } //do a breath step before returning to measuring touch again for ( int i = 0; i < breathDelay; i++){ digitalWrite(stp, HIGH); delayMicroseconds(1); digitalWrite(stp, LOW); delayMicroseconds(1); } //} } void enterWorkStatus() { Serial.println( "Enter work" ); sessionStart = millis(); touched = false ; foxStatus = work; breathDelay = 6; breathDepthTop = 800; breathDepthBottom = 0; digitalWrite(ledWork, HIGH); //TODO turn on again digitalWrite(ledPanic, LOW); lastTouchTime = millis(); } void enterPanicStatus() { Serial.println( "Enter panic" ); touched = false ; foxStatus = panic; breathDelay = 10; breathDepthTop = 1500; breathDepthBottom = 1000; digitalWrite(ledWork, LOW); digitalWrite(ledPanic, HIGH); } void enterPauseStatus() { Serial.println( "Enter pause" ); touched = false ; foxStatus = pause; breathDelay = 2; breathDepthTop = 800; breathDepthBottom = 0; digitalWrite(ledWork, LOW); digitalWrite(ledPanic, LOW); lastTouchTime = millis(); } void exhaleAndDie(){ digitalWrite(dir, LOW); while (pos > 0){ digitalWrite(stp, HIGH); delayMicroseconds(1); digitalWrite(stp, LOW); delayMicroseconds(1); pos--; } } void handleThreashold(){ } } |
粘合下部并连线
1、将齿轮粘连到步进电机和胶合板的下面,并将步进电机粘在上面。
2、使用针和线,每个角内折叠,形成狐狸的形状。
3、将电线缠绕步进电机本两圈,然后稍微拉紧一下。另外,确保可逆时针旋转。
组装所有部件
部件布局如下:
1、底部预留9伏电池的地方。
2、中间为步进电机。
3、顶部为Arduino pro micro和电机驱动器。
4、将皮革的开口边缘缝合在一起。
最后,将所有剩余的开口侧缝合在一起,项目就完成了。
你还可以连上 USB 数据线,对小狐狸重新编程做一番个性化的调整!
http://www.quwj.com/2018/11/28/crimson-fox-raising-awareness-to-take-a-break-whil.html
发表评论
要发表评论,您必须先登录。