arduino时钟制作教程(用Arduino做一只会撒娇的狐狸)
arduino时钟制作教程(用Arduino做一只会撒娇的狐狸)代码可在本项目文件库中下载。http://make.quwj.com/project/81创建一个触摸传感器,感应是否有人正在触摸或抚摸狐狸。将4层铝箔纸粘贴在里面以便制作成电容式传感器。对于 Arduino 电容式触控开关原理可以参考这里。将长边缝合在一起然后将铝箔纸粘在纸板上。确保内部折叠部分留出一些空间,以便铝箔纸不会破裂。预留一个地方连接到 Arduino 的接线处。操作预警:使用的人造革确保它不含任何PVC成分。人造皮将经过激光切割,如果含有PVC,切割时会释放氯化物的有毒气体。如你不能确定所用皮革是否含有PVC,可用剪刀来切割线条。根据模板用激光切割机切割所有材料。如图所示,所有红线都需要切割,所有黑线需要雕刻。根据自己的要求设置好激光切割机。我建议,可先用一张人造革测试一下,以测定雕刻部件的深度是否足够。如果没有激光切割机,也可以在纸上打印模板并手动切割所有模板,只是会花费更
这是一只会撒娇求安抚的绯红狐狸。用萌动得让你难以忽视的姿势撩你,提醒你给它安抚。
在它的央求下,你暂时放下手上的枯燥工作,和它来个互动、小憩一下,你原本机械的工作状态也平添了几分乐趣和安慰……(有创造力的朋友当然可以发挥一下,直接做个小姐姐也没有什么不可以。)
咳……进入正题。这只可爱的小狐狸会像动物一样呼吸。当你开始工作时,轻轻地抚摸它,表示你开始工作了。当你工作许久后,小狐狸就会躁动起来,呼吸好像会变得沉重。发生这种情况,你得再次抚摸它,可以让它恢复平静。你也会马上意识到自己也需要休息调剂一下,喝个茶、吃点东西亦或是起身做个瑜伽。
经过短暂休憩,你可以再次轻轻地抚摸狐狸,告诉它你将继续工作。当你再次忽略它的时候,它会再次来讨你的宠爱,十分乖巧!
材料清单
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
/**
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 数据线,对小狐狸重新编程做一番个性化的调整!