sds011

package module
v0.0.0-...-5517d99 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 17, 2019 License: MIT Imports: 12 Imported by: 0

README

sds011

SDS011 air quality sensor interface for golang

Design goal is to also support multiple SDS011 sensors on same bus (using uart<->RS485 etc..) At the moment I own only one sensor. And do not have real need for multi sensor support. And multisensor is not tested

Structure

The lowest level is serial link library that convert serial port resource into channels.

Over that there is sensor layer that keeps sensor model state and converts packages to measurement results Sensor layer reacts only packages that have specified device id

Initialize link with. function

func InitializeSerialLink( deviceportName string, recievingCh chan SDS011Packet, expectedRecievePacketSize int, sendingCh chan SDS011Packet, expectedSendPacketSize int) (Sds011Serial, error) {

On client expectedRecievePacketSize is sds011.SDS011FROMSENSORSIZE sendingCh is sds011.SDS011TOSENSORSIZE

On simulator: expectedRecievePacketSize is sds011.SDS011TOSENSORSIZE expectedSendPacketSize is sds011.SDS011FROMSENSORSIZE

Then call .Run() method and link runs

Sensor layer

Sensor layer is model of sensor and filtering mechanism

When using single sensor, just pass channels to sensor layer

For multiple sensors, extra goroutine is needed for distributing data coming from serial link layer to each sensor.

create sensor model by calling func InitSds011( Id uint16, passive bool, toSensorCh chan SDS011Packet, fromSensorCh chan SDS011Packet, resultCh chan Sds011Result, initialMeasurementCounter int) Sds011 {

on passive mode, software is not sending queries for sensor.

When calling .Run method for this sensor, sensor runs and results are coming to resultCh Initial counter is needed for tracking up how many measurements (approx) are made. This will give rough estimate when sensor replacement is needed (laser/detector weardown in few years). Library user must plan and implement how to persist counter

If some setting have to be changed. Please check example

func interactiveMode(deviceFile string, devId uint16) error {

from "simple example". And google sds011 datasheet for further technical details

Simulator

This package includes also crude sds011 sensor simulator program. It hosts its own user interface for simulated sensor.

Simulator allows to simulate also error modes. Like disconnecting RX wire or bad RS485 driver (echo 0 when direction changes etc...). Or bytes from other communication protocols moving in wires while there is no need for sds011 (bad design)

For using simulator on pc without sensor, you need real rs232 loopback cables from port to port or use two usb-ttl cables in usb-ttl-ttl-usb config.

Documentation

Overview

sds011serial

This module handles serial port link. Lowest possible One instance per serial port. Possible to use on client or on simulator Just transmits and recieves. Trying to prepare for case where there are multiple sensors on same bus

Ignores all invalid communication.

Following rules when capturing packages

- Packet starts ALWAYS with 0xAA Ends 0xAB - PC -> sensor is 19 bytes ALWAYS - sensor -> PC is 10

Index

Constants

View Source
const (
	TIMEOUTRESPONSE  = 500  //Query is sent, how long wait sensor response
	SYNCRETRYINTEVAL = 3000 //How long to wait before syncing settings from sensor
)
View Source
const (
	SDS011TOSENSORSIZE   = 19
	SDS011FROMSENSORSIZE = 10
)

Get optimized serial transmit by exact packet size

View Source
const (
	SDS011PACKETSTART = 0xAA
	SDS011PACKETSTOP  = 0xAB
)
View Source
const (
	COMMANDID_CMD       = 0xB4
	COMMANDID_RESPONSE  = 0xC5
	COMMANDID_DATAREPLY = 0xC0 //First byte in data is not function number
)
View Source
const (
	FUNNUMBER_REPORTINGMODE = 2 //NON- volatile
	FUNNUMBER_QUERYDATA     = 4
	FUNNUMBER_SETID         = 5 //NON-volatile
	FUNNUMBER_SLEEPWORK     = 6 //Is needed? Trigger?
	FUNNUMBER_PERIOD        = 8 //NON -volatile
	FUNNUMBER_VERSION       = 7
)
View Source
const ANYDEVICE = 0xFFFF

Variables

This section is empty.

Functions

func CutToStartWith

func CutToStartWith(firstMustBe byte, arr []byte) []byte

func NormalizePM10

func NormalizePM10(pm10 float64, humidity float64) float64

func NormalizePM25

func NormalizePM25(pm25 float64, humidity float64) float64

Stolen from https://github.com/piotrkpaul/esp8266-sds011

Types

type SDS011Packet

type SDS011Packet struct {
	CommandID byte
	DeviceID  uint16
	Checksum  byte
	Data      []byte
	Uptime    int64 //Extra information to carry around.. timestamping
	Valid     bool  //Is ok or not
}

func NewPacket_DataReply

func NewPacket_DataReply(deviceId uint16, pm2_5 uint16, pm10 uint16) SDS011Packet

func NewPacket_QueryData

func NewPacket_QueryData(deviceId uint16) SDS011Packet

func NewPacket_QueryVersion

func NewPacket_QueryVersion(deviceId uint16) SDS011Packet

Version

func NewPacket_QueryVersionReply

func NewPacket_QueryVersionReply(deviceId uint16, year byte, month byte, day byte) SDS011Packet

func NewPacket_SetId

func NewPacket_SetId(deviceId uint16, newDeviceId uint16) SDS011Packet

Set device id. DO NOT USE. Unless really wanted

func NewPacket_SetIdReply

func NewPacket_SetIdReply(deviceId uint16) SDS011Packet

func NewPacket_SetPeriod

func NewPacket_SetPeriod(deviceId uint16, write bool, period byte) SDS011Packet

Set working period

func NewPacket_SetPeriodReply

func NewPacket_SetPeriodReply(deviceId uint16, write bool, period byte) SDS011Packet

func NewPacket_SetQueryMode

func NewPacket_SetQueryMode(deviceId uint16, write bool, query bool) SDS011Packet

func NewPacket_SetQueryModeReply

func NewPacket_SetQueryModeReply(deviceId uint16, write bool, query bool) SDS011Packet

func NewPacket_SetWorkMode

func NewPacket_SetWorkMode(deviceId uint16, write bool, work bool) SDS011Packet

4)Set device sleep work time

func NewPacket_SetWorkModeReply

func NewPacket_SetWorkModeReply(deviceId uint16, write bool, work bool) SDS011Packet

func (*SDS011Packet) CalcChecksum

func (p *SDS011Packet) CalcChecksum() byte

func (*SDS011Packet) ChecksumOk

func (p *SDS011Packet) ChecksumOk() bool

func (*SDS011Packet) FromBytes

func (p *SDS011Packet) FromBytes(uptimeNow int64, arr []byte) error

Require packet starting with 0xAA and end 0xAB Remember to add uptime here. (exact timestamp)

func (*SDS011Packet) GetIsWrite

func (p *SDS011Packet) GetIsWrite() bool

func (*SDS011Packet) GetMeasurement

func (p *SDS011Packet) GetMeasurement() (Sds011Result, error)

func (*SDS011Packet) GetPeriod

func (p *SDS011Packet) GetPeriod() (byte, error)

func (*SDS011Packet) GetQueryMode

func (p *SDS011Packet) GetQueryMode() (bool, error)

func (*SDS011Packet) GetSetId

func (p *SDS011Packet) GetSetId() (uint16, error)

func (*SDS011Packet) GetVersionString

func (p *SDS011Packet) GetVersionString() (string, error)

func (*SDS011Packet) GetWorkMode

func (p *SDS011Packet) GetWorkMode() (bool, error)

Assuming valid packet (it have data, only valid function)

func (*SDS011Packet) MatchToId

func (p *SDS011Packet) MatchToId(id uint16) bool

func (*SDS011Packet) ToBytes

func (p *SDS011Packet) ToBytes() []byte

func (*SDS011Packet) ToDebugText

func (p *SDS011Packet) ToDebugText() string

func (*SDS011Packet) ToString

func (p *SDS011Packet) ToString() string

type Sds011

type Sds011 struct {
	PassiveMode    bool //Only listen
	SettingsInSync bool //If flips to offline (timeout etc... require settings check)

	Id uint16 //Listen only these messages

	ErrorsCh       chan error  //Push nil if recovered or came online
	DetectedSensor chan uint16 //In case of multiple sensors. add item here when found valid package with new ID
	// contains filtered or unexported fields
}

func InitSds011

func InitSds011(Id uint16, passive bool, toSensorCh chan SDS011Packet, fromSensorCh chan SDS011Packet, resultCh chan Sds011Result, initialMeasurementCounter int) Sds011

func (*Sds011) ChangeToWork

func (p *Sds011) ChangeToWork(toWork bool) error

func (*Sds011) DoQuery

func (p *Sds011) DoQuery() error

Response comes from result channel TODO Timeout checking?

func (*Sds011) IsWorking

func (p *Sds011) IsWorking() (bool, error)

Not like working/broken.... it means working not sleeping

func (*Sds011) PowerLine

func (p *Sds011) PowerLine(enabled bool)

If system have hiside power enable for sensor

func (*Sds011) Run

func (p *Sds011) Run()

func (*Sds011) SetSettings

func (p *Sds011) SetSettings(newSettings Sds011Settings) error

Check situation first from sensor. Do not update if not needed, avoid re-flashing eeprom

func (*Sds011) SyncSettings

func (p *Sds011) SyncSettings() (Sds011Settings, error)

Called after disconnect Also allows to query current (desired) settings... even sensor is offline. Or if it is online.. it returns what setting really is

type Sds011Result

type Sds011Result struct {
	MeasurementCounter int
	Uptime             int64
	SmallReg           uint16
	LargeReg           uint16
}

func (*Sds011Result) ToString

func (p *Sds011Result) ToString() string

NOTICE: non calibrated values, used for debug

type Sds011Serial

type Sds011Serial struct {
	Serialport *os.File // *serial.Port //Using this as public, simulator needs
	// contains filtered or unexported fields
}
func InitializeSerialLink(deviceportName string,
	recievingCh chan SDS011Packet, expectedRecievePacketSize int,
	sendingCh chan SDS011Packet, expectedSendPacketSize int) (Sds011Serial, error)

func (*Sds011Serial) Run

func (p *Sds011Serial) Run() error

Depending on is this to sensor or from sensor

type Sds011Settings

type Sds011Settings struct {
	QueryMode bool
	Period    byte   //0=30sec no sleep, 1=1 minute period
	Version   string //can be queried if active mode   READONLY
}

func (*Sds011Settings) PeriodDuration

func (p *Sds011Settings) PeriodDuration() time.Duration

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL