|
| 1 | +# VID6608 Automotive gauge driver |
| 2 | + |
| 3 | +??? failure "This feature is not included in precompiled binaries" |
| 4 | + |
| 5 | + When [compiling your build](Compile-your-build) add the following to `user_config_override.h`: |
| 6 | + ```arduino |
| 7 | + #ifndef USE_VID6608 |
| 8 | + #//#define USE_VID6608 // Add support for VID6608 Automotive analog gauge driver (+0k7 code) |
| 9 | + #endif |
| 10 | + ``` |
| 11 | + |
| 12 | +This driver implements support for following driver chips for analog automotive gauges (Switec X25.168, X27.168 and clones) with microstepping support: |
| 13 | + |
| 14 | +* VID6606 (2 motors) |
| 15 | +* VID6608 (4 motors) |
| 16 | +* VT6608S |
| 17 | +* AX1201728SG |
| 18 | +* BY8920 |
| 19 | +* many others |
| 20 | + |
| 21 | +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. |
| 22 | + |
| 23 | +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. |
| 24 | + |
| 25 | + |
| 26 | + |
| 27 | +## Features |
| 28 | + |
| 29 | +Driver provides following features: |
| 30 | + |
| 31 | +* Smooth movement with analog gauge emulation; |
| 32 | +* Built-in homing routine; |
| 33 | +* Advanced homing routine; |
| 34 | + |
| 35 | +## Configuration |
| 36 | + |
| 37 | +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: |
| 38 | + |
| 39 | + |
| 40 | + |
| 41 | +See full description and recommendations: [VID6608 Datasheet (EN)](_media/vid6608/VID6608.pdf). |
| 42 | + |
| 43 | +Configuration options: |
| 44 | + |
| 45 | +* `USE_VID6608` - Enables driver globally, default is not enabled; |
| 46 | +* `VID6608_RESET_ON_INIT` - Enables default homing operation at startup, default is `true`; |
| 47 | + |
| 48 | +### Wiring |
| 49 | + |
| 50 | +| VID6608 | ESP | |
| 51 | +|---------|-------| |
| 52 | +| VCC | 5V | |
| 53 | +| GND | GND | |
| 54 | +| f(scx) | GPIOx | |
| 55 | +| CW | GPIOy | |
| 56 | + |
| 57 | +Pin `CW` used to select movement direction, `f(scx)` used to drive motor with steps. |
| 58 | + |
| 59 | +Example wiring: |
| 60 | + |
| 61 | + |
| 62 | + |
| 63 | +### Tasmota Settings |
| 64 | + |
| 65 | +In the **_Configuration -> Configure Module_** page assign: |
| 66 | + |
| 67 | +1. GPIOx to `VID6608 F` |
| 68 | +2. GPIOy to `VID6608 CW` |
| 69 | + |
| 70 | +After a reboot the driver should detect motor(s) and: |
| 71 | + |
| 72 | +* Issue homing operation at startup (if enabled); |
| 73 | +* Display "Gauge X" information on web page; |
| 74 | + |
| 75 | +## ESP8266 notes |
| 76 | + |
| 77 | +With ESP8266, the driver also works, but gauge movement is _much_ slower (~2 sec per degree). |
| 78 | + |
| 79 | +## Commands |
| 80 | + |
| 81 | +Driver defines following commands: |
| 82 | + |
| 83 | +| Console Commands | Description | Values | |
| 84 | +|------------------|--------------------------------------------------|-------------| |
| 85 | +| `GaugeSet` | Set position in absolute steps | `0` - `3840`| |
| 86 | +| `GaugeSetPercent`| Set position in percent | `0` - `100` | |
| 87 | +| `GaugeZero` | Reset drive; optional argument is saved position | `0` - `3840`| |
| 88 | + |
| 89 | +All commands have Drive suffix. If not set, it drives first motor. If set, it uses Drive number. |
| 90 | +If suffix is `0` - it drives all motors. Examples: |
| 91 | + |
| 92 | +* `GaugeZero3`: Reset drive number 3 with default reset routine; |
| 93 | +* `GaugeZero2 751`: Reset drive number 2 with expected last position as `751`; |
| 94 | +* `GaugeSet0 366`: Set all drives absolute position 366; |
| 95 | +* `GaugeSetPercent 30`: Set drive number 1 position to 30%; |
| 96 | + |
| 97 | +### Reset routine |
| 98 | + |
| 99 | +Driver has no feedback option, so the current position is calculated from commands sent only. To ensure |
| 100 | +that current steps sent match the real position, the driver performs a reset routine: the driver makes a **half** cycle forward, |
| 101 | +then **full** cycle back. If drive will reach end-stop in this case, it will skip steps. |
| 102 | +This method guarantees that drive movement will end up at position 0. You can observe |
| 103 | +similar routine in real car dashboard for some models. |
| 104 | + |
| 105 | +Disadvantage of this method is that the motor has to reach the end-stop and bounce there. You can avoid this |
| 106 | +by saving last commanded position in the external memory and use last known position for advanced homing routine. |
| 107 | + |
| 108 | +The `GaugeZero` command has an optional argument, where you can pass the last saved position. |
| 109 | +If this position matches real hardware position, drive will perform full homing without end-stop bounce. |
| 110 | +This requires disabling default homing by setting: |
| 111 | + |
| 112 | +``` c |
| 113 | +#define VID6608_RESET_ON_INIT false |
| 114 | +``` |
| 115 | +
|
| 116 | +and managing external memory to track all commands and restore it on startup. |
| 117 | +
|
| 118 | +Here is example for save / restore method into FRAM MB85RC04V I²C memory using Berry Script: |
| 119 | +
|
| 120 | +``` ruby |
| 121 | +# Connect and prepare i2c FRAM MB85RC04V |
| 122 | +var fram_addr = 0x50 |
| 123 | +var wire = tasmota.wire_scan(fram_addr) |
| 124 | +# Address in FRAM to store last gauge position |
| 125 | +var addr_pos = 0x0000 |
| 126 | +# Check initialization |
| 127 | +if !wire |
| 128 | + print("FRAM not found") |
| 129 | +end |
| 130 | +# Function to write FRAM memory, 2 bytes |
| 131 | +def fram_write_u16(addr, data) |
| 132 | + if !wire |
| 133 | + return 0 |
| 134 | + end |
| 135 | + # Split address and data into two bytes |
| 136 | + var addr_hi = (addr >> 8) & 0x7F |
| 137 | + var addr_lo = addr & 0xFF |
| 138 | + var data_hi = (data >> 8) |
| 139 | + var data_lo = data & 0xFF |
| 140 | + # ---------------- WRITE ---------------- |
| 141 | + wire._begin_transmission(fram_addr) |
| 142 | + wire._write(addr_hi) |
| 143 | + wire._write(addr_lo) |
| 144 | + wire._write(data_hi) |
| 145 | + wire._write(data_lo) |
| 146 | + wire._end_transmission(true) |
| 147 | +end |
| 148 | +# Function to read FRAM memory, 2 bytes |
| 149 | +def fram_read_u16(addr) |
| 150 | + if !wire |
| 151 | + return 0 |
| 152 | + end |
| 153 | + # Split address and data into two bytes |
| 154 | + var addr_hi = (addr >> 8) & 0x7F |
| 155 | + var addr_lo = addr & 0xFF |
| 156 | + # ---------------- READ ---------------- |
| 157 | + wire._begin_transmission(fram_addr) |
| 158 | + wire._write(addr_hi) |
| 159 | + wire._write(addr_lo) |
| 160 | + wire._end_transmission(true) |
| 161 | + wire._request_from(fram_addr, 2) |
| 162 | + var value_hi = wire._read() |
| 163 | + var value_lo = wire._read() |
| 164 | + var value = (value_hi << 8) | value_lo |
| 165 | + return value |
| 166 | +end |
| 167 | +# Read last gauge position from FRAM |
| 168 | +var last_gauge_pos = fram_read_u16(addr_pos) |
| 169 | +if last_gauge_pos |
| 170 | + print("FRAM gauge pos read:", last_gauge_pos) |
| 171 | +end |
| 172 | +# Call Reset option from saved position, and save zero |
| 173 | +tasmota.cmd("GaugeZero " + str(last_gauge_pos)) |
| 174 | +fram_write_u16(addr_pos, 0) |
| 175 | +# Function to update Gauge position on CO2 change |
| 176 | +def co2_update(value, trigger) |
| 177 | + var drivePos = 180 + ((int(value) - 400) * 2) |
| 178 | + if last_gauge_pos != drivePos |
| 179 | + tasmota.cmd("GaugeSet " + str(drivePos)) |
| 180 | + last_gauge_pos = drivePos |
| 181 | + # Save current position into FRAM |
| 182 | + fram_write_u16(addr_pos, int(drivePos)) |
| 183 | + end |
| 184 | +end |
| 185 | +# Add rule to monitor CO2 changes |
| 186 | +tasmota.add_rule("S8#CarbonDioxide", co2_update) |
| 187 | +``` |
| 188 | + |
| 189 | +This script reads commands from the CO2 sensor, saves them in FRAM, and commands the drive to display them. |
| 190 | +On startup, last value is read back from FRAM memory and used as argument for `GaugeZero` to perform |
| 191 | +calibrated homing operation. |
| 192 | + |
| 193 | +Example FRAM memory is fast and has a minimum 10¹² write operations capacity, which allows a minimum of |
| 194 | +31 years of non-stop operation with 1 write per second ratio. You can use other methods as well (i.e. |
| 195 | +Microchip 74L04: EERAM with flash backup). |
| 196 | + |
| 197 | +Remember that using on-board Flash directly is not safe, due to limited write count and because external power-loss |
| 198 | +detection circuits are required. |
0 commit comments