Skip to content
This repository has been archived by the owner on Aug 17, 2021. It is now read-only.

Commit

Permalink
controller: mechanical relay implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
andy-haynes committed Apr 7, 2018
1 parent 5ce1fa5 commit 5c7ca1e
Show file tree
Hide file tree
Showing 7 changed files with 108 additions and 7 deletions.
3 changes: 3 additions & 0 deletions controller/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ export default {
PID: {
strikeThreshold: 0.95, // percentage of target temp to reach before switching to PID control
},
Relay: {
pins: [10, 12]
},
thermometer: {
defaultTemperature: -1, // uninitialized temperature value
sampleIntervalMS: 750, // ms between temperature measurements
Expand Down
8 changes: 4 additions & 4 deletions controller/controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@ import BrewConfig from '../core/models/BrewConfig';
import BrewStep from '../core/models/BrewStep';
import BrewUpdate from '../core/models/BrewUpdate';
import controllerConfig from './config';
import { MockRelay } from './mocks';
import { PIDController } from './pid';
import { PiThermometer } from './thermometer';
import { MechanicalRelay } from './relay';
import { TemperatureUnits, ZynetMessageType} from '../core/constants';
import ZynetConnection from './connection';
import ZynetMessage from '../core/models/ZynetMessage';

const relay = new MockRelay();
const relay = new MechanicalRelay(controllerConfig.Relay.pins[0]);
const thermometer = new PiThermometer();
const mockUpdate = new BrewUpdate(1, 1, 60, 68, 152, false, 0);

Expand All @@ -35,10 +35,10 @@ function subscribeThermometer() {
if (config) {
if (pidThresholdReached) {
pidController.updateTemperature(temperature);
relay.switch(pidController.state);
relay.toggle(pidController.state);
} else {
pidThresholdReached = temperature >= (config.steps[currentStepIndex].temperature * controllerConfig.PID.strikeThreshold);
relay.switch(!pidThresholdReached);
relay.toggle(!pidThresholdReached);
}
}

Expand Down
4 changes: 3 additions & 1 deletion controller/interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@ export interface Connection {

export interface Relay {
on: boolean;
switch(on: boolean): void;
switchOn(): void;
switchOff(): void;
toggle(on: boolean): void;
}

export interface Thermometer {
Expand Down
4 changes: 3 additions & 1 deletion controller/mocks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ export class MockRelay implements Relay {
this.on = false;
}

switch(on: boolean): void { this.on = on; }
switchOn(): void { this.on = true; }
switchOff(): void { this.on = false; }
toggle(on: boolean): void { this.on = on; }
}

export class MockThermometer implements Thermometer {
Expand Down
19 changes: 19 additions & 0 deletions controller/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion controller/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
"license": "ISC",
"dependencies": {
"ds18b20": "^0.1.0",
"node-pid-controller": "^1.0.0"
"node-pid-controller": "^1.0.0",
"rpio": "^0.9.20"
}
}
74 changes: 74 additions & 0 deletions controller/relay.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import * as rpio from 'rpio';

import config from './config';
import { Relay } from './interfaces';


export class MechanicalRelay implements Relay {
public on: boolean;

constructor(private pin: number) {
this.on = false;
rpio.open(this.pin, rpio.OUTPUT);
}

switchOn(): void {
this.toggle(true);
}

switchOff(): void {
this.toggle(false);
}

toggle(on: boolean): void {
rpio.write(this.pin, !on ? rpio.HIGH : rpio.LOW);
this.on = !on;
}
}

// in order to spread out the wear on the mechanical relays, keep
// a pointer to the current relay and only turn it on when a relay
// needs is activated
// on the next activation increment the relay pointer
export class RelayArray implements Relay {
private currentRelayIndex: number;
private relays: Relay[];

constructor(private reversed = true) {
this.currentRelayIndex = 0;
this.relays = config.Relay.pins.map(pin => new MechanicalRelay(pin));
}

public get on(): boolean {
return this.currentRelay.on;
}

private get currentRelay(): Relay {
return this.relays[this.currentRelayIndex];
}

switchOn(): void {
// check that the current relay is not already switched on
if (!this.currentRelay.on) {
// increment the relay pointer
this.currentRelayIndex = (this.currentRelayIndex + 1) % this.relays.length;
// switch on the current relay
this.currentRelay.switchOn();
}
}

switchOff(): void {
// turn off any relays that are on
this.relays
.filter(relay => relay.on)
.forEach(relay => relay.switchOff());
}

toggle(on: boolean): void {
if (!(on && this.reversed)) {
this.switchOn();
} else {
this.switchOff();
}
}
}

0 comments on commit 5c7ca1e

Please sign in to comment.