last updated: 2020-12-29
XMas :). So here is the not completely useless box. All the material are recycled or were part of my basic electronics stock. The idea and parts of the code are from this page: https://www.labdomotic.com/2017/10/24/youtube-useless-box-fai-da-te/. To ensure that the box is not completely useless, it has a 3D printed compartment for jewellery (right corner).
Here some of the 16 different actions:
/* useless_box.ino
* weigu.lu
* idea: https://www.labdomotic.com/2017/10/24/youtube-useless-box-fai-da-te/
*/
#include <Servo.h>
#include <PlayRtttl.h>
Servo Servo_Arm;
Servo Servo_Lid;
const byte PIN_SWITCH = 6;
const byte PIN_SERVO_ARM = 0;
const byte PIN_SERVO_LID = 2;
const byte PIN_SPEAKER = 10;
const byte PIN_RELAY = 13;
const byte MIN_SERVO_ARM = 10;
const byte MAX_SERVO_ARM_NS = 165;
const byte MAX_SERVO_ARM_S = 178;
const byte SERVO_ARM_1 = 125;
const byte SERVO_ARM_2 = 135;
const byte SERVO_ARM_3 = 160;
const byte SERVO_LID_1 = 85;
const byte SERVO_LID_2 = 95;
const byte SERVO_LID_3 = 115;
const byte SERVO_LID_4 = 120;
const byte SERVO_LID_5 = 140;
int switch_state=0, action=1;
char *song1 = "MissionImp:d=16,o=6,b=95:32d,32d#,32d,32d#,32d,32d#,32d,32d#,32d,32d,32d#,
32e,32f,32f#,32g,g,8p,g,8p,a#,p,c7,p,g,8p,g,8p,f,p,f#,p,g,8p,g,8p,a#,p,c7,p,
g,8p,g,8p,f,p,f#,p,a#,g,2d,32p,a#,g,2c#,32p,a#,g,2c,a#5,8c,2p,32p,a#5,g5,
2f#,32p,a#5,g5,2f,32p,a#5,g5,2e,d#,8d";
char *song2 = "MahnaMahna:d=16,o=6,b=125:c#,c.,b5,8a#.5,8f.,4g#,a#,g.,4d#,8p,c#,c.,b5,
8a#.5,8f.,g#.,8a#.,4g,8p,c#,c.,b5,8a#.5,8f.,4g#,f,g.,8d#.,f,g.,8d#.,f,8g,
8d#.,f,8g,d#,8c,a#5,8d#.,8d#.,4d#,8d#.";
void setup() {
pinMode(PIN_RELAY, OUTPUT);
digitalWrite(PIN_RELAY,HIGH);
Serial.begin(115200);
delay(1000);
Serial.println("Hello from the useless box!");
pinMode(LED_BUILTIN, OUTPUT);
digitalWrite(LED_BUILTIN,HIGH);
pinMode(PIN_SWITCH, INPUT_PULLUP);
Servo_Arm.attach(PIN_SERVO_ARM);
Servo_Lid.attach(PIN_SERVO_LID);
Servo_Arm.write(MIN_SERVO_ARM);
Servo_Lid.write(SERVO_LID_1);
}
void loop() {
switch_state = digitalRead(PIN_SWITCH);
//action = random(1,16);
if (non_blocking_delay(1200000)) { // 20 minutes
digitalWrite(PIN_RELAY,LOW);
}
if (switch_state == LOW) {
// slow = s, quick = q, o = opening, c = closing
switch(action) {
case 1:
Serial.println("Action 1"); // s_o s_s+1s s_c
for (int i = SERVO_LID_1; i <= SERVO_LID_5; i++) {
Servo_Lid.write(i);
delay(20);
}
for (int i = MIN_SERVO_ARM; i <= MAX_SERVO_ARM_NS; i++) {
Servo_Arm.write(i);
delay(20);
}
delay(1000);
Servo_Arm.write(MAX_SERVO_ARM_S);
delay(200);
for (int i = MAX_SERVO_ARM_S; i >= MIN_SERVO_ARM; i--) {
Servo_Arm.write(i);
delay(20);
}
for (int i = SERVO_LID_5; i >= SERVO_LID_1; i--) {
Servo_Lid.write(i);
delay(20);
}
action++;
break;
case 2:
Serial.println("Action 2"); // q_o q_s q_c 1.5s q_o 3s q_c
for (int i = SERVO_LID_1; i <= SERVO_LID_5; i++) {
Servo_Lid.write(i);
delay(6);
}
delay(550);
Servo_Arm.write(MAX_SERVO_ARM_S);
delay(700);
Servo_Arm.write(MIN_SERVO_ARM);
delay(550);
Servo_Lid.write(SERVO_LID_1);
delay(1500);
for (int i = SERVO_LID_1; i <= SERVO_LID_5; i++) {
Servo_Lid.write(i);
delay(6);
}
delay(3000);
Servo_Lid.write(SERVO_LID_1);
action++;
break;
case 3:
Serial.println("Action 3"); // q_o 1s q_c 2s q_o q_s q_c
for (int i = SERVO_LID_1; i <= SERVO_LID_5; i++) {
Servo_Lid.write(i);
delay(6);
}
delay(1000);
Servo_Lid.write(SERVO_LID_1);
delay(2000);
for (int i = SERVO_LID_1; i <= SERVO_LID_5; i++) {
Servo_Lid.write(i);
delay(6);
}
Servo_Arm.write(MAX_SERVO_ARM_S);
delay(700);
Servo_Arm.write(MIN_SERVO_ARM);
delay(500);
Servo_Lid.write(SERVO_LID_1);
action++;
break;
case 4:
Serial.println("Action 4"); // s_o s_s+1s q_c
for (int i = SERVO_LID_1; i <= SERVO_LID_5; i++) {
Servo_Lid.write(i);
delay(20);
}
for (int i = MIN_SERVO_ARM; i <= MAX_SERVO_ARM_NS; i++) {
Servo_Arm.write(i);
delay(20);
}
delay(2000);
Servo_Arm.write(MAX_SERVO_ARM_S);
delay(700);
Servo_Arm.write(MIN_SERVO_ARM);
delay(400);
Servo_Lid.write(SERVO_LID_1);
action++;
break;
case 5:
Serial.println("Action 5"); // q_o 2s arm_toggling q_c
for (int i = SERVO_LID_1; i <= SERVO_LID_5; i++) {
Servo_Lid.write(i);
delay(6);
}
delay(2000);
Servo_Arm.write(SERVO_ARM_2);
delay(550);
Servo_Arm.write(SERVO_ARM_3);
delay(200);
Servo_Arm.write(SERVO_ARM_2);
delay(200);
Servo_Arm.write(SERVO_ARM_3);
delay(200);
Servo_Arm.write(SERVO_ARM_2);
delay(200);
Servo_Arm.write(SERVO_ARM_3);
delay(200);
Servo_Arm.write(SERVO_ARM_2);
delay(200);
Servo_Arm.write(SERVO_ARM_3);
delay(200);
Servo_Arm.write(SERVO_ARM_2);
delay(200);
Servo_Arm.write(SERVO_ARM_3);
delay(200);
Servo_Arm.write(SERVO_ARM_2);
delay(2000);
Servo_Arm.write(MAX_SERVO_ARM_S);
delay(700);
Servo_Arm.write(MIN_SERVO_ARM);
delay(400);
Servo_Lid.write(SERVO_LID_1);
action++;
break;
case 6:
Serial.println("Action 6"); // s_o lid_toggling s_s q_c 1.5s q_o 3s q_c
for (int i = SERVO_LID_1; i <SERVO_LID_5; i++) {
Servo_Lid.write(i);
delay(20);
}
delay(1000);
for (int i = 0; i < 12; i++) {
for (int j = SERVO_LID_1; j <= SERVO_LID_5; j++) {
Servo_Lid.write(j);
delay(6);
}
delay(200);
}
for (int i = MIN_SERVO_ARM; i <= MAX_SERVO_ARM_NS; i++) {
Servo_Arm.write(i);
delay(20);
}
Servo_Arm.write(MAX_SERVO_ARM_S);
delay(700);
Servo_Arm.write(MIN_SERVO_ARM);
delay(400);
Servo_Lid.write(SERVO_LID_1);
delay(1500);
for (int i = SERVO_LID_1; i <= SERVO_LID_5; i++) {
Servo_Lid.write(i);
delay(6);
}
delay(3000);
Servo_Lid.write(SERVO_LID_2);
action++;
break;
case 7:
Serial.println("Action 7"); // q_o lid_toggle_3 song1 q_s q_c
for (int i = SERVO_LID_1; i <= SERVO_LID_5; i++) {
Servo_Lid.write(i);
delay(6);
}
delay(400);
Serial.println("here");
Servo_Arm.write(MIN_SERVO_ARM);
Serial.println("here2");
delay(1000);
for (int i = 0; i < 3; i++) {
for (int j = SERVO_LID_1; j <= SERVO_LID_5; j++) {
Servo_Lid.write(j);
delay(6);
}
delay(200);
}
//delay(500);
playRtttlBlocking(PIN_SPEAKER, song1);
Servo_Arm.write(MAX_SERVO_ARM_S);
delay(700);
Servo_Arm.write(MIN_SERVO_ARM);
delay(400);
Servo_Lid.write(SERVO_LID_1);
action++;
break;
case 8:
Serial.println("Action 8"); //
for (int i = SERVO_LID_1; i <= SERVO_LID_5; i++) {
Servo_Lid.write(i);
delay(6);
}
Servo_Arm.write(MAX_SERVO_ARM_S);
delay(2000);
for (int i = 0; i < 7; i++) {
Servo_Arm.write(SERVO_ARM_1);
delay(100);
Servo_Arm.write(SERVO_ARM_3);
delay(100);
}
delay(500);
Servo_Arm.write(MAX_SERVO_ARM_S);
delay(700);
Servo_Arm.write(MIN_SERVO_ARM);
delay(400);
Servo_Lid.write(SERVO_LID_1);
action++;
break;
case 9:
Serial.println("Action 9"); //
for (int i = SERVO_LID_1; i <= SERVO_LID_4; i++) {
Servo_Lid.write(i);
delay(6);
}
delay(2000);
Servo_Lid.write(SERVO_LID_5);
for (int i = MIN_SERVO_ARM; i <= MAX_SERVO_ARM_NS; i++) {
Servo_Arm.write(i);
delay(40);
}
delay(500);
Servo_Arm.write(MAX_SERVO_ARM_S);
delay(200);
for (int i = MAX_SERVO_ARM_S; i >= MIN_SERVO_ARM; i--) {
Servo_Arm.write(i);
delay(40);
}
Servo_Lid.write(SERVO_LID_1);
delay(2000);
Servo_Lid.write(SERVO_LID_3);
delay(3000);
Servo_Lid.write(SERVO_LID_1);
action++;
break;
case 10:
Serial.println("Action 10"); //
for (int i = SERVO_LID_1; i <= SERVO_LID_4; i++) {
Servo_Lid.write(i);
delay(100);
}
delay(1000);
for (int i = 0; i < 10; i++) {
for (int j = SERVO_LID_1; j <= SERVO_LID_3; j++) {
Servo_Lid.write(j);
delay(6);
}
delay(100);
}
Servo_Lid.write(SERVO_LID_5);
delay(100);
Servo_Arm.write(MAX_SERVO_ARM_S);
delay(650);
Servo_Arm.write(MIN_SERVO_ARM);
delay(400);
Servo_Lid.write(SERVO_LID_1);
action++;
break;
case 11:
Serial.println("Action 11"); //
for (int i = SERVO_LID_1; i <= SERVO_LID_5; i++) {
Servo_Lid.write(i);
delay(6);
}
Servo_Arm.write(MAX_SERVO_ARM_S);
delay(2000);
for (int i = 0; i < 3; i++) {
Servo_Arm.write(SERVO_ARM_2);
delay(200);
Servo_Arm.write(SERVO_ARM_3);
delay(200);
}
delay(1500);
Servo_Arm.write(MIN_SERVO_ARM);
delay(400);
Servo_Lid.write(SERVO_LID_1);
delay(1500);
for (int i = SERVO_LID_1; i <= SERVO_LID_5; i++) {
Servo_Lid.write(i);
delay(6);
}
Servo_Arm.write(MAX_SERVO_ARM_S);
delay(3000);
Servo_Arm.write(MIN_SERVO_ARM);
delay(400);
Servo_Lid.write(SERVO_LID_1);
action++;
break;
case 12:
Serial.println("Action 12"); //
for (int i = SERVO_LID_1; i <= SERVO_LID_5; i++) {
Servo_Lid.write(i);
delay(50);
}
delay(1000);
for (int i = MIN_SERVO_ARM; i <= MAX_SERVO_ARM_NS; i++) {
Servo_Arm.write(i);
delay(50);
}
delay(2000);
Servo_Arm.write(MAX_SERVO_ARM_S);
delay(700);
Servo_Arm.write(MIN_SERVO_ARM);
delay(400);
Servo_Lid.write(SERVO_LID_1);
action++;
break;
case 13:
Serial.println("Action 13"); //
for (int i = SERVO_LID_1; i <= SERVO_LID_5; i++) {
Servo_Lid.write(i);
delay(6);
}
delay(2000);
for (int i = MIN_SERVO_ARM; i >= SERVO_ARM_2; i--) { // orig 60
Servo_Arm.write(i);
delay(40);
}
for (int i = 0; i < 3; i++) {
Servo_Arm.write(SERVO_ARM_2);
delay(200);
Servo_Arm.write(SERVO_ARM_3);
delay(800);
}
Servo_Arm.write(MAX_SERVO_ARM_S);
delay(2000);
Servo_Arm.write(MIN_SERVO_ARM);
delay(500);
Servo_Lid.write(SERVO_LID_1);
action++;
break;
case 14:
Serial.println("Action 14"); //
for (int i = SERVO_LID_1; i <= SERVO_LID_4; i++) {
Servo_Lid.write(i);
delay(6);
}
delay(4000);
Servo_Lid.write(SERVO_LID_5);
Servo_Arm.write(MAX_SERVO_ARM_S);
delay(650);
Servo_Arm.write(MIN_SERVO_ARM);
delay(500);
Servo_Lid.write(SERVO_LID_3);
delay(4000);
Servo_Lid.write(SERVO_LID_1);
action++;
break;
case 15:
Serial.println("Action 15"); //
for (int i = SERVO_LID_1; i <= SERVO_LID_4; i++) {
Servo_Lid.write(i);
delay(6);
}
delay(1000);
for (int i = 0; i < 3; i++) {
for (int j = SERVO_LID_1; j <= SERVO_LID_4; j++) {
Servo_Lid.write(j);
delay(50);
}
for (int j = SERVO_LID_4; j >= SERVO_LID_1; j--) {
Servo_Lid.write(j);
delay(50);
}
}
for (int j = SERVO_LID_1; j <= SERVO_LID_5; j++) {
Servo_Lid.write(j);
delay(50);
}
for (int i = MIN_SERVO_ARM; i <= MAX_SERVO_ARM_NS; i++) {
Servo_Arm.write(i);
delay(40);
}
delay(1000);
Servo_Arm.write(MAX_SERVO_ARM_S);
delay(700);
Servo_Arm.write(MIN_SERVO_ARM);
delay(400);
Servo_Lid.write(SERVO_LID_1);
action = 16;
break;
case 16:
Serial.println("Action 16"); //
for (int i = SERVO_LID_1; i <= SERVO_LID_5; i++) {
Servo_Lid.write(i);
delay(6);
}
delay(1000);
playRtttlBlocking(PIN_SPEAKER, song2);
Servo_Arm.write(MAX_SERVO_ARM_S);
delay(700);
Servo_Arm.write(MIN_SERVO_ARM);
delay(400);
Servo_Lid.write(SERVO_LID_1);
delay(200);
digitalWrite(PIN_RELAY,LOW);
break;
}
}
}
// non blocking delay using millis(), returns true if time is up
bool non_blocking_delay(unsigned long milliseconds) {
static unsigned long nb_delay_prev_time = 0;
if(millis() >= nb_delay_prev_time + milliseconds) {
nb_delay_prev_time += milliseconds;
return true;
}
return false;
}