hand

package
v0.0.0-...-f61a68e Latest Latest
Warning

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

Go to latest
Published: Jun 16, 2021 License: Apache-2.0 Imports: 15 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Calibrate

func Calibrate(run bool, e *Encoder, h *Hand, reference int)

Calibrate moves the hand at least 4 revolutions to allow the encoder to measure the actual steps for 360 degrees of movement, and to discover the location of the encoder mark.

func ClockServer

func ClockServer(port int, clock []*Hand)

ClockServer starts a HTTP server that displays a clock face and status information about the clock.

Types

type ClockConfig

type ClockConfig struct {
	Name    string        // Name of the hand
	Gpio    []int         // Output pins for the stepper
	Speed   float64       // Speed the stepper runs at (RPM)
	Period  time.Duration // Period of the hand (e.g time.Hour)
	Update  time.Duration // How often the hand updates.
	Steps   int           // Initial reference steps per revolution
	Encoder int           // Input pin for encoder
	Notch   int           // Minimum width of encoder mark
	Offset  int           // Hand offset from midnight to encoder mark
}

Configuration data for the clock hand, usually read from a configuration file.

func Config

func Config(conf *config.Config, name string) (*ClockConfig, error)

Config reads and validates a ClockHand config from a config file section. Sample config:

[name]                   # name of hand e.g hours, minutes, seconds
stepper=4,17,27,22,3.0   # GPIOs for stepper motor, and speed in RPM
period=12h               # The clock period for this hand
update=5m                # The update rate as a duration
steps=4096               # Reference number of steps in a revolution
encoder=21               # GPIO for encoder
notch=100                # Min width of sensor mark
offset=2100              # The offset of the hand at the encoder mark

type ClockHand

type ClockHand struct {
	Stepper *action.Stepper
	Input   *io.Gpio
	Hand    *Hand
	Encoder *Encoder
	Config  *ClockConfig
}

ClockHand combines the I/O for a hand and an encoder. A clock is comprised of multiple hands, each of which runs independently. Each clock hand consists of a Hand which generates move requests according to the current time, an Encoder which provides feedback as to the actual location of the hand, and the I/O providers for the Hand and Encoder. A config for each hand is parsed from a configuration file.

func NewClockHand

func NewClockHand(hc *ClockConfig) (*ClockHand, error)

NewClockHand initialises the I/O, Hand, and Encoder using the configuration provided.

func (*ClockHand) Close

func (c *ClockHand) Close()

Close shuts down the clock hand and release the resources.

func (*ClockHand) GetLocation

func (c *ClockHand) GetLocation() int64

GetLocation returns the current absolute location.

func (*ClockHand) Move

func (c *ClockHand) Move(steps int)

Move moves the stepper motor the steps indicated. This is a shim between the hand and the stepper so that the motor can be turned off between movements. Waits until the motor completes the steps before returning. TODO: Turning the motor off immediately will miss steps under load, so some kind of delay is needed.

func (*ClockHand) Run

func (c *ClockHand) Run()

Run starts the clock hand, initially running a calibration so that the encoder mark position can be discovered, and then starting the hand processing if requested.

type Encoder

type Encoder struct {
	Name string

	Invert   bool // Invert input signal
	Measured int  // Measured steps per revolution
	// contains filtered or unexported fields
}

Encoder is an interrupter encoder driver used to measure shaft rotations. The count of current step values is used to track the number of steps in a rotation between encoder signals, and this is used to calculate the actual number of steps in a revolution.

func NewEncoder

func NewEncoder(name string, stepper GetStep, syncer Syncer, io IO, size int) *Encoder

NewEncoder creates a new Encoder structure.

func (*Encoder) Location

func (e *Encoder) Location() int

Location returns the current location as a relative position from the encoder mark

type GetStep

type GetStep interface {
	GetStep() int64
}

GetStep provides a method to read the absolute location of the stepper motor.

type Hand

type Hand struct {
	Name    string // Name of this hand
	Ticking bool   // True if the clock has completed initialisation and is ticking.

	Marks       int // Number of times encoder mark hit
	Skipped     int // Number of skipped moves
	FastForward int // Number of fast forward movements
	Adjusted    int // Number of hand adjustments
	// contains filtered or unexported fields
}

Hand represents a clock hand. A single revolution of the hand is represented by a number of ticks, determined by the update duration for the hand e.g a minute hand takes 60 minutes for a revolution, and is updated every 5 seconds (to make the motion smooth), so this hand has 720 ticks (60 * 60 / 5). Ticking the clock involves moving the hand by one tick each update period. Ticks are not steps; a single tick is usually a number of steps.

The number of steps in a single revolution is held in actual, which is initially set from a reference value, and can be updated by an external encoder tracking the actual physical movement of the hand.

Moving is done by calculating the step location of a tick, and then sending a step count to a Mover to move the hand to the required step location. E.g if there are 4000 steps in a revolution, and 720 ticks for a minute hand, and the time is 17 minutes past the hour, this is tick 720 * 17 / 60 = 204. The target step location for this tick is 4000 * 204 / 720 = 1133. The current step number is used to determine how many steps the hand needs to move to get to 1133.

Moving is only performed in a clockwise direction. An offset may be provided that correlates the encoder mark reference point and the actual physical location of the hand - when the hand is at the encoder reference point, the offset represents the relative offset of the physical clock hand e.g when the hand is at the encoder mark, the offset represents the location of the hand as steps away from the top of the clock face.

func NewHand

func NewHand(name string, unit time.Duration, mover MoveHand, update time.Duration, steps, offset int) *Hand

NewHand creates and initialises a Hand structure.

func (*Hand) Adjust

func (h *Hand) Adjust(adj int) int

Adjust adjusts the offset so that the physical position can be tweaked. A positive value reduces the offset so that the hand is closer to the encoder mark. The initial offset in the configuration should also be adjusted.

func (*Hand) Get

func (h *Hand) Get() (int, int, int)

Get returns the current relative position, the number of steps in a revolution, and the current offset.

func (*Hand) Mark

func (h *Hand) Mark(adj int, loc int64)

Mark updates the steps per revolution and sets the current location to a preset value. Usually called from a sensor encoder at the point when an encoder mark is detected, indicating a known physical location of the hand.

func (*Hand) Run

func (h *Hand) Run()

Run starts the ticking of the hand. The hand processing basically involves starting a ticker at the update rate specified for the hand, and then moving the hand to match the step location correlating to the time value the ticker sends.

type IO

type IO interface {
	Get() (int, error)
}

IO provides a method to return when an input changes.

type MoveHand

type MoveHand interface {
	Move(int)
	GetLocation() int64 // Get current location
}

MoveHand is the interface to move the hand by a selected number of steps.

type Syncer

type Syncer interface {
	Mark(int, int64)
}

Syncer provides an interface for a callback when the encoder mark is hit. The measured steps in a revolution is provided.

Jump to

Keyboard shortcuts

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