xoseperez / hlw8012

HLW8012 library for Arduino and ESP8266 using the Arduino Core for ESP8266.
GNU General Public License v3.0
126 stars 48 forks source link

Document a safe way to develop code and algorithms for the HLW8012 #4

Open xoseperez opened 6 years ago

xoseperez commented 6 years ago

Originally reported by: Julian Todd (Bitbucket: goatchurch, GitHub: Unknown)


For most arduino sensors, I program the algorithms and send print statements through the serial line in order to debug it.

But everywhere it says DO NOT CONNECT TO SERIAL LINE WHEN THE HLW8012 IS WORKING (ie when it is connected to the mains).

It's good to be told what not to do. But even nicer to be told how we should do it instead.

NdK73 commented 6 years ago

What I'm doing:

#include <WiFiUdp.h>
...
IPAddress mcast(239,255,215,74);
WiFiUDP logger;

void setup() [
...
  logger.beginMulticast(WiFi.localIP(), mcast, 55114);
}

void sendlog(const char *logmessage) {
  logger.beginPacketMulticast(mcast, 55114, WiFi.localIP());
  logger.printf("* %s", logmessage);
  logger.endPacket();
}

The generated multicast packets can be monitored with

#!/usr/bin/python
# Multicast client
# Adapted from: http://chaos.weblogs.us/archives/164

import socket

ANY = "0.0.0.0" 
MCAST_ADDR = "239.255.215.74"
MCAST_PORT = 55114

# Create a UDP socket
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)

# Allow multiple sockets to use the same PORT number
sock.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)

# Bind to the port that we know will receive multicast data
sock.bind((ANY,MCAST_PORT))

# Tell the kernel that we want to add ourselves to a multicast group
# The address for the multicast group is the third param
status = sock.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, socket.inet_aton(MCAST_ADDR) + socket.inet_aton(ANY))

# setblocking(0) is equiv to settimeout(0.0) which means we poll the socket.
# But this will raise an error if recv() or send() can't immediately find or send data. 
sock.setblocking(1)

while 1:
    try:
        data, addr = sock.recvfrom(1024)
    except socket.error as e:
        pass
    else:
        print "From: ", addr
        print "Data: ", data

Note that this address and port are used by the domotic protocol I'm developing so I can use a single monitor both for protocol messages and logging (the "* " guarantees that log messages cannot be interpreted by protocol decoder).