2021-11-20 15:17:23 +00:00
# include <bitset>
# include <string>
2021-11-28 14:19:46 +00:00
// #include <ArduinoJson.h>
2021-11-20 18:52:55 +00:00
# include <ESP8266WiFi.h>
2021-11-28 21:23:39 +00:00
2021-11-23 20:44:26 +00:00
# include "./lib/pubsubclient/PubSubClient.h"
# include "./lib/pubsubclient/PubSubClient.cpp"
2021-11-20 18:52:55 +00:00
2021-11-28 21:23:39 +00:00
// 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>
2021-11-20 18:52:55 +00:00
# include "settings.h"
2022-01-10 14:35:12 +00:00
// WAS D5 D6 D7
2021-11-20 15:17:23 +00:00
2022-01-10 14:35:12 +00:00
# define MULTIPLEX_PINA 17
# define MULTIPLEX_PINB 16
# define MULTIPLEX_PINC 4
// WAS A0
# define ANALOG_PIN 34
2021-11-20 15:17:23 +00:00
/*
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
2021-11-23 20:44:26 +00:00
# define REFERENCE_VOLTAGE 3.3
2021-11-20 15:17:23 +00:00
// Ref https://stackoverflow.com/a/523737/1460422
# define CHECK_BIT(var,pos) ((var) & (1<<(pos)))
2021-12-14 18:45:45 +00:00
# ifndef MQTT_NO_TLS
2021-11-20 18:52:55 +00:00
WiFiClientSecure transport ;
2021-12-14 18:45:45 +00:00
# else
WiFiClient transport ;
# endif
2021-11-20 18:52:55 +00:00
PubSubClient mqtt ;
2021-11-20 15:17:23 +00:00
2021-11-28 21:23:39 +00:00
Adafruit_BME280 bme ; // I2C
2021-12-14 15:53:49 +00:00
# ifdef WIFI_ENTERPRISE_ENABLED
// Ref https://gist.github.com/Matheus-Garbelini/2cd780aed2eddbe17eb4adb5eca42bd6
extern " C " {
# include "user_interface.h"
# include "wpa2_enterprise.h"
# include "c_types.h"
}
# endif
void connect_wifi ( ) {
2021-12-14 18:45:45 +00:00
# ifndef WIFI_ENTERPRISE_ENABLED
Serial . print ( " personal " ) ;
2021-12-14 15:53:49 +00:00
WiFi . begin ( WIFI_SSID , WIFI_PASSWORD ) ;
2021-12-14 18:45:45 +00:00
# else
Serial . print ( " enterprise " ) ;
2021-12-14 15:53:49 +00:00
// Ref https://gist.github.com/Matheus-Garbelini/2cd780aed2eddbe17eb4adb5eca42bd6
// Setting ESP into STATION mode only (no AP mode or dual mode)
wifi_set_opmode ( STATION_MODE ) ;
struct station_config wifi_config ;
memset ( & wifi_config , 0 , sizeof ( wifi_config ) ) ;
strcpy ( ( char * ) wifi_config . ssid , WIFI_SSID ) ;
strcpy ( ( char * ) wifi_config . password , WIFI_ENTERPRISE_PASSWORD ) ;
wifi_station_set_config ( & wifi_config ) ;
// wifi_set_macaddr(STATION_IF,target_esp_mac);
wifi_station_set_wpa2_enterprise_auth ( 1 ) ;
// Clean up to be sure no old data is still inside
wifi_station_clear_cert_key ( ) ;
wifi_station_clear_enterprise_ca_cert ( ) ;
wifi_station_clear_enterprise_identity ( ) ;
wifi_station_clear_enterprise_username ( ) ;
wifi_station_clear_enterprise_password ( ) ;
wifi_station_clear_enterprise_new_password ( ) ;
wifi_station_set_enterprise_identity ( ( uint8 * ) WIFI_ENTERPRISE_USERNAME , strlen ( WIFI_ENTERPRISE_USERNAME ) ) ;
wifi_station_set_enterprise_username ( ( uint8 * ) WIFI_ENTERPRISE_USERNAME , strlen ( WIFI_ENTERPRISE_USERNAME ) ) ;
wifi_station_set_enterprise_password ( ( uint8 * ) WIFI_ENTERPRISE_PASSWORD , strlen ( ( char * ) WIFI_ENTERPRISE_PASSWORD ) ) ;
wifi_station_connect ( ) ;
2021-12-14 18:45:45 +00:00
# endif
2021-12-14 15:53:49 +00:00
}
2021-11-20 15:17:23 +00:00
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 ) ;
2021-11-23 20:44:26 +00:00
float parsedValue = ( ( float ) rawValue ) / 1024.0 * REFERENCE_VOLTAGE ;
2021-11-20 15:17:23 +00:00
return parsedValue ;
}
2021-11-28 14:19:46 +00:00
bool send_mqtt ( String id , String sensor , float value ) {
// StaticJsonDocument<96> data;
//
// data["id"] = id;
// data["sensor"] = sensor;
// data["value"] = value;
2021-11-23 20:44:26 +00:00
2021-12-04 02:59:02 +00:00
String payload = " { \" id \" : \" " + id + " \" , \" sensor \" : \" " + sensor + " \" , \" value \" : " + String ( value ) + " } " ;
2021-11-28 14:19:46 +00:00
// int length = measureJson(&data);
// char* payload = new char[length]();
// serializeJson(data, payload, length);
2021-11-23 20:44:26 +00:00
2021-11-28 14:19:46 +00:00
bool result = mqtt . publish ( " sensors/data " , payload . c_str ( ) ) ;
// delete[] payload;
2021-11-23 20:44:26 +00:00
return result ;
2021-11-20 18:52:55 +00:00
}
2021-11-20 15:17:23 +00:00
void setup ( ) {
Serial . begin ( 9600 ) ;
2021-11-20 18:52:55 +00:00
delay ( 1000 ) ;
Serial . println ( " \n Analogue Soil Sensor Test " ) ;
2021-11-20 15:17:23 +00:00
Serial . println ( " ========================= " ) ;
2021-11-20 18:52:55 +00:00
Serial . print ( " PIN MODES: " ) ;
2021-11-20 15:17:23 +00:00
pinMode ( MULTIPLEX_PINA , OUTPUT ) ;
pinMode ( MULTIPLEX_PINB , OUTPUT ) ;
pinMode ( MULTIPLEX_PINC , OUTPUT ) ;
2021-11-20 18:52:55 +00:00
Serial . println ( " ok " ) ;
2021-11-28 14:19:46 +00:00
// Enterprise WiFi example:
// https://gist.github.com/Matheus-Garbelini/2cd780aed2eddbe17eb4adb5eca42bd6
// TODO Add support for enterprise WiFi here so we can connect to eduroam
2021-11-20 18:52:55 +00:00
Serial . print ( " WIFI: " ) ;
2021-12-14 15:53:49 +00:00
connect_wifi ( ) ;
2021-11-20 18:52:55 +00:00
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: " ) ;
2021-12-14 18:45:45 +00:00
# ifdef MQTT_NO_TLS
Serial . print ( " notls " ) ;
# else
Serial . print ( " tls " ) ;
2021-11-28 14:19:46 +00:00
transport . setInsecure ( ) ; Serial . print ( " . " ) ;
2021-12-14 18:45:45 +00:00
# endif
// mqtt.setBufferSize(1000);
2021-11-28 14:19:46 +00:00
mqtt . setClient ( transport ) ; Serial . print ( " . " ) ;
mqtt . setServer ( MQTT_SERVER , MQTT_PORT ) ; Serial . print ( " . " ) ;
2021-12-14 18:45:45 +00:00
// Serial.print(MQTT_SERVER);
// Serial.print(":");
// Serial.print(MQTT_PORT);
// Serial.print(".");
2021-11-23 20:44:26 +00:00
if ( ! mqtt . connect (
2021-12-14 18:45:45 +00:00
( " autoplant_ " + String ( random ( 0 , 999999 ) ) ) . c_str ( ) ,
2021-11-23 20:44:26 +00:00
MQTT_USERNAME , MQTT_PASSWORD )
) {
2021-11-28 14:19:46 +00:00
/* 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 ) ) ;
2021-11-20 18:52:55 +00:00
while ( true ) delay ( 10000 ) ;
}
Serial . println ( " ok " ) ;
2021-11-28 21:23:39 +00:00
Serial . print ( " BME280: " ) ;
if ( ! bme . begin ( 0x76 ) ) {
Serial . println ( " failed! " ) ;
}
else {
Serial . println ( " ok " ) ;
}
2021-11-20 15:17:23 +00:00
}
void loop ( ) {
2021-11-20 18:52:55 +00:00
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 ) ;
2021-11-28 21:23:39 +00:00
float temp = bme . readTemperature ( ) ;
float humidity = bme . readHumidity ( ) ;
float pressure = bme . readPressure ( ) / 100.0F ;
2021-11-20 18:52:55 +00:00
2021-11-28 14:19:46 +00:00
// StaticJsonDocument<96> data;
2021-11-20 18:52:55 +00:00
2021-11-23 20:44:26 +00:00
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 " ) ;
2021-11-28 21:23:39 +00:00
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 " ) ;
2021-11-23 20:44:26 +00:00
// 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");
2021-11-20 18:52:55 +00:00
2021-11-20 15:17:23 +00:00
Serial . print ( " SOIL_A \t " ) ;
2021-11-20 18:52:55 +00:00
Serial . println ( soil_a ) ;
2021-11-20 15:17:23 +00:00
Serial . print ( " SOIL_B \t " ) ;
2021-11-20 18:52:55 +00:00
Serial . println ( soil_b ) ;
2021-11-20 15:17:23 +00:00
Serial . print ( " WATER_LEVEL_A \t " ) ;
2021-11-20 18:52:55 +00:00
Serial . println ( water_level_a ) ;
2021-11-20 15:17:23 +00:00
Serial . print ( " WATER_LEVEL_B \t " ) ;
2021-11-20 18:52:55 +00:00
Serial . println ( water_level_b ) ;
2021-11-20 15:17:23 +00:00
Serial . println ( " \n \n \n \n \n " ) ;
2021-11-20 18:52:55 +00:00
delay ( INTERVAL ) ;
2021-11-20 15:17:23 +00:00
}