This forum uses cookies
This forum makes use of cookies to store your login information if you are registered, and your last visit if you are not. Cookies are small text documents stored on your computer; the cookies set by this forum can only be used on this website and pose no security risk. Cookies on this forum also track the specific topics you have read and when you last read them. Please confirm whether you accept or reject these cookies being set.

A cookie will be stored in your browser regardless of choice to prevent you being asked this question again. You will be able to change your cookie settings at any time using the link in the footer.

Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
esp32/8266 signalk or mqtt?
#1
Good morning,
i just managed to assembly and make an esp32 with bm388 works with espsens comunicate directly in signalk.
It cost for me a lot of work, and now i'm planning to make a wifi sensor for the water tank. 
As i'm more confortable with mqtt, i's better to use esphome and mqtt and then the integration for signalk via node-red or working with espsens?
I want to use a no contact water sensor, so some calulation is necessary to extract the amount of water.
Some of you have try to make it? 
Some idea or advice?
Reply
#2
I made one for my holding tank using a capacitive sensor (used the MODA tank sensor from https://tankedge.com/accessories.html). I used SensESP, a voltage reducer (for reading the sensor), a 12volt to 5 volt buck converter (to power the board off of 12 volt) and a lot of trial and error to get it working. It lives in a water-proof case under my mattress next to the tank and connects to signalk via wifi.

Just upgraded it to the new SensESP, which took a few minutes, as I had to update the programming a bit, but it was even easier and cleaner than the first time. Once I figure out the concepts and stopped trying to "Over Program" the code, it all came together.

There is some calculations needed, but those are outside of SensESP. I add an extra SKPath so I can monitor the ADC read values (for empty & full), and then do the calculation for needed Mulitplier and Offset, which I can enter in the web set up for SensESP. I also use a long period for MovingAverage to help smooth out reading fluctuations. It's all done in a couple lines of code. Here's what I have:


//
// This application demonstrates core SensESP concepts in a very
// concise manner. You can build and upload the application as is
// and observe the value changes on the serial port monitor.
//
// You can use this source file as a basis for your own projects.
// Remove the parts that are not relevant to you, and add your own code
// for external hardware libraries.

#include "sensesp/sensors/analog_input.h"
#include "sensesp/sensors/sensor.h"
#include "sensesp/signalk/signalk_output.h"
#include <sensesp/transforms/linear.h>
#include <sensesp/transforms/moving_average.h>
#include "sensesp_app_builder.h"

using namespace sensesp;

reactesp::ReactESP app;

// The setup function performs one-time application initialization.
void setup() {
#ifndef SERIAL_DEBUG_DISABLED
  SetupSerialDebug(115200);
#endif

  // Construct the global SensESPApp() object
  SensESPAppBuilder builder;
  sensesp_app = (&builder)
                    // Set a custom hostname for the app.
                    ->set_hostname("New-SensESP")
                    ->set_wifi_manager_password("SensESP32")
                    // Optionally, hard-code the WiFi and Signal K server
                    // settings. This is normally not needed.
                    //->set_wifi("My WiFi SSID", "my_wifi_password")
                    //->set_sk_server("192.168.10.3", 80)
                    ->get_app();


  const char* sk_path0 = "tanks.blackWater.0.currentLevel";
  const char* sk_read0 = "tanks.blackWater.0.reading";
  
  const char* analog_in_config_path = "/blackWater/analogInput";
  const char* linear_config_path = "/blackWater/linear";
  const char* level_avg_samples = "/blackWater/average";
  
  uint8_t pin0 = 35;        // read pin for sensor "0"
  uint read_delay = 1000;    // read frequency
  const float multiplier = 0.00862517325816782;  // 100% divided by total range (high-low read)
  const float offset = -0.380027721306852;     // Offset to compensate for low-end
  float scale = 1.0;

  // Create a new Analog Input Sensor that reads an analog input pin0
  // and sends it to SignalK.
  auto* blackwater_read = new AnalogInput(
      pin0, read_delay, analog_in_config_path);

  blackwater_read->connect_to(new SKOutputFloat(sk_read0))
                 ->connect_to(new Linear(multiplier, offset, linear_config_path))  // adjust for vacuum reading
                 ->connect_to(new MovingAverage(120,scale, level_avg_samples))
                 ->connect_to(new SKOutputFloat(
                    sk_path0,              // Signal K path
                    new SKMetadata("ratio",   // Define output units
                            "Blackwater Tank Volume")  // Value description
      ))
         ->attach([blackwater_read]() {
    debugD("Analog input value: %f", blackwater_read->get());
  });
 

  // Start networking, SK server connections and other SensESP internals
  sensesp_app->start();
}

void loop() { app.tick(); }


_________

Works great.


I'm moving on to a vacuum switch on my fuel filters next with the idea I can monitor fuel suction and get an alarm when it's time to change filters or if there's water in the bowl.
Reply
#3
(2022-07-10, 10:18 PM)SCarns Wrote: I made one for my holding tank using a capacitive sensor (used the MODA tank sensor from https://tankedge.com/accessories.html). I used SensESP, a voltage reducer (for reading the sensor), a 12volt to 5 volt buck converter (to power the board off of 12 volt) and a lot of trial and error to get it working. It lives in a water-proof case under my mattress next to the tank and connects to signalk via wifi.

Just upgraded it to the new SensESP, which took a few minutes, as I had to update the programming a bit, but it was even easier and cleaner than the first time. Once I figure out the concepts and stopped trying to "Over Program" the code, it all came together.

There is some calculations needed, but those are outside of SensESP. I add an extra SKPath so I can monitor the ADC read values (for empty & full), and then do the calculation for needed Mulitplier and Offset, which I can enter in the web set up for SensESP. I also use a long period for MovingAverage to help smooth out reading fluctuations. It's all done in a couple lines of code. Here's what I have:


//
// This application demonstrates core SensESP concepts in a very
// concise manner. You can build and upload the application as is
// and observe the value changes on the serial port monitor.
//
// You can use this source file as a basis for your own projects.
// Remove the parts that are not relevant to you, and add your own code
// for external hardware libraries.

#include "sensesp/sensors/analog_input.h"
#include "sensesp/sensors/sensor.h"
#include "sensesp/signalk/signalk_output.h"
#include <sensesp/transforms/linear.h>
#include <sensesp/transforms/moving_average.h>
#include "sensesp_app_builder.h"

using namespace sensesp;

reactesp::ReactESP app;

// The setup function performs one-time application initialization.
void setup() {
#ifndef SERIAL_DEBUG_DISABLED
  SetupSerialDebug(115200);
#endif

  // Construct the global SensESPApp() object
  SensESPAppBuilder builder;
  sensesp_app = (&builder)
                    // Set a custom hostname for the app.
                    ->set_hostname("New-SensESP")
                    ->set_wifi_manager_password("SensESP32")
                    // Optionally, hard-code the WiFi and Signal K server
                    // settings. This is normally not needed.
                    //->set_wifi("My WiFi SSID", "my_wifi_password")
                    //->set_sk_server("192.168.10.3", 80)
                    ->get_app();


  const char* sk_path0 = "tanks.blackWater.0.currentLevel";
  const char* sk_read0 = "tanks.blackWater.0.reading";
  
  const char* analog_in_config_path = "/blackWater/analogInput";
  const char* linear_config_path = "/blackWater/linear";
  const char* level_avg_samples = "/blackWater/average";
  
  uint8_t pin0 = 35;        // read pin for sensor "0"
  uint read_delay = 1000;    // read frequency
  const float multiplier = 0.00862517325816782;  // 100% divided by total range (high-low read)
  const float offset = -0.380027721306852;     // Offset to compensate for low-end
  float scale = 1.0;

  // Create a new Analog Input Sensor that reads an analog input pin0
  // and sends it to SignalK.
  auto* blackwater_read = new AnalogInput(
      pin0, read_delay, analog_in_config_path);

  blackwater_read->connect_to(new SKOutputFloat(sk_read0))
                 ->connect_to(new Linear(multiplier, offset, linear_config_path))  // adjust for vacuum reading
                 ->connect_to(new MovingAverage(120,scale, level_avg_samples))
                 ->connect_to(new SKOutputFloat(
                    sk_path0,              // Signal K path
                    new SKMetadata("ratio",   // Define output units
                            "Blackwater Tank Volume")  // Value description
      ))
         ->attach([blackwater_read]() {
    debugD("Analog input value: %f", blackwater_read->get());
  });
 

  // Start networking, SK server connections and other SensESP internals
  sensesp_app->start();
}

void loop() { app.tick(); }


_________

Works great.


I'm moving on to a vacuum switch on my fuel filters next with the idea I can monitor fuel suction and get an alarm when it's time to change filters or if there's water in the bowl.

Thank you for your answer. I appraciate it.
Some questions:
How dou you extract the parameters 
  const float multiplier = 0.00862517325816782;  // 100% divided by total range (high-low read)
  const float offset = -0.380027721306852;     // Offset to compensate for low-end
  float scale = 1.0;
?

what do you mean with "then do the calculation for needed Mulitplier and Offset, which I can enter in the web set up for SensESP": i can't find in the web interface the possibility to insert this parameters  Blush


Here my code if someone can find it useful...

Quote:// Signal K application template file.
//
// This application demonstrates core SensESP concepts in a very
// concise manner. You can build and upload the application as is
// and observe the value changes on the serial port monitor.
//
// You can use this source file as a basis for your own projects.
// Remove the parts that are not relevant to you, and add your own code
// for external hardware libraries.

// Boilerplate #includes:
#include "sensesp_app_builder.h"
#include "sensesp/signalk/signalk_output.h"

// Sensor-specific #includes:
#include <Wire.h>
#include <SPI.h>
#include <Adafruit_Sensor.h>
#include "Adafruit_BMP3XX.h"

#define BMP_SCK 18
#define BMP_MISO 19
#define BMP_MOSI 23
#define BMP_CS 5

#define SEALEVELPRESSURE_HPA (1013.25)

// For RepeatSensor:
#include "sensesp/sensors/sensor.h"

using namespace sensesp;

// SensESP builds upon the ReactESP framework. Every ReactESP application
// must instantiate the "app" object.
reactesp::ReactESP app;

// (Specific to the BMP280, and I2C. Replace this with similar code to create an instance
// of whatever sensor you may be using in your project.)
// Create an instance of the sensor using its I2C interface.
Adafruit_BMP3XX bmp;

// (Replace this with whatever function you need to read whatever value you want
// to read from any other sensor you're using in your project.)
// Define the function that will be called every time we want
// an updated temperature value from the sensor. The sensor reads degrees
// Celsius, but all temps in Signal K are in Kelvin, so add 273.15.
float read_temp_callback() { return (bmp.temperature + 273.15); }
float read_press_callback() { return (bmp.pressure); }

// The setup function performs one-time application initialization
void setup() {

// Some initialization boilerplate when in debug mode
#ifndef SERIAL_DEBUG_DISABLED
  SetupSerialDebug(115200);
#endif

  // Create the global SensESPApp() object
  SensESPAppBuilder builder;
  sensesp_app = builder.set_hostname("Pressione")
->set_sk_server("10.10.10.1", 3000)
->set_wifi("*****", "******")
->get_app();
  

  // (Do whatever is required to "start" your project's sensor here)
  // Initialize the BMP280 using the default address
  bmp.begin_I2C();
  bmp.setTemperatureOversampling(BMP3_OVERSAMPLING_8X);
  bmp.setPressureOversampling(BMP3_OVERSAMPLING_4X);
  bmp.setIIRFilterCoeff(BMP3_IIR_FILTER_COEFF_3);
  bmp.setOutputDataRate(BMP3_ODR_50_HZ);

  // Read the sensor every 2 seconds
  unsigned int read_interval = 2000;

  // Create a RepeatSensor with float output that reads the temperature
  // using the function defined above.
  auto* air_press =
      new RepeatSensor<float>(read_interval, read_press_callback);

  // Set the Signal K Path for the output
  const char* sk_path = "environment.outside.pressure";

  // Send the temperature to the Signal K server as a Float
  air_press->connect_to(new SKOutputFloat(sk_path));

  // Start the SensESP application running
  sensesp_app->start();

}

// loop simply calls `app.tick()` which will then execute all reactions as needed
void loop() {
  bmp.performReading();
  app.tick();
  
}

A question... as you see the sensor should read also the temerature, but i don't understand how to correct make two RepeatSernsor. Can you link some guide?
By the way, As you see, I have to manually set signalk ip adress and port as you see in the code, because espsens didn't find it automatically as it si suppoused should be.
Reply
#4
I don’t assign the SignalK access point in the code, as SenESP sets up its own Wi-Fi access point, which I simply connect to and assign client setting from there. That way, if I ever have to change a router or have other settings, I can just reconnect and change them without having to reprogram the unit.

SensESP starting documentation is here: https://signalk.org/SensESP/
SenESP sytanx, definitions, etc is here: https://signalk.org/SensESP/generated/docs/index.html
Project template is here: https://github.com/SensESP/SensESP-project-template
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)