diff --git a/BaseConfig.h b/BaseConfig.h
new file mode 100644
index 0000000..e203d16
--- /dev/null
+++ b/BaseConfig.h
@@ -0,0 +1,32 @@
+/*
+ R. J. Tidey 2019/12/30
+ Basic config
+*/
+#define FILESYSTYPE 1
+
+/*
+Wifi Manager Web set up
+*/
+#define WM_NAME "uselessbox"
+#define WM_PASSWORD "password"
+
+//Update service set up
+String host = "uselessbox";
+const char* update_password = "password";
+
+//define actions during setup
+//define any call at start of set up
+#define SETUP_START 1
+//define config file name if used
+#define CONFIG_FILE "/uselessConfig.txt"
+//set to 1 if SPIFFS or LittleFS used
+#define SETUP_FILESYS 1
+//define to set up server and reference any extra handlers required
+#define SETUP_SERVER 1
+//call any extra setup at end
+#define SETUP_END 1
+
+// comment out this define unless using modified WifiManager with fast connect support
+#define FASTCONNECT true
+
+#include "BaseSupport.h"
diff --git a/README.md b/README.md
index 79a728e..c2643b6 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,48 @@
-# Smart Useless Box with ESP8266 and Gesture Sensor
+# Smart Useless Box with ESP8266 and Gesture Sensor modified
+
+This is a modification of the excellent Useless Box from balassy.
+
+https://github.com/balassy/useless-box
+
+The enclosure is the same but the software now has following additions.
+
+- Wifi support via WifiManager
+- SPIFFS support with filing and uploads
+- Configuration via a file in SPIFFS
+- Software update via OTA web browser
+- Modfied schematic with an amplifier and loudspeaker to give speech responses
+- Audio output via a software DAC using ESP8266Audio library
+
+The SPIFFS config file controls
+- servo positions and speeds
+- Actions are defined in the config file as sequences of base commands which control servo movements, delays, audio responses and sensor control
+- Sensor audio responses may be varied
+- Comments in the example config file list possible commands to be used in the sequences.
+- Sequences can either run one after another or can be selected at random.
+
+For my hardware I used an ESP-12F rather than the Wemos but that is a personal preference.
+The speaker in my case was a 21mm diameter but larger ones can be used.
+I made the switch a bit easier to toggle by taking 1mm off the internal spindle to reduce spring tension.
+
+
+
+[](https://youtu.be/ker99iGVxNo "Smart Useless Box in Action")
+
+##Set up Notes
+- Use BaseSupprt library at https://github.com/roberttidey/BaseSupport
+- Modify passwords for Wifimanager and firmware updates in BasicConfig.h.ino
+- Compile and serial upload using Arduino ESP8266 IDE. Code / SPIFFS split needs to be 2MB/2MB to allow for OTA to work.
+- WifiManager will start an AP portal when first used to set local wifi parameters. After that it will hook into local network.
+- Browse to the device using its IPaddress/upload and upload from data director (edit.htm.gz, favicon.ico, graphs.js.gz). From then on IPaddress/edit may be used to manage SPIFFs content
+- Upload uselessConfig.txt, index.html, and .mp3 audio files to SPIFFs
+- You can customise these as required. Audio files can be created using an online text to audio service like Notevibes.
+- Simple test of servos and audio may be done from base index page at IPaddress/edit
+- OTA updates may be done by exporting a compiled binary in Arduino IDE and then browsing to IPAddress/firmware
+
+
+The following is directly from balassy README
+
+## Smart Useless Box with ESP8266 and Gesture Sensor modified
A useless box made smarter with an ESP8266 microcontroller on a Wemos D1 Mini board and an APDS-9960 proximity sensor to give more funny responses.
diff --git a/config.h b/config.h
index 4775cd3..c81f8f8 100644
--- a/config.h
+++ b/config.h
@@ -1,18 +1,11 @@
-const char* APP_VERSION = "0.0.1";
+//const char* APP_VERSION = "0.0.1";
#ifndef LED_BUILTIN
-#define LED_BUILTIN D4
+#define LED_BUILTIN 2
#endif
-const int PIN_LID_SERVO = D8; // The GPIO number of the pin where the lid opener servo is connected.
-const int PIN_SWITCH_SERVO = D0; // The GPIO number of the pin where the switch manipulator servo is connected.
-const int PIN_SWITCH = D5; // The GPIO number of the pin where the switch is connected.
-const int PIN_SENSOR_SDA = D2; // The GPIO number of the pin where the SDA pin of the APDS-9660 sensor is connected.
-const int PIN_SENSOR_SCL = D1; // The GPIO number of the pin where the SCL pin of the APDS-9660 sensor is connected.
-const uint8_t SENSOR_TRIGGER_THRESHOLD = 100; // The proximity value level that triggers a lid opening. (lower=brighter, higher=darker)
-
-const int LID_START_POSITION = 90;
-const int LID_END_POSITION = 40;
-const int SWITCH_START_POSITION = 0;
-const int SWITCH_END_POSITION = 145;
-const int SWITCH_HALF_POSITION = 90;
+const int PIN_LID_SERVO = 12; // The GPIO number of the pin where the lid opener servo is connected.
+const int PIN_SWITCH_SERVO = 5; // The GPIO number of the pin where the switch manipulator servo is connected.
+const int PIN_SWITCH = 4; // The GPIO number of the pin where the switch is connected.
+const int PIN_SENSOR_SDA = 13; // The GPIO number of the pin where the SDA pin of the APDS-9660 sensor is connected.
+const int PIN_SENSOR_SCL = 14; // The GPIO number of the pin where the SCL pin of the APDS-9660 sensor is connected.
diff --git a/data/00.mp3 b/data/00.mp3
new file mode 100644
index 0000000..bca20b2
Binary files /dev/null and b/data/00.mp3 differ
diff --git a/data/01.mp3 b/data/01.mp3
new file mode 100644
index 0000000..a9d74be
Binary files /dev/null and b/data/01.mp3 differ
diff --git a/data/02.mp3 b/data/02.mp3
new file mode 100644
index 0000000..b04fb86
Binary files /dev/null and b/data/02.mp3 differ
diff --git a/data/03.mp3 b/data/03.mp3
new file mode 100644
index 0000000..a40d401
Binary files /dev/null and b/data/03.mp3 differ
diff --git a/data/04.mp3 b/data/04.mp3
new file mode 100644
index 0000000..a9eb37d
Binary files /dev/null and b/data/04.mp3 differ
diff --git a/data/05.mp3 b/data/05.mp3
new file mode 100644
index 0000000..1a0205d
Binary files /dev/null and b/data/05.mp3 differ
diff --git a/data/06.mp3 b/data/06.mp3
new file mode 100644
index 0000000..1aac03d
Binary files /dev/null and b/data/06.mp3 differ
diff --git a/data/07.mp3 b/data/07.mp3
new file mode 100644
index 0000000..54b1d69
Binary files /dev/null and b/data/07.mp3 differ
diff --git a/data/08.mp3 b/data/08.mp3
new file mode 100644
index 0000000..645d100
Binary files /dev/null and b/data/08.mp3 differ
diff --git a/data/09.mp3 b/data/09.mp3
new file mode 100644
index 0000000..059bbe6
Binary files /dev/null and b/data/09.mp3 differ
diff --git a/data/10.mp3 b/data/10.mp3
new file mode 100644
index 0000000..ca10451
Binary files /dev/null and b/data/10.mp3 differ
diff --git a/data/11.mp3 b/data/11.mp3
new file mode 100644
index 0000000..0522ea4
Binary files /dev/null and b/data/11.mp3 differ
diff --git a/data/12.mp3 b/data/12.mp3
new file mode 100644
index 0000000..49b5a85
Binary files /dev/null and b/data/12.mp3 differ
diff --git a/data/audio.txt b/data/audio.txt
new file mode 100644
index 0000000..1336ae7
--- /dev/null
+++ b/data/audio.txt
@@ -0,0 +1,16 @@
+00 a-round-of-applause-for-trying-again1574765538
+01 back-and-forth-back-and-forth-never1574765904
+02 cant-quite-make-it-lets-try-again1574765609
+03 cant-you-read-the-instructions1574765146
+04 i-am-getting-bored-with-this1574765806
+05 i-said-i-was-useless1574764811
+06 i-told-you-not-to1574764680
+07 my-arm-is-getting-tired1574765448
+08 slow-slow-quick-quick-slow1574765781
+09 you-are-wasting-your-time-here1574765348
+10 you-did-it-again
+11 This is fun. Not.
+12 Here we go again.
+
+
+sensor Naughty. Naughty.
diff --git a/data/edit.htm.gz b/data/edit.htm.gz
new file mode 100644
index 0000000..69ce414
Binary files /dev/null and b/data/edit.htm.gz differ
diff --git a/data/favicon.ico b/data/favicon.ico
new file mode 100644
index 0000000..71b25fe
Binary files /dev/null and b/data/favicon.ico differ
diff --git a/data/graphs.js.gz b/data/graphs.js.gz
new file mode 100644
index 0000000..7243544
Binary files /dev/null and b/data/graphs.js.gz differ
diff --git a/data/index.htm b/data/index.htm
new file mode 100644
index 0000000..dc55d78
--- /dev/null
+++ b/data/index.htm
@@ -0,0 +1,30 @@
+
+
+
+
+ESP8266 Useless test
+
+
+
+Useless
+
+
+
+
\ No newline at end of file
diff --git a/data/sensor1.mp3 b/data/sensor1.mp3
new file mode 100644
index 0000000..df129af
Binary files /dev/null and b/data/sensor1.mp3 differ
diff --git a/data/sensor2.mp3 b/data/sensor2.mp3
new file mode 100644
index 0000000..49b5a85
Binary files /dev/null and b/data/sensor2.mp3 differ
diff --git a/data/uselessConfig.txt b/data/uselessConfig.txt
new file mode 100644
index 0000000..4fd41b9
--- /dev/null
+++ b/data/uselessConfig.txt
@@ -0,0 +1,38 @@
+#Config file for weather / train access
+# lines are
+#host;switchStart;switchHalf;switchEnd;switchFast;switchSlow;lidStart;lidEnd;lidSlow;lidFast
+#sensorTriggerThreshold (0= no sensor)
+#mode (0=sequence, 1=random)
+#audioGain (0-39)
+#modeLines made up following actions
+#SS switch start slow;SF witch start fast;HS switch half slow;HF switch half fast;ES switch end slow;EF switch end fast
+#CS lid close slow;CF lid close fast;OS lid open slow;OF lid open fast
+#XSSPPP switch move to PPP with speed factor SS
+#YSSPPP lid move to PPP with speed factor SS
+#M0 proximity monitor off;M1 proximity monitor on
+#P0 mode to sequential;P1 mode to random
+#Afilename play audio from filename
+esp8266-useless
+0
+90
+118
+5
+15
+90
+50
+5
+15
+190
+0
+25
+OS,A05,ES,SS,CS
+OS,A06,ES,SS,CS,M0
+D5000,OF,A10,EF,SF,CF
+OF,A03,EF,SF,CF
+OF,A09,EF,SF,CF,OF,CF,M1
+OS,A04,D2000,CS,D2000,OF,EF,SF,CF,M0
+OF,HS,A02,D3000,SS,D3000,EF,SF,CF
+OS,A01,D4000,EF,SF,CF,M0
+OF,A00,CF,OF,CF,OF,CF,OF,CF,OF,EF,SF,CF,M2
+OF,HS,A07,D3000,EF,SF,CS,M0
+OS,A08,HS,EF,SF,CS,P1
\ No newline at end of file
diff --git a/media/Useless-Box1.jpg b/media/Useless-Box1.jpg
new file mode 100644
index 0000000..25fc573
Binary files /dev/null and b/media/Useless-Box1.jpg differ
diff --git a/media/Useless-Box1Preview.jpg b/media/Useless-Box1Preview.jpg
new file mode 100644
index 0000000..9ae7402
Binary files /dev/null and b/media/Useless-Box1Preview.jpg differ
diff --git a/speed-servo.cpp b/speed-servo.cpp
index 577cbbe..2772d9c 100644
--- a/speed-servo.cpp
+++ b/speed-servo.cpp
@@ -1,41 +1,24 @@
#include "speed-servo.h"
-const int SLOW_MOVE_DELAY = 15;
-const int Fast_MOVE_DELAY = 2;
-
void SpeedServo::attach(uint8_t pin) {
- _servo.attach(pin);
-}
-
-// Valid position: 0-180.
-void SpeedServo::moveNowTo(int newPosition) {
- _lastPosition = newPosition;
- _servo.write(newPosition);
+ _servo.attach(pin);
}
// Valid position: 0-180.
-void SpeedServo::moveFastTo(int newPosition) {
- _moveTo(newPosition, Fast_MOVE_DELAY);
-}
-
-// Valid position: 0-180.
-void SpeedServo::moveSlowTo(int newPosition) {
- _moveTo(newPosition, SLOW_MOVE_DELAY);
-}
-
-// Valid position: 0-180.
-void SpeedServo::_moveTo(int newPosition, unsigned long stepDelay) {
- if(newPosition > _lastPosition) {
- for (int pos = _lastPosition; pos <= newPosition; pos++) {
- _servo.write(pos);
- delay(stepDelay);
- }
- } else {
- for (int pos = _lastPosition; pos >= newPosition; pos--) {
- _servo.write(pos);
- delay(stepDelay);
- }
- }
-
- _lastPosition = newPosition;
+void SpeedServo::moveTo(int newPosition, unsigned long stepDelay) {
+ if(stepDelay == 0) {
+ _lastPosition = newPosition;
+ _servo.write(newPosition);
+ } else if(newPosition > _lastPosition) {
+ for (int pos = _lastPosition; pos <= newPosition; pos++) {
+ _servo.write(pos);
+ delay(stepDelay);
+ }
+ } else {
+ for (int pos = _lastPosition; pos >= newPosition; pos--) {
+ _servo.write(pos);
+ delay(stepDelay);
+ }
+ }
+ _lastPosition = newPosition;
}
diff --git a/speed-servo.h b/speed-servo.h
index 0429716..80d617e 100644
--- a/speed-servo.h
+++ b/speed-servo.h
@@ -7,14 +7,11 @@
class SpeedServo {
public:
void attach(uint8_t pin);
- void moveNowTo(int position);
- void moveFastTo(int position);
- void moveSlowTo(int position);
+ void moveTo(int newPosition, unsigned long stepDelay);
private:
Servo _servo;
int _lastPosition;
- void _moveTo(int newPosition, unsigned long stepDelay);
};
#endif /* speed_servo_h */
diff --git a/useless-box.ino b/useless-box.ino
index 2c2e433..840df05 100644
--- a/useless-box.ino
+++ b/useless-box.ino
@@ -1,217 +1,351 @@
// Platform libraries.
#include // To add IntelliSense for platform constants.
+#include "BaseConfig.h"
// Third-party libraries.
+#include "AudioFileSourceSPIFFS.h"
+#include "AudioFileSourceID3.h"
+#include "AudioGeneratorMP3.h"
+#include "AudioOutputI2SNoDAC.h"
// My classes.
#include "speed-servo.h"
#include "status-led.h"
#include "proximity-sensor.h"
-
#include "config.h" // To store configuration and secrets.
+
+int timeInterval = 250;
+unsigned long elapsedTime;
+#define MAX_ACTIONS 25
+
+int switchStart = 0;
+int switchHalf = 50;
+int switchEnd = 118;
+int switchFast = 5;
+int switchSlow = 15;
+int lidStart = 90;
+int lidEnd = 40;
+int lidFast = 5;
+int lidSlow = 1;
+int sensorTriggerThreshold = 100;
+int mode = 0;
+int actionCount= 0;
+String actions[MAX_ACTIONS];
+
SpeedServo lidServo;
SpeedServo switchServo;
StatusLed led;
ProximitySensor sensor;
int lastSwitchState = 0;
-long playCount = 0;
+long actionIndex = 0;
bool isLidOpen = false;
-bool monitorSensor = false;
-
-void setup() {
- initSerial();
- initServos();
- initLed();
- initSensor();
- pinMode(PIN_SWITCH, INPUT);
-
- Serial.printf("Application version: %s\n", APP_VERSION);
- Serial.println("Setup completed.");
+int monitorSensor = 0;
+
+#define START_AUDIO "/start.mp3"
+#define SENSOR_AUDIO "/sensor"
+
+AudioGeneratorMP3 *mp3;
+AudioFileSourceSPIFFS *file;
+AudioOutputI2SNoDAC *out;
+AudioFileSourceID3 *id3;
+
+#define MAX_FILES 10
+char filename[8] = "/00.mp3";
+int fileIndex = 0;
+float audioGain = 3.9;
+
+// Called when a metadata event occurs (i.e. an ID3 tag, an ICY block, etc.
+void MDCallback(void *cbData, const char *type, bool isUnicode, const char *string) {
+ (void)cbData;
+ Serial.printf("ID3 callback for: %s = '", type);
+
+ if (isUnicode) {
+ string += 2;
+ }
+
+ while (*string) {
+ char a = *(string++);
+ if (isUnicode) {
+ string++;
+ }
+ Serial.printf("%c", a);
+ }
+ Serial.println();
+ Serial.flush();
}
-void initSerial() {
- Serial.begin(115200);
- Serial.println();
- Serial.println("Initializing serial connection DONE.");
+void handleAudio() {
+ String filename = server.arg("audio");
+ if(filename.length()) {
+ playAudio("/" + filename + ".mp3");
+ }
+ server.send(200, "text/json", "audio was requested");
}
-void initServos() {
- lidServo.attach(PIN_LID_SERVO);
- lidServo.moveNowTo(LID_START_POSITION);
-
- switchServo.attach(PIN_SWITCH_SERVO);
- switchServo.moveNowTo(SWITCH_START_POSITION);
+void handleLid() {
+ String pos = server.arg("pos");
+ if(pos.length()) {
+ lidServo.moveTo(pos.toInt(), lidSlow);
+ }
+ server.send(200, "text/json", "lid servo to " + pos);
}
-void initLed() {
- led.setPin(LED_BUILTIN);
- led.turnOff();
+void handleSwitch() {
+ String pos = server.arg("pos");
+ if(pos.length()) {
+ switchServo.moveTo(pos.toInt(), switchSlow);
+ }
+ server.send(200, "text/json", "switch servo to " + pos);
}
-void initSensor() {
- sensor.attach(PIN_SENSOR_SDA, PIN_SENSOR_SCL, SENSOR_TRIGGER_THRESHOLD);
+void handleProximity() {
+ String pos = server.arg("pos");
+ if(pos.length()) {
+ switchServo.moveTo(pos.toInt(), switchSlow);
+ }
+ server.send(200, "text/json", "Proximity = " + String(sensor.getProximity()));
}
-void loop() {
- int switchState = digitalRead(PIN_SWITCH);
- boolean isSwitchTurnedOn = (switchState != lastSwitchState) && (switchState == LOW);
-
- if (isSwitchTurnedOn) {
- led.turnOn();
- run();
- isLidOpen = false;
- led.turnOff();
- } else {
- // Check the proximity sensor.
- if (sensor.isInRange()) {
- if (!isLidOpen && monitorSensor) {
- openLidFast();
- isLidOpen = true;
- }
- } else {
- if (isLidOpen) {
- closeLidFast();
- isLidOpen = false;
- }
- }
- }
-
- lastSwitchState = switchState;
-
- // Wait 250 ms before next reading (required for the sensor).
- delay(250);
-}
-
-void run() {
- switch (playCount % 10) {
- case 0:
- case 1:
- runSlow();
- break;
- case 2:
- runWaitThenFast();
- break;
- case 3:
- runFast();
- break;
- case 4:
- runFastThenClap();
- monitorSensor = true;
- break;
- case 5:
- runOpenCloseThenFast();
- monitorSensor = false;
- break;
- case 6:
- runPeekThenFast();
- break;
- case 7:
- runFastWithDelay();
- monitorSensor = true;
- break;
- case 8:
- runClap();
- monitorSensor = false;
- break;
- case 9:
- runHalf();
- break;
- default:
- break;
- }
-
- playCount++;
-}
-
-void runSlow() {
- openLidSlow();
- flipSwitchSlow();
- closeLidSlow();
-}
-
-void runWaitThenFast() {
- delay(5000);
- flipSwitchFast();
-}
-
-void runFast() {
- flipSwitchFast();
-}
-
-void runFastThenClap() {
- flipSwitchFast();
- clapLid();
-}
-
-void runOpenCloseThenFast() {
- openLidSlow();
- delay(2000);
- closeLidSlow();
- delay(2000);
- flipSwitchFast();
-}
-
-void runPeekThenFast() {
- switchServo.moveSlowTo(SWITCH_HALF_POSITION);
- delay(3000);
- switchServo.moveFastTo(SWITCH_START_POSITION);
- delay(3000);
- flipSwitchFast();
-}
+/*
+ load config
+*/
+void loadConfig() {
+ String line = "";
+ int config = 0;
+
+ actionCount = 0;
+ File f = SPIFFS.open(CONFIG_FILE, "r");
+ if(f) {
+ while(f.available()) {
+ line =f.readStringUntil('\n');
+ line.replace("\r","");
+ if(line.length() > 0 && line.charAt(0) != '#') {
+ switch(config) {
+ case 0: host = line; break;
+ case 1: switchStart = line.toInt(); break;
+ case 2: switchHalf = line.toInt(); break;
+ case 3: switchEnd = line.toInt(); break;
+ case 4: switchFast = line.toInt(); break;
+ case 5: switchSlow = line.toInt(); break;
+ case 6: lidStart = line.toInt(); break;
+ case 7: lidEnd = line.toInt(); break;
+ case 8: lidFast = line.toInt(); break;
+ case 9: lidSlow = line.toInt(); break;
+ case 10: sensorTriggerThreshold = line.toInt();break;
+ case 11: mode = line.toInt(); break;
+ case 12: audioGain = line.toInt()/10; break;
+ default :
+ if(actionCount < MAX_ACTIONS) {
+ actions[actionCount] = line;
+ actionCount++;
+ }
+ break;
+ }
+ config++;
+ }
+ }
+ f.close();
+ Serial.println(F("Config loaded"));
+ Serial.print(F("host:"));Serial.println(host);
+ Serial.print(F("switchStart:"));Serial.println(String(switchStart));
+ Serial.print(F("switchHalf:"));Serial.println(String(switchHalf));
+ Serial.print(F("switchEnd:"));Serial.println(String(switchEnd));
+ Serial.print(F("switchFast:"));Serial.println(String(switchFast));
+ Serial.print(F("switchSlow:"));Serial.println(String(switchSlow));
+ Serial.print(F("lidStart:"));Serial.println(String(lidStart));
+ Serial.print(F("lidEnd:"));Serial.println(String(lidEnd));
+ Serial.print(F("lidFast:"));Serial.println(String(lidFast));
+ Serial.print(F("lidSlow:"));Serial.println(String(lidSlow));
+ Serial.print(F("sensorTriggerThreshold:"));Serial.println(String(sensorTriggerThreshold));
+ Serial.print(F("mode:"));Serial.println(String(mode));
+ Serial.print(F("audioGain:"));Serial.println(String(audioGain));
+ Serial.print(String(actionCount));Serial.println(F(" Actions loaded"));
+ } else {
+ Serial.println(String(CONFIG_FILE) + " not found");
+ }
+}
-void runFastWithDelay() {
- openLidSlow();
- delay(4000);
- flipSwitchFast();
- closeLidFast();
+void updateactionIndex() {
+ if(mode == 0) {
+ actionIndex++;
+ actionIndex = actionIndex % actionCount;
+ } else {
+ actionIndex = random(actionCount);
+ }
}
-void runClap() {
- clapLid();
- clapLid();
- clapLid();
- clapLid();
- openLidFast();
- flipSwitchFast();
- closeLidFast();
+void playAudio(String filename) {
+ Serial.println("Play " + filename);
+ if(SPIFFS.exists(filename)) {
+ file = new AudioFileSourceSPIFFS(filename.c_str());
+ id3 = new AudioFileSourceID3(file);
+ id3->RegisterMetadataCB(MDCallback, (void*)"ID3TAG");
+ out = new AudioOutputI2SNoDAC();
+ mp3 = new AudioGeneratorMP3();
+ delay(100);
+ out->SetGain(audioGain);
+ mp3->begin(id3, out);
+ while(mp3->isRunning()) {
+ if (!mp3->loop()) {delay(500);mp3->stop();}
+ }
+ delete mp3;
+ delete out;
+ delete id3;
+ delete file;
+ }
}
-void runHalf() {
- switchServo.moveSlowTo(SWITCH_HALF_POSITION);
- delay(3000);
- switchServo.moveFastTo(SWITCH_END_POSITION);
- switchServo.moveFastTo(SWITCH_START_POSITION);
+void runEx() {
+ int i = 0;
+ int j = 0;
+ int servo;
+ int position;
+ int speed;
+ String action;
+ unsigned long t = millis();
+ String msg;
+ char actionChar;
+ char actionChar1;
+
+ Serial.println("run " + actions[actionIndex]);
+ while(j < actions[actionIndex].length()) {
+ msg = String((millis() -t)) + " ";
+ j = actions[actionIndex].indexOf(',', i);
+ if(j < 0) j = actions[actionIndex].length();
+ servo = 0;
+ action = actions[actionIndex].substring(i,j);
+ actionChar = action.charAt(0);
+ action = action.substring(1);
+ if(actionChar == 'D') {
+ //delay
+ delay(action.toInt());
+ msg += "Delay " + action;
+ } else if(actionChar == 'A') {
+ //Audio
+ msg += "AudioPlay \/" + action + ".mp3";
+ Serial.println(msg);
+ playAudio("/" + action + ".mp3");
+ msg = "";
+ } else if(actionChar == 'X' || actionChar == 'Y') {
+ speed = action.substring(0,2).toInt();
+ position = action.substring(3).toInt();
+ if(actionChar == 'X') {
+ servo = 1;
+ position = switchStart + (switchEnd - switchStart) * position / 100;
+
+ } else {
+ position = lidStart + (lidEnd - lidStart) * position / 100;
+ servo = 2;
+ }
+ } else if(actionChar == 'S') {
+ position = switchStart;
+ speed = (action == "S") ? switchSlow : switchFast;
+ servo = 1;
+ } else if(actionChar == 'H') {
+ position = switchHalf;
+ speed = (action == "S") ? switchSlow : switchFast;
+ servo = 1;
+ } else if(actionChar == 'E') {
+ position = switchEnd;
+ speed = (action == "S") ? switchSlow : switchFast;
+ servo = 1;
+ } else if(actionChar == 'C') {
+ position = lidStart;
+ speed = (action == "S") ? lidSlow : lidFast;
+ servo = 2;
+ } else if(actionChar == 'O') {
+ position = lidEnd;
+ speed = (action == "S") ? lidSlow : lidFast;
+ servo = 2;
+ } else if(actionChar == 'M') {
+ monitorSensor = action.toInt();
+ msg+= "monitorSensor " + action;
+ } else if(actionChar == 'P') {
+ mode = action.toInt();
+ msg+= "mode " + action;
+ }
+ if(servo == 1) {
+ switchServo.moveTo(position, speed);
+ msg += "switch to " + String(position) + " speed " + String(speed);
+ } else if (servo == 2) {
+ lidServo.moveTo(position, speed);
+ msg += "lid to " + String(position) + " speed " + String(speed);
+ }
+ if(msg != "") Serial.println(msg);
+ i = j + 1;
+ }
}
-void openLidSlow() {
- lidServo.moveSlowTo(LID_END_POSITION);
+void initServos() {
+ lidServo.attach(PIN_LID_SERVO);
+ lidServo.moveTo(lidStart, 0);
+
+ switchServo.attach(PIN_SWITCH_SERVO);
+ switchServo.moveTo(switchStart, 0);
}
-void openLidFast() {
- lidServo.moveFastTo(LID_END_POSITION);
+void initLed() {
+ led.setPin(LED_BUILTIN);
+ led.turnOff();
}
-void closeLidSlow() {
- lidServo.moveSlowTo(LID_START_POSITION);
+void initSensor() {
+ sensor.attach(PIN_SENSOR_SDA, PIN_SENSOR_SCL, sensorTriggerThreshold);
}
-void closeLidFast() {
- lidServo.moveFastTo(LID_START_POSITION);
+void setupStart() {
+ audioLogger = &Serial;
}
-void clapLid() {
- openLidFast();
- closeLidFast();
+void extraHandlers() {
+ server.on("/audio", HTTP_GET, handleAudio);
+ server.on("/lid", HTTP_GET, handleLid);
+ server.on("/switch", HTTP_GET, handleSwitch);
+ server.on("/proximity", HTTP_GET, handleProximity);
}
-void flipSwitchSlow() {
- switchServo.moveSlowTo(SWITCH_END_POSITION);
- switchServo.moveSlowTo(SWITCH_START_POSITION);
+void setupEnd() {
+ initServos();
+ initLed();
+ initSensor();
+ randomSeed(analogRead(0));
+ pinMode(PIN_SWITCH, INPUT_PULLUP);
+ playAudio(START_AUDIO);
}
-void flipSwitchFast() {
- switchServo.moveFastTo(SWITCH_END_POSITION);
- switchServo.moveFastTo(SWITCH_START_POSITION);
+void loop() {
+ int switchState = digitalRead(PIN_SWITCH);
+ boolean isSwitchTurnedOn = (switchState != lastSwitchState) && (switchState == LOW);
+
+ if (isSwitchTurnedOn) {
+ led.turnOn();
+ runEx();
+ updateactionIndex();
+ isLidOpen = false;
+ led.turnOff();
+ } else {
+ // Check the proximity sensor.
+ if (sensorTriggerThreshold && sensor.isInRange()) {
+ if (!isLidOpen && monitorSensor) {
+ lidServo.moveTo(lidEnd, lidFast);
+ playAudio(SENSOR_AUDIO + String(monitorSensor) + ".mp3");
+ isLidOpen = true;
+ }
+ } else {
+ if (isLidOpen) {
+ lidServo.moveTo(lidStart, lidFast);
+ isLidOpen = false;
+ }
+ }
+ }
+
+ lastSwitchState = switchState;
+
+ // Wait 250 ms before next reading (required for the sensor).
+ delay(timeInterval);
+ elapsedTime++;
+ server.handleClient();
}
+
diff --git a/wiring/Schematic_UselessBox.jpg b/wiring/Schematic_UselessBox.jpg
new file mode 100644
index 0000000..5c84e49
Binary files /dev/null and b/wiring/Schematic_UselessBox.jpg differ