Thursday, October 19, 2017

Randomness (to 17 Oct 2017)

Not too much on the solar tracker, directly. But:

1. Side project: Installed some reed switch door sensors yesterday. Significant note: It's way WAY easier to get the magnets and sensors lined up when you use expanded PVC board, and heat it up to flex it into position.

2. Reduced the complexity of wifi messaging for IoT devices to a basic 8 types:

  1. Condition
  2. Configuration
  3. Command
  4. Communication
Each has a requestor state and response state, so that makes 8. This allows for all combinations of state-machine transitions and responses that make sense for both buffered and real-time scenarios.

3. Finally got the garlic planted. Although this appears to have little involvement with electronics, it will later when I start instrumenting the garden, and how to deploy that in a weather sealed fashion. Short version: ABS pipe + fittings.

Sunday, October 15, 2017

Multiport Server in Go...

Today was a little windy for outdoor work on the solar panel tracker, so I updated the Go code to include a more graceful exit:

  • Logging server listens to quit chan
  • Time server listens to quit chan
  • Quit server closes quit chan
  • All servers quit, which causes defer to close all db & net connections
  • Main quits and exits to os.

This way I can telnet to port 6660 and kill all the services in one swoop, and know that the db connection was also gracefully closed.

Friday, October 13, 2017

Quick note on generic logging packet formats

Before I forget - I now have a generic logger running on a Mac, written in Go.

It listens on a specified IP address + TCP port number, and if the format is ok, writes it to a mySQL table. I can send from any wifi enable project, like from an ESP-01, for example.

The format (today) is composed of pairs of values, to 24 bytes long (so, 12 pairs). The two parameters are called opr (operator) and prm (parameter). The byte layout is:

0,1Source Network (opr) could be RF, WiFi, wired I2C, SPI, etc
Source Node ID (prm) the node ID on that network
2,3Destination Network (opr)
Destination Node ID (prm)
4,5Payload Type (opr) - actually - split into 16 media types + 16 payload types
Payload Version (prm) - for any media+payload, also a version to support mixed version environments to allow for graceful / rolling upgrades of equipment firmware
6,7MAC - Message Authentication / Challenge - Lo (opr) : 16 bits of message authentication
MAC - Message Authentication / Challenge - Hi (prm)

The choice of length might seem arbitrary (and REALLY short) but it's to allow for nodes connected via RF (i.e. a Nordic radio, like the nRF24l01) to send at an optimal packet size. Some of the tests I've seen but not yet replicated suggest that good performance can be had with 24 byte packets, but loss/corruption seems to be more of an issue at 32 bytes.

To maintain flexibility for true WiFi connections it shouldn't be too much of a stretch to specify a different Payload Type which could extend the packet to hundreds of byte pairs, probably 1k is a good limit if the ESP-8266 is going to have to buffer any of this.

I specify the networks and node ID's separately from the IP info because it's likely that some nodes are only connected via I2C/UART or IR links. In this way intermediate nodes can act as routers to forward the packets, hopefully to some kind of hub or handler.

The data section, for logging, can be viewed two ways, depending on log type.

The first version is to send register values; so the opr is the register #, and the prm is that registers value. This means I don't have to send sequential register space, but it's twice as slow to send. It does mean I can send ANY register space in any order, however.

The other version is to send specific formats, where every byte from 8..23 has a specific meaning for that node. It's less flexible, but might be quicker for sending mid-rate data blocks, like compressed audio.

I'm leaving encryption out of this spec. Adding it would mean simply a prior encryption exchange, and then probably encrypting only the data bytes. I suspect I'll use offline updates of one-time pad tables - but that's another post.

The last note (and probably kinda important) is why the bytes are labeled as OPERATOR and PARAMETER. Not written (quite this way, anyway) is an interpreter that basically looks like assembly language, and consumes ONLY two byte instructions; one byte for opcode, on byte for parameter (literal, offset, etc).

So this means that while I can use the transport right away for logging, it can also carry command and configuration instructions later, in different payload types.