diff --git a/.gitignore b/.gitignore index 11954d3..03fb36e 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,8 @@ +# Artifacts *_secrets.h +_build +version.h + +# Binaries +*.FCStd1 +*.stl diff --git a/window_control/firmware/Makefile b/window_control/firmware/Makefile new file mode 100644 index 0000000..fe9caa9 --- /dev/null +++ b/window_control/firmware/Makefile @@ -0,0 +1,116 @@ +# Kitsune Scientific + +# What project to build +PROJ := firmware + + +# What board to build for and its core +CORE ?= esp8266:esp8266 +FQBN ?= esp8266:esp8266:generic + +# Tools, their links and versions +ARDUINO_CLI_VERSION := +ARDUINO_CLI_URL := https://raw.githubusercontent.com/arduino/arduino-cli/master/install.sh +ARDUINO_LINT_VERSION := +ARDUINO_LINT_URL := https://raw.githubusercontent.com/arduino/arduino-lint/main/etc/install.sh + +# The version and time we're compiling from +GIT_VERSION := "$(shell git describe --abbrev=4 --dirty --always --tags)" +COMPILED_DATE := "$(shell date)" + +# Treat all warnings as errors. +BUILDPROP := compiler.warning_flags.all='-Wall -Wextra -Werror' + +# Locations +ROOT := $(PWD) +BINDIR := $(ROOT)/_build/bin +BUILDDIR := $(ROOT)/_build + +# What port to build on +ifndef SERIAL_DEV + ifneq (,$(wildcard /dev/ttyUSB0)) + SERIAL_DEV = /dev/ttyUSB0 + else ifneq (,$(wildcard /dev/ttyACM0)) + SERIAL_DEV = /dev/ttyACM0 + else + SERIAL_DEV = unknown + endif +endif + + +.PHONY: all help build upload version release requirements + +# Do everything +all: tools requirements version build + + +help: + @echo + @echo "Targets:" + @echo " lint De-lint the software." + @echo " build Build the software." + @echo " upload Upload the software." + @echo " requirements Fetch all requirements." + @echo + + +# Set VERBOSE=1 to not run in --silent + +ifndef VERBOSE +.SILENT: +endif + +# Only build the code +build: version $(PROJ).ino + $(BINDIR)/arduino-cli core install $(CORE) + $(BINDIR)/arduino-cli compile -b $(FQBN) $(PROJ) + +# Make binaries +bin: tools requirements version $(PROJ).ino + $(BINDIR)/arduino-cli core install $(CORE) + $(BINDIR)/arduino-cli compile -b $(FQBN) $(PROJ) -e + + # Clean and rename (could be optimized) + mv build/* _build + rm -rv build + +# Only upload the software +upload: version build $(PROJ).ino + $(BINDIR)/arduino-cli upload -b $(FQBN) $(PROJ) -p $(SERIAL_DEV) + +# Only update the version +version: + echo "#define VERSION \"$(GIT_VERSION)\"" > version.h + echo "#define COMPILED_ON \"$(COMPILED_DATE)\"" >> version.h + +# Generate an artifact +release: build $(PROJ).ino + $(BINDIR)/arduino-cli compile -b $(FQBN) $(PROJ) --output-dir $(BUILDDIR) + +# Only fetch the requirements +requirements: + @if [ -e requirements.txt ]; \ + then while read -r i ; do echo ; \ + echo "---> Installing " '"'$$i'"' ; \ + $(BINDIR)/arduino-cli lib install "$$i" ; \ + done < requirements.txt ; \ + else echo "---> MISSING requirements.txt file"; \ + fi + +# Monitor the serial (debug) output. +# Requires minicom +monitor: upload + minicom -D $(SERIAL_DEV) -b 115200 + +lint: tools + $(BINDIR)/arduino-lint --compliance strict + +# Fetches all the tools required +tools: + mkdir -p $(BINDIR) + curl -fsSL $(ARDUINO_CLI_URL) | BINDIR=$(BINDIR) sh -s $(ARDUINO_CLI_VERSION) + curl -fsSL $(ARDUINO_LINT_URL) | BINDIR=$(BINDIR) sh -s $(ARDUINO_LINT_VERSION) + +# Messy, come back and fix? +clean: + rm -rv _build/arduino.avr.mega diff --git a/window_control/firmware/README.md b/window_control/firmware/README.md new file mode 100644 index 0000000..7382122 --- /dev/null +++ b/window_control/firmware/README.md @@ -0,0 +1,8 @@ +# To install + +You will have to add `https://arduino.esp8266.com/stable/package_esp8266com_index.json` to your arduino-cli.yaml + +```shell +arduino-cli config init +vim ~/.arduino15/arduino-cli.yaml +``` diff --git a/window_control/firmware/firmware.ino b/window_control/firmware/firmware.ino new file mode 100644 index 0000000..aefe531 --- /dev/null +++ b/window_control/firmware/firmware.ino @@ -0,0 +1,98 @@ +#include // Enables the ESP8266 to connect to the local network (via WiFi) +#include // Allows us to connect to, and publish to the MQTT broker + +const int ledPin = 0; // This code uses the built-in led for visual feedback that the button has been pressed +const int buttonPin = 13; // Connect your button to pin #13 + +// WiFi +// Make sure to update this for your own WiFi network! +const char *ssid = "internet_of_insecure_things"; +const char *wifi_password = "pass"; + +// MQTT +const char *clientID = "window_0"; // Unique to this device +// Make sure to update this for your own MQTT Broker! +const char *mqtt_server = "mqtt.kitsunehosting.net"; +const char *mqtt_topic = "home/upstairs_lab/actuators/window_0"; +const char *mqtt_username = "user"; +const char *mqtt_password = "pass"; + +// Initialise the WiFi and MQTT Client objects +WiFiClient wifiClient; +PubSubClient client(mqtt_server, 1883, wifiClient); // 1883 is the listener port for the Broker + +void setup() +{ + pinMode(ledPin, OUTPUT); + + // Switch the on-board LED off to start with + digitalWrite(ledPin, HIGH); + + // Begin Serial on 115200 + // Remember to choose the correct Baudrate on the Serial monitor! + // This is just for debugging purposes + Serial.begin(115200); + + Serial.print("Connecting to "); + Serial.println(ssid); + + // Connect to the WiFi + WiFi.begin(ssid, wifi_password); + + // Wait until the connection has been confirmed before continuing + while (WiFi.status() != WL_CONNECTED) + { + delay(500); + Serial.print("."); + } + + // Debugging - Output the IP Address of the ESP8266 + Serial.println("WiFi connected"); + Serial.print("IP address: "); + Serial.println(WiFi.localIP()); + + // Connect to MQTT Broker + // client.connect returns a boolean value to let us know if the connection was successful. + // If the connection is failing, make sure you are using the correct MQTT Username and Password (Setup Earlier in the Instructable) + if (client.connect(clientID, mqtt_username, mqtt_password)) + { + Serial.println("Connected to MQTT Broker!"); + } + else + { + Serial.println("Connection to MQTT Broker failed..."); + } +} + +void loop() +{ + digitalWrite(ledPin, LOW); + if (client.publish(mqtt_topic, "0")) + { + Serial.println("Button pushed and message sent!"); + } + else + { + Serial.println("Message failed to send. Reconnecting to MQTT Broker and trying again"); + client.connect(clientID, mqtt_username, mqtt_password); + delay(10); // This delay ensures that client.publish doesn't clash with the client.connect call + client.publish(mqtt_topic, "-1"); + } + + delay(400); + + digitalWrite(ledPin, HIGH); + if (client.publish(mqtt_topic, "1")) + { + Serial.println("Button pushed and message sent!"); + } + else + { + Serial.println("Message failed to send. Reconnecting to MQTT Broker and trying again"); + client.connect(clientID, mqtt_username, mqtt_password); + delay(10); // This delay ensures that client.publish doesn't clash with the client.connect call + client.publish(mqtt_topic, "-1"); + } + + delay(400); +} diff --git a/window_control/firmware/requirements.txt b/window_control/firmware/requirements.txt new file mode 100644 index 0000000..51e3bdf --- /dev/null +++ b/window_control/firmware/requirements.txt @@ -0,0 +1 @@ +PubSubClient diff --git a/window_control/firmware/window_control.ino b/window_control/firmware/window_control.ino deleted file mode 100644 index e85d076..0000000 --- a/window_control/firmware/window_control.ino +++ /dev/null @@ -1,102 +0,0 @@ -// Include the esp wifi lib -#include -// Include the mqtt client lib -#include - -// Include any secrets. -#include "window_control_secrets.h" - -#define wifi_ssid SECRET_SSID -#define wifi_password SECRET_PASS - -#define mqtt_server "mqtt.kitsunehosting.net" -#define mqtt_port 1883 -#define mqtt_user SECRET_MQTT_USER -#define mqtt_password SECRET_MQTT_PASS - -#define in_topic "/testing/in" -#define out_topic "/testing/out" -// Replace by 2 if you aren't enable to use Serial Monitor... Don't forget to Rewire R1 to GPIO2! -#define in_led 2 - -WiFiClient espClient; -PubSubClient client; - -void setup() { - Serial.begin(115200); - setup_wifi(); - client.setClient(espClient); - client.setServer(mqtt_server, mqtt_port); - client.setCallback(callback); - - // initialize digital pin LED_BUILTIN as an output. - pinMode(in_led, OUTPUT); - digitalWrite(in_led, HIGH); -} - -void setup_wifi() { - delay(10); - // We start by connecting to a WiFi network - Serial.println(); - WiFi.hostname("ESP-Test1"); - Serial.print("Connecting to "); - Serial.println(wifi_ssid); - - WiFi.begin(wifi_ssid, wifi_password); - - while (WiFi.status() != WL_CONNECTED) { - delay(500); - Serial.println("Not yet connected.. Waiting 500ms to check again.."); - } - - Serial.println(""); - Serial.println("WiFi connected"); - Serial.println("IP address: "); - Serial.println(WiFi.localIP()); -} - -void reconnect() { - // Loop until we're reconnected - while (!client.connected()) { - Serial.print("Attempting MQTT connection..."); - // Attempt to connect - // If you do not want to use a username and password, change next line to - // if (client.connect("ESP8266Client")) { - if (client.connect("ESP8266Client", mqtt_user, mqtt_password)) { - Serial.println("connected"); - } else { - Serial.print("failed, rc="); - Serial.print(client.state()); - Serial.println(" try again in 5 seconds"); - // Wait 5 seconds before retrying - delay(5000); - } - } -} - -void callback(char* topic, byte* payload, unsigned int length) { - Serial.print("Message arrived ["); - Serial.print(topic); - Serial.print("] "); - for (int i = 0; i < length; i++) { - char receivedChar = (char)payload[i]; - Serial.print(receivedChar); - if (receivedChar == '0') - digitalWrite(in_led, LOW); - if (receivedChar == '1') - digitalWrite(in_led, HIGH); - } - Serial.println(); -} - -void loop() { - if (!client.connected()) { - reconnect(); - } - client.loop(); - // Publishes a random 0 and 1 like someone switching off and on randomly (random(2)) - client.publish(out_topic, String(random(2)).c_str(), true); - delay(1000); - client.subscribe(in_topic); - delay(1000); -} diff --git a/window_control/firmware/window_control_secrets.h.example b/window_control/firmware/window_control_secrets.h.example deleted file mode 100644 index aa57159..0000000 --- a/window_control/firmware/window_control_secrets.h.example +++ /dev/null @@ -1,5 +0,0 @@ -#define SECRET_SSID "secret_ssid" -#define SECRET_PASS ""Ah ah ah, you didn't say the magic word."" - -#define SECRET_MQTT_USER "mqtt_user" -#define SECRET_MQTT_PASS "mqtt_pass" \ No newline at end of file diff --git a/window_control/models/Automatic Gearbox Electronics Mount.FCStd b/window_control/models/Automatic Gearbox Electronics Mount.FCStd index 21a4023..fd75f12 100644 Binary files a/window_control/models/Automatic Gearbox Electronics Mount.FCStd and b/window_control/models/Automatic Gearbox Electronics Mount.FCStd differ