Skip to content

Commit 5f08188

Browse files
committed
position and vibration fixes
1 parent daa7a42 commit 5f08188

File tree

6 files changed

+66
-28
lines changed

6 files changed

+66
-28
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,5 @@
44
.vscode/launch.json
55
.vscode/settings.json
66
.vscode/ipch
7+
*.log
78
NOTES.md

CHANGELOG.md

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
# Change log
22

3-
## v0.3
4-
- Reduced the maximum setting for the vibration amplitude from 25 to 20 (position units).
3+
## v0.3 - 02/06/2023
4+
- Fix: Divide by zero crash during vibration calculations.
5+
- `L0` Up Position: mapped range was changed from (-1000 -> 1000) to (-750 -> 750). Based on analysis of Pendant behavior which does not send values higher than 750. Testing values at 1000 causes slamming of the actuator piston to occur against its enclosure.
6+
- `V0` Vibration Amplitude: internal range was changed from (0 -> 20) to (0 -> 25) position units. Its default is now 25, which matches more closely with the NimbleStroker Pendant behavior.
7+
- `V0` Vibration Amplitude: changes will now ease in and out rather than a linear change.
8+
- `A2` Vibration Speed: default was changed from 10hz to 20hz.
59

610
## v0.2 - 02/05/2023
711
- Added new aux axis for controlling vibration speed via tcode

README.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,23 +8,23 @@
88
- `D1` - Identify TCode version: `TCode v0.4`
99
- `D2` - List available axes and user range preferences:
1010
- `L0 0 9999 Up`: **Up/down position** linear motion (default: `5000`)
11-
- Maps to NimbleStroker positions: -1000 to 1000
11+
- Maps to NimbleStroker positions: -750 to 750
1212
- `V0 0 9999 Vibe`: **Vibration intensity** (default: `0`)
1313
- An oscillation is applied to the position when sent to the NimbleStroker.
14-
- Maps to the amplitude of oscillation: 0 to 20 (position units)
14+
- Maps to the amplitude of oscillation: 0 to 25 (position units)
1515
- `A0 0 9999 Air`: **Auxilliary air in/out valve** (default `5000`)
1616
- Value `0000` = air-out valve (looser)
1717
- Value `5000` = stop valve (default)
1818
- Value `9999` = air-in valve (tighter)
1919
- `A1 0 9999 Force`: **Force command** (default `9999`)
2020
- Maps to NimbleStroker force command values: 0 to 1023
2121
- Controls the air pressure force of the actuator(?)
22-
- `A2 0 9999 VibSpeed`: **Vibration speed** (default: `5000`)
23-
- Maps to an oscillation speed for vibration: 0 to 20.0hz (default 10.0hz)
22+
- `A2 0 9999 VibSpeed`: **Vibration speed** (default: `9999`)
23+
- Maps to an oscillation speed for vibration: 0 to 20hz (default 20hz)
2424

2525
Other info:
2626

27-
- Sending live control values to an axis will ease to target over multiple frames rather than jump immediately, if the difference in change is large (> 100 t-code units, or >50 position units). This is intended to protect the user and device. ([Source1](https://github.com/mnh86/NimbleTCodeSerial/blob/6ab66638b2670115e770fdee9d2ec5c7b04f9390/include/TCodeAxis.h#L217-L228), [Source2](https://github.com/mnh86/NimbleTCodeSerial/blob/6ab66638b2670115e770fdee9d2ec5c7b04f9390/src/main.cpp#L104-L111))
27+
- Sending live control values to an axis will ease to target over multiple frames rather than jump immediately when the difference in change is large (> 100 t-code units, or >50 position units). This is intended to protect the user and device. ([Source1](https://github.com/mnh86/NimbleTCodeSerial/blob/6ab66638b2670115e770fdee9d2ec5c7b04f9390/include/TCodeAxis.h#L217-L228), [Source2](https://github.com/mnh86/NimbleTCodeSerial/blob/6ab66638b2670115e770fdee9d2ec5c7b04f9390/src/main.cpp#L104-L111))
2828

2929
## Usage
3030

include/nimbleConModule.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ struct Pendant
104104
struct Pendant pendant; // Declare pendant
105105

106106
// Actuator Variables
107-
#define ACTUATOR_MAX_POS 1000
107+
#define ACTUATOR_MAX_POS 750
108108

109109
struct Actuator
110110
{

platformio.ini

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ monitor_eol = LF
1919
monitor_filters =
2020
default
2121
colorize
22+
time
2223
lib_deps =
2324
madhephaestus/ESP32Encoder@^0.10.1
2425
mickey9801/ButtonFever@^1.0

src/main.cpp

Lines changed: 52 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,11 @@ int16_t targetPos = 0; // position controlled via TCode
1818
int16_t lastFramePos = 0; // positon that was sent to the actuator last loop frame
1919
int16_t frameForce = IDLE_FORCE; // next force to send to the actuator (0 to 1023)
2020

21-
#define VIBRATION_MAX_AMP 20
21+
#define VIBRATION_MAX_AMP 25
2222
#define VIBRATION_MAX_SPEED 20.0 // hz
2323

24-
float vibrationSpeed = 10.0; // hz
25-
uint16_t vibrationAmplitude = 0; // in position units (0 to 10)
24+
float vibrationSpeed = VIBRATION_MAX_SPEED; // hz
25+
uint16_t vibrationAmplitude = 0; // in position units (0 to 25)
2626
int16_t vibrationPos = 0;
2727

2828
#define RUN_MODE_OFF 0
@@ -76,17 +76,22 @@ void setup()
7676

7777
// TCode setup
7878
tcode.init();
79-
tcode.axisRegister("L0", F("Up"));
80-
tcode.axisRegister("V0", F("Vibe"));
81-
tcode.axisRegister("A0", F("Air"));
79+
tcode.axisRegister("L0", F("Up")); // Up stroke position
80+
tcode.axisWrite("L0", 5000); // 5000: midpoint
81+
tcode.axisEasingType("L0", EasingType::EASEINOUT);
82+
83+
tcode.axisRegister("V0", F("Vibe")); // Vibration Amplitude
84+
tcode.axisWrite("V0", 0); // 0: vibration off
85+
tcode.axisEasingType("V0", EasingType::EASEINOUT);
86+
87+
tcode.axisRegister("A0", F("Air")); // Air in/out valve
88+
tcode.axisWrite("A0", 5000); // 0: air out, 5000: stop, 9999: air in
89+
8290
tcode.axisRegister("A1", F("Force"));
91+
tcode.axisWrite("A1", 9999); // 9999: max force
92+
8393
tcode.axisRegister("A2", F("VibeSpeed"));
84-
tcode.axisEasingType("L0", EasingType::EASEINOUT);
85-
tcode.axisWrite("L0", 5000);
86-
tcode.axisWrite("V0", 0);
87-
tcode.axisWrite("A0", 5000);
88-
tcode.axisWrite("A1", 9999);
89-
tcode.axisWrite("A2", 5000);
94+
tcode.axisWrite("A2", 9999); // 9999: max vibration speed
9095

9196
// Button interface
9297
btn.onDoublePress(pressHandler)
@@ -120,10 +125,10 @@ void logTimer()
120125

121126
void ledPulse(short int pos, short int vibPos, bool isOn = true)
122127
{
123-
byte ledScale = map(abs(pos), 1, ACTUATOR_MAX_POS, 1, LED_MAX_DUTY);
128+
byte ledScale = map(abs(pos), 0, ACTUATOR_MAX_POS, 1, LED_MAX_DUTY);
124129
byte ledState1 = 0;
125130
byte ledState2 = 0;
126-
byte vibScale = map(abs(vibPos), 1, VIBRATION_MAX_AMP, 1, LED_MAX_DUTY);
131+
byte vibScale = map(abs(vibPos), 0, VIBRATION_MAX_AMP, 1, LED_MAX_DUTY);
127132
byte vibState1 = 0;
128133
byte vibState2 = 0;
129134

@@ -165,7 +170,7 @@ void updateLEDs()
165170
}
166171

167172
/**
168-
* Up position is mixed with a vibration oscillator wave
173+
* L0 Up position is mixed with a V0/A2 vibration oscillator
169174
*/
170175
void positionHandler()
171176
{
@@ -179,11 +184,20 @@ void positionHandler()
179184
vibrationAmplitude = map(val, 0, 9999, 0, VIBRATION_MAX_AMP);
180185
}
181186

182-
int vibSpeedMillis = 1000 / vibrationSpeed;
183-
int vibModMillis = millis() % vibSpeedMillis;
184-
float tempPos = float(vibModMillis) / vibSpeedMillis;
185-
int vibWaveDeg = tempPos * 360;
186-
vibrationPos = sin(radians(vibWaveDeg)) * vibrationAmplitude;
187+
if (vibrationAmplitude > 0 && vibrationSpeed > 0) {
188+
int vibSpeedMillis = 1000 / vibrationSpeed;
189+
int vibModMillis = millis() % vibSpeedMillis;
190+
float tempPos = float(vibModMillis) / vibSpeedMillis;
191+
int vibWaveDeg = tempPos * 360;
192+
vibrationPos = round(sin(radians(vibWaveDeg)) * vibrationAmplitude);
193+
} else {
194+
vibrationPos = 0;
195+
}
196+
// Serial.printf("A:%5d S:%0.2f P:%5d\n",
197+
// vibrationAmplitude,
198+
// vibrationSpeed,
199+
// vibrationPos
200+
// );
187201

188202
int targetPosTmp = targetPos;
189203
if (targetPos - vibrationAmplitude < -ACTUATOR_MAX_POS) {
@@ -233,6 +247,18 @@ void loop()
233247
airHandler();
234248
forceHandler();
235249

250+
// if (readFromPend())
251+
// { // Read values from pendant. If the function returns true, the values were updated so update the pass-through values.
252+
// // Pass through data from pendant to actuator
253+
// // actuator.positionCommand = pendant.positionCommand; // We control this
254+
// // actuator.forceCommand = pendant.forceCommand; // We control this
255+
256+
// Serial.printf("P P:%4d F:%4d\n",
257+
// pendant.positionCommand,
258+
// pendant.forceCommand
259+
// );
260+
// }
261+
236262
// Send packet of values to the actuator when time is ready
237263
if (checkTimer())
238264
{
@@ -252,6 +278,12 @@ void loop()
252278
// if (actuator.tempLimiting) {
253279
// setRunMode(RUN_MODE_OFF);
254280
// }
281+
282+
// Serial.printf("A P:%4d F:%4d T:%s\n",
283+
// actuator.positionFeedback,
284+
// actuator.forceFeedback,
285+
// actuator.tempLimiting ? "true" : "false"
286+
// );
255287
}
256288

257289
updateLEDs();

0 commit comments

Comments
 (0)