New build, work in progress.

The fruits of our labor. We welcome all types of plants, but grows posted here must be legal.
Shimbob
LED Wizard
LED Wizard
Reactions:
Posts: 642
Joined: Mon Nov 27, 2017 11:29 pm

Come on now, please deliver!
Screenshot_2021-07-23_11-37-27.png
Shimbob
LED Wizard
LED Wizard
Reactions:
Posts: 642
Joined: Mon Nov 27, 2017 11:29 pm

Delivery pushed back to august 2nd, figured.
It's that damn chip shortage I bet, if only they weren't putting all those chips in the vaccines I'd have my driver by now. Right?
Capt. Saicin
LED Enthusiast
LED Enthusiast
Reactions:
Posts: 83
Joined: Mon Jul 30, 2018 7:20 pm

I got that one within a week, last week :D
Shimbob
LED Wizard
LED Wizard
Reactions:
Posts: 642
Joined: Mon Nov 27, 2017 11:29 pm

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
Shimbob
LED Wizard
LED Wizard
Reactions:
Posts: 642
Joined: Mon Nov 27, 2017 11:29 pm

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.

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);
}
Shimbob
LED Wizard
LED Wizard
Reactions:
Posts: 642
Joined: Mon Nov 27, 2017 11:29 pm

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.
Shimbob
LED Wizard
LED Wizard
Reactions:
Posts: 642
Joined: Mon Nov 27, 2017 11:29 pm

IMG_20211025_092555.jpg
I think I've finally gotten the light power just the way I want it.
Subpanel, AC meter, contactor, outlet/plug, driver, DC meters, and to the light. Tidy.
Shimbob
LED Wizard
LED Wizard
Reactions:
Posts: 642
Joined: Mon Nov 27, 2017 11:29 pm

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.
118.jpg
Shimbob
LED Wizard
LED Wizard
Reactions:
Posts: 642
Joined: Mon Nov 27, 2017 11:29 pm

DIY wiring porn?
Resizer_16415362961650.jpg
User avatar
LEDG
Site Admin
Reactions:
Posts: 1599
Joined: Sun Jun 04, 2017 8:15 pm

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!
Post Reply