Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/Supported-Peripherals.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Binary file added docs/_media/vid6608/VID6608.pdf
Binary file not shown.
Binary file added docs/_media/vid6608/hardware-example.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/_media/vid6608/operation-configuration.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/_media/vid6608/vid6608-example-sketch_bb.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
198 changes: 198 additions & 0 deletions docs/vid6608.md
Original file line number Diff line number Diff line change
@@ -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.