Medidor de consumo de gás para aba energia + Nível botijão de gás

Estava querendo completar minha aba de energia então resolvi criar este medidor de consumo de gás.
O projeto foi feito usando a um ESP32 (Arduino Platform IO) e um medidor de gás Daeflex G1.0
Obs.: Gosto da liberdade de programar via Arduino por isso não usei o ESPHome ou similar.

Todos os arquivos estão aqui.

Equemático (o capacitor não foi necessário):

No arquivo funções, entre com os dados do WiFi e também do MQTT.

#define WIFISSID "WiFi Rede SSID"                   // Rede WIFI SSID
#define WIDIPASS "WiFi Senha"                       // Seha WIFI

const char* mqttserver = "192.168.X.XXX";           // IP
const char* mqttuser = "Usuario MQTT";              // Usuário
const char* mqttpass = "Senha MQTT";                // Senha

As variáveis que são disponibilizadas são as seguintes:

Para o consumo ser usado na aba energia deve ser criado um medidor de utilidade.


Devido a característica “Redefinindo periodicamente” - total_increasing se a variável de entrada cair para zero o HA entende que o dispositivo reiniciou.

A variável “Tempo de atualização do sinal” define o intervalo de tempo que o ESP enviará a força do sinal e o IP ara o HA.
A variável “Tempo cálculo vazão” define o intervalo de tempo que o ESP calcula a vazão de gás e envia o valor atualizado para o HA.
A variável “Status” está atrelada ao Last Will and Testament, o MQTT a definirá como offline se não receber dados do medidor de gás em um período de 90 segundos e com isso todas as variáveis do medidor ficarão indisponíveis com exceção da status em si.

Ao criar o medidor de utilidades o HA as vezes buga (quase fiquei careca com isso) e não puxa o device_class nem o unit_of_measurement do sensor fonte e o medidor acaba não sendo aceito pela aba energia, para evitar adicione esses dados via yaml:

homeassistant:
  customize:
    sensor.utilidade_consumo_de_gas:
      device_class: gas
      state_class: total_increasing
      unit_of_measurement: m³

Sistema montado (arquivos para impressão e edição Fusion360 estão no link para download):



Aba de energia:


Estou há um mês verificando o funcionamento e até agora está ok ele mede o consum de gás perfeitamente… Notei que no momento do envio do pulso a relojoaria do medidor Daeflex G1.0 da uma trava e depois destrava, passando rápido pelo ímã… Acredito que isso ajudou a evitar erros na medição pois criei um medidor de consumo de água e não consegui eliminar os ruídos do chaveamento da reed switch usando interrupção externa, o medidor de gás foi de primeira direto da bancada para operação sem problemas. Continuo monitorando e se medir errado já possuo a solução.

Para o futuro:

  • Usar a biblioteca WiFi manager para que o ESP crie um AP e as configurações do WiFi (SSID e senha) e MQTT (IP, senha e porta) sejam feitas sem a necessidade de fazer ulpload no código.
  • usar a medição de consumo de gás para definir o momento de troca do botijão de gás (gás acabando).
  • A aba HA não aceita o consumo de gás em litros, vi algumas pessoas reclamando sobre iso, provavelmente os desenvolvedores devem mudar essa característica, quando for mudado alterar a variável de consumo de gás de m3 para L.
3 curtidas

Achei muito interessante o projeto, porém, fiquei imaginar sobre a montagem do sensor que vai no medidor de gás Daeflex G1.0, acredito que tenha um imã rotativo e o sr usou reed e converteu para pulsos.

Visto na foto que tem 2 botijões, poderia até incrementar sensor para identificar a fuga de gás e uma eletrochave para fechar o fluxo. Meus botijões ficam separados, 1 na cozinha e outro na área grumete.

Penso em fazer um projeto com sensor de fluxo https://pt.aliexpress.com/item/1005005880428518.html?spm=a2g0o.productlist.main.3.58ec6c20h1fXuZ&algo_pvid=9eb4f0cb-10b7-439f-949b-1ce44c6c7091&algo_exp_id=9eb4f0cb-10b7-439f-949b-1ce44c6c7091-1&pdp_npi=4%40dis!BRL!56.33!30.43!!!77.71!!%402101eeda16960154816771484e601b!12000034682594903!sea!BR!126833961!&curPageLogUid=txBlmVCFaArD

Pode ser uma alternativa para ver quando o botijão esta acabando, existem alguns tutorias que fazem uma balança e verifica o peso do botijão, o seu tutorial pode ser uma substituição legal. Sabe se tem outros medidores no estilo desse seu?

Pensei em usar esse sensor aí mas o problema é a qualidade da medição, assisti a um vídeo do greatscott usando esse sensor e a medição da vazão variava de acordo com a pressão daí perdi a confiança nele. Nem mesmo para medição do consumo de água eu usei esse sensor aí, usei um hidrômetro com saída pulsada, se for pra medir é melhor fazê-lo com qualidade. Ainda vou postar o código do medidor de consumo de água, nível de caixa de água, umidade do solo e chuva. A dificuldade com o hidrômetro foi eliminar os ruídos gerados durante a comutação da Reed switch, mas consegui (usei um.cosigo debounce criado pela lady Ada).





Será a próxima atualização do código, Adicionar a configuração da rede wi-fi e do mqtt por access point (usando a biblioteca wi-fi manager) e dar um jeito de medir o estado do botijão de gás, minha ideia e adicionar um botão (resetar gás) mas preciso saber quantos litros possui um botijão p13, usamos pouco aqui mas vou tentar medir na prática mesmo.

Edit:
Para medir o nível do botijão de gás acho que essa é a melhor solução mas ainda não conseguiu encontrar o datasheert para ver como comunicar uart ou iic com ele, vamos ver se os chinas enviam fiz a solicitação.

2 curtidas

Muito interessante esse sensor, jamais imaginei que existisse algo assim, diz que usa tecnologia ultrassonica para medir, será que deve ser preciso até do início ao fim, isso resolveria, só quero ter um percentual da carga do botijão…

Pelo que vi ele mede de 3cm a 1 metro, quando o nível cai abaixo de 3cm ele continuará indicando 3cm mas deve ser suficiente, eu ia comprar um pra testar mas preciso do datasheet para saber como se comunicar com ele se não não tem como usar… O fabricante ainda não mandou o datasheet.

O botijão p13 possui 13kg de gás glp, com densidade de 2,5kg/m3 (vi na Net) então ele possui o equivalente a 5,2m3 ou 5300L de gás quando o medidor medir isso o gás estará acabando.

Quando o usuário trocar o gás é só ele apertar um botão e então o ESP reinicia a contagem…

Mas quando ele resetar fica meio complicado, da para pegar o valor armazenado no home assistant e continuar medindo a partir daí mas pode acontecer de o HA estar Off, aí complica, mas e outra solução.

O ideal seria esse sensor aí de coma mas preciso do datasheet :face_exhaling:

1 curtida

Estou na torcida desse sensor ser compatível, seria uma forma muito boa de saber quando o gás estiver no final, próximo dos 3 cm…

1 curtida

Me enviaram o datasheet vou comprar duas unidades para atualizar o código e montar meu medidor, vai demorar pra chegar e também pra eu atualizar mas assim que fazê-lo posto aqui.

A comunicação com ele é bem simples, da pra implementar de boa.

Dtahseet.

2 curtidas

Que bom, torcendo pra ser de fácil implantação, quanto que custou esse sensor, acredito que vai ser uma ótima solução para verificar em percentual a quantidade de gás e automatizar um alerta quando chegar a uns 20 ou 30%. Antecipar o fim…

Chegou logo começo a testar, será necessário converter de serial TTL para 485 (usando Max 488) para evitar problemas com distância do sensor, daí pode usar cabo de rede de vários metros.

1 curtida

Top. Ansioso pelos testes.

Promissor, na expectativa… no meu caso, vou analisar a possibilidade de jogar o sinal do sensor para um espXX, um compacto que tenha as portas certas, aproveitar e por sensor p monitorar vazamento de gas. Seu projeto é inédito na internet e uma forma segura pra todo tipo de uso, em casa ou motorhome…

1 curtida

Deu certo.

Gás em uso
1
83mm de gas liquefeito de petróleo.
24,7 graus Celsius
140,6 Inclinação horizontal do sensor

Gas novo (eu acho que esta novo)
2
283mm de gas liquefeito de petróleo.
25,3 graus Celsius
153,1 Inclinação horizontal do sensor

As medições são bem constantes mas eu estava com o notebook e segurando o sensor o que atrapalhou mas deu para ver que mede bem.

Vou ver se crio uma peca 3D com ima neodímio para que o sensor fique bem afixado no botijão e também para ser possível retira-lo e coloca-lo novamente durante a mudança do botijão.

Meu objetivo eh adicionar esse sensor ao projeto ja existente fazer com o o sensor que mede o consumo de gas meça também o nível do botijão de gas e envie tudo via MQTT, vou tentar criar uma biblioteca para o Arduino, se não conseguir vou postar o código aqui, eh bem simples.

Código usado para teste ainda ha uns erros absurdos mas meu interesse era o nível, depois corrijo:
#include <SoftwareSerial.h>

#define l06_frame_header  0
#define l06_data_h        1
#define l06_data_l        2
#define l06_temp_h        3
#define l06_temp_l        4
#define l06_rssi_h        5
#define l06_rssi_l        6
#define l06_angle_h       7
#define l06_angle_l       8
#define l06_sum           9

class TestClass: public Stream {
public:
  unsigned int liquidLevel, signalStrength, horizontalInclination, calculatedSum;
  unsigned long timeout;
  int temperature;
  byte frameHeader, receivedSum, aux, byte dadosRecebidos[11];
  bool readDone = 0;

  TestClass(Stream &s) : stream(s) {
  }

  virtual ~TestClass() {
  }

  virtual size_t write(uint8_t u) {
    return stream.write(u);
  }

  virtual int available() {
    return stream.available();
  }

  virtual int read() {
    return stream.read();
  }

  virtual int peek() {
    return stream.peek();
  }

  virtual void flush() {
    stream.flush();
  }

private:
  Stream &stream;
};

SoftwareSerial sfSerial(2, 3);
TestClass tc(sfSerial);
byte contatdorByteRecebidos;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
  sfSerial.begin(115200);
  //tc.println("Software Serial");
  Serial.println("Hardware Serial");
}

void loop() {
  // put your main code here, to run repeatedly:
  if(tc.available() >= 10) {
    contatdorByteRecebidos = 0;
    while(tc.available()) {
      tc.dadosRecebidos[contatdorByteRecebidos] = tc.read();
      contatdorByteRecebidos++;
    }
    Serial.println("");

    tc.frameHeader = tc.dadosRecebidos[l06_frame_header];

    tc.liquidLevel = (unsigned int)tc.dadosRecebidos[l06_data_h]<<8;
    tc.liquidLevel |= tc.dadosRecebidos[l06_data_l];

    tc.temperature = (unsigned int)tc.dadosRecebidos[l06_temp_h]<<8;
    tc.temperature |= tc.dadosRecebidos[l06_temp_l];

    tc.signalStrength = (unsigned int)tc.dadosRecebidos[l06_rssi_h]<<8;
    tc.signalStrength |= tc.dadosRecebidos[l06_rssi_l];

    tc.horizontalInclination = (unsigned int)tc.dadosRecebidos[l06_angle_h]<<8;
    tc.horizontalInclination |= tc.dadosRecebidos[l06_angle_l];

    tc.receivedSum = tc.dadosRecebidos[l06_sum];

    tc.calculatedSum = 0;
    for(tc.aux=0; tc.aux<9; tc.aux++) {
      tc.calculatedSum += tc.dadosRecebidos[tc.aux];
    }
    tc.calculatedSum &= 0x00FF;
   

    Serial.print("Frme header: "); Serial.println(tc.frameHeader, HEX);
    Serial.print("Nivel do liquido: "); Serial.println(tc.liquidLevel);
    Serial.print("Temperatura: "); Serial.println(tc.temperature);
    Serial.print("Forca do ultrassom: "); Serial.println(tc.signalStrength);
    Serial.print("Inclinacao horizontal: "); Serial.println(tc.horizontalInclination);
    Serial.print("Soma recebida: "); Serial.println(tc.receivedSum);
    Serial.print("Soma calculada: "); Serial.println(tc.calculatedSum);
  }
  delay(2000);
  tc.println("Iniciar leitura"); // pode enviar qualquer coisa assim que eh detectado pulso baixo em seu pino RX ele iniciara uma leitura.
}
1 curtida

Top!!! Comprando meus sensores agora, valeu demais pelo feedback.

Código melhorado
#include <SoftwareSerial.h>

#define l06_frame_header  0
#define l06_data_h        1
#define l06_data_l        2
#define l06_temp_h        3
#define l06_temp_l        4
#define l06_rssi_h        5
#define l06_rssi_l        6
#define l06_angle_h       7
#define l06_angle_l       8
#define l06_sum           9
#define l06_baudrate      115200
#define l06_frame_size    10

class l06Class: public Stream {
public:
  unsigned int liquidLevel, signalStrength, horizontalInclination, calculatedSum;
  int temperature;
  byte frameHeader, receivedSum, aux, dadosRecebidos[11], dummy;

  l06Class(Stream &s) : stream(s) {
  }

  virtual ~l06Class() {
  }

  virtual size_t write(uint8_t u) {
    return stream.write(u);
  }

  virtual int available() {
    return stream.available();
  }

  virtual int read() {
    return stream.read();
  }

  virtual int peek() {
    return stream.peek();
  }

  virtual void flush() {
    stream.flush();
  }

  void start_reading() {
    while(stream.available() > 0)
      dummy = stream.read();

    stream.print("@");
  }

  bool reading_complete() {
    if(stream.available() >= 10) {

      readBytes(dadosRecebidos, l06_frame_size);

      frameHeader = dadosRecebidos[l06_frame_header];

      liquidLevel = (unsigned int)dadosRecebidos[l06_data_h]<<8;
      liquidLevel |= dadosRecebidos[l06_data_l];

      temperature = (unsigned int)dadosRecebidos[l06_temp_h]<<8;
      temperature |= dadosRecebidos[l06_temp_l];

      signalStrength = (unsigned int)dadosRecebidos[l06_rssi_h]<<8;
      signalStrength |= dadosRecebidos[l06_rssi_l];

      horizontalInclination = (unsigned int)dadosRecebidos[l06_angle_h]<<8;
      horizontalInclination |= dadosRecebidos[l06_angle_l];

      receivedSum = dadosRecebidos[l06_sum];

      calculatedSum = 0;
      for(aux=0; aux<9; aux++) {
        calculatedSum += (unsigned int)dadosRecebidos[aux];
      }
      calculatedSum &= 0x00FF;    

      return true;  
    }
    else
      return false;;
  }

private:
  Stream &stream;
};

SoftwareSerial sfSerial(2, 3); //2 arduino uno RX (L06 TX) / 3 arduino uno TX (L06 RX)
l06Class l06(sfSerial);

void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);

  sfSerial.begin(l06_baudrate);
  Serial.println("Teste sensor de nivel de botijao L06.");
  Serial.println("");

  delay(2000); // Espera o sensor de estabilizar
  l06.start_reading(); // Inicia uma leitura
}

void loop() {
  // put your main code here, to run repeatedly:
  if(l06.reading_complete()) { // Se ha dados a serem lidos, leitura completa --- Se o sensor nao enviar os dados este IF nunca sera verdadeiro
    Serial.println("");

    Serial.print("Frme header: "); Serial.println(l06.frameHeader, HEX);
    Serial.print("Nivel do liquido: "); Serial.print(l06.liquidLevel); Serial.println("mm");
    Serial.print("Temperatura: "); Serial.print((float)l06.temperature/10); Serial.println("gC");
    Serial.print("Forca do ultrassom: "); Serial.print(l06.signalStrength); Serial.println("mV");
    Serial.print("Inclinacao horizontal: "); Serial.print((float)l06.horizontalInclination/10); Serial.println(" graus");
    Serial.print("Soma recebida: "); Serial.println(l06.receivedSum);
    Serial.print("Soma calculada: "); Serial.println(l06.calculatedSum);

    Serial.println("");

    delay(2000); // Espera um tempo antes de iniciar a nova leitura
    l06.start_reading();
  }
  else {
    Serial.println("Aguardando dados do sensor.");
    delay(300);
  }
}

Parabéns pelo sucesso, agora é fazer aquisição da peça e ajustar as necessidades… nem sei por onde começar, isso nos ajuda a te o domínio sobre a quantidade de gás, será que consegue converter para usar no daskboard de energia…

Até daria, não sei o quão preciso seria, mas se você possui o diâmetro do botijão de gás e o nível do líquido no interior você tem o volume total de fluido, para calcular o valor consumido basta diminuir o volume anterior pelo volume atual… Para evitar erros de leituras esporádicas incorretas pode ser aplicado um filtro digital passa baixa pois só o tempo dirá se o sensor de fato não apresentará leituras incorretas de tempo em tempo.

Faz sentido o filtro, a mudança de temperatura pode aumentar ou diminuir o “volume do liquido” daí o sensor pode informar hora maior ou menor o volume sem ninguém usar o gás… Aqui em casa usamos botijões de 13 kg. Até entendo a lógica, mais não tenho conhecimento avançado para usar essa estratégia, mas consigo implementar muitos tutorias e criar coisas simples no esphome.

Fiz uma integração da cerca elétrica JFL ECR 18 plus: Cerca elétrica ECR18 Plus controlar e monitorar - Tutoriais - Home Assistant BR
Quem tiver esse equipamento, nem precisa ter a placa internet o esp8266 faz bem o serviço com precisão, vem funcionando perfeitamente.

1 curtida

Quem tiver esse equipamento, nem precisa ter a placa internet o esp8266 faz bem o serviço com precisão, vem funcionando perfeitamente.

Rapaz, e isso que eu nao entendo, deve haver um motivo mas nao consigo enxergar. o pessoal das empresas brasileiras deviriam comecao a adotar esses CIs, a placa do portao do meu pai queimou fui olhar o preco de uma nova e ela estava em torno de R$490.00 montei um sistema do zero com ESP32 e gastei menos ainda adicionei controle via internet e acesso por digital (na epoca nao conhecia o home assistant):

Até entendo a lógica, mais não tenho conhecimento avançado para usar essa estratégia, mas consigo implementar muitos tutorias e criar coisas simples no esphome.

@marvan51 eu sou zerado no ESPHOME, ainda nao usei ele, nao sei fazer nada nele :sweat_smile:… Depois eu deixarei um codigo para uso somente do sensor L06 (nivel de gas) e um ESP8266 ele se conectara via MQTT pois assim quem quiser montar somente o sensor de nivel do gas fica mais facil.

Continuando… Montei um suporte com imas para que o sesnor possa ser facilmente fixado na parte inferior podendo ser remoivido sempre que necessario. Imas de neodimio 10x4mm (6 unidades foram suficientes para segurar).

Montei tambem um conversor de UART para RS485 utilizando cabo de rede o sensor podera estar a varios metros (ou km :upside_down_face:) de distancia, nao necessario se o sensor ficar perto do ESP.

Tudo montado:


1 curtida