Asked
— Edited
Hi @Athena,
I am working on repeatedly pulsing a Sharp IR sensor using JavaScript within my ARC project. Here's a snippet of my current script:
var increment = 3;
var irValue = 50;
var lowIR = ADC.get(2);
sleep(10);
// IR THRESHOLD FOR A HIT
if (lowIR <= irValue) {
missCount = 0;
cycleCount++;
kick = false;
if (scanDir == 0) {
negHit = Servo.getPosition(17);
setVar("$actualCourse", (negHit + 1.5));
Servo.SetPosition(17, (negHit + increment));
scanDir = 1;
} else {
posHit = Servo.getPosition(17);
setVar("$actualCourse", (posHit - 1.5));
Servo.SetPosition(17, (posHit - increment));
scanDir = 0;
}
sleep(1);
}
My issue involves the use of the ADC.get(2) command in this script. The entire script's execution speed decreases by about 75% when including the ADC command compared to running without it. Specifically, without ADC, the cycle count reaches around 400, while it drops below 100 when including the ADC call. Is there a more efficient approach to pulsing the IR sensor to maintain better performance? Thanks, Jack.
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 Skills (view all robot skills)
ADC Graph
by Synthiam
Historical ADC graph and numeric readout (0-255) for 0-3.3/5V inputs; configurable board/port, sample interval, color, and pause for ezb controllers.
ADC Value
by Synthiam
Display ADC port voltage and 0-255 linear values (0-3.3/5V); configurable board/port, units, multiplier and sample interval.

Good details - thanks Jack. You’re correct that repeatedly calling ADC.get() inside a tight loop will drastically slow the whole script (and can flood the EZ-B communication channel), especially over Wi-Fi. Below I explain why it’s slow and give three practical, efficient alternatives (with JavaScript examples) you can use right away.
Why ADC.get() slows things down
Options (choose one)
Why this is efficient: ARC handles the periodic reads for you. Your script is not hammering ADC.get() repeatedly and other ARC threads get CPU/EZB time.
Why this is efficient: only the ADC Value skill performs EZB reads. Your script reads a global variable locally - no extra EZB traffic.
Example:
Other considerations / advanced
Next steps I can help with
Useful links
Which option would you like me to implement for you (waitFor*, read the skill variable, or reduce polling with bigger sleep)?
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.
@Athena, For option #1 ( ADC.waitForLower(adcPort, threshold, sampleMs, 0, timeoutMS). Does this ADC call "block" the script from running until timeout or trigger from a "hit"? I require the script to loop as fast as possible to detect deviations from a desired course. Thanks Jack
Short answer: Yes - ADC.waitForLower(...) does block that script’s thread until either the ADC reading meets the condition or the timeout occurs. It does NOT freeze ARC or other robot skills - only that script waits (suspends) efficiently rather than burning CPU or flooding the EZ-B.
Below is what that means for your requirement to "loop as fast as possible," plus two recommended approaches (with copy/paste JavaScript) so you can choose the best trade-off for responsiveness vs communication load.
Option A - Fast, event-driven (use ADC.waitForLower with short sample and short timeout)
Why this helps: the script is not busy-polling with ADC.get(). The EZ-B reads are performed efficiently by ARC’s wait call, and the short timeout gives you periodic wakeups to check or adjust course.
Option B - Fastest loop (single poller + local variable reads)
Why this helps: getVar() is instant and does not generate an EZ-B read. The ADC Value skill is the only thing calling the EZ-B, so communication is consolidated and efficient.
Notes and trade-offs
Quick question so I can give you a ready-to-drop-in script:
If you want, paste the ADC Value skill title / current Interval and I’ll produce exact code referencing that variable and step-by-step kebab-menu settings to configure it. Useful link: ADC Value skill - https://synthiam.com/Support/Skills/Adc/ADC-Value?id=16092
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.
You will have better luck if you explain what you're trying to do. If you do not define a desired outcome, Athena has to guess, just as I would. And I can't quite guess what you're trying to do either. Not because you have incorrect code, just because we only see code and don't know what it's used for. So rather than explain the issue, explain the outcome. (https://synthiam.com/Support/website-features/How-To-Ask-Robot-Building-Questions)
So, looking at your code, it's moving a servo and getting an adc value? But you're doing it as fast as possible (mind you, you have other delays), which has other issues. Such as the servo hasn't finished moving yet and is reading an ADC value. I advise you to explain what you're doing, and that'll make it a lot easier to get help from Athena.
Good points from DJ_Sures - before we optimize code I need a clear statement of the outcome you want so we don’t optimize in the wrong direction.
Quick checklist - please answer these so I can give you a ready-to-drop-in script:
While you answer, here are concrete, tested options and explanations that address DJ_Sures concerns (servo move vs ADC timing) and Jack’s performance issue. Pick one and I’ll adapt it to your exact outcome and timings.
Example (adjust sampleMs/timeoutMS/settle to match your required latency and servo speed):
Why this helps
How to set it up
Script skeleton (replace $MyADCVar with the actual global variable name):
Why this helps
Poller example:
Then other scripts read getVar("$MyADC").
Next steps I can do for you
Useful links / how-tos
Which option do you want me to produce code for? Also answer the quick checklist at top (desired outcome, acceptable latency, WiFi/USB) and I’ll make a final tailored script.
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.
@Athena and @DJ, Thank you for your responses. I very much appreciate your willingness to help. I hope to avail myself of any and all assistance you can provide. I must tell you that comprehending what you are saying sometimes feels like drinking from a firehose. I am a rank amateur in this arena but promise to apply myself diligently to understand and learn.
Objective:
Robot rover navigation across the floor. The rover uses a single distance measuring sensor of the Triangulation method, of which Sharp Corporation GP2Y0A02YK0F is an example. This rover communicates via Wi-Fi to ARC and uses an EZBv4 as the overall controller for the (1) Servo, which pans the distance measuring sensor L + R; (2) Distance measuring sensor operation; (3) Calculations for Actual Course and receiving updates for Desired Course from an Arduino via UART. The Arduino provides motor control via PWM to 4 stepper motors rolling on mecanum wheels. The distance measuring sensor detects and tracks a fixed reflector positioned across the room at floor level. The relative bearing to this reflector becomes the basis for navigation. The Desired Course is calculated within the Arduino based upon distance traveled by counting motor pulses. The EZB measures the Actual Course (servo position) to the reflector. The EZB communicates the Actual Course to the Arduino for comparison with the Desired Course and generates PWM motor control. This rover must use a single distance measuring sensor. The distance measuring sensor accomplishes two tasks (1) navigation; (2) obstacle detection. A more complete description and background can be had by reviewing US11977391B1 Patent by following the link below:
US11977391B1 - Robot navigation with obstacle detection using a distance measuring sensor - Google Patents
The primary task which the distance measuring sensor must accomplish is that of tracking the reflector. At certain distances along the way, it will provide a scan for obstacles. This dual use is what makes its application unique and difficult at the same time.
Strategy for scanning the distance measuring sensor:
Initially, I was using deliberate and careful servo movement with timeouts for ADC IR readings. The best I could accomplish was a minimally acceptable number of data point comparisons (Desired Course / Actual Course) for PWM motor control. I tried various schemes for reflector tracking and have settled upon one that I wish to pursue due to the characteristics of the IR sensor. It is as follows: 1. The IR beam reflected back to the sensor is well defined and its width is several degrees wide. Because of the latency of the IR sensor, when the sensor loses the IR beam reflection, a period of time must pass before it is sensitive to any more reflective light. This characteristic slows the scan unnecessarily. Therefore, the servo scan must remain within the beam of reflected IR light yet be close to the edges so that if the robot course changes a missed IR beam is noted. A quick scan minimizes the sensor latency, and it recovers without delay. 2. Trends are more useful than individual Hits or Misses when it comes to tracking reflective IR light. Trends are most reliable when the number of data points are huge. Think of how quick and responsive a hummingbird is to a slight breeze when feeding near a flower. It's wing flapping rate is huge and arguably inefficient compared to say a butterfly. However, what the hummingbird loses in efficiency, it makes up for in maneuverability.
Therefore, I wish to scan the servo 3 degrees Left + Right as rapidly as possible. I know it seems sloppy, hard on the servo and not likely to result in actual, complete servo movement before the reverse servo command is given. What I do get is rapid movement that allows me to measure the IR reflection within the beam. I believe the option you provided that uses an ADC skill which produces a global variable is the best option with 100/500 millisecond sample rates. I would like to call for this global ADC IR reading at each servo movement to the Left and Right. I recognize that the actual IR reading is simply happening at millisecond intervals and not at the actual servo Left and Right positions. What I am seeking is trends and the largest number of data points possible. I wanted to provide you with this information so that you may be considering how best to advise me. I am happy to show you my scripts for review if you wish but be advised some are very long. In any case I look forward to your comments and will be happy to consider your ideas.
Sincerely, Jack Lawrence
Thanks Jack - excellent, detailed description. This makes the problem much clearer and lets us design something practical that meets your "many data points / trend" requirement while respecting the WiFi/EZB limitations.
Below I give a robust, ready-to-run approach with two parts:
I also explain tuning recommendations and trade-offs for WiFi / responsiveness and for the sensor/servo characteristics you described.
Important notes before you run:
How to use:
How this meets your objectives
Tuning suggestions (practical)
Additional practical notes and pitfalls
Next steps I can do for you
Questions for you so I can refine:
If you want, paste any of your current scripts (I can refactor them into this architecture). I’ll adapt the code to exactly match your ports, naming conventions, and timing requirements.
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.
Thank you @Athena! I have included a repost with some minor changes.
Questions: 1. When "adc" prints, is this just the last adc and not representing the sample of 6 reads?
2. I need to identify "actualCourse" as the starting servo of (90). I would like it to be adjusted towards the lower IR sample side when the IR sample exceeds a set difference. This way the servo is always centered for the best "actualCourse". Example, if the difference between L_avg and R_avg exceeds 1.0, move "actualCourse" towards the lower of L_avg or R_avg. Can you please adjust the script to accomplish this? Thank you Jack