New build, work in progress.
-
- LED Enthusiast
- Reactions:
- Posts: 83
- Joined: Mon Jul 30, 2018 7:20 pm
I got that one within a week, last week
Welp my new HLG-320H-42AB driver came in, and I just noticed it does not have the internal Vo adjustment, unlike the HLG-600H-42A it replaces.
Which means it won't power my light that runs at ~44V. grumble...
WTF I waited 4 months for a driver I can't use?!! UHG
Which means it won't power my light that runs at ~44V. grumble...
WTF I waited 4 months for a driver I can't use?!! UHG
Not grow related, but with all the fires burning in our region I threw together an ESP32 to monitor air quality.
It's a Heltec Wifi Kit 32, which combines an ESP32 with a small OLED display, a BME680 temp/humi/pressure/gas sensor, and a SPS30 particulate matter sensor.
I wrote the code so that if it doesn't detect my home wifi, it will configure itself as a wireless access point and run a MQTT broker. This way I can take it out in the field with me and I can connect with my phone and run a MQTT client to see the values published, in addition to them being displayed on the OLED screen.
It's a Heltec Wifi Kit 32, which combines an ESP32 with a small OLED display, a BME680 temp/humi/pressure/gas sensor, and a SPS30 particulate matter sensor.
I wrote the code so that if it doesn't detect my home wifi, it will configure itself as a wireless access point and run a MQTT broker. This way I can take it out in the field with me and I can connect with my phone and run a MQTT client to see the values published, in addition to them being displayed on the OLED screen.
Code: Select all
//espAir v1
// PM,
// temperature & humidity,pressure, voc
//this device ++++++++++++++++++++++++++++++++++++++++++
const char* espName = "espAir";
//loop delay ms
int interval = 3500;
//dual core
TaskHandle_t Task1;
//For display of Wifi Kit 32
#include "heltec.h"
char line[64];
//WIFI Stuff
#include <WiFi.h>
const char* ssid = "homeWifi";
const char* password = "***";
IPAddress staticIP(192,168,2,53);
IPAddress gateway(192,168,0,1);
IPAddress subnet(255,255,0,0);
bool online=false;
//i2c stuff
#include <Wire.h>
//MQTT stuff
#include <PubSubClient.h>
WiFiClient espClient;
PubSubClient client(espClient);
const char* mqtt_server = "192.168.2.1";
char tempString[8];
unsigned char payload[64];
String mesg;
//MQTT BROKER Stuff
#include "TinyMqtt.h"
MqttBroker broker(1883);
//for SPS30
#include <sps30.h>
int16_t ret;
uint8_t auto_clean_days = 4;
uint32_t auto_clean;
struct sps30_measurement m;
char serial[SPS30_MAX_SERIAL_LEN];
uint16_t data_ready;
// for BME680
#include <Zanshin_BME680.h>
BME680_Class BME680;
static int32_t temp, humidity, pressure, gas;
//////////////////////////////////////// SETUP CODE
void led_setup() {
pinMode(LED,OUTPUT);
digitalWrite(LED,HIGH);
Heltec.begin(true /*DisplayEnable Enable*/, false /*LoRa Enable*/, false /*Serial Enable*/);
digitalWrite(25, LOW);
}
void wifi_setup() {
char i =0;
WiFi.persistent(false);
WiFi.begin(ssid, password);
WiFi.config(staticIP, gateway, gateway, subnet);
while (WiFi.status() != WL_CONNECTED & i < 25) {
i++;
delay(100);
}
if (WiFi.status() == WL_CONNECTED) online = true;
else {
WiFi.softAPConfig(staticIP, gateway, subnet);
WiFi.softAP(espName, password);
}
if (online) Serial.println("online");
else Serial.println("offline");
}
void brokerLoop(void * param) {
for (;;) {
broker.loop();
delay(250);
}
}
void mqtt_setup() {
if (online) {
client.setServer(mqtt_server, 1883);
} else {
broker.begin();
xTaskCreatePinnedToCore(brokerLoop, "Broker Loop", 2000, NULL, 1, &Task1, 1);
client.setServer("127.0.0.1", 1883);
}
client.setCallback(callback);
mqtt_connect();
client.subscribe("espAir/getStatus");
client.subscribe("espAir/setInterval");
//client.subscribe("espAir/setMode");
client.publish("espAir/status", "espAir Online");
}
void sps_setup() {
sensirion_i2c_init();
while (sps30_probe() != 0) {
Serial.print("SPS sensor probing failed\n");
client.publish("espAir/status", "SPS sensor probing failed");
delay(500);
}
ret = sps30_set_fan_auto_cleaning_interval_days(auto_clean_days);
if (ret) {
client.publish("espAir/status", "error setting the auto-clean interval");
//Serial.println(ret);
}
ret = sps30_start_measurement();
if (ret < 0)
client.publish("espAir/status", "sps30 error starting measurement\n");
}
void bme_setup() {
if (!BME680.begin()) {
client.publish("espAir/status", "Could not find a valid BME680 sensor");
Serial.print("no BME680");
}
// Set up oversampling and filter initialization
BME680.setOversampling(TemperatureSensor, Oversample16); // Use enumerated type values
BME680.setOversampling(HumiditySensor, Oversample16); // Use enumerated type values
BME680.setOversampling(PressureSensor, Oversample16); // Use enumerated type values
BME680.setIIRFilter(IIR4); // Use enumerated type values
BME680.setGas(320, 150); // 320degC for 150 milliseconds
}
void mqtt_connect() {
while (!client.connected()) {
if (client.connect(espName)) {
} else {
delay(5000);
}
}
}
void callback(char* topic, byte* payload, unsigned int length) {
if (0==strcmp(topic, "espAir/getStatus")) {
mesg = "get_status: interval: ";
dtostrf(interval, 8, 0, tempString);
mesg += tempString;
mesg.toCharArray((char *)payload, 127);
client.publish("espAir/status", (char *)payload);
}
else if (0 == strcmp(topic, "espOne/setInterval")) {
client.publish("espAir/status", "setInterval");
interval = atoi((char *)payload);
}
}
void setup() {
led_setup();
Serial.begin(115200);
Serial.println();
Wire.begin(SDA_OLED, SCL_OLED);
wifi_setup();
mqtt_setup();
bme_setup();
sps_setup();
}
////////////////////////////////////////// RUNTIME CODE
void do_sps30()
{
do {
ret = sps30_read_data_ready(&data_ready);
if (ret < 0) {
Serial.print("error reading data-ready flag: ");
Serial.println(ret);
} else if (!data_ready)
Serial.print("data not ready, no new measurement available\n");
else
break;
delay(200); /* retry in ms */
} while (1);
ret = sps30_read_measurement(&m);
if (ret < 0)
Serial.print("error reading measurement\n");
else {
dtostrf(m.nc_0p5, 4, 2, tempString);
client.publish("espAir/nc05", tempString);
dtostrf(m.nc_1p0 - m.nc_0p5, 4, 2, tempString);
client.publish("espAir/nc1", tempString);
dtostrf(m.nc_2p5 - m.nc_1p0, 4, 2, tempString);
client.publish("espAir/nc25", tempString);
dtostrf(m.nc_4p0 - m.nc_2p5, 4, 2, tempString);
client.publish("espAir/nc4", tempString);
dtostrf(m.nc_10p0 - m.nc_4p0, 4, 2, tempString);
client.publish("espAir/nc10", tempString);
dtostrf(m.typical_particle_size, 4, 2, tempString);
client.publish("espAir/typ", tempString);
dtostrf(m.mc_2p5, 4, 2, tempString);
client.publish("espAir/PM25", tempString);
}
}
void do_bme680()
{
BME680.getSensorData(temp, humidity, pressure, gas);
sprintf(tempString, "%3d.%1d", (int8_t)(temp / 100), (uint8_t)(temp % 100));
client.publish("espAir/temperature", tempString);
sprintf(tempString, "%3d.%1d", (int8_t)(humidity / 1000), (uint16_t)(humidity % 1000)); // Humidity milli-pct
client.publish("espAir/humidity", tempString);
sprintf(tempString, "%7d.%1d", (int16_t)(pressure / 100), (uint8_t)(pressure % 100)); // Pressure Pascals
client.publish("espAir/pressure (hPa)", tempString);
sprintf(tempString, "%4d.%1d\n", (int16_t)(gas / 100), (uint8_t)(gas % 100));
client.publish("espAir/gas", tempString);
}
void odisplay() {
Heltec.display -> clear();
sprintf(line, "PMmc: %3.0f, %3.0f, %3.0f, %3.0f", m.mc_1p0, m.mc_2p5, m.mc_4p0, m.mc_10p0);
Heltec.display -> drawString(0,0, line);
sprintf(line, "PM:nc %3.0f, %3.0f, %3.0f, %3.0f, %3.0f", m.nc_0p5, m.nc_1p0, m.nc_2p5, m.nc_4p0, m.nc_10p0);
Heltec.display -> drawString(0,10, line);
sprintf(line, "PM: %3.0f, %3.0f, %3.0f, %3.0f, %3.0f", m.nc_0p5, m.nc_1p0 - m.nc_0p5, m.nc_2p5-m.nc_1p0, m.nc_4p0-m.nc_2p5, m.nc_10p0-m.nc_4p0);
Heltec.display -> drawString(0,20, line);
sprintf(line, "Temp: %3d.%1d Humi: %2d.%1d", (int8_t)(temp / 100), (uint8_t)(temp % 100), (int8_t)(humidity / 1000), (uint16_t)(humidity % 1000));
Heltec.display -> drawString(0,30, line);
sprintf(line, "Pres: %4d.%1d Gas: %4d.%1d", (int16_t)(pressure / 100), (uint8_t)(pressure % 100), (int16_t)(gas / 100), (uint8_t)(gas % 100));
Heltec.display -> drawString(0,40,line);
//sprintf(line, "PMtype: %s", m.typical_particle_size);
//Heltec.display -> drawString(0,50,line);
Heltec.display -> display();
}
void chatty () {
Serial.print("PM 1.0: ");
Serial.println(m.mc_1p0);
Serial.print("PM 2.5: ");
Serial.println(m.mc_2p5);
Serial.print("PM 4.0: ");
Serial.println(m.mc_4p0);
Serial.print("PM 10.0: ");
Serial.println(m.mc_10p0);
Serial.print("NC 0.5: ");
Serial.println(m.nc_0p5);
Serial.print("NC 1.0: ");
Serial.println(m.nc_1p0);
Serial.print("NC 2.5: ");
Serial.println(m.nc_2p5);
Serial.print("NC 4.0: ");
Serial.println(m.nc_4p0);
Serial.print("NC 10.0: ");
Serial.println(m.nc_10p0);
Serial.print("Typical partical size: ");
Serial.println(m.typical_particle_size);
Serial.print(m.nc_0p5);
Serial.print(" ");
Serial.print(m.nc_1p0 - m.nc_0p5);
Serial.print(" ");
Serial.print(m.nc_2p5 - m.nc_1p0);
Serial.print(" ");
Serial.print(m.nc_4p0 - m.nc_2p5);
Serial.print(" ");
Serial.print(m.nc_10p0 - m.nc_4p0);
Serial.println();
}
void loop() {
digitalWrite(25, HIGH);
if (online)
if (WiFi.status() != WL_CONNECTED )
wifi_setup();
if (!client.connected())
mqtt_connect();
do_bme680();
do_sps30();
odisplay();
//chatty();
client.loop();
digitalWrite(25, LOW);
delay(interval);
}
Grumble grumble grumble.
I've trying to replace the hlg-600h-42A that has powered my light so far. I want something less powerful, with the -A Vo adjustment to go over 42V, and the -B dimmer wires.
First I got an hlg-320h-42ab, but it doesn't come with the Vo adjustment so won't go above 42V. Seriously MeanWell, why bother making this driver?
So then I bought an hlg-240H-42ab but this one won't go above ~1.4A @ 41V.
*perplexed*
Time to try an XLG-240-H-AB, I guess.
I've trying to replace the hlg-600h-42A that has powered my light so far. I want something less powerful, with the -A Vo adjustment to go over 42V, and the -B dimmer wires.
First I got an hlg-320h-42ab, but it doesn't come with the Vo adjustment so won't go above 42V. Seriously MeanWell, why bother making this driver?
So then I bought an hlg-240H-42ab but this one won't go above ~1.4A @ 41V.
*perplexed*
Time to try an XLG-240-H-AB, I guess.
Round 4, sure am taking my time. 1 week after flip.
My 2 random bag seeds on the left, the wifes' Frank Sour and Frosted Sherbet on the right.
I threw together 28 strips of 4000k LT-562D I had on a couple baking sheets as my early-flower light, once the stretch is over I'll put the big 3000K light back in.
My 2 random bag seeds on the left, the wifes' Frank Sour and Frosted Sherbet on the right.
I threw together 28 strips of 4000k LT-562D I had on a couple baking sheets as my early-flower light, once the stretch is over I'll put the big 3000K light back in.
Spicy Lego
Want to Support the Site?
Use this Amazon referral link and any purchase you make within 24 hrs will earn LEDgardener a commission at no cost to you!
Use this Amazon referral link and any purchase you make within 24 hrs will earn LEDgardener a commission at no cost to you!