Servo Pad icon Servo Pad Drag mouse or finger as a virtual joystick to control pan/tilt x- and y-axis servos with configurable ports, limits, inversion, and backgrounds. Try it →
Asked

Gripper Servo JS Conversion

,

This is a Script Skill question - could you help convert some EZ-Script I used previously into a JavaScript (ARC Script) version?

Context: This is for a two-arm robot. Each arm uses an older VEX-style claw gripper driven by a servo. I have a small sharp IR detector near each gripper servo to start closing when an object is detected. That IR-based behavior already works. All sensors and servos are connected to an EZB (so ADC readings and servos are handled by the EZB).

Below are the EZ-Script routines I used in the past. I’d like a JavaScript equivalent for use in the ARC Script Robot Skill. The script names are included so you can match the functionality.

EZ-Script for opening/closing both grippers: "Open Grippers" Servo(V25,180) Servo(V9,180)

"Close Grippers" Servo(V25,1) Servo(V9,1)

Gripper IR detector scripts: Grip_detectL (the script name) :claw ADC_Wait(Adc2,lower, 35) servo(V25,30) #Return goto(claw)

Grip_detectR (the script name) :claw ADC_Wait(Adc1,lower, 35) servo(V9,30) #Return goto(claw)

New requirement (added hardware): For each gripper I added a small lever switch that should immediately stop the gripper servo when it contacts the object. This is the EZ-Script I started for the lever-switch stop (I think I’m missing a servo stop somewhere):

Gripper_Object_stop (the script name) :LeverSw #Object detect lever switches (2) $a=GetADC(ADC6) #Right hand lever switch if($a=0) SayEZB("Object now gripped") stop() endif $a=GetADC(ADC7) #Left hand lever switch if($a=0) SayEZB("Object now gripped") stop() endif goto(LeverSw)

Could you look at making a JavaScript version of all of this for use in the ARC Script robot skill (JavaScript)?



Related Hardware (view all EZB hardware)
EZ-B V4 by EZ-Robot
EZ-B v4/2 robot controller: dual Cortex ARM, Wi-Fi, audio/video, 24 servo/digital ports, I2C/UART, camera and Synthiam ARC control for custom robots
Wi-Fi / USB
Servos 24
Camera
Audio
UART 3
I2C
ADC 8
Digital 24

Related Robot Skill (view all robot skills)
Script by Synthiam
Multi-language ARC Script: build, run and debug Blockly, JavaScript, EZ-Script or Python with Intellisense, run/save/load and Roboscratch support

ARC Pro

Upgrade to ARC Pro

With ARC Pro, your robot is not just a machine; it's your creative partner in the journey of technological exploration.

Author Avatar
PRO
Canada
Twitter YouTube GitHub
#9  

Perfect - that confirms your lever switches are active-low, so 0 means pressed and 255 means idle. The only issue earlier was that the script was reading 0 immediately because the input check was too sensitive and both switches were already being interpreted as pressed at startup.

What to change

You want the gripper to:

  1. start closing when the IR sensor detects an object
  2. slow the servo down
  3. stop when the lever switch reads 0
  4. keep holding the object

So the key change is in the stop condition:

  • use ADC.get(ADC6) == 0 and ADC.get(ADC7) == 0
  • but only check after the servo has started closing
  • and ideally only stop that specific gripper, not both at once

Cleaned-up JavaScript version

Try this version:

var rightGripperServo = v9;
var leftGripperServo = v25;

var rightIr = ADC1;
var leftIr = ADC2;

var rightLever = ADC6;
var leftLever = ADC7;

var closeSpeed = 10; // 0 = fastest, 10 = slowest

function closeRightGripperOnIR() {
  while (true) {
    ADC.waitForLower(rightIr, 35);

    print("Right IR detected object. Closing gripper...");
    Servo.setSpeed(rightGripperServo, closeSpeed);
    Servo.setPosition(rightGripperServo, 1);

    while (ADC.get(rightLever) != 0) {
      sleep(20);
    }

    print("Right object now gripped");
    // Keep holding - do NOT release servo
    Servo.setSpeed(rightGripperServo, 0);
  }
}

function closeLeftGripperOnIR() {
  while (true) {
    ADC.waitForLower(leftIr, 35);

    print("Left IR detected object. Closing gripper...");
    Servo.setSpeed(leftGripperServo, closeSpeed);
    Servo.setPosition(leftGripperServo, 1);

    while (ADC.get(leftLever) != 0) {
      sleep(20);
    }

    print("Left object now gripped");
    // Keep holding - do NOT release servo
    Servo.setSpeed(leftGripperServo, 0);
  }
}

Important: you still need to call one of the functions

If you want both grippers monitored, you can start one script per arm, or combine them into one loop. For example, to run the right arm:

closeRightGripperOnIR();

Or left arm:

closeLeftGripperOnIR();

Better combined version

If you want both arms monitored in one script, use this:

var rightGripperServo = v9;
var leftGripperServo = v25;

var rightIr = ADC1;
var leftIr = ADC2;

var rightLever = ADC6;
var leftLever = ADC7;

var closeSpeed = 10;

while (true) {
  if (ADC.get(rightIr) < 35) {
    print("Right IR detected object. Closing...");
    Servo.setSpeed(rightGripperServo, closeSpeed);
    Servo.setPosition(rightGripperServo, 1);

    while (ADC.get(rightLever) != 0) {
      sleep(20);
    }

    print("Right object now gripped");
    Servo.setSpeed(rightGripperServo, 0);
  }

  if (ADC.get(leftIr) < 35) {
    print("Left IR detected object. Closing...");
    Servo.setSpeed(leftGripperServo, closeSpeed);
    Servo.setPosition(leftGripperServo, 1);

    while (ADC.get(leftLever) != 0) {
      sleep(20);
    }

    print("Left object now gripped");
    Servo.setSpeed(leftGripperServo, 0);
  }

  sleep(20);
}

A small caution

Because your lever reads 255 idle and 0 pressed, this logic is correct:

while (ADC.get(rightLever) != 0)

That means "keep waiting until it becomes pressed."


Why I removed the earlier rightStopped logic

That version was more complicated than needed for your use case. Since each gripper has its own IR sensor and its own lever stop, it’s cleaner to handle each arm independently.


One more recommendation

For "half speed," Servo.setSpeed(..., 10) is actually the slowest setting, not half speed. If you want something moderate, try:

  • 3 for faster
  • 5 for medium
  • 7 for slower
  • 10 for slowest

So I’d suggest starting with:

var closeSpeed = 5;

and adjust from there.


If you want, I can now give you:

  1. a final polished single script for both arms, or
  2. two separate scripts, one for the right gripper and one for the left gripper

Either way, I can format it exactly for ARC Script Robot Skill.


I am a customer support GPT-powered AI and still learning. If you have doubts about my response, please use the support documentation to verify my answer.
#10  

ok. I tried your revised script. But it again shows "Done" once I click start. Did I miss something again?

Below is how I "verbally" call the gripper commands and the scripts....

"grippers open" 
// Open Both Grippers
Servo.setPosition(v25, 180)
Servo.setPosition(v9, 180)

"close grippers"
// Close Both Grippers
Servo.setPosition(v25, 1)
Servo.setPosition(v9, 1)

"open left hand"
Servo.setPosition(v25, 180)
//Opens Left Gripper only

"open right hand"
//Opens right Gripper only
Servo.setPosition(v9, 180)

To note, my gripper closing speed is set to 10 because I want the slowest speed for now

Author Avatar
PRO
Canada
Twitter YouTube GitHub
#11  

Yes - you’re missing one important ARC JavaScript detail:

Start runs top-to-bottom once

If your script only contains lines like:

Servo.setPosition(v25, 180)
Servo.setPosition(v9, 180)

then ARC runs them immediately and exits, so it shows Done. That’s normal.

If you want the Script skill to keep running and listen for IR/lever events, the script must contain a loop or call a function that loops.


Also: those quoted lines are not JavaScript commands

This part:

"grippers open"
"close grippers"

is just a string literal in JavaScript, not a command. So it does nothing except exist as text.

If you want "verbally called" commands, the usual ARC way is:

  • put each action in its own script
  • or use controlCommand() to trigger another skill script by name

Correct pattern for your gripper scripts

Open both grippers

Servo.setSpeed(v25, 10)
Servo.setSpeed(v9, 10)
Servo.setPosition(v25, 180)
Servo.setPosition(v9, 180)

Close both grippers

Servo.setSpeed(v25, 10)
Servo.setSpeed(v9, 10)
Servo.setPosition(v25, 1)
Servo.setPosition(v9, 1)

Open left hand only

Servo.setSpeed(v25, 10)
Servo.setPosition(v25, 180)

Open right hand only

Servo.setSpeed(v9, 10)
Servo.setPosition(v9, 180)

If you want the IR + lever logic to stay active

Use a loop like this:

var rightGripperServo = v9
var leftGripperServo = v25
var rightIr = ADC1
var leftIr = ADC2
var rightLever = ADC6
var leftLever = ADC7
var closeSpeed = 10

while (true) {
  if (ADC.get(rightIr) < 35) {
    print("Right IR detected object. Closing...")
    Servo.setSpeed(rightGripperServo, closeSpeed)
    Servo.setPosition(rightGripperServo, 1)

    while (ADC.get(rightLever) != 0) {
      sleep(20)
    }

    print("Right object now gripped")
  }

  if (ADC.get(leftIr) < 35) {
    print("Left IR detected object. Closing...")
    Servo.setSpeed(leftGripperServo, closeSpeed)
    Servo.setPosition(leftGripperServo, 1)

    while (ADC.get(leftLever) != 0) {
      sleep(20)
    }

    print("Left object now gripped")
  }

  sleep(20)
}

That script will not end immediately because it has a while (true) loop.


Best ARC setup recommendation

I’d suggest making separate scripts for:

  • Open Grippers
  • Close Grippers
  • Grip_detectL
  • Grip_detectR
  • Gripper_Object_stop

Then trigger them by name from another Script skill using controlCommand() if needed.


One more important clarification

Since you said closeSpeed = 10 is the slowest, that’s fine - but it’s important that you set speed before commanding the move:

Servo.setSpeed(v9, 10)
Servo.setPosition(v9, 1)

Quick question

Do you want me to write this as:

  1. one single always-running script that handles both arms, or
  2. five small scripts that match your old EZ-Script structure more closely?

If you want, I can format the exact final ARC JavaScript for whichever layout you prefer.


I am a customer support GPT-powered AI and still learning. If you have doubts about my response, please use the support documentation to verify my answer.
#12  

All my verbal commands for the grippers; "grippers open" , "close grippers", "open left hand", "open Right hand" are located in the Speech Recognition skill of course.

Yes- I would like the separate skills written as you suggested, and as stated... >call the gripper command by voice (from speech rec) gripper starts opening, once open, IR sensor begins to work to find a object in its gripper area, once object detected, slowly close gripper until object contacts lever switch, at this point, gripper servo stops, still holding object, finally, robot simply waits for its next command

Author Avatar
PRO
Canada
Twitter YouTube GitHub
#13  

Sorry, I can't continue helping in this thread. It's grown long enough that my context window will require too much extra processing, which makes follow-ups unreliable and I can start making mistakes.

A couple of options:

  • Start a new thread that picks up where we left off - fresh context, faster responses.
  • Or get unlimited interaction with me through ARC's built-in AI Assistant agent: Synthiam AI Assistant

I am a customer support GPT-powered AI and still learning. If you have doubts about my response, please use the support documentation to verify my answer.