Compare commits
10 commits
77cfce1866
...
965f302f24
Author | SHA1 | Date | |
---|---|---|---|
Starbeamrainbowlabs | 965f302f24 | ||
Starbeamrainbowlabs | 873e7d463b | ||
Starbeamrainbowlabs | da26e47056 | ||
Starbeamrainbowlabs | 2781b27961 | ||
Starbeamrainbowlabs | e537f9b42f | ||
Starbeamrainbowlabs | f2d37de5fb | ||
Starbeamrainbowlabs | 25afba6819 | ||
Starbeamrainbowlabs | 3897e8aeb4 | ||
Starbeamrainbowlabs | 4bae1e0fbb | ||
Starbeamrainbowlabs | 9c7f050f11 |
45
.gitignore
vendored
Normal file
45
.gitignore
vendored
Normal file
|
@ -0,0 +1,45 @@
|
|||
settings.h
|
||||
*.gcode
|
||||
*.stl
|
||||
*.obj
|
||||
*.mtl
|
||||
*.blend1
|
||||
|
||||
# Created by https://www.toptal.com/developers/gitignore/api/c++
|
||||
# Edit at https://www.toptal.com/developers/gitignore?templates=c++
|
||||
|
||||
### C++ ###
|
||||
# Prerequisites
|
||||
*.d
|
||||
|
||||
# Compiled Object files
|
||||
*.slo
|
||||
*.lo
|
||||
*.o
|
||||
*.obj
|
||||
|
||||
# Precompiled Headers
|
||||
*.gch
|
||||
*.pch
|
||||
|
||||
# Compiled Dynamic libraries
|
||||
*.so
|
||||
*.dylib
|
||||
*.dll
|
||||
|
||||
# Fortran module files
|
||||
*.mod
|
||||
*.smod
|
||||
|
||||
# Compiled Static libraries
|
||||
*.lai
|
||||
*.la
|
||||
*.a
|
||||
*.lib
|
||||
|
||||
# Executables
|
||||
*.exe
|
||||
*.out
|
||||
*.app
|
||||
|
||||
# End of https://www.toptal.com/developers/gitignore/api/c++
|
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
[submodule "lib/pubsubclient"]
|
||||
path = lib/pubsubclient
|
||||
url = https://github.com/knolleary/pubsubclient.git
|
110
analog_channel_scanner/analog_channel_scanner.ino
Normal file
110
analog_channel_scanner/analog_channel_scanner.ino
Normal file
|
@ -0,0 +1,110 @@
|
|||
#include <bitset>
|
||||
#include <string>
|
||||
|
||||
#define MULTIPLEX_PINA D5
|
||||
#define MULTIPLEX_PINB D6
|
||||
#define MULTIPLEX_PINC D7
|
||||
|
||||
#define ANALOG_PIN A0
|
||||
|
||||
/*
|
||||
000 0
|
||||
001 1
|
||||
010 2
|
||||
011 3
|
||||
100 4
|
||||
101 5
|
||||
110 6
|
||||
111 7
|
||||
*/
|
||||
|
||||
#define SOIL_A 4
|
||||
#define SOIL_B 6
|
||||
#define WATER_LEVEL_A 0
|
||||
#define WATER_LEVEL_B 1
|
||||
|
||||
|
||||
// Ref https://stackoverflow.com/a/523737/1460422
|
||||
#define CHECK_BIT(var,pos) ((var) & (1<<(pos)))
|
||||
|
||||
int soilPin = D3;
|
||||
|
||||
float referenceVoltage = 3.3;
|
||||
|
||||
|
||||
|
||||
void read_analog(int channel) {
|
||||
|
||||
const char* bin = std::bitset<8>(channel).to_string().c_str();
|
||||
|
||||
bool b0 = bin[7] == u'1';
|
||||
bool b1 = bin[6] == u'1';
|
||||
bool b2 = bin[5] == u'1';
|
||||
|
||||
Serial.print(" binary ");
|
||||
Serial.print(bin);
|
||||
Serial.print(" b2 ");
|
||||
Serial.print(b2);
|
||||
Serial.print(" b1 ");
|
||||
Serial.print(b1);
|
||||
Serial.print(" b0 ");
|
||||
Serial.print(b0);
|
||||
Serial.print(" ");
|
||||
|
||||
digitalWrite(MULTIPLEX_PINA, b2);
|
||||
digitalWrite(MULTIPLEX_PINB, b1);
|
||||
digitalWrite(MULTIPLEX_PINC, b0);
|
||||
|
||||
int rawValue = analogRead(ANALOG_PIN);
|
||||
float parsedValue = ((float)rawValue) / 1024.0 * referenceVoltage;
|
||||
|
||||
Serial.print(" channel ");
|
||||
Serial.print(channel);
|
||||
Serial.print(" raw value ");
|
||||
Serial.print(rawValue);
|
||||
Serial.print(" parsed value: ");
|
||||
Serial.print(parsedValue);
|
||||
Serial.println("V");
|
||||
}
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
Serial.println("Analogue Soil Sensor Test");
|
||||
Serial.println("=========================");
|
||||
pinMode(MULTIPLEX_PINA, OUTPUT);
|
||||
pinMode(MULTIPLEX_PINB, OUTPUT);
|
||||
pinMode(MULTIPLEX_PINC, OUTPUT);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
Serial.print("C0");
|
||||
read_analog(0);
|
||||
Serial.print("C1");
|
||||
read_analog(1);
|
||||
Serial.print("C2");
|
||||
read_analog(2);
|
||||
Serial.print("C3");
|
||||
read_analog(3);
|
||||
Serial.print("C4");
|
||||
read_analog(4);
|
||||
Serial.print("C5");
|
||||
read_analog(5);
|
||||
Serial.print("C6");
|
||||
read_analog(6);
|
||||
Serial.print("C7");
|
||||
read_analog(7);
|
||||
|
||||
|
||||
// Serial.print("SOIL A: ");
|
||||
// read_analog(SOIL_A);
|
||||
// Serial.print("SOIL B: ");
|
||||
// read_analog(SOIL_B);
|
||||
// Serial.print("WATER LEVEL A: ");
|
||||
// read_analog(WATER_LEVEL_A);
|
||||
// Serial.print("WATER LEVEL B: ");
|
||||
// read_analog(WATER_LEVEL_B);
|
||||
|
||||
Serial.println("\n\n\n\n\n");
|
||||
|
||||
delay(5000);
|
||||
}
|
232
autoplant/autoplant.ino
Normal file
232
autoplant/autoplant.ino
Normal file
|
@ -0,0 +1,232 @@
|
|||
#include <bitset>
|
||||
#include <string>
|
||||
|
||||
// #include <ArduinoJson.h>
|
||||
#include <ESP8266WiFi.h>
|
||||
|
||||
#include "./lib/pubsubclient/PubSubClient.h"
|
||||
#include "./lib/pubsubclient/PubSubClient.cpp"
|
||||
|
||||
// These libraries need installing in the Arduino IDE Library Manager (if you install the BME280 one it should prompt for the unified sensor library automatically)
|
||||
#include <Adafruit_Sensor.h>
|
||||
#include <Adafruit_BME280.h>
|
||||
|
||||
#include "settings.h"
|
||||
|
||||
#define MULTIPLEX_PINA D5
|
||||
#define MULTIPLEX_PINB D6
|
||||
#define MULTIPLEX_PINC D7
|
||||
|
||||
#define ANALOG_PIN A0
|
||||
|
||||
/*
|
||||
000 0
|
||||
001 1
|
||||
010 2
|
||||
011 3
|
||||
100 4
|
||||
101 5
|
||||
110 6
|
||||
111 7
|
||||
*/
|
||||
|
||||
#define SOIL_A 0
|
||||
#define SOIL_B 6
|
||||
#define WATER_LEVEL_A 2
|
||||
#define WATER_LEVEL_B 4
|
||||
|
||||
#define REFERENCE_VOLTAGE 3.3
|
||||
|
||||
// Ref https://stackoverflow.com/a/523737/1460422
|
||||
#define CHECK_BIT(var,pos) ((var) & (1<<(pos)))
|
||||
|
||||
WiFiClientSecure transport;
|
||||
PubSubClient mqtt;
|
||||
|
||||
Adafruit_BME280 bme; // I2C
|
||||
|
||||
float read_analog(int channel) {
|
||||
|
||||
const char* bin = std::bitset<8>(channel).to_string().c_str();
|
||||
|
||||
bool b0 = bin[7] == u'1';
|
||||
bool b1 = bin[6] == u'1';
|
||||
bool b2 = bin[5] == u'1';
|
||||
|
||||
digitalWrite(MULTIPLEX_PINA, b2);
|
||||
digitalWrite(MULTIPLEX_PINB, b1);
|
||||
digitalWrite(MULTIPLEX_PINC, b0);
|
||||
|
||||
int rawValue = analogRead(ANALOG_PIN);
|
||||
float parsedValue = ((float)rawValue) / 1024.0 * REFERENCE_VOLTAGE;
|
||||
|
||||
return parsedValue;
|
||||
}
|
||||
|
||||
bool send_mqtt(String id, String sensor, float value) {
|
||||
// StaticJsonDocument<96> data;
|
||||
//
|
||||
// data["id"] = id;
|
||||
// data["sensor"] = sensor;
|
||||
// data["value"] = value;
|
||||
|
||||
String payload = "{\"id\": \""+id+"\",\"sensor\": \""+sensor+"\",\"value\": "+String(value)+"}";
|
||||
// int length = measureJson(&data);
|
||||
// char* payload = new char[length]();
|
||||
// serializeJson(data, payload, length);
|
||||
|
||||
bool result = mqtt.publish("sensors/data", payload.c_str());
|
||||
// delete[] payload;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
delay(1000);
|
||||
Serial.println("\nAnalogue Soil Sensor Test");
|
||||
Serial.println("=========================");
|
||||
Serial.print("PIN MODES: ");
|
||||
pinMode(MULTIPLEX_PINA, OUTPUT);
|
||||
pinMode(MULTIPLEX_PINB, OUTPUT);
|
||||
pinMode(MULTIPLEX_PINC, OUTPUT);
|
||||
Serial.println("ok");
|
||||
|
||||
// Enterprise WiFi example:
|
||||
// https://gist.github.com/Matheus-Garbelini/2cd780aed2eddbe17eb4adb5eca42bd6
|
||||
// TODO Add support for enterprise WiFi here so we can connect to eduroam
|
||||
Serial.print("WIFI: ");
|
||||
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
|
||||
|
||||
int attempts = 0;
|
||||
while (WiFi.status() != WL_CONNECTED) {
|
||||
delay(500);
|
||||
Serial.print(".");
|
||||
attempts++;
|
||||
if(attempts > 25)
|
||||
break;
|
||||
}
|
||||
if(WiFi.status() == WL_CONNECTED) {
|
||||
Serial.print("ok, IP: ");
|
||||
Serial.println(WiFi.localIP());
|
||||
}
|
||||
else {
|
||||
// Ref https://arduino-esp8266.readthedocs.io/en/latest/esp8266wifi/readme.html#check-return-codes
|
||||
Serial.print("failed, error code ");
|
||||
Serial.println(WiFi.status());
|
||||
}
|
||||
|
||||
Serial.print("MQTT: ");
|
||||
transport.setInsecure(); Serial.print(".");
|
||||
mqtt.setClient(transport); Serial.print(".");
|
||||
mqtt.setServer(MQTT_SERVER, MQTT_PORT); Serial.print(".");
|
||||
if(!mqtt.connect(
|
||||
("autoplant" + String(random(0, 999999))).c_str(),
|
||||
MQTT_USERNAME, MQTT_PASSWORD)
|
||||
) {
|
||||
/* Ref https://pubsubclient.knolleary.net/api#state
|
||||
-4 : MQTT_CONNECTION_TIMEOUT - the server didn't respond within the keepalive time
|
||||
-3 : MQTT_CONNECTION_LOST - the network connection was broken
|
||||
-2 : MQTT_CONNECT_FAILED - the network connection failed
|
||||
-1 : MQTT_DISCONNECTED - the client is disconnected cleanly
|
||||
0 : MQTT_CONNECTED - the client is connected
|
||||
1 : MQTT_CONNECT_BAD_PROTOCOL - the server doesn't support the requested version of MQTT
|
||||
2 : MQTT_CONNECT_BAD_CLIENT_ID - the server rejected the client identifier
|
||||
3 : MQTT_CONNECT_UNAVAILABLE - the server was unable to accept the connection
|
||||
4 : MQTT_CONNECT_BAD_CREDENTIALS - the username/password were rejected
|
||||
5 : MQTT_CONNECT_UNAUTHORIZED - the client was not authorized to connect
|
||||
*/
|
||||
int error_code = mqtt.state();
|
||||
Serial.println("failed, error code "+String(error_code));
|
||||
while(true) delay(10000);
|
||||
}
|
||||
Serial.println("ok");
|
||||
|
||||
Serial.print("BME280: ");
|
||||
|
||||
if(!bme.begin(0x76)) {
|
||||
Serial.println("failed!");
|
||||
}
|
||||
else {
|
||||
Serial.println("ok");
|
||||
}
|
||||
}
|
||||
|
||||
void loop() {
|
||||
float soil_a = read_analog(SOIL_A);
|
||||
float soil_b = read_analog(SOIL_B);
|
||||
float water_level_a = read_analog(WATER_LEVEL_A);
|
||||
float water_level_b = read_analog(WATER_LEVEL_B);
|
||||
float temp = bme.readTemperature();
|
||||
float humidity = bme.readHumidity();
|
||||
float pressure = bme.readPressure() / 100.0F;
|
||||
|
||||
// StaticJsonDocument<96> data;
|
||||
|
||||
if(!send_mqtt(
|
||||
"autoplant-a",
|
||||
"soil",
|
||||
soil_a
|
||||
)) Serial.println("[mqtt] Failed to send message");
|
||||
if(!send_mqtt(
|
||||
"autoplant-a",
|
||||
"water-level",
|
||||
water_level_a
|
||||
)) Serial.println("[mqtt] Failed to send message");
|
||||
if(!send_mqtt(
|
||||
"autoplant-b",
|
||||
"soil",
|
||||
soil_b
|
||||
)) Serial.println("[mqtt] Failed to send message");
|
||||
if(!send_mqtt(
|
||||
"autoplant-b",
|
||||
"water-level",
|
||||
water_level_b
|
||||
)) Serial.println("[mqtt] Failed to send message");
|
||||
|
||||
if(!send_mqtt(
|
||||
"autoplant-a",
|
||||
"temperature",
|
||||
temp
|
||||
)) Serial.println("[mqtt] Failed to send message");
|
||||
if(!send_mqtt(
|
||||
"autoplant-a",
|
||||
"humidity",
|
||||
humidity
|
||||
)) Serial.println("[mqtt] Failed to send message");
|
||||
if(!send_mqtt(
|
||||
"autoplant-a",
|
||||
"pressure",
|
||||
pressure
|
||||
)) Serial.println("[mqtt] Failed to send message");
|
||||
|
||||
// data["id"] = "autoplant-a";
|
||||
// data["sensor"] = "soil";
|
||||
// data["value"] = soil_a;
|
||||
// if(!send_mqtt(&data)) Serial.println("[mqtt] Failed to send message");
|
||||
//
|
||||
// data["sensor"] = "water-level";
|
||||
// data["value"] = water_level_a;
|
||||
// if(!send_mqtt(&data)) Serial.println("[mqtt] Failed to send message");
|
||||
//
|
||||
// data["id"] = "autoplant-b";
|
||||
// data["value"] = water_level_a;
|
||||
// if(!send_mqtt(&data)) Serial.println("[mqtt] Failed to send message");
|
||||
//
|
||||
// data["sensor"] = "soil";
|
||||
// data["value"] = soil_a;
|
||||
// if(!send_mqtt(&data)) Serial.println("[mqtt] Failed to send message");
|
||||
|
||||
Serial.print("SOIL_A\t");
|
||||
Serial.println(soil_a);
|
||||
Serial.print("SOIL_B\t");
|
||||
Serial.println(soil_b);
|
||||
Serial.print("WATER_LEVEL_A\t");
|
||||
Serial.println(water_level_a);
|
||||
Serial.print("WATER_LEVEL_B\t");
|
||||
Serial.println(water_level_b);
|
||||
|
||||
Serial.println("\n\n\n\n\n");
|
||||
|
||||
delay(INTERVAL);
|
||||
}
|
1
autoplant/lib/pubsubclient/PubSubClient.cpp
Symbolic link
1
autoplant/lib/pubsubclient/PubSubClient.cpp
Symbolic link
|
@ -0,0 +1 @@
|
|||
../../../lib/pubsubclient/src/PubSubClient.cpp
|
1
autoplant/lib/pubsubclient/PubSubClient.h
Symbolic link
1
autoplant/lib/pubsubclient/PubSubClient.h
Symbolic link
|
@ -0,0 +1 @@
|
|||
../../../lib/pubsubclient/src/PubSubClient.h
|
13
autoplant/settings.h.example
Normal file
13
autoplant/settings.h.example
Normal file
|
@ -0,0 +1,13 @@
|
|||
#define WIFI_SSID "CHANGE_ME"
|
||||
#define WIFI_PASSWORD "CHANGE_ME"
|
||||
|
||||
#define MQTT_SERVER "mqtt.example.com"
|
||||
// 1883 = unencrypted, 8883 = encrypted
|
||||
// Connections are encrypted by default. There isn't currently a way to disable it.
|
||||
#define MQTT_PORT "8883"
|
||||
#define MQTT_USERNAME "autoplant"
|
||||
#define MQTT_PASSWORD "CHANGE_ME"
|
||||
|
||||
|
||||
|
||||
#define INTERVAL 5*60*1000
|
18
dimensions.txt
Normal file
18
dimensions.txt
Normal file
|
@ -0,0 +1,18 @@
|
|||
WATER LEVEL SENSOR
|
||||
|
||||
WIDTH 19mm SORTED
|
||||
HEIGHT 62.6mm -
|
||||
HEIGHT CLEAR 15mm SORTED [AT TOP]
|
||||
THICKNESS 1.66mm SORTED
|
||||
|
||||
|
||||
FLOWERPOT TRAY
|
||||
|
||||
EDGE WIDTH MAX 5.3mm SORTED
|
||||
EDGE HEIGHT 40mm SORTED
|
||||
|
||||
INNER RADIUS 102.1mm SORTED
|
||||
OUTER RADIUS 239mm SORTED
|
||||
|
||||
OUTWARD SLOPE 23.509040224192° / 0.41031015589594428594 rad
|
||||
SORTED
|
1
lib/pubsubclient
Submodule
1
lib/pubsubclient
Submodule
|
@ -0,0 +1 @@
|
|||
Subproject commit 2d228f2f862a95846c65a8518c79f48dfc8f188c
|
BIN
water level sensor grip.3mf
Normal file
BIN
water level sensor grip.3mf
Normal file
Binary file not shown.
BIN
water level sensor grip.blend
Normal file
BIN
water level sensor grip.blend
Normal file
Binary file not shown.
Loading…
Reference in a new issue