diff --git a/docs/Supported-Peripherals.md b/docs/Supported-Peripherals.md index 6ec42e4092..c22d747f90 100644 --- a/docs/Supported-Peripherals.md +++ b/docs/Supported-Peripherals.md @@ -140,6 +140,7 @@ DS3502 | Digital potentiometer| I^2^C [**VEML7700**](VEML7700) | Ambient light intensity sensor| I^2^C [**VL53L0x**](VL53Lxx) | Time of flight sensor| I^2^C [**VL53L1x**](VL53Lxx) | Time of flight sensor| I^2^C +[**VID6608**](vid6608) | Analog gauges stepper motor | **[VINDRIKTNING](https://blakadder.com/vindriktning-tasmota/)** | IKEA VINDRIKTNING particle concentration sensor | serial **WindMeter** | Analog cup anemometer [**Winsen ZH03B**](https://github.com/arendst/Tasmota/pull/19850) | Particle concentration sensor | serial diff --git a/docs/_media/vid6608/VID6608.pdf b/docs/_media/vid6608/VID6608.pdf new file mode 100644 index 0000000000..ed44fed83b Binary files /dev/null and b/docs/_media/vid6608/VID6608.pdf differ diff --git a/docs/_media/vid6608/hardware-example.jpg b/docs/_media/vid6608/hardware-example.jpg new file mode 100644 index 0000000000..1aa825c9cb Binary files /dev/null and b/docs/_media/vid6608/hardware-example.jpg differ diff --git a/docs/_media/vid6608/operation-configuration.png b/docs/_media/vid6608/operation-configuration.png new file mode 100644 index 0000000000..aa24adec05 Binary files /dev/null and b/docs/_media/vid6608/operation-configuration.png differ diff --git a/docs/_media/vid6608/vid6608-example-sketch_bb.png b/docs/_media/vid6608/vid6608-example-sketch_bb.png new file mode 100644 index 0000000000..508d7c8d65 Binary files /dev/null and b/docs/_media/vid6608/vid6608-example-sketch_bb.png differ diff --git a/docs/vid6608.md b/docs/vid6608.md new file mode 100644 index 0000000000..464be85846 --- /dev/null +++ b/docs/vid6608.md @@ -0,0 +1,198 @@ +# VID6608 Automotive gauge driver + +??? failure "This feature is not included in precompiled binaries" + + When [compiling your build](Compile-your-build) add the following to `user_config_override.h`: + ```arduino + #ifndef USE_VID6608 + #//#define USE_VID6608 // Add support for VID6608 Automotive analog gauge driver (+0k7 code) + #endif + ``` + +This driver implements support for following driver chips for analog automotive gauges (Switec X25.168, X27.168 and clones) with microstepping support: + +* VID6606 (2 motors) +* VID6608 (4 motors) +* VT6608S +* AX1201728SG +* BY8920 +* many others + +Driver chips with microstepping are the recommended way to drive such motors. They provide much more reliable and smooth movement with reduced noise and help avoid skipped steps. + +Driver is configured to perform 320° rotation angle with 12 steps per degree. Total capacity is 3840 steps for whole scale. Driver supports up to 4 motors. + +![Example hardware](_media/vid6608/hardware-example.jpg) + +## Features + +Driver provides following features: + +* Smooth movement with analog gauge emulation; +* Built-in homing routine; +* Advanced homing routine; + +## Configuration + +The IC driver requires only 2 pins to drive a single motor, similar to other stepper drivers: one is for step and one for direction. Configuration example from the datasheet: + +![Example datasheet](_media/vid6608/operation-configuration.png) + +See full description and recommendations: [VID6608 Datasheet (EN)](_media/vid6608/VID6608.pdf). + +Configuration options: + +* `USE_VID6608` - Enables driver globally, default is not enabled; +* `VID6608_RESET_ON_INIT` - Enables default homing operation at startup, default is `true`; + +### Wiring + +| VID6608 | ESP | +|---------|-------| +| VCC | 5V | +| GND | GND | +| f(scx) | GPIOx | +| CW | GPIOy | + +Pin `CW` used to select movement direction, `f(scx)` used to drive motor with steps. + +Example wiring: + +![Example wiring](_media/vid6608/vid6608-example-sketch_bb.png) + +### Tasmota Settings + +In the **_Configuration -> Configure Module_** page assign: + +1. GPIOx to `VID6608 F` +2. GPIOy to `VID6608 CW` + +After a reboot the driver should detect motor(s) and: + +* Issue homing operation at startup (if enabled); +* Display "Gauge X" information on web page; + +## ESP8266 notes + +With ESP8266, the driver also works, but gauge movement is _much_ slower (~2 sec per degree). + +## Commands + +Driver defines following commands: + +| Console Commands | Description | Values | +|------------------|--------------------------------------------------|-------------| +| `GaugeSet` | Set position in absolute steps | `0` - `3840`| +| `GaugeSetPercent`| Set position in percent | `0` - `100` | +| `GaugeZero` | Reset drive; optional argument is saved position | `0` - `3840`| + +All commands have Drive suffix. If not set, it drives first motor. If set, it uses Drive number. +If suffix is `0` - it drives all motors. Examples: + +* `GaugeZero3`: Reset drive number 3 with default reset routine; +* `GaugeZero2 751`: Reset drive number 2 with expected last position as `751`; +* `GaugeSet0 366`: Set all drives absolute position 366; +* `GaugeSetPercent 30`: Set drive number 1 position to 30%; + +### Reset routine + +Driver has no feedback option, so the current position is calculated from commands sent only. To ensure +that current steps sent match the real position, the driver performs a reset routine: the driver makes a **half** cycle forward, +then **full** cycle back. If drive will reach end-stop in this case, it will skip steps. +This method guarantees that drive movement will end up at position 0. You can observe +similar routine in real car dashboard for some models. + +Disadvantage of this method is that the motor has to reach the end-stop and bounce there. You can avoid this +by saving last commanded position in the external memory and use last known position for advanced homing routine. + +The `GaugeZero` command has an optional argument, where you can pass the last saved position. +If this position matches real hardware position, drive will perform full homing without end-stop bounce. +This requires disabling default homing by setting: + +``` c +#define VID6608_RESET_ON_INIT false +``` + +and managing external memory to track all commands and restore it on startup. + +Here is example for save / restore method into FRAM MB85RC04V I²C memory using Berry Script: + +``` ruby +# Connect and prepare i2c FRAM MB85RC04V +var fram_addr = 0x50 +var wire = tasmota.wire_scan(fram_addr) +# Address in FRAM to store last gauge position +var addr_pos = 0x0000 +# Check initialization +if !wire + print("FRAM not found") +end +# Function to write FRAM memory, 2 bytes +def fram_write_u16(addr, data) + if !wire + return 0 + end + # Split address and data into two bytes + var addr_hi = (addr >> 8) & 0x7F + var addr_lo = addr & 0xFF + var data_hi = (data >> 8) + var data_lo = data & 0xFF + # ---------------- WRITE ---------------- + wire._begin_transmission(fram_addr) + wire._write(addr_hi) + wire._write(addr_lo) + wire._write(data_hi) + wire._write(data_lo) + wire._end_transmission(true) +end +# Function to read FRAM memory, 2 bytes +def fram_read_u16(addr) + if !wire + return 0 + end + # Split address and data into two bytes + var addr_hi = (addr >> 8) & 0x7F + var addr_lo = addr & 0xFF + # ---------------- READ ---------------- + wire._begin_transmission(fram_addr) + wire._write(addr_hi) + wire._write(addr_lo) + wire._end_transmission(true) + wire._request_from(fram_addr, 2) + var value_hi = wire._read() + var value_lo = wire._read() + var value = (value_hi << 8) | value_lo + return value +end +# Read last gauge position from FRAM +var last_gauge_pos = fram_read_u16(addr_pos) +if last_gauge_pos + print("FRAM gauge pos read:", last_gauge_pos) +end +# Call Reset option from saved position, and save zero +tasmota.cmd("GaugeZero " + str(last_gauge_pos)) +fram_write_u16(addr_pos, 0) +# Function to update Gauge position on CO2 change +def co2_update(value, trigger) + var drivePos = 180 + ((int(value) - 400) * 2) + if last_gauge_pos != drivePos + tasmota.cmd("GaugeSet " + str(drivePos)) + last_gauge_pos = drivePos + # Save current position into FRAM + fram_write_u16(addr_pos, int(drivePos)) + end +end +# Add rule to monitor CO2 changes +tasmota.add_rule("S8#CarbonDioxide", co2_update) +``` + +This script reads commands from the CO2 sensor, saves them in FRAM, and commands the drive to display them. +On startup, last value is read back from FRAM memory and used as argument for `GaugeZero` to perform +calibrated homing operation. + +Example FRAM memory is fast and has a minimum 10¹² write operations capacity, which allows a minimum of +31 years of non-stop operation with 1 write per second ratio. You can use other methods as well (i.e. +Microchip 74L04: EERAM with flash backup). + +Remember that using on-board Flash directly is not safe, due to limited write count and because external power-loss +detection circuits are required.