Skip to content

Commit 625c491

Browse files
authored
Merge pull request #1549 from petrows/arduino-vid6608
Analog gauges stepper motor: VID6608 driver (xdrv 92) documentation
2 parents 837e2db + 164dbe8 commit 625c491

File tree

6 files changed

+199
-0
lines changed

6 files changed

+199
-0
lines changed

docs/Supported-Peripherals.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,7 @@ DS3502 | Digital potentiometer| I^2^C
140140
[**VEML7700**](VEML7700) | Ambient light intensity sensor| I^2^C
141141
[**VL53L0x**](VL53Lxx) | Time of flight sensor| I^2^C
142142
[**VL53L1x**](VL53Lxx) | Time of flight sensor| I^2^C
143+
[**VID6608**](vid6608) | Analog gauges stepper motor |
143144
**[VINDRIKTNING](https://blakadder.com/vindriktning-tasmota/)** | IKEA VINDRIKTNING particle concentration sensor | serial
144145
**WindMeter** | Analog cup anemometer
145146
[**Winsen ZH03B**](https://github.com/arendst/Tasmota/pull/19850) | Particle concentration sensor | serial

docs/_media/vid6608/VID6608.pdf

333 KB
Binary file not shown.
1.03 MB
Loading
127 KB
Loading
97.5 KB
Loading

docs/vid6608.md

Lines changed: 198 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,198 @@
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+
![Example hardware](_media/vid6608/hardware-example.jpg)
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+
![Example datasheet](_media/vid6608/operation-configuration.png)
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+
![Example wiring](_media/vid6608/vid6608-example-sketch_bb.png)
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

Comments
 (0)