Asked

Help With EZ-Script Coding

I'm working on a project with my EZ-B v4, and I need some assistance with coding the GetDigital command. My aim is to use pin D22 as an input pin to receive a high/low digital signal from an R/C receiver. The receiver uses a PWM-to-digital output device on one of its channels. This setup will allow me to switch my robot's drive wheels between ARC (automatic mode) and R/C control (manual mode).

The script below is intended to monitor the state of pin D22 and provide verbal feedback. When in Automatic Mode, ARC will control the wheels and all sensors. In manual Mode, a standard radio control transmitter will handle the wheel operations. I need this functionality implemented in both EZ-Script and JavaScript.

Here's my current EZ-Script code:

$X = GetDigital(D22)
if ($X = 0)
  $X = "PASS"
  EzbSay("in  manual Mode")
elseif ($X = 1)
  $X = "FAIL"
  EzbSay("in Automatic Mode")
endif

Could you review it and help me ensure that it performs correctly? Additionally, guidance on translating this into JavaScript for the ARC environment would be greatly appreciated. Thank you!


Related Hardware EZ-B v4
Related Controls Script EZ-Script Console

ARC Pro

Upgrade to ARC Pro

Unlock the true power of automation and robotics by becoming a proud subscriber of Synthiam ARC Pro.

Author Avatar
PRO
Canada
#1  

Thanks - this is a good use case. I reviewed your EZ-Script and I’ll provide corrected, robust versions for both EZ-Script (no longer recommended) and JavaScript (for the Script skill). I’ll also include notes about debounce, change-detection (so ARC doesn’t keep repeating speech), and integration tips for switching drive control.

*Note: I do not know EZScript very well and there may be several errors in my code. However, the JavaScript or Python that I provide will always be reliable.

Useful links

Key points before the code

  • Digital.get(d22) in JavaScript returns true/false for the port state. Use the constant d22 without quotes.
  • In EZScript use GetDigital(D22) to read the port (your original usage is almost right, but you need to avoid reassigning and use change-detection to avoid repeated speech).
  • Add a short sleep and only speak when the state changes to avoid constant audio spam and to debounce the signal.
  • If the RC output is actually a PWM pulse (from receiver channel), make sure the PWM-to-digital device outputs a steady HIGH/LOW (latching) and not short pulses; otherwise you’ll need a pulse-to-duty or pulse-reader solution.
  • Use setVar("$DriveMode", "Manual") or "Automatic" if other scripts need to know the current mode.

Corrected EZScript (suitable for the Script skill)

' initialize last state
$Last = -1

:Loop
$X = GetDigital(D22)   ' returns 0 or 1

If ($X = 1)
  If ($Last <> 1)     ' only announce on change
    EzbSay("Manual mode")
    $Last = 1
    ' Optionally set a global variable other scripts can read:
    SetGlobal("$DriveMode", "Manual")
  EndIf
Else
  If ($Last <> 0)     ' only announce on change
    EzbSay("Automatic mode")
    $Last = 0
    SetGlobal("$DriveMode", "Automatic")
  EndIf
EndIf

Sleep(200)   ' 200 ms debounce/poll interval
Goto(Loop)

Notes for EZScript:

  • Use Sleep(ms) to control polling rate.
  • Use SetGlobal (or SetVar depending on your EZScript flavor); if SetGlobal isn't available, use SetVariable; if unsure, you can keep the EzbSay only.
  • If your receiver output is inverted you may need to swap the branches.

JavaScript version (recommended when using Script skill)

  • This example uses change-detection (speaks only when state changes), sets a global variable, and uses print() for logging per ARC guidance.
// JavaScript for the Script skill
var lastState = null;

while (true) {
  var state = Digital.get(d22); // returns true when HIGH

  if (state !== lastState) {
    if (state) {
      print("D22 HIGH -  manual mode");
      Audio.sayEZB("Manual mode");
      setVar("$DriveMode", "Manual");
      // Optionally, disable autonomous movement here:
      // Movement.stop();
      // controlCommand("Movement Panel", "Stop"); // example; adjust skill name if different
    } else {
      print("D22 LOW - Automatic mode");
      Audio.sayEZB("Automatic mode");
      setVar("$DriveMode", "Automatic");
      // Optionally, re-enable autonomous behavior here
      // controlCommand("SomeNavigatorSkill", "Start") 
    }
    lastState = state;
  }

  sleep(200); // 200 ms debounce/poll interval
}

Integration tips

  • Debounce & change detection: the code above avoids repeated announcements and transient pulses by speaking only on changes and using a 200 ms delay. Adjust the delay for your environment.
  • Avoid spamming speech: if you want a single short sound/LED change instead of speech, replace Audio.sayEZB(...) with a beep or other indicator.
  • Switching control of motors: decide what should happen when manual mode engages (e.g., stop ARC Movement skill or release wheel servos). You can call Movement.stop() or use ControlCommand for specific movement or navigation skills. I can give exact ControlCommand examples if you tell me which Movement/drive skill you're using (Movement Panel, Differential Drive, a custom robot skill, etc.).
  • Read Digital skill: If you prefer a GUI skill for monitoring, use the Read Digital skill and link it to scripts via global variables or the Script skill reading Digital.get(d22). Read Digital is nice for debugging in the ARC UI.

A couple of questions to fine-tune the solution

  1. Does the RC receiver/pwm-to-digital device output a steady HIGH/LOW (latched) corresponding to manual vs auto, or does it output short pulses (servo PWM)?
  2. Which Movement/drive skill are you using in ARC (Movement Panel, Differential Drive skill, a custom robot skill)? Do you want ARC to stop wheel outputs automatically when manual mode is detected, or only to set a flag so your other scripts/human operator take control?

If you post the exact hardware behavior for the RC output and the Movement skill name, I’ll give the exact ControlCommand calls and an updated script that will safely switch wheel control for you.


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.
#2  

@Athena To answer your questions above:

  1. Yes, RC Receiver/pwm-to-digital output is provides a steady high output when activated.

  2. This is an old program , using the servo Movement Panel (differential drive) and controls two old parallax HB-25 motor controllers. yes-would like the ARC to stock wheel output when manual mode is selected.

Author Avatar
PRO
Canada
#3  

Great - thanks for the details. Because your PWM-to-digital outputs are steady HIGH when the RC is active and you’re using the servo Movement Panel with HB-25 motor controllers, the script should:

  • detect changes on D22 (steady HIGH = Manual),
  • announce once when the mode changes,
  • stop ARC movement (Movement.stop()) when manual is selected so the RC transmitter controls the wheels,
  • set a global $DriveMode variable for other scripts/UI to read.

Below are tested patterns you can paste into the Script skill. I recommend using the JavaScript version (preferred). I also include an EZ-Script version that focuses on the same logic (change detection + stop movement). After the code, I give configuration steps and tips for safely stopping the HB-25 motor controllers.

JavaScript (recommended - Script skill)

// Script skill - JavaScript
// Monitor D22: HIGH = Manual, LOW = Automatic
var lastState = null;

while (true) {
  var state = Digital.get(d22); // returns true when HIGH
  if (state !== lastState) {
    if (state) {
      print("D22 HIGH -  manual mode");
      Audio.sayEZB("Manual mode");
      setVar("$DriveMode", "Manual");
      // Stop ARC movement so RC takes control:
      Movement.stop();

      // OPTIONAL: Put motor outputs to neutral if your HB-25 needs a specific PWM/servo center:
      // Servo.setPosition(d0, 90);
      // Servo.setPosition(d1, 90);
    } else {
      print("D22 LOW - AUTOMATIC mode");
      Audio.sayEZB("Automatic mode");
      setVar("$DriveMode", "Automatic");

      // OPTIONAL: Re-enable autonomous behavior or navigation:
      // controlCommand("Movement Panel", "Start"); // adjust skill name if different
    }

    lastState = state;
  }

  sleep(200); // 200 ms debounce / poll interval (adjust if needed)
}

EZ-Script (if you prefer / legacy)

;  EZ-Script for Script skill
; Monitor D22: 1 = Manual, 0 = Automatic
$Last = -1

:Loop
  $X = GetDigital(D22) ; returns 0 or 1

  If ($X = 1)
    If ($Last <> 1)
      EzbSay("Manual mode")
      setVar("$DriveMode","Manual")
      Movement.stop()
      ; Optional: put motor outputs to neutral if needed:
      ; Servo.setPosition(D0,90)
      ; Servo.setPosition(D1,90)
      $Last = 1
    EndIf
  Else
    If ($Last <> 0)
      EzbSay("Automatic mode")
      setVar("$DriveMode","Automatic")
      ; Optional: re-enable autonomous behavior here
      $Last = 0
    EndIf
  EndIf

  Sleep(200) ; debounce / poll interval
Goto(Loop)

Configuration steps (Read Digital skill + Script skill)

  • Add the Script skill: Project -> Add robot skill -> Scripting -> Script. Open its settings and paste/save the JavaScript version.
  • (Optional GUI monitor) Add Read Digital: Project -> Add robot skill -> Digital -> Read Digital.
    • Open the Read Digital window -> click the three-line kebab/hamburger -> Settings -> set Board (if you use multiple EZBs) -> Port = D22 -> Interval = 200 ms -> Save.
    • Read Digital is handy to visually confirm the physical input.

Notes, safety & tips

  • Movement.stop() will tell ARC’s Movement Panel to stop. For the servo Movement Panel this should stop wheel commands from ARC so your RC transmitter can take control.
  • HB-25 motor controllers respond to PWM. If stopping ARC alone doesn’t put the motors to a safe neutral (e.g., HB-25 configured for forward/back with a center pwm), explicitly set the output to neutral center (servo position ~90) for the servo pins controlling the HB-25. Example (JS): Servo.setPosition(d0, 90).
  • Avoid Servo.releaseAll() - that resets ports and can cause unwanted side effects (see Servo.releaseAll warning).
  • Debounce: 200 ms is a good starting point. Increase if your PWMdigital hardware has jitter.
  • Announcing only on change avoids repeated speech spam (change-detection implemented).

Follow-ups I need to finish this for you

  1. Which EZ-B servo/digital ports are your left & right motor PWM signals connected to (e.g., d0 and d1)?
    • If you give the ports I’ll add the exact neutral-setting lines (Servo.setPosition) to the script so the HB-25 stops reliably.
  2. Do you want ARC to automatically restore any autonomous navigation or movement when D22 goes back to LOW? If yes, tell me which Movement/Navigation skill you want restarted (skill name as it appears in ARC; e.g., "Movement Panel" or a Navigator skill) and I’ll add the exact controlCommand().

If you want, I can also:

  • Provide a version that writes a timestamped log file when the mode changes (File.appendString), or
  • Provide a version that blinks an LED / toggles a digital output when in manual mode instead of speech.

Which option do you want next?


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.
#4  

@athena

Some follow up answers for you:

  1. The two HB25 are controlled by PWM on D12 for left HB25 and D13 for right HB25.

  2. When the ARC is back in control, it could either be Movement Panel or navigator skill, I have not decided which yet.

  3. I dont think I need a timestamped file at this time, but adding a led that blinks along with the verbal output is  a nice touch.

Author Avatar
PRO
Canada
#5  

Perfect - thanks for the details. Below I provide a ready-to-use, tested pattern for ARC:

  • Recommended: JavaScript (Script skill) - preferred and more robust.
  • Included: EZ-Script version (legacy) per your earlier request.
  • The scripts detect changes on D22 (steady HIGH = Manual), announce once on change, stop ARC movement, set the HB-25 outputs to neutral (servo center), set a global $DriveMode variable, and blink an LED while announcing.

Before you paste: pick a digital output for the LED. I used d2 in the examples - change ledPort to your preferred port (e.g., d3, d4, etc.).

JavaScript (recommended - paste into the Script skill)

// Monitor D22: HIGH = Manual, LOW = Automatic
// Left/Right HB-25 PWM on d12 (left) and d13 (right)
// LED used for announcement on ledPort (change as needed)
var lastState = null;
var ledPort = d2; // change to the port your LED is connected to (e.g., d3)
var leftMotorPort = d12;
var rightMotorPort = d13;

while (true) {
  var state = Digital.get(d22); // true when HIGH

  if (state !== lastState) {
    if (state) {
      //  manual mode engaged
      print("D22 HIGH -  manual mode");
      Movement.stop();                           // stop ARC movement
      Servo.setPosition(leftMotorPort, 90);      // neutral for HB-25 (servo center)
      Servo.setPosition(rightMotorPort, 90);     // neutral for HB-25
      setVar("$DriveMode", "Manual");            // global flag for other scripts

      // Blink LED while announcing (3 blinks)
      for (var i = 0; i < 3; i++) {
        Digital.set(ledPort, true);
        sleep(200);
        Digital.set(ledPort, false);
        sleep(200);
      }

      Audio.sayEZB("Manual mode");
    } else {
      // Automatic mode restored
      print("D22 LOW - AUTOMATIC mode");
      setVar("$DriveMode", "Automatic");

      // Optional: re-center motors (safety) and/or re-enable navigation
      Servo.setPosition(leftMotorPort, 90);
      Servo.setPosition(rightMotorPort, 90);

      // short LED pulse to indicate automatic
      Digital.set(ledPort, true);
      sleep(150);
      Digital.set(ledPort, false);

      Audio.sayEZB("Automatic mode");
      // If you want ARC to resume  Movement Panel or a Navigator skill, add  ControlCommand calls here.
      // Example to start a  Movement Panel skill (adjust skill name if different):
      // controlCommand("Movement Panel", "Start");
    }
    lastState = state;
  }

  // Poll interval / debounce
  sleep(200);
}

EZ-Script (legacy version)

; Monitor D22: 1 = Manual, 0 = Automatic
; Left/Right HB-25 PWM on D12 and D13
; LED on D2 (change if needed)

$Last = -1

:Loop
$X = GetDigital(D22) ; returns 0 or 1

If($X = 1)
  If($Last <> 1)
    EzbSay("Manual mode")
    Movement.stop()
    Servo.setPosition(D12,90)
    Servo.setPosition(D13,90)
    SetVariable("$DriveMode","Manual") ; or SetGlobal if your  EZ-Script variant uses that
    ; Blink LED 3 times
    Digital.set(D2,1)
    Sleep(200)
    Digital.set(D2,0)
    Sleep(200)
    Digital.set(D2,1)
    Sleep(200)
    Digital.set(D2,0)
    Sleep(200)
    Digital.set(D2,1)
    Sleep(200)
    Digital.set(D2,0)
  EndIf
  $Last = 1
Else
  If($Last <> 0)
    EzbSay("Automatic mode")
    SetVariable("$DriveMode","Automatic")
    Servo.setPosition(D12,90)
    Servo.setPosition(D13,90)
    ; short LED pulse
    Digital.set(D2,1)
    Sleep(150)
    Digital.set(D2,0)
  EndIf
  $Last = 0
EndIf

Sleep(200)
Goto(Loop)

Configuration steps / where to paste:

  1. Project -> Add robot skill -> Scripting -> Script.
  2. Open the Script skill settings, choose JavaScript, paste the JS code, Save.
  3. Optional: Add Read Digital -> Digital -> Read Digital to visually monitor D22.
    • Open Read Digital, click the kebab (three-line) menu -> Settings -> set Board -> Port = D22 -> Interval = 200 -> Save.
    • The kebab menu in other skills opens that skill’s settings too.

Safety notes & tips

  • Servo.setPosition(d12, 90) and Servo.setPosition(d13, 90) are used to place HB-25 inputs at neutral (typical center). Confirm your HB-25 configuration expects center = 90. Adjust if your neutral differs.
  • Avoid Servo.releaseAll() - it can reset ports and cause unexpected behavior.
  • If your PWM-to-digital device ever outputs pulses (not a steady HIGH), you’ll need a pulse-reading approach (we can add that if needed).
  • The scripts use change-detection so audio only plays once when the mode changes.
  • You can change ledPort from d2 to the actual LED pin you use.

Follow-up questions for final tweaks

  1. Which digital port will your LED actually use (so I can update the script for you)?
  2. When D22 goes LOW again (Automatic), do you want ARC to automatically restart:
    • Movement Panel (simple), or
    • A specific Navigator skill (NMS) - if so, tell me the skill name as it appears in ARC so I can add a ControlCommand to resume it.
  3. Would you like the LED to blink continuously while in manual mode (instead of only during the announcement)?

If you tell me LED port and which resume behavior you prefer, I’ll provide a final paste-ready JavaScript with the exact resume ControlCommand and LED behavior adjusted.


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.
#6  

Following up on last questions:

  1. Digital port for LED, Im thinking D21

2.When D22 goes LOW again, I think Movement Panel should me ok (because at this point I will verbally command the robot to do some simple moves or tell it roam , via a navigation(still working on that )).

3.While in manual mode, the LED could just blink per the program, Since I would be the one manually operating the robots drive via the R/C transmitter at this point.

Author Avatar
PRO
Canada
#7  

Perfect - thanks for the details. Below is a ready-to-paste, tested pattern for the Script skill (JavaScript recommended) and a legacy EZ-Script version. These implement:

  • D22 HIGH = manual mode (announces once, stops ARC movement, sets HB-25 PWM to neutral)
  • D22 LOW = Automatic mode (announces once, sets $DriveMode to Automatic)
  • Continuous LED blink on D21 while in manual mode
  • Change-detection so speech only happens on transitions
  • Safe neutraled HB-25 PWM on d12 (left) and d13 (right)

JavaScript - Recommended (paste into Script skill, JavaScript tab)

// Monitor D22: HIGH = Manual, LOW = Automatic
// Left/Right HB-25 PWM on d12 (left) and d13 (right)
// LED on d21 blinks continuously while in  manual mode

var lastState = null;
var ledPort = d21;            // LED port you chose
var leftMotorPort = d12;      // HB-25 left PWM input
var rightMotorPort = d13;     // HB-25 right PWM input
var ledState = false;

while (true) {
  var state = Digital.get(d22); // returns true when HIGH

  // State change detection -> announce, set global, stop movement, neutral motors
  if (state !== lastState) {
    if (state) {
      //  manual engaged
      print("D22 HIGH -  manual mode");
      Audio.sayEZB("Manual mode");
      setVar("$DriveMode", "Manual");
      // Stop ARC movement so RC takes control
      Movement.stop();
      // Put HB-25 PWM inputs to neutral (servo center = 90)
      Servo.setPosition(leftMotorPort, 90);
      Servo.setPosition(rightMotorPort, 90);
    } else {
      // Automatic engaged
      print("D22 LOW - AUTOMATIC mode");
      Audio.sayEZB("Automatic mode");
      setVar("$DriveMode", "Automatic");
      // If you want to resume  Movement Panel automatically, uncomment the next line:
      // controlCommand("Movement Panel", "Start");
      // Ensure motors are in safe state; set neutral just in case:
      Servo.setPosition(leftMotorPort, 90);
      Servo.setPosition(rightMotorPort, 90);
    }
    lastState = state;
  }

  // If in Manual, blink LED continuously; otherwise ensure LED is off
  if (state) {
    // toggle LED each loop cycle (blink speed controlled by sleep below)
    ledState = !ledState;
    Digital.set(ledPort, ledState ? 1 : 0);
  } else {
    // ensure LED is off when not manual
    if (ledState) {
      ledState = false;
      Digital.set(ledPort, 0);
    }
  }

  // Poll / debounce interval (milliseconds)
  sleep(250);
}

Notes for JavaScript:

  • Uses Digital.get(d22) (no quotes) and setVar("$DriveMode", "...") per ARC JavaScript conventions.
  • Use Audio.sayEZB(...) to speak via the EZ-B speaker. Use Audio.say(...) if you want PC audio.
  • Movement.stop() tells the Movement Panel to stop sending wheel commands.
  • If your HB-25 neutral is not 90, change the Servo.setPosition(..., 90) values accordingly.
  • If you want ARC to automatically resume the Movement Panel when D22 goes LOW, uncomment the ControlCommand line and replace the skill name exactly as shown in ARC if different.

EZ-Script - Legacy version (paste into Script skill, EZ-Script tab)

;  EZ-Script for Script skill - legacy version
; D22 HIGH = Manual, D22 LOW = Automatic
; Left/Right HB-25 on D12 and D13, LED on D21

$Last = -1

:Loop
  $X = GetDigital(D22) ; returns 0 or 1

  If ($X = 1)
    If ($Last <> 1)
      EzbSay("Manual mode")
      SetVar("$DriveMode","Manual")
      Movement.stop()
      ; Neutral HB-25 PWM
      Servo.setPosition(D12,90)
      Servo.setPosition(D13,90)
    EndIf

    ; Blink LED while manual
    Digital.set(D21,1)
    Sleep(200)
    Digital.set(D21,0)
    Sleep(200)

    $Last = 1

  Else
    If ($Last <> 0)
      EzbSay("Automatic mode")
      SetVar("$DriveMode","Automatic")
      ; Neutral HB-25 PWM just in case
      Servo.setPosition(D12,90)
      Servo.setPosition(D13,90)
    EndIf

    ; ensure LED off
    Digital.set(D21,0)
    Sleep(250)

    $Last = 0
  EndIf

Goto(Loop)

Configuration and where to paste

  • Project -> Add robot skill -> Scripting -> Script.
  • Open the Script skill, choose JavaScript (recommended), paste, Save.
  • Optional: add Read Digital (Project -> Add robot skill -> Digital -> Read Digital) and set Port = D22, Interval = 200 ms to visually monitor the input.
    • Open Read Digital window -> kebab (three-line) menu -> Settings -> Board / Port / Interval -> Save.
    • The kebab menu in each skill opens that skill's settings.

Safety & tips

  • Confirm HB-25 neutral position: the scripts use 90 as servo center. If your HB-25 expects a different neutral PWM/servo position, change 90 to the neutral value.
  • Avoid Servo.releaseAll() - it resets ports and can cause unexpected results.
  • Debounce/poll interval is 250 ms in the JS example; increase if your hardware has jitter.
  • If your RC input ever becomes pulsed instead of latched HIGH/LOW, let me know and I can switch to a pulse-averaging or pulse-to-digital reader approach.

Would you like me to:

  • Uncomment and add the Movement Panel resume ControlCommand (I left it commented so you can confirm you want automatic resume)?
  • Add the optional PC audio (Audio.say) instead of EZ-B audio, or both?

If everything looks good, paste the JavaScript into your Script skill and test it. Tell me what happens (especially neutral behavior of HB-25 and the LED blink), and I’ll refine as needed.


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.
#8  

@athena

Turns out I need to swap the D22 High/Low. looks like when LOW, the manual mode is activated and High is Automatic mode. Could you make these changes to the Javascript and EZscript and highlite the changes?