From 0c7e3bdc9b286218ec202e0911855235a84568d1 Mon Sep 17 00:00:00 2001 From: Kevin J Walters Date: Wed, 3 Jan 2024 13:26:25 +0000 Subject: [PATCH 1/3] Constraining servo rotation to 90-180 range. #38 Using defines for servo range and arduino constrain macro to guarantee value is between 90 and 180. Adding clarity to the pause of 10 seconds expressed in ms. --- software/ClawController/ClawController.ino | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/software/ClawController/ClawController.ino b/software/ClawController/ClawController.ino index 93b5e95..1b18d24 100644 --- a/software/ClawController/ClawController.ino +++ b/software/ClawController/ClawController.ino @@ -38,6 +38,8 @@ #define SERVO_PIN 9 #define EMG_MIN 2 #define EMG_MAX 10 +#define SERVO_MIN 90 +#define SERVO_MAX 180 int circular_buffer[BUFFER_SIZE]; int data_index, sum; @@ -54,11 +56,13 @@ void setup() { void loop() { //For initial setup only if(flag==0){ - Serial.println("Servo is now at 180 degree. Place the Servo arm & screw it in place."); + Serial.print("Servo is now at "); + Serial.print(SERVO_MAX); + Serial.println(" degrees. Place the Servo arm & screw it in place."); Serial.println("It is recommended to remove USB while placing servo arm."); - servo.write(180); - delay(10000); + servo.write(SERVO_MAX); + delay(10 * 1000); // 10 second pause flag=1; } @@ -76,9 +80,10 @@ void loop() { if(timer < 0) { timer += 1000000 / SAMPLE_RATE; int sensor_value = analogRead(INPUT_PIN); - int signal = EMGFilter(sensor_value); + int signal = (int)EMGFilter((float)sensor_value); int envelop = getEnvelop(abs(signal)); - int servo_position = map(envelop, EMG_MIN, EMG_MAX, 90, 180); + int servo_position = constrain(map(envelop, EMG_MIN, EMG_MAX, SERVO_MIN, SERVO_MAX), + SERVO_MIN, SERVO_MAX); servo.write(servo_position); Serial.print(signal); Serial.print(","); From 18bd1859c790ab631ff9fa6c6239ed204497e11c Mon Sep 17 00:00:00 2001 From: Kevin J Walters Date: Wed, 3 Jan 2024 13:27:54 +0000 Subject: [PATCH 2/3] Enlarging sum variable to avoid overflow. #38 Arduino UNO 16bit int overflows with a large summation, switching to int32_t --- software/ClawController/ClawController.ino | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/software/ClawController/ClawController.ino b/software/ClawController/ClawController.ino index 1b18d24..361f033 100644 --- a/software/ClawController/ClawController.ino +++ b/software/ClawController/ClawController.ino @@ -25,6 +25,8 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. +#include + #if defined(ESP32) #include #else @@ -42,7 +44,8 @@ #define SERVO_MAX 180 int circular_buffer[BUFFER_SIZE]; -int data_index, sum; +int32_t sum; +int data_index; int flag=0; Servo servo; From 4845c5910aab8ec27649d13bb801ece7e01dfb4f Mon Sep 17 00:00:00 2001 From: Kevin J Walters Date: Fri, 12 Jan 2024 18:28:48 +0000 Subject: [PATCH 3/3] Improving resolution of servo control. Changing getEnvelop to return a float and using a locally defined mapf to avoid the coarse conversion which happens with int values of 2 to 10. #38 --- software/ClawController/ClawController.ino | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/software/ClawController/ClawController.ino b/software/ClawController/ClawController.ino index 361f033..a158fcf 100644 --- a/software/ClawController/ClawController.ino +++ b/software/ClawController/ClawController.ino @@ -26,6 +26,7 @@ // SOFTWARE. #include +#include #if defined(ESP32) #include @@ -49,6 +50,10 @@ int data_index; int flag=0; Servo servo; +inline float mapf(float x, float in_min, float in_max, float out_min, float out_max) { + return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min; +} + void setup() { // Serial connection begin Serial.begin(BAUD_RATE); @@ -84,8 +89,10 @@ void loop() { timer += 1000000 / SAMPLE_RATE; int sensor_value = analogRead(INPUT_PIN); int signal = (int)EMGFilter((float)sensor_value); - int envelop = getEnvelop(abs(signal)); - int servo_position = constrain(map(envelop, EMG_MIN, EMG_MAX, SERVO_MIN, SERVO_MAX), + float envelop = getEnvelop(abs(signal)); + int servo_position = constrain((int)roundf(mapf(envelop, + EMG_MIN, EMG_MAX, + SERVO_MIN, SERVO_MAX)), SERVO_MIN, SERVO_MAX); servo.write(servo_position); Serial.print(signal); @@ -95,12 +102,12 @@ void loop() { } // Envelop detection algorithm -int getEnvelop(int abs_emg){ +float getEnvelop(int abs_emg){ sum -= circular_buffer[data_index]; sum += abs_emg; circular_buffer[data_index] = abs_emg; data_index = (data_index + 1) % BUFFER_SIZE; - return (sum/BUFFER_SIZE) * 2; + return (float(sum) / BUFFER_SIZE) * 2.0f; } // Band-Pass Butterworth IIR digital filter, generated using filter_gen.py.