Skip to content

tinybrain/spaduino

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

30 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

spaduino

spaduino is a hot tub controller implemented using an arduino UNO compatible controller. It was used as a drop-in MCU replacement for a Spa Quip SP500AMKI, manufactured by Spa Quip/Davey in New Zealand.

I really can't stress enough how much anyone reading this should regard this project as INFORMATIONAL ONLY, and should not under ANY circumstances attempt anything remotely similar. This project involves rediculous quantities of both high pressure water and high current electricity in potentially LETHAL proximity.

The project consists of three applications:

  • SpaController is the audino sketch for the core firmware. The rpi-ios branch is the version used during the development phase, which used a serial protocol for interactivity and an RTC source. The master branch is the final self-contained version providing user interaction and display via the unit's original front-panel interface, and an integrated module as an RTC source.

  • SpaServer is a simple server which in the first phase was run on a raspberry-pi running Arch Linux, connected to the arduino via RS232. It primarily acted as a Wi-Fi enabled console host and relay on top of the arduino's serial protocol, as well as providing an RTC source via a chrony NTP daemon.

  • Slimer is an iOS frontend also used during the first phase. It connected to the SpaServer using Google Protocol Buffers over TCP using NSStream, and provided an interface for system interaction and status display.

Schematics I used to grok the original design are available separately:

SpaController

1. Test Mode

The controller can be started in a pin-assignment mode which basically flips each IO pin in sequence each second. The mode is set with a magic number in EEPROM, 23 for test mode, and 42 for normal operation.

2. Peripherals

  • Control Panel - the unit's original panel providing:

    • Error LED: ERR_LED
    • Piezo alarm: PAD_PZ
    • Three digit 7 segment LED display via external shift registers: SHR_LATCH SHR_DATA SHR_CLK.
    • Navigation buttons: PAD_LEFT PAD_RIGHT PAD_UP PAD_DOWN
  • RTC - Maxim DS3232 on a module: I2C_SDA I2C_SCL

  • Water Level - IR LED transmitter and photodiode receiver: WL_OUT WL_IN

  • High Limit Sense - Vishay H11AA1 Optocoupler for current sensing through the heating element: HL_IN.

  • Temperature - Maxim DS18S20 1-Wire Thermometer : ONE_WIRE.

  • Four channel FET driver on a module for switching external lighting.

3. Power Relays

Each of the four power relays uses a +5V GPIO line connected to a ULN2803 darlington array. The array outputs a high current +12V signal which drives the relay coils.

  • RLY_SAFETY

    A master relay supplying the other relays. When entering an error state, driving this line provides additional protection against electrical failures where the other power relays fail to open.

  • RLY_PUMP

    Supplies the main pump induction motor (1.6kW).

  • RLY_HEAT

    Supplies the heating element (2kW), and is wired to the output of RLY_PUMP (see Pump.Heat).

  • RLY_AUX

    Supplies an auxiliary blower induction motor (700W).

4. Finite State Machines

Mode

The controller's primary and "high level" state, corresponding to the various user selectable modes and error states.

  • ERR:Mode.Error

    A fatal error produced by sensor failure or limits. The displayed error codes are:

    • ___:Unknown
    • CLK:Clock (i.e. RTC)
    • TPS:TemperatureSensor
    • H20:WaterLevelSensor
    • CUR:HighLimit
  • INI:Mode.Init

    Entry state, during which sensors and peripherals are configured.

  • OFF:Mode.Off

    Idle state with all sensors peripherals initialised.

  • AUT:Mode.Autoheat

    The default idle state, during which operation is determined via the scheduler and thermal control.

  • RPD:Mode.Rapidheat

    A 24hr cycle during which thermal regulation takes priority over any scheduling rules. This is for bringing the water back to temperature after changing out the water.

  • ON_:Mode.Soak

    The whole point of the exercise. A 1hr cycle during which automatic scheduling is suspended and the pump is enabled.

Pump

Controls the pump motor relay RLY_PUMP and heating element relay RLY_HEAT. These are combined into a single state as the heating element must only be supplied when there is sufficient water flow and is therefore dependent on the pump.

The Pump FSM also enforces the dependancy by all relay states - including the independent Aux FSM - on the master relay RLY_SAFETY.

  • Pump.Error

    Set when entering Mode.Error. RLY_SAFETY RLY_PUMP RLY_HEAT are cleared, as well as RLY_AUX by setting Aux.Off.

  • Pump.Off

    RLY_SAFETY enabled.

  • Pump.On

    RLY_SAFETY RLY_PUMP enabled.

  • Pump.Heat

    RLY_SAFETY RLY_PUMP RLY_HEAT enabled.

Aux

Provides independent control of the auxiliary relay RLY_AUX. It is a separate state machine as its operation does not depend on the state of the pump. It is however dependent on the state of the heater, as well as the master relay RLY_SAFETY.

  • Aux.Off

    RLY_AUX is cleared.

  • Aux.On

    RLY_AUX enabled. If supplying a blower which causes the total load to exceed the rating of the mains circuit, it must ensure the heater is disabled by switching from Pump.Heat to Pump.On

Menu

Manages the handlers and output relevant to the control panel.

  • Menu.Error

    Set from Mode.Error, displaying the relevant error code.

  • Menu.Mode

    Displays the mode when entering any mode during normal operation.

  • NN.N:Menu.Setpoint

    Allows adjustment of the thermal control setpoint in 0.1°C increments.

  • ---:Menu.Timer

    Displays a countdown or other value relevant to the current scheduler mode.

  • BL._:Menu.Blower

    Allows selection between Aux.Off and Aux.On

  • FT._:Menu.Footwell

    ST._:Menu.Steps

    HD._:Menu.Head

    PT._:Menu.Path

    Allows switching of low voltage auxiliary lighting circuits.

  • RST:Menu.SoftReset

    Executes asm volatile (" jmp 0")

5. Thermal Control

Because of the latencies inherent in the system, a complicated PID controller isn't required, and the thermal regulation is fairly basic.

A setpoint is adjustable from the control panel in 0.1°C increments, and set with Thermal::setSetPoint which limits the value within the range of 20°C and 40°C.

The thermal controller is updated by Thermal::update, called by a timer with an interval defined using the TS_INTERVAL macro, which calculates the sensor's response time based on TS_RESOLUTION.

To adjust for noise in local temperature measurements, an average temperature value is continuously updated by smoothing it with the incoming sensor values.

A trigger state is then evaluated by comparing the averaged temperature against the setpoint using a sort of poor man's binary hysteresis. The trigger state is set to tsHigh when the setpoint is reached, and to tsLow when the temperature drops at least 1°C below.

The combination of the smoothing and the trigger results in sensibly conservative durations of heater operation, at the same time barely reaching the duty cycle limits set by the scheduler, while sufficiently aggressive in maintaining a comfortable temperature during use.

6. Scheduler

The scheduler is a bit ad-hoc and lacks any interactivity features. My requirements were pretty straight forward, requiring temperature maintenance to be predominantly performed during off-peak periods, and either disabling or restricting operation during shoulder and peak periods. I also wanted to define exception periods such as ensuring the temperature was correct at the end of the week.

To allow for flexible tweaking, the scheduler implemented a system of ordered schedule items, which could be enabled during any given period of time on one or more days of the week, and system operation quotas defined in terms of an "ideal duty cycle", specified as a minimum and maximum permitted durations over a given period.

Minimum quotas are required to ensure that the system performs complete filtration of the water on a regular basis.

The schedule is defined as an array of schedule items, each consisting

  • Days

    The days of the week are enumerated bit masks which are used in some useful combinations:

    enum eWeekDay
    {
      Sun = 0x02,
      Mon = 0x04,
      Tue = 0x08,
      Wed = 0x10,
      Thu = 0x20,
      Fri = 0x40,
      Sat = 0x80
    };
    
    #define Weekdays  Mon | Tue | Wed | Thu | Fri
    #define Weekend   Sun | Sat
    #define AllWeek   Weekdays | Weekend
  • Start & End

    Times between which the schedule item is in effect on the specified days, specified as the number of seconds since midnight. Schedule items are defined within a 24hr period, and so Start must be less than End.

  • Period

    Defines the duration within which duty cycle quotas must be met.

  • MinDuty & MaxDuty

    The minimum and maximum durations of pump and/or heating operation for each Period.

About

An arduino hot tub controller.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published