sds011

package module
v0.0.2 Latest Latest
Warning

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

Go to latest
Published: Jan 26, 2025 License: MIT Imports: 11 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.

There is Conn interface for that.

type Conn interface {
	Send(packet Packet) error
	Recieve() (*Packet, error) //Return immediately. nil if not yet complete packet
	Close() error
}

The LinuxConn is one implementations for linux targets.

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 CreateLinuxSerial(deviceportName string) (*LinuxConn, error)

Then call Recieve functions of Conn when need to recieve or send.

Or use Sensor layer sds011 for handling messaging

Sensor layer

Sensor layer is model of sensor and filtering mechanism

func InitSds011(Id uint16, passive bool, conn Conn, resultCh chan Result, initialMeasurementCounter int) Sds011 {

When calling .Run method for this sensor, sensor runs and results coming from serial interface are processed result to channel

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. Or use socat

TIP for socat

For testing with simulator, use following socat command

socat -d -d pty,raw,echo=0 pty,raw,echo=0

it will create pair of pty serial devices that are connected together. Open one with simulator and another with actual software

Documentation

Overview

SDS011conn is connection for writing and reading packages from serial line

This is interface. Different implementations are made for linux and tinygo-microcontroller environments

Index

Constants

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 (
	TIMEOUTRESPONSE  = 500  //Query is sent, how long wait sensor response
	SYNCRETRYINTEVAL = 3000 //How long to wait before syncing settings from sensor
)
View Source
const ANYDEVICE = 0xFFFF

Variables

This section is empty.

Functions

func EnoughBytes

func EnoughBytes(arr []byte) bool

func GetUptime

func GetUptime() int64

Util function if running on linux TODO OTHER MODULE

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 Conn

type Conn interface {
	Send(packet Packet) error
	Recieve() (*Packet, error) //Return immediately. nil if not yet complete packet
	Close() error
}

type LinuxConn

type LinuxConn struct {
	// contains filtered or unexported fields
}

func CreateLinuxSerial

func CreateLinuxSerial(deviceportName string) (*LinuxConn, error)

Uses fixed settings for SDS0101

func (*LinuxConn) Close

func (p *LinuxConn) Close() error

func (*LinuxConn) Recieve

func (p *LinuxConn) Recieve() (*Packet, error)

func (*LinuxConn) Send

func (p *LinuxConn) Send(packet Packet) error

func (*LinuxConn) SendBytes

func (p *LinuxConn) SendBytes(data []byte) error

type Packet

type Packet 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) Packet

func NewPacket_QueryData

func NewPacket_QueryData(deviceId uint16) Packet

func NewPacket_QueryVersion

func NewPacket_QueryVersion(deviceId uint16) Packet

Version

func NewPacket_QueryVersionReply

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

func NewPacket_SetId

func NewPacket_SetId(deviceId uint16, newDeviceId uint16) Packet

Set device id. DO NOT USE. Unless really wanted

func NewPacket_SetIdReply

func NewPacket_SetIdReply(deviceId uint16) Packet

func NewPacket_SetPeriod

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

Set working period

func NewPacket_SetPeriodReply

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

func NewPacket_SetQueryMode

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

func NewPacket_SetQueryModeReply

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

func NewPacket_SetWorkMode

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

4)Set device sleep work time

func NewPacket_SetWorkModeReply

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

func (*Packet) CalcChecksum

func (p *Packet) CalcChecksum() byte

func (*Packet) ChecksumOk

func (p *Packet) ChecksumOk() bool

func (*Packet) FromBytes

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

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

func (*Packet) GetIsWrite

func (p *Packet) GetIsWrite() bool

func (*Packet) GetMeasurement

func (p *Packet) GetMeasurement() (Result, error)

func (*Packet) GetPeriod

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

func (*Packet) GetQueryMode

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

func (*Packet) GetSetId

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

func (*Packet) GetVersionString

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

func (*Packet) GetWorkMode

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

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

func (*Packet) MatchToId

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

func (Packet) String

func (p Packet) String() string

func (*Packet) ToBytes

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

func (*Packet) ToDebugText

func (p *Packet) ToDebugText() string

type Result

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

func (*Result) Large

func (p *Result) Large() float64

func (*Result) Small

func (p *Result) Small() float64

func (*Result) ToString

func (p *Result) ToString() string

NOTICE: non calibrated values, used for debug

type Sds011

type Sds011 struct {
	PassiveMode bool //Only listen

	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, conn Conn, resultCh chan Result, 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) GetSettings

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

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() error

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) SyncSettingsFromDevice

func (p *Sds011) SyncSettingsFromDevice() error

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

Jump to

Keyboard shortcuts

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