cmd/turbidity: write netsender client for turbidity sensor

Issue #24 new
Harry Telford created an issue

We now have the ability to communicate with the Remond modbus based turbidity sensor using an arduino uno. However, to make use of the received values, we require WIFI connectivity to be able to connect to the rig router and send the data to the cloud. It is therefore proposed, in the interest of time, that we use a raspberry pi (WIFI variant) to receive values over USB serial from the arduino, and then send using a go based netsender client for which we already have most of the code.

it’s proposed this client be housed under cmd/turbidity. There will be two files, i.e. main.go and turbidity.go. The main.go file will house code dealing with the netsender stuff, and will be mostly consistent with other netsender clients such as utils/cmd/alignment/alignment-netsender, av/cmd/rv and av/cmd/treatment. The turbidity.go file will house code dealing with the reading of turbidity values. This functionality will likely read from stdout of a background python process <insert details here>, similar to the current method of getting values from the LSM303 magnetomer inside utils/cmd/alignment/alignment-netsender/compass.go.

A bare bones netsender client is attached. The code for the turbidity code will need to be started from the main function before run() is called (which will probably in turn start a background routine that reads from the external process to keep a current value stored accessible from a method like TurbiditySensor.Turbidity()). Then sensor.Turbidity() will need to be used in the readPin callback to set a software defined pin with the turbidity value (code below). We can assign turbidity to software define pin “X24”. These changes to main.go should be enough to achieve the fundamental behaviour we’re trying to achieve.

// readPin provides a callback function of consistent signature for use by
// netsender to retrieve software defined pin values e.g. revid bitrate (X23).
// Here we report the median difference of bearing with target bearing.
func readPin(aligner *CPEAligner, log *logger.Logger) func(pin *netsender.Pin) error {
    return func(pin *netsender.Pin) error {
        if pin.Name == "X24" {
            pin.Value = -1
            t := sensor.Turbidity()
            if t != -1 {
                pin.Value = t
            }
        }
        return nil
    }
}

In the turbidity.go file, where the TurbiditySensor functionality is housed, is proposed to look something like this at a minimum (very similar to cmd/alignment-netsender/compass.go code; see as example):

type TurbiditySensor struct {
  ...
  cmd *exec.Cmd // Hold background process for communicating with arduino uno.
  mu sync.Mutex // Need to synchronise access to up to date stored turbidity values.
  ...
}

func NewTurbiditySensor() (*TurbiditySensor,error) {
  // Create the turbidity sensor.
  ....

  // Create background process and pipe stdout.
  ...

  // Create scanner for reading out pipe and start process
  ...

  // Start stdout reading routine i.e. "go ts.readValues()"
  ...
}

// routine for reading values from background python process.
func (ts *TurbiditySensor) readValues(){
  for {
    // Check any termination signals.
    ...

    // Scan the output for any lines and deal with any problems.
    ...

    // Get the output text and parse out turbidity value.
    ...

    // Set turbidity value using method adopting synchronisation.
    ...

  }
}

// Turbidity returns most current turbidity reading, being safe using synchronisation.
func (ts *TurbiditySensor) Turbidity(){
  ...
}

// Updates turbidity reading safely using synchronisation.
func (ts *TurbiditySensor) setTurbidity(v int){
  ...
}

Comments (2)

  1. Log in to comment