• Witaj na Forum Arduino Polska! Zapraszamy do rejestracji!
  • Znajdziesz tutaj wiele informacji na temat hardware / software.
Witaj! Logowanie Rejestracja


Ocena wątku:
  • 0 głosów - średnia: 0
  • 1
  • 2
  • 3
  • 4
  • 5
Pzem-017 plus aplikacja blink(stary) jako monitoring DC
#1
Witam
Wykonałem  projekt  na podstawie tego poradnika: 
https://solarduino.com/pzem-017-dc-energ...blynk-app/

I problem jest taki, że niby wszystko działa, ale aplikacja  Blynk nie pokazuje  żadnych danych z pzem-017.
Program wgrał się bez żadnych błędów. Blynk odpowiednio skonfigurowany, łączy się z serwerem. Pzem-017 sprawdzony bo przy podłączenie bezpośrednio do PC pokazuje wszystkie dane.
Czy w sofcie trzeba coś zmienić, żeby dane z Psem-017 pokazały się w aplikacji Blynk?

Proszę o pomoc, poniżej załączam oryginalny program ( oczywiście w swoim zmieniłem token, oraz ustawienia wifi i serwera na swoje).
Jakie macie pomysły, czemu to nie działa?



Kod:
// PZEM-017 DC Energy Meter Online Monitoring using Blynk App By Solarduino

// Note Summary
// Note :  Safety is very important when dealing with electricity. We take no responsibilities while you do it at your own risk.
// Note :  This DC Energy Monitoring Code needs PZEM-017 DC Energy Meter to measure values and Arduio Mega / UNO for communication and display.
// Note :  This Code monitors DC Voltage, current, Power, and Energy.
// Note :  The values are calculated internally by energy meter and function of Node MCU is only to read the value and for further submission to Blynk Server for display
// Note :  The first step is need to select shunt value and change the value accordingly in this code. look for line "static uint16_t NewshuntAddr = 0x0000; "
// Note :  You need to download and install (modified) Modbus Master library at our website (https://solarduino.com/pzem-014-or-016-ac-energy-meter-with-arduino/ )
// Note :  You need to download the Blynk App on your smart phone for display.
// Note :  The Core of the code was from EvertDekker.com 2018 which based on the example from http://solar4living.com/pzem-arduino-modbus.htm
// Note :  Solarduino only amend necessary code and integrate with Blynk Server.
// Note :  Blog page for this code : https://solarduino.com/pzem-017-dc-energy-meter-online-monitoring-with-blynk-app/

/*/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////*/////////////*/

        /* Virtual Serial Port */

        #include <SoftwareSerial.h>                          /* include virtual Serial Port coding */
        SoftwareSerial PZEMSerial;                            // Move the PZEM DC Energy Meter communication pins from Rx to pin D1 = GPIO 5 & TX to pin D2 = GPIO 4

        /* 0- Blynk Server and Wifi Connection */

        #include <ESP8266WiFi.h>                              // Enable the use of wifi module. Make sure you downloaded and installed the ESP8266 library
        #include <BlynkSimpleEsp8266.h>                    
        char auth[] = "55dt91QmWb3TNWJRxy6sE2HJJXFStdw1";    // Put in the Auth Token for the project from Blynk. You should receive it in your email.
        char ssid[] = "unififibreLKH@unifi";                  // Key in your wifi name. You can check with your smart phone for your wifi name
        char pass[] = "58828515";                            // Key in your wifi password.

        /* 1- PZEM-017 DC Energy Meter */
      
        #include <ModbusMaster.h>                            // Load the (modified) library for modbus communication command codes. Kindly install at our website.
        #define MAX485_DE  16                                // Define DE Pin to Arduino pin. Connect DE Pin of Max485 converter module to Pin D0 (GPIO 16) Node MCU board
        #define MAX485_RE  5                                  // Define RE Pin to Arduino pin. Connect RE Pin of Max485 converter module to Pin D1 (GIPO 5) Node MCU board
                                                              // These DE anr RE pins can be any other Digital Pins to be activated during transmission and reception process.
        static uint8_t pzemSlaveAddr = 0x01;                  // Declare the address of device (meter 1) in term of 8 bits.
        static uint16_t NewshuntAddr = 0x0000;                // Declare your external shunt value for DC Meter. Default 0x0000 is 100A, replace to "0x0001" if using 50A shunt, 0x0002 is for 200A, 0x0003 is for 300A
    
        ModbusMaster node;                                    /* activate modbus master codes*/
      
        float PZEMVoltage =0;                                /* Declare value for DC voltage */
        float PZEMCurrent =0;                                /* Declare value for DC current*/
        float PZEMPower =0;                                  /* Declare value for DC Power */
        float PZEMEnergy=0;                                  /* Declare value for DC Energy */

        unsigned long startMillisPZEM;                        /* start counting time for LCD Display */
        unsigned long currentMillisPZEM;                      /* current counting time for LCD Display */
        const unsigned long periodPZEM = 1000;                // refresh every X seconds (in seconds) in LED Display. Default 1000 = 1 second

        /* 2 - Data submission to Blynk Server  */

        unsigned long startMillisReadData;                    /* start counting time for data collection */
        unsigned long currentMillisReadData;                  /* current counting time for data collection */
        const unsigned long periodReadData = 1000;            /* refresh every X seconds (in seconds) in LED Display. Default 1000 = 1 second */
        int ResetEnergy = 0;                                  /* reset energy function */
        int a = 1;
        unsigned long startMillis1;                          // to count time during initial start up (PZEM Software got some error so need to have initial pending time)

void setup()
{
      
        /*0 General*/
      
        startMillis1 = millis();
      
        Serial.begin(9600);                                  /* To assign communication port to communicate with meter. with 2 stop bits (refer to manual)*/
        PZEMSerial.begin(9600,SWSERIAL_8N2,4,0);              // 4 = Rx/R0/ GPIO 4 (D2) & 0 = Tx/DI/ GPIO 0 (D3) on NodeMCU
        Blynk.begin(auth, ssid, pass);  

        /* 1- PZEM-017 DC Energy Meter */

        startMillisPZEM = millis();                          /* Start counting time for run code */
        pinMode(MAX485_RE, OUTPUT);                          /* Define RE Pin as Signal Output for RS485 converter. Output pin means Arduino command the pin signal to go high or low so that signal is received by the converter*/
        pinMode(MAX485_DE, OUTPUT);                          /* Define DE Pin as Signal Output for RS485 converter. Output pin means Arduino command the pin signal to go high or low so that signal is received by the converter*/
        digitalWrite(MAX485_RE, 0);                          /* Arduino create output signal for pin RE as LOW (no output)*/
        digitalWrite(MAX485_DE, 0);                          /* Arduino create output signal for pin DE as LOW (no output)*/
                                                              // both pins no output means the converter is in communication signal receiving mode
        node.preTransmission(preTransmission);                // Callbacks allow us to configure the RS485 transceiver correctly
        node.postTransmission(postTransmission);
        node.begin(pzemSlaveAddr,PZEMSerial);                        
        delay(1000);                                          /* after everything done, wait for 1 second */

        /* 2 - Data submission to Blynk Server  */

        startMillisReadData = millis();                      /* Start counting time for data submission to Blynk Server*/

}

void loop()
{
      
        /* 0- General */
      
        Blynk.run();
    
        if ((millis()- startMillis1 >= 10000) && (a ==1))
        {
          setShunt(pzemSlaveAddr);                                      // Delete the "//" to set shunt rating (0x01) is the meter address by default. If you changed the meter address, you must change here as well.  
          changeAddress(0XF8, pzemSlaveAddr);                            // By delete the double slash symbol, the meter address will be set as 0x01.
          a = 0;
        }                                                    // By default I allow this code to run every program startup. Will not have effect if you only have 1 meter

        /* 1- PZEM-017 DC Energy Meter */
      
        currentMillisPZEM = millis();
      
        if (currentMillisPZEM - startMillisPZEM >= periodPZEM)                                            /* for every x seconds, run the codes below*/
        {  
          uint8_t result;                                                                                /* Declare variable "result" as 8 bits */
          result = node.readInputRegisters(0x0000, 6);                                                    /* read the 9 registers (information) of the PZEM-014 / 016 starting 0x0000 (voltage information) kindly refer to manual)*/
          if (result == node.ku8MBSuccess)                                                                /* If there is a response */
            {
              uint32_t tempdouble = 0x00000000;                                                          /* Declare variable "tempdouble" as 32 bits with initial value is 0 */
              PZEMVoltage = node.getResponseBuffer(0x0000) / 100.0;                                      /* get the 16bit value for the voltage value, divide it by 100 (as per manual) */
                                                                                                          // 0x0000 to 0x0008 are the register address of the measurement value
              PZEMCurrent = node.getResponseBuffer(0x0001) / 100.0;                                      /* get the 16bit value for the current value, divide it by 100 (as per manual) */
            
              tempdouble =  (node.getResponseBuffer(0x0003) << 16) + node.getResponseBuffer(0x0002);      /* get the power value. Power value is consists of 2 parts (2 digits of 16 bits in front and 2 digits of 16 bits at the back) and combine them to an unsigned 32bit */
              PZEMPower = tempdouble / 10.0;                                                              /* Divide the value by 10 to get actual power value (as per manual) */
            
              tempdouble =  (node.getResponseBuffer(0x0005) << 16) + node.getResponseBuffer(0x0004);      /* get the energy value. Energy value is consists of 2 parts (2 digits of 16 bits in front and 2 digits of 16 bits at the back) and combine them to an unsigned 32bit */
              PZEMEnergy = tempdouble;                                                                  
            
              if (pzemSlaveAddr==2)                                                                      /* just for checking purpose to see whether can read modbus*/
                {
                }
            }
              else
                {
                }
              startMillisPZEM = currentMillisPZEM ;                                                      /* Set the starting point again for next counting time */
        }
                                                                                                        /* count time for program run every second (by default)*/
        /* 2 - Data submission to Blynk Server  */
      
        currentMillisReadData = millis();                                                                /* Set counting time for data submission to server*/
        if (currentMillisReadData - startMillisReadData >= periodReadData)                                /* for every x seconds, run the codes below*/
          {
            Serial.print("Vdc : "); Serial.print(PZEMVoltage); Serial.println(" V ");
            Serial.print("Idc : "); Serial.print(PZEMCurrent); Serial.println(" A ");
            Serial.print("Power : "); Serial.print(PZEMPower); Serial.println(" W ");
            Serial.print("Energy : "); Serial.print(PZEMEnergy); Serial.println(" Wh ");
            Blynk.virtualWrite(V0,PZEMVoltage);                                                          // Send data to Blynk Server. Voltage value as virtual pin V0
            Blynk.virtualWrite(V1,PZEMCurrent);
            Blynk.virtualWrite(V2,PZEMPower);
            Blynk.virtualWrite(V3,PZEMEnergy);
            startMillisReadData = millis();
          }
        
}

void preTransmission()                                                                                    /* transmission program when triggered*/
{
        /* 1- PZEM-017 DC Energy Meter */
        if(millis() - startMillis1 > 5000)                                                                // Wait for 5 seconds as ESP Serial cause start up code crash
        {
          digitalWrite(MAX485_RE, 1);                                                                    /* put RE Pin to high*/
          digitalWrite(MAX485_DE, 1);                                                                    /* put DE Pin to high*/
          delay(1);                                                                                      // When both RE and DE Pin are high, converter is allow to transmit communication
        }
}

void postTransmission()                                                                                  /* Reception program when triggered*/
{
      
        /* 1- PZEM-017 DC Energy Meter */
        if(millis() - startMillis1 > 5000)                                                                // Wait for 5 seconds as ESP Serial cause start up code crash
        {
          delay(3);                                                                                      // When both RE and DE Pin are low, converter is allow to receive communication
          digitalWrite(MAX485_RE, 0);                                                                    /* put RE Pin to low*/
          digitalWrite(MAX485_DE, 0);                                                                    /* put DE Pin to low*/
        }
}

void setShunt(uint8_t slaveAddr)                                                                          //Change the slave address of a node
{

        /* 1- PZEM-017 DC Energy Meter */
      
        static uint8_t SlaveParameter = 0x06;                                                            /* Write command code to PZEM */
        static uint16_t registerAddress = 0x0003;                                                        /* change shunt register address command code */
      
        uint16_t u16CRC = 0xFFFF;                                                                        /* declare CRC check 16 bits*/
        u16CRC = crc16_update(u16CRC, slaveAddr);                                                        // Calculate the crc16 over the 6bytes to be send
        u16CRC = crc16_update(u16CRC, SlaveParameter);
        u16CRC = crc16_update(u16CRC, highByte(registerAddress));
        u16CRC = crc16_update(u16CRC, lowByte(registerAddress));
        u16CRC = crc16_update(u16CRC, highByte(NewshuntAddr));
        u16CRC = crc16_update(u16CRC, lowByte(NewshuntAddr));
    
        preTransmission();                                                                                /* trigger transmission mode*/
    
        PZEMSerial.write(slaveAddr);                                                                      /* these whole process code sequence refer to manual*/
        PZEMSerial.write(SlaveParameter);
        PZEMSerial.write(highByte(registerAddress));
        PZEMSerial.write(lowByte(registerAddress));
        PZEMSerial.write(highByte(NewshuntAddr));
        PZEMSerial.write(lowByte(NewshuntAddr));
        PZEMSerial.write(lowByte(u16CRC));
        PZEMSerial.write(highByte(u16CRC));
        delay(10);
        postTransmission();                                                                              /* trigger reception mode*/
        delay(100);
}

BLYNK_WRITE(V4)                                              // Virtual push button to reset energy for Meter 1
{
        if(param.asInt()==1)
          {
            uint16_t u16CRC = 0xFFFF;                        /* declare CRC check 16 bits*/
            static uint8_t resetCommand = 0x42;              /* reset command code*/
            uint8_t slaveAddr = pzemSlaveAddr;                // if you set different address, make sure this slaveAddr must change also
            u16CRC = crc16_update(u16CRC, slaveAddr);
            u16CRC = crc16_update(u16CRC, resetCommand);
            preTransmission();                                /* trigger transmission mode*/              
            PZEMSerial.write(slaveAddr);                      /* send device address in 8 bit*/
            PZEMSerial.write(resetCommand);                  /* send reset command */
            PZEMSerial.write(lowByte(u16CRC));                /* send CRC check code low byte  (1st part) */
            PZEMSerial.write(highByte(u16CRC));              /* send CRC check code high byte (2nd part) */
            delay(10);
            postTransmission();                              /* trigger reception mode*/
            delay(100);
          }
}

void changeAddress(uint8_t OldslaveAddr, uint8_t NewslaveAddr)                                            //Change the slave address of a node
{

        /* 1- PZEM-017 DC Energy Meter */
  
        static uint8_t SlaveParameter = 0x06;                                                            /* Write command code to PZEM */
        static uint16_t registerAddress = 0x0002;                                                        /* Modbus RTU device address command code */
        uint16_t u16CRC = 0xFFFF;                                                                        /* declare CRC check 16 bits*/
        u16CRC = crc16_update(u16CRC, OldslaveAddr);                                                      // Calculate the crc16 over the 6bytes to be send
        u16CRC = crc16_update(u16CRC, SlaveParameter);
        u16CRC = crc16_update(u16CRC, highByte(registerAddress));
        u16CRC = crc16_update(u16CRC, lowByte(registerAddress));
        u16CRC = crc16_update(u16CRC, highByte(NewslaveAddr));
        u16CRC = crc16_update(u16CRC, lowByte(NewslaveAddr));
        preTransmission();                                                                                /* trigger transmission mode*/
        PZEMSerial.write(OldslaveAddr);                                                                      /* these whole process code sequence refer to manual*/
        PZEMSerial.write(SlaveParameter);
        PZEMSerial.write(highByte(registerAddress));
        PZEMSerial.write(lowByte(registerAddress));
        PZEMSerial.write(highByte(NewslaveAddr));
        PZEMSerial.write(lowByte(NewslaveAddr));
        PZEMSerial.write(lowByte(u16CRC));
        PZEMSerial.write(highByte(u16CRC));
        delay(10);
        postTransmission();                                                                                /* trigger reception mode*/
        delay(100);
}
 
#2
Jak chcesz tu pokazać jakiś kod, to wstawiaj go w pełnej edycji przez opcję code.
Arduino to tylko połowa tego co należy wykonać, druga część jest w samej aplikacji Blynk na Androidzie, gdzie trzeba wykonać sobie widget obsługujący wszystkie zmienne wirtualne wysyłane do Blynka.
Miło być decenianym https://buycoffee.to/kaczakat
 
#3
(04-10-2022, 18:06)kaczakat napisał(a): Jak chcesz tu pokazać jakiś kod, to wstawiaj go w pełnej edycji przez opcję code.
Arduino to tylko połowa tego co należy wykonać, druga część jest w samej aplikacji Blynk na Androidzie, gdzie trzeba wykonać sobie widget obsługujący wszystkie zmienne wirtualne wysyłane do Blynka.
Już poprawiłem, chociaż chyba samo się poprawiło,  dziękuję za radę.
Widget, jak wcześniej pisałem  jest dodany i działa, łączy się z serwerem i szczytuje dane. Problem w tym, że pzem nie chce (chyba) wysyłać danych do nodemcu przez konwerter Max485, więc Blink pokazuje  dane zerowe. A być może problem leży gdzie indziej.
 
#4
No jak działa, skoro sam ustaliłeś, że nie działa. Nie działa cała część od Blynk, bo na serial Ci drukuje prawidłowe wartości.
Więc stwórz sobie inny, czysty projekt, gdzie w loop co 10s będziesz zmieniał wartości zmiennych wirtualnych blynk, zwykłe ++ i je wysyłał, sprawdzisz czy funkcje blynk działają, widget to odbiera i wizualizuje.
Miło być decenianym https://buycoffee.to/kaczakat
 
#5
(05-10-2022, 02:05)kaczakat napisał(a): No jak działa, skoro sam ustaliłeś, że nie działa. Nie działa cała część od Blynk, bo na serial Ci drukuje prawidłowe wartości.
Więc stwórz sobie inny, czysty projekt, gdzie w loop co 10s będziesz zmieniał wartości zmiennych wirtualnych blynk, zwykłe ++ i je wysyłał, sprawdzisz czy funkcje blynk działają, widget to odbiera i wizualizuje.
 Na pzem dawałem 18V, 0,8A.  I jak uruchomiałem  pogląd portu w Arduino, wszystkie wartości były  na zero.
 
#6
"Pzem-017 sprawdzony bo przy podłączenie bezpośrednio do PC pokazuje wszystkie dane. "
Z tego zrozumiałem, że ten program działa tu prawidłowo, że odczytywałeś wartości ESP podłączonym do licznika.
Znajdź sobie inny projekt, skoro ten nie zauważa, że dostaje same 0 i nic z tym nie robi.
W każdym bądź razie taka jest droga postępowania, jak cały projekt nie ruszył od strzału, to ja bym jeszcze spróbował podmiany pinów wybranych do komunikacji, 4 i 5 dla UART, 12-15 dla pozostałych DE RE. Ale generalnie osobno sprawdziłbym działanie Blynk, osobno RS485. A jak to nie pomoże to zostaje sprawdzanie RS-485, może masz na 5V i nie chce działać na 3.3V ESP.
Ja miałem taki konwerter RS485 z którego wywaliłem wszystko z RE, z pre i post i begin, D6 czyli 12 był dla DE, do komunikacji użyłem UART sprzętowego: node.begin(slaveID, Serial);
Mam też taki dedykowany do 3.3V i tam w ogóle nie ma RE/DE, automatyczna kontrola kierunku, podłącza się tylko RX/TX z jednej i A/B z drugiej strony transceivera "Nazwa produktu:3 sztuk 3.3V Auto RS485 do LvTTL RS232 Transceiver konwerter SP3485 moduł dla esp8266 raspberry pi breadboard nodemcu banana pi".
Piny 0,2, 15 i 16 mają ograniczone zastosowanie, są używane do startu, mogą być podłączone do tranzystorów, rezystorów i mieć już ustalone stany do pewnego stopnia.
Miło być decenianym https://buycoffee.to/kaczakat
 
#7
(05-10-2022, 13:33)kaczakat napisał(a): "Pzem-017 sprawdzony bo przy podłączenie bezpośrednio do PC pokazuje wszystkie dane. "
Z tego zrozumiałem, że ten program działa tu prawidłowo, że odczytywałeś wartości ESP podłączonym do licznika.
Znajdź sobie inny projekt, skoro ten nie zauważa, że dostaje same 0 i nic z tym nie robi.
W każdym bądź razie taka jest droga postępowania, jak cały projekt nie ruszył od strzału, to ja bym jeszcze spróbował podmiany pinów wybranych do komunikacji, 4 i 5 dla UART, 12-15 dla pozostałych DE RE. Ale generalnie osobno sprawdziłbym działanie Blynk, osobno RS485. A jak to nie pomoże to zostaje sprawdzanie RS-485, może masz na 5V i nie chce działać na 3.3V ESP.
Ja miałem taki konwerter RS485 z którego wywaliłem wszystko z RE, z pre i post i begin, D6 czyli 12 był dla DE, do komunikacji użyłem UART sprzętowego:  node.begin(slaveID, Serial);
Mam też taki dedykowany do 3.3V i tam w ogóle nie ma RE/DE, automatyczna kontrola kierunku, podłącza się tylko RX/TX z jednej i A/B z drugiej strony transceivera "Nazwa produktu:3 sztuk 3.3V Auto RS485 do LvTTL RS232 Transceiver konwerter SP3485 moduł dla esp8266 raspberry pi breadboard nodemcu banana pi".
Piny 0,2, 15 i 16 mają ograniczone zastosowanie, są używane do startu, mogą być podłączone do tranzystorów, rezystorów i mieć już ustalone stany do pewnego stopnia.

Mam konwerter MAX485 identyczny jak na tym linku,
https://sklep.avt.pl/konwerter-uart-ttl-...cvEALw_wcB
,bo 
 nie wiem jak wstawić zdjęcie. 
Zasilanie 5V i sprawdzałem miernikiem, jest 5V na zasilaniu. Spróbuje jak radzisz zamienić piny DE i RE. Rozumiem, że te piny odpowiadają za komunikację output, input ?
 
#8
Te piny są opcjonalne, przykładowa funkcja u mnie wygląda tak:
void preTransmission()
{
  //digitalWrite(MAX485_RE_NEG, 1);
  digitalWrite(MAX485_DE, 1);
}
I tak w każdej funkcji do RS485. A w związku z tym piny RE i DE mam połączone, nie pamiętam dlaczego, robiłem to kilka lat temu, ale wrzucone hasło w Google "MAX485 Arduino Schematic" pokazuje właśnie takie połączenie, może to jest opcja by było mniej pinów używanych, może tak trzeba, tak mam i działa, moduł RS485 mam taki sam.

Poniżej przykładowy kod, on Ci się nie skompiluje bo nie ma pliku z hasłami i kodem serwera WWW w HTML, poza tym jest do innego licznika, ale pokazuje jak powinny wyglądać funkcje, np. drukuje wartości odczytane, jeśli faktycznie zostały odczytane. Do komunikacji RS485 wykorzystuje UART0 sprzętowy, a dane na PC wysyła przez UART1, ten gdzie jest tylko TX w ESP8266, trzeba sobie podłączyć to przez jakiś konwerter USB-UART do PC.
Kod:
#include <ESP8266WiFi.h>
#include <ESPAsyncTCP.h>
#include <ESP8266mDNS.h>
#include <Hash.h>
#include <ModbusMaster.h>
#include <ESPAsyncWebServer.h>
#include <WebSocketsServer.h>
#include <ArduinoOTA.h>

#include "hasla.h"
#include "index.h"

 


//***************************************************************
//ustawienia MODBUS
#define MAX485_DE      D6
//#define MAX485_RE_NEG  6 //podłączony do MAX485_DE

// instantiate ModbusMaster object
ModbusMaster node;
void preTransmission()
{
  //digitalWrite(MAX485_RE_NEG, 1);
  digitalWrite(MAX485_DE, 1);
}

void postTransmission()
{
// digitalWrite(MAX485_RE_NEG, 0);
  digitalWrite(MAX485_DE, 0);
}
  uint8_t slaveID=1;
  uint8_t result;
  uint16_t data[16];
  //uint32_t kwh;
  bool state = true;
 
void ModbusBegin()
{
// pinMode(MAX485_RE_NEG, OUTPUT);
  pinMode(MAX485_DE, OUTPUT);
  // Init in receive mode
  //digitalWrite(MAX485_RE_NEG, 0);
  digitalWrite(MAX485_DE, 0);
    // Modbus communication runs at 115200 baud
  Serial.begin(9600);

  // Modbus slave ID 2
  node.begin(slaveID, Serial);
  // Callbacks allow us to configure the RS485 transceiver correctly
  node.preTransmission(preTransmission);
  node.postTransmission(postTransmission);
}





 
//const char* ssid = "yourssid";
//const char* password = "pass";


const char * hostName = "esp_PZEM16-01";
const char* http_username = "admin";
const char* http_password = "admin";
const int LED1PIN = 5; //Tu definiujesz do jakiego pinu podlaczas przelacznik
const int LED2PIN = 5; //PIN ESP LED_BUILTIN zapala sie po wlaczeniu do masy, czyli w tym przykladzie podanie zera, OFF
const int LED3PIN = 5; //D4 to pin niebieskiej diody modulu ESP zapala się po zwarciu pinu do masy, czyli tu wciśniecie OFF
const int LED4PIN = 5;
const int LED_R = 5;
const int LED_G = 5;
const int LED_B = 5;

uint8_t ledklik;
// Current LED status
bool LED1Status;
bool LED2Status;
bool LED3Status;
bool LED4Status;

// Commands sent through Web Socket
const char LED1ON[] = "led1on";
const char LED1OFF[] = "led1off";
const char LED2ON[] = "led2on";
const char LED2OFF[] = "led2off";
const char LED3ON[] = "led3on";
const char LED3OFF[] = "led3off";
const char LED4ON[] = "led4on";
const char LED4OFF[] = "led4off";
String webString = "", token="@&";


uint16_t VAR4,VAR5;
float VAR1,VAR2,VAR3;
uint32_t rgb;

static void writeLED1(bool);
static void writeLED2(bool);
static void writeLED3(bool);
static void writeLED4(bool);


uint32_t czasTeraz,czasPoprzedni,tik=100; //tik musi byc mniejszy niz 1000 i dzilic 1000ms na rowne czesci
uint8_t nTik,sekundy,minuty,godziny,dni; //liczniki tikow, sekund, itd.
bool fnTik,fsekundy,fminuty,fgodziny,fdni; //flagi zdarzen nowy tik, nowa sekunda,minuta, godzina, dzien
char napis[10];


AsyncWebServer server(80);
WebSocketsServer webSocket = WebSocketsServer(81);
AsyncEventSource events("/events");



void setup(){
   Serial1.begin(115200); //Serial 1 GPIO2 D4 w NodeMCU i Wemos
    ModbusBegin();
  pinMode(LED1PIN, OUTPUT);
  writeLED1(0);
  pinMode(LED2PIN, OUTPUT);
  writeLED4(1);
  pinMode(LED3PIN, OUTPUT);
  writeLED4(1);
  pinMode(LED4PIN, OUTPUT);
  writeLED4(1);

 
  #if (reczneIP)
WiFi.config(ip, dns, gateway, subnet); 
#endif
//  Serial.begin(115200);


  Serial1.println();
  Serial1.println();
  Serial1.println();

for(uint8_t t = 4; t > 0; t--) {
    Serial1.printf("[SETUP] BOOT WAIT %d...\r\n", t);
    Serial1.flush();
    delay(1000);
  }



  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial1.println("Connecting to WiFi..");
  }

  Serial1.println(WiFi.localIP());

//Send OTA events to the browser
  ArduinoOTA.onStart([]() { events.send("Update Start", "ota"); });
  ArduinoOTA.onEnd([]() { events.send("Update End", "ota"); });
  ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
    char p[32];
    sprintf(p, "Progress: %u%%\n", (progress/(total/100)));
    events.send(p, "ota");
  });
  ArduinoOTA.onError([](ota_error_t error) {
    if(error == OTA_AUTH_ERROR) events.send("Auth Failed", "ota");
    else if(error == OTA_BEGIN_ERROR) events.send("Begin Failed", "ota");
    else if(error == OTA_CONNECT_ERROR) events.send("Connect Failed", "ota");
    else if(error == OTA_RECEIVE_ERROR) events.send("Recieve Failed", "ota");
    else if(error == OTA_END_ERROR) events.send("End Failed", "ota");
  });
  ArduinoOTA.setHostname(hostName);
  ArduinoOTA.begin();
 

  /*  if (!MDNS.begin("espWebSock")) {
        Serial.println("Error setting up MDNS responder!");
        while(1) {
            delay(1000);
       
    }
    Serial.println("mDNS responder started");}*/

     webSocket.begin();

  webSocket.onEvent(webSocketEvent);

  server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send(200, "text/html", INDEX_HTML);
  });
  /*
  server.on("/hello", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send(200, "text/html", INDEX_HTML);
  });
 
  server.on("/post", HTTP_POST, [](AsyncWebServerRequest *request){
    request->send(200, "text/plain", "Post route");
  });

  server.on("/put", HTTP_PUT, [](AsyncWebServerRequest *request){
    request->send(200, "text/plain", "Put route");
  });

  server.on("/get", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send(200, "text/plain", "Get route");
  });

  server.on("/any", HTTP_ANY, [](AsyncWebServerRequest *request){
    request->send(200, "text/plain", "Any route");
  });*/
 

 
  server.begin();

}

void loop(){
  czas();
  webSocket.loop();

  ArduinoOTA.handle();
   unsigned long currentMillis = millis();
  if ( fsekundy)
  { VAR4++;
      webSocket.broadcastTXT("start"+token+String(VAR1)+token+String(VAR2)+token+String(VAR3)+token+String((VAR3*3/1.05))+token+String(VAR4)+token+String(VAR4/60)+token+String(VAR4/3600)+token+String(rgb));
  }
  if ( fsekundy and ( sekundy%5==0))
  {
    odczytModbus();
  }
 
}




void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t length)
{
//  Serial.printf("webSocketEvent(%d, %d, ...)\r\n", num, type);
  switch(type) {
    case WStype_DISCONNECTED:
//      Serial.printf("[%u] Disconnected!\r\n", num);
      break;
    case WStype_CONNECTED:
      {
        IPAddress ip = webSocket.remoteIP(num);
//        Serial.printf("[%u] Connected from %d.%d.%d.%d url: %s\r\n", num, ip[0], ip[1], ip[2], ip[3], payload);
       
        webString="start"+token;
        if (LED1Status) {
        webSocket.sendTXT(num, LED1ON, strlen(LED1ON));
         //  webString+=LED1ON+token;
        }
        else {
           webSocket.sendTXT(num, LED1OFF, strlen(LED1OFF));
          //  webString+=LED1OFF+token;
        }
        if (LED2Status) {
          webSocket.sendTXT(num, LED2ON, strlen(LED2ON));
        //    webString+=LED2ON+token;
        }
        else {
           webSocket.sendTXT(num, LED2OFF, strlen(LED2OFF));
         //   webString+=LED2OFF+token;
        }
        if (LED3Status) {
           webSocket.sendTXT(num, LED3ON, strlen(LED3ON));
        //   webString+=LED3ON+token;
        }
        else {
           webSocket.sendTXT(num, LED3OFF, strlen(LED3OFF));
          //  webString+=LED3OFF+token;
        }
        if (LED4Status) {
           webSocket.sendTXT(num, LED4ON, strlen(LED4ON));
        //    webString+=LED4ON+token;
        }
        else {
          webSocket.sendTXT(num, LED4OFF, strlen(LED4OFF));
          // webString+=LED4OFF+token;
        }
        webString+=String(VAR1)+token+String(VAR2)+token+String(VAR3)+token+String(VAR4)+token+String(VAR5)+token+String(VAR5)+token+String(VAR5)+token+String(rgb)+token;
         webSocket.sendTXT(num,webString);  //to dziala tylko przy otwieraniu nowego polaczenia               
      }
      break;
    case WStype_TEXT:
//      Serial.printf("[%u] get Text: %s\r\n", num, payload);
      ledziklik();
      if (strcmp(LED1ON, (const char *)payload) == 0) {
        writeLED1(true);
      }
      else if (strcmp(LED1OFF, (const char *)payload) == 0) {
        writeLED1(false);
      }
      else if (strcmp(LED2ON, (const char *)payload) == 0) {
        writeLED2(true);
      }
      else if (strcmp(LED2OFF, (const char *)payload) == 0) {
        writeLED2(false);
      }
      else if (strcmp(LED3ON, (const char *)payload) == 0) {
        writeLED3(true);
      }
      else if (strcmp(LED3OFF, (const char *)payload) == 0) {
        writeLED3(false);
      }
      else if (strcmp(LED4ON, (const char *)payload) == 0) {
        writeLED4(true);
      }
      else if (strcmp(LED4OFF, (const char *)payload) == 0) {
        writeLED4(false);
      }
      /////////////////////////////////////RGB
      else if   (payload[0] == '#') {
                // we get RGB data

                // decode rgb data
                  rgb = (uint32_t) strtol((const char *) &payload[1], NULL, 16);

                analogWrite(LED_R,  ((rgb >> 16) & 0xFF));
                analogWrite(LED_G,  ((rgb >> 8) & 0xFF));
                analogWrite(LED_B,  (VAR5=(rgb >> 0) & 0xFF));
            }
      /////////////////////////////////////
      else {
//        Serial.println("Unknown command");
      }
      // send data to all connected clients
      webSocket.broadcastTXT(payload, length);

      break;
    case WStype_BIN:
//      Serial.printf("[%u] get binary length: %u\r\n", num, length);
      hexdump(payload, length);

      // echo data back to browser
      webSocket.sendBIN(num, payload, length);
      break;
    default:
//      Serial.printf("Invalid WStype [%d]\r\n", type);
      break;
  }
}

static void ledziklik()
{
ledklik++;
  }
//W zaleznosci od podlaczenia LED 1 moze ja zapalac lub gasic
static void writeLED1(bool LED1on)
{
  LED1Status = LED1on;
   
  if (LED1on) {
    digitalWrite(LED1PIN, 1);
  }
  else {
    digitalWrite(LED1PIN, 0);
  }
}

static void writeLED2(bool LED2on)
{
  LED2Status = LED2on;
   
  if (LED2on) {
    digitalWrite(LED2PIN, 1);
  }
  else {
    digitalWrite(LED2PIN, 0);
  }
}
static void writeLED3(bool LED3on)
{
  LED3Status = LED3on;
 
  if (LED3on) {
    digitalWrite(LED3PIN, 1);
  }
  else {
    digitalWrite(LED3PIN, 0);
  }
}

static void writeLED4(bool LED4on)
{
  LED4Status = LED4on;
   
  if (LED4on) {
    digitalWrite(LED4PIN, 1);
  }
  else {
    digitalWrite(LED4PIN, 0);
  }
}


void odczytModbus()
{


   
    result = node.readInputRegisters(0x0, 9); //odczyt rejsestrow 0-9 PZEM-016
    if (result == node.ku8MBSuccess)
    {
      uint32_t tempdouble = 0x00000000;

      float voltage = node.getResponseBuffer(0x0000) / 10.0;  //get the 16bit value for the voltage, divide it by 10 and cast in the float variable

      tempdouble =  (node.getResponseBuffer(0x0002) << 16) + node.getResponseBuffer(0x0001);  // Get the 2 16bits registers and combine them to an unsigned 32bit
      float current = tempdouble / 1000.00;   // Divide the unsigned 32bit by 1000 and put in the current float variable

      tempdouble =  (node.getResponseBuffer(0x0004) << 16) + node.getResponseBuffer(0x0003);
      float power = tempdouble / 10.0;

      tempdouble =  (node.getResponseBuffer(0x0006) << 16) + node.getResponseBuffer(0x0005);
      float kwh = tempdouble;

      float hz = node.getResponseBuffer(0x0007) / 10.0;
      float pf = node.getResponseBuffer(0x0008) / 100.00;
VAR1=voltage;
VAR2=power;
VAR3=kwh/1000.0;
    Serial1.print("Licznik nr ");
    Serial1.print(slaveID);
    Serial1.print(": ");

      Serial1.print(voltage, 1);  // Print Voltage with 1 decimal
      Serial1.print("V   ");

      Serial1.print(hz, 1);
      Serial1.print("Hz   ");

      Serial1.print(current, 3);
      Serial1.print("A   ");

      Serial1.print(power, 1);
      Serial1.print("W  ");

      Serial1.print(pf, 2);
      Serial1.print("pf   ");

      Serial1.print(kwh, 0);
      Serial1.print("kWh  ");
      Serial1.println();
      }
     else
    {
      Serial1.println("Failed to read modbus");
    }


}

void czas()
{
  czasTeraz=millis();
fnTik=fsekundy=fminuty=fgodziny=fdni=0;
if((uint32_t)(czasTeraz-czasPoprzedni)>=tik) //tan napisany warunek jest odporny na "klątwe 50 dni millis()"
{
  czasPoprzedni=czasTeraz;
  fnTik=1;
  nTik++;
  if(nTik>=(1000/tik))
  {
    nTik=0;
    sekundy++;
    fsekundy=1;
     if (sekundy>=60)
    {
      sekundy=0;
      minuty++;
      fminuty=1;
      if (minuty>=60)
      {
        minuty=0;
        godziny++;
        fgodziny=1;
        if (godziny>=24)
        {
          godziny=0;
          fdni=1;
          dni++;
   
        }
      }
    }
  }
}
}
Miło być decenianym https://buycoffee.to/kaczakat
 
#9
Nie wiem po co wrzucasz ten kod. Ja nie chce rozkminiać od podstaw jakiś zasad programowania. Chce się dowiedzieć, dlaczego ten konkretny  układ nie działa z konkretnym licznikiem PZEM-017 przy konkretnym kodzie i w konkretnym zestawieniu. Wszystkie części i kroki są podane w linku, a mimo to coś nie bangla tak jak trzeba. 
A ja pytam ludzi z większym doświadczeniem, którzy się na tym znają. DLACZEGO? CO JEST NIE TAK? Ja się nie znam na programowaniu, ale znam się na innych rzeczach o których programiści nie maja zielonego pojęcia.
 Nie pytam o zasady i naukę programowania, bo zdaje sobie sprawę, ze tego nie da się nauczyć w 5 czy 10 postach. Według mnie jest jakiś myk w kodzie, coś co trzeba ustawić według siebie, nie wiem , może adres licznika?
 
#10
Temat zamykam, niby forum Arduino, a nikt nie ma zielonego pojęcia
 
  


Skocz do:


Przeglądający: 1 gości