From ebcf05f1b5e83fc8d6e75654112280531b8532fd Mon Sep 17 00:00:00 2001 From: James Wood Date: Tue, 14 Jul 2020 14:57:42 +1000 Subject: [PATCH] first commit --- .bzEmpty | 0 Deskbot.ino | 278 +++++++++++++++++++++++++++++++++++++++++++++++ EEPROMAnything.h | 20 ++++ README.md | 1 + 4 files changed, 299 insertions(+) create mode 100644 .bzEmpty create mode 100644 Deskbot.ino create mode 100644 EEPROMAnything.h create mode 100644 README.md diff --git a/.bzEmpty b/.bzEmpty new file mode 100644 index 0000000..e69de29 diff --git a/Deskbot.ino b/Deskbot.ino new file mode 100644 index 0000000..7d7adba --- /dev/null +++ b/Deskbot.ino @@ -0,0 +1,278 @@ +#include +#include "EEPROMAnything.h" +//#include +#include +#include +#include + +#define motorPinUp 3 +#define motorPinDown 2 +#define sonarPongPin 4 +#define sonarPingPin 5 +#define buttonDownPin 6 +#define buttonUpPin 7 +#define beeperPin 12 + +LiquidCrystal_I2C lcd(0x27,8,2); + +enum directions { none, up, down, setUp, setDown, checking, moving }; + +const unsigned int floorOffset = 935-280; +const unsigned int maxSafeHeight = 410; +const unsigned int minSafeHeight = 48; +const unsigned int buttonHoldTime = 2000; +const unsigned int setButtonTimeout = 5000; +const unsigned int sonarTimeout = 50; +const unsigned int screenTimeout = 10000; + +directions operationMode = none; +unsigned int topHeight = 390; +unsigned int bottomHeight = 50; +unsigned int targetHeight; +unsigned int lastMeasuredHeight = 0; +unsigned int reportedHeight = 0; +unsigned int heightAccuracy = 1; +unsigned long beepEndTime = 0; +unsigned long buttonPushTime = 0; +unsigned long lastMeasuredTime = 0; +unsigned long screenLastUpdatedTime = 0; + +NewPing sonar(sonarPingPin, sonarPongPin); +Bounce upDebounce = Bounce(); +Bounce downDebounce = Bounce(); + +void setup() { + Serial.begin(115200); + Serial.println(); + lcd.init(); + resetScreen(); + pinMode(motorPinUp, OUTPUT); + pinMode(motorPinDown, OUTPUT); + pinMode(beeperPin, OUTPUT); + pinMode(sonarPongPin, INPUT); + pinMode(sonarPingPin, OUTPUT); + pinMode(buttonUpPin, INPUT_PULLUP); + pinMode(buttonDownPin, INPUT_PULLUP); + digitalWrite(motorPinUp, LOW); + digitalWrite(motorPinDown, LOW); + upDebounce.attach(buttonUpPin); + upDebounce.interval(5); + downDebounce.attach(buttonDownPin); + downDebounce.interval(5); + Serial.println(F("================ Deskbot 1.2 ================")); + loadSettings(); + if (topHeight > maxSafeHeight) { + topHeight = maxSafeHeight; + saveSettings(); + } + if (bottomHeight < minSafeHeight || bottomHeight > topHeight) { + bottomHeight = minSafeHeight; + saveSettings(); + } + reportVitals(); + beep(50); +} + +void loop() { + beep(); + upDebounce.update(); + downDebounce.update(); + if (millis() > screenLastUpdatedTime + screenTimeout) resetScreen(); + if (!upDebounce.read() && !downDebounce.read()) operationMode = none; // if both pressed, then abort + + switch (operationMode) { + case checking: + if (millis() < buttonPushTime + buttonHoldTime) { + if (upDebounce.rose()) { + operationMode = moving; + targetHeight = topHeight; + } + else if (downDebounce.rose()){ + operationMode = moving; + targetHeight = bottomHeight; + } + } else { + if (!upDebounce.read()) operationMode = setUp; + else if (!downDebounce.read()) operationMode = setDown; + buttonPushTime = millis(); + beep(50); + } + break; + + case moving: + if (!upDebounce.read() || !downDebounce.read()) { // abort if any button pressed + motorDirection(none); //redundant - safety + operationMode = none; + beep(100); + Serial.println(F("Stop.")); + resetScreen(); + break; + } + if (moveDesk(targetHeight)) operationMode = none; + break; + + case setUp: + operationMode = none; + // if (!upDebounce.read() && !downDebounce.read()) { // abort if both buttons pressed + // motorDirection(none); //redundant - safety + // operationMode = none; + // Serial.println(F("Stop.")); + // break; + // } + // if (millis() < buttonPushTime + setButtonTimeout) { + // if(upDebounce.fell() || downDebounce.fell()) { + // buttonPushTime = millis(); + // if(upDebounce.fell()) settingHeight = measureHeight() + 1; + // if(downDebounce.fell()) settingHeight = measureHeight() - 1; + // Serial.println(F("Setting height: ") + String(settingHeight)); + // moveDesk(settingHeight); + // } + // } else { + // topHeight = settingHeight; + // saveSettings(); + // Serial.println("New top height set: " + String(topHeight)); + // operationMode = none; + // } + break; + + case setDown: + operationMode = none; + break; + + default: + motorDirection(none); + if ((upDebounce.fell() && !downDebounce.fell()) || (!upDebounce.fell() && downDebounce.fell())) { + buttonPushTime = millis(); + operationMode = checking; + beep(10); + } + break; + } +} + +void motorDirection(directions motorDirection) { + switch (motorDirection) { + case up: + digitalWrite(motorPinUp, HIGH); + digitalWrite(motorPinDown, LOW); + break; + case down: + digitalWrite(motorPinUp, LOW); + digitalWrite(motorPinDown, HIGH); + break; + default: + digitalWrite(motorPinUp, LOW); + digitalWrite(motorPinDown, LOW); + break; + } +} + +bool moveDesk(int newHeight) { + int currentHeight = measureHeight(); + if (reportedHeight != currentHeight) { + Serial.println("Current height: " + String(currentHeight) + ". Target height: " + String(newHeight) + "."); + lcd.setCursor(0,0); + lcd.print(F("At: ")); + lcd.print(currentHeight); + lcd.print(F(" ")); + lcd.setCursor(0,1); + lcd.print(F("To: ")); + lcd.print(newHeight); + lcd.print(F(" ")); + reportedHeight = currentHeight; + } +// if ((currentHeight > maxSafeHeight) || (currentHeight < minSafeHeight)) { +// beep(500); +// operationMode = none; +// motorDirection(none); +// Serial.println("Out of safe operating range"); +// lcd.setCursor(0,0); +// lcd.print(F("Out of R")); +// lcd.setCursor(0,1); +// lcd.print(F("ange. ")); +// return false; +// } + + if ( currentHeight > newHeight + heightAccuracy ) { + motorDirection(down); + return false; + } else if ( currentHeight < newHeight - heightAccuracy ) { + motorDirection(up); + return false; + } else { + motorDirection(none); + Serial.println("Target height reached: " + String(newHeight) + "mm."); + lcd.setCursor(0,0); + lcd.print(F("Height: ")); + lcd.setCursor(0,1); + lcd.print(newHeight); + lcd.print(F("mm ")); + screenLastUpdatedTime = millis(); + return true; + } +} + +void resetScreen() { + lcd.setCursor(0,0); + lcd.print(F(" Desk")); + lcd.setCursor(0,1); + lcd.print(F("bot! ")); + screenLastUpdatedTime = millis(); +} + +void beep() { + if ( beepEndTime - millis() > 10000 ) { + beepEndTime = millis(); + } else if (millis() < beepEndTime) { + digitalWrite(beeperPin, HIGH); + } else { + digitalWrite(beeperPin, LOW); + } +} + +void beep(int beepLength) { + beepEndTime = millis() + beepLength; +} + +int measureHeight() { + if ((millis() - lastMeasuredTime >= sonarTimeout) || (lastMeasuredTime == 0)) { + lastMeasuredTime = millis(); + lastMeasuredHeight = sonar.ping_cm() * 10; + } + return lastMeasuredHeight; +} + +void saveSettings() { + int eepromAddress = 0; + eepromAddress += EEPROM_writeAnything(eepromAddress, topHeight); + eepromAddress += EEPROM_writeAnything(eepromAddress, bottomHeight); + Serial.println(" Saved Top: " + String(topHeight)); + Serial.println("Saved Bottom: " + String(bottomHeight)); +} + +void loadSettings() { + int eepromAddress = 0; + eepromAddress += EEPROM_readAnything(eepromAddress, topHeight); + eepromAddress += EEPROM_readAnything(eepromAddress, bottomHeight); + Serial.println(" Loaded Top: " + String(topHeight) + "mm"); + Serial.println(" Loaded Bottom: " + String(bottomHeight) + "mm"); +} + +void reportVitals() { + Serial.print(F(" Top height: ")); + Serial.print(topHeight); + Serial.println(F("mm")); + + Serial.print(F(" Bottom height: ")); + Serial.print(bottomHeight); + Serial.println(F("mm")); + + Serial.print(F("Current Height: ")); + Serial.print(measureHeight()); + Serial.println(F("mm")); + +// Serial.print(F(" Free Memory: ")); +// Serial.print(freeMemory()); +// Serial.println(F(" thingies.")); + Serial.println(F("=============================================")); +} diff --git a/EEPROMAnything.h b/EEPROMAnything.h new file mode 100644 index 0000000..c548cbf --- /dev/null +++ b/EEPROMAnything.h @@ -0,0 +1,20 @@ +#include +#include // for type definitions + +template int EEPROM_writeAnything(int ee, const T& value) +{ + const byte* p = (const byte*)(const void*)&value; + unsigned int i; + for (i = 0; i < sizeof(value); i++) + EEPROM.write(ee++, *p++); + return i; +} + +template int EEPROM_readAnything(int ee, T& value) +{ + byte* p = (byte*)(void*)&value; + unsigned int i; + for (i = 0; i < sizeof(value); i++) + *p++ = EEPROM.read(ee++); + return i; +} diff --git a/README.md b/README.md new file mode 100644 index 0000000..b7f4671 --- /dev/null +++ b/README.md @@ -0,0 +1 @@ +# Deskbot