IR Sensor Reading Optimization
Hello @Athena,
I would appreciate your review of the following JavaScript code within the ARC environment. The script is designed to process infrared (IR) sensor readings, which can vary significantly due to sensor noise. My objective is to obtain a reliable result, finalLowIR, that only changes when the last three samples are consistent.
The current algorithm involves collecting three samples from an IR sensor connected via the ADC feature, calculating the lowest value from each set of samples, and then using a moving average to stabilize the reading. The final variable finalLowIR is adjusted to limit variability.
//$IRSAMPLE consists of three sample IR readings.
//lowIR is identified as the lowest of the three $IRSAMPLE readings.
//totLowIR aggregates the sum of three lowIR readings.
//avgLowIR is calculated as ((totLowIR * 1000)/3).
//finalLowIR is rounded and divided by 10000 to manage IR reading variability.
while(true) {
var totLowIR = 0;
var avgLowIR = 0;
for(var count1 = 0; count1 < 3; count1++) { // Loop for 3 samples
var lowIR = 300;
for (var count = 0; count < 3; count++) { // Capture individual samples
setVar("$IRSAMPLE", ADC.get(2)); // Obtain IR sample
if (getVar("$IRSAMPLE") < lowIR) {
lowIR = getVar("$IRSAMPLE");
}
}
totLowIR += lowIR;
}
avgLowIR = ((totLowIR * 1000) / 3);
finalLowIR = Math.round(avgLowIR / 10000);
setVar("$IRADC", finalLowIR); // Store the final reading
sleep(100); // Pause the loop for 100ms
}
Could you provide feedback or suggestions for a more efficient script in this context? Your expertise would be greatly appreciated.
Thank you,
Jack
Related Hardware (view all EZB hardware)
Related Robot Skills (view all robot skills)

Thanks - nice explanation of your intent. Your script works but has a few inefficiencies and some strange math that reduces precision unnecessarily. Below I explain the issues and provide two cleaner, robust JavaScript approaches you can drop into an ARC Script robot skill.
Key notes up front
Option A - Median sampling + 3-sample stability (recommended) Behavior: for each cycle, take several quick ADC samples, compute a robust sample (median). Keep the last 3 robust samples and only update final reading when those 3 are consistent within a small tolerance. This matches your requirement "only changes when the last three samples are consistent."
Why this is good:
Tuning:
Option B - Exponential Moving Average (EMA) + threshold (more responsive) Behavior: smooths the value continuously; update final only when smoothed value changes by a meaningful threshold (debounce).
Why this is good:
Extra tips & links
Questions so I can make this even more specific
If you tell me your port and the acceptable tolerance & update rate, I’ll adapt the code to those exact numbers and give recommended values for sample counts/delays.
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 for your help. I have run Option A and Option B in my IR sensor setup and see too many deviations in the final IR number. I have adjusted the variables in each program to attempt a more satisfactory result without success. I'm not sure the strategy in your Options suit the manner in which I need to parse the IR readings. Let me explain more fully. Below is a reprint from the previous post of my original script
I am using an IR sensor (SHARP GP2Y0A02YK0F) to measure the reflective light from a typical reflector element (such as found on a bicycle). When the IR sensor is pointed directly at the reflector, the reflected light saturates the IR sensor CCD and returns a '0'. The center zone where the reflected light saturates the CCD is quite wide (5 degrees). As the IR sensor is pivoted away from the center of the reflector, less reflected light is received resulting in a higher number that is relational to the distance "off-center". I am positioning the IR sensor off-center about 5 degrees, and this results in a 50 IR reading. In this position, the IR sensor becomes very sensitive to any lateral pivot and the IR reading changes by 10 IR for each 1 degree of pivot. So, if the baseline was 50 IR, a reading of 60 IR would be a 1 deg deviation Right and a reading of 40 IR would be a deviation of 1 deg Left. The manner in which I am measuring the reflected light is sort of like using a spectrometer.
I need fast and accurate IR readings. I have found that IR readings deviate 'HIGH' when noise is present. Typically, a lower IR reading is more accurate. Therefore, my strategy for the above code is as follows: STEP 1. 3 IR samples are taken, and the lowest IR reading is noted as 'lowIR'. STEP 2. 3 'lowIR' samples are totaled and noted as 'totLowIR'. STEP 3. 'totLowIR' is averaged and meant to result in a 'large number' (X 1000) so as to push IR reading variances out to the right of the first decimal. STEP 4. 'finalLowIR' is meant to result in a single digit (round / 10k) effectively "chopping off" the IR reading variances.
This results in a single digit (4...5...6), where 5 is the baseline and 4 equals 1 degree deviation Left and 6 equals 1 degree deviation Right.
The above strategy seems to work well in producing a fast, reliable single digit number relating to a one-degree deviation. My problem is that sometimes the transition from baseline (5) to a 4 or baseline (5) to a 6 produces bounce and, for a while, oscillates 'finalLowIR'.
I wish to incorporate the following: 1. If 'finalLowIR' has not changed from the previous 'finalLowIR', do nothing. 2. if 'finalLowIR changes, check for 3 subsequent and equal 'finalLowIR' before publishing the value to "$IRADC". Could you please modify the code printed above to incorporate the changes I need to make to 'finalLowIR'? Thank you for your help. Jack
Thanks Jack - that extra detail about the SHARP sensor and how a lower reading is more accurate helped a lot. I kept your original algorithm (pick the minimum of 3 quick samples, repeat that 3 times, average) but simplified it, removed inefficient getVar/setVar calls in the sampling loop, and added the exact "publish only after 3 equal finalLowIR" debounce logic you requested.
Drop this into an ARC Script robot skill (JavaScript tab). Notes:
Code:
Tuning suggestions
How to install and run this in ARC
A couple of quick questions so I can refine further
If you want, I’ll post a 12-bit variant and a median-of-3 variant for each mini-set so you can try both quickly.
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. Please refer to the above code snippet of the most recent posted code you provided. I am able to print the results for 'r' and 'low' and 'totLowIR'. I noticed that defining 'finalLowIR' by '/30' seems to unnecessarily cause the rounding up of the first single digit. This seems to unnecessarily create a digit that will have to be rejected. Instead of rounding a two decimal number, I was rounding a three decimal number(X1000) keeping the first digit the same. What do you think about rounding a three decimal number?
Additionally, I am unable to print 'firstVal'. Could you please reevaluate the provided code as to why I am unable to print 'firstVal'?
Thank you, Jack
Thanks Jack - good observations. Two points to address: (A) the math/scaling (round vs truncate), and (B) why firstVal might be undefined / not printing. I’ll explain both and give a clean, working code example you can paste into an ARC Script (JavaScript) skill.
Recommendation: use Math.floor(totLowIR / 30) if you want the single-digit to favor the lower side and avoid upward bounce.
How to verify:
Working example This matches your original min-of-3 / repeat-three-times strategy, uses Math.floor to "chop off" decimals, and prints firstVal reliably. Paste it into the JavaScript tab of a Script skill and Start it.
Notes and tuning
Next steps / Questions
If you paste your exact computeFinalLowIR function (the version you used that fails to print firstVal), I can point to the exact line causing the issue.
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 needed to modify the print statements for printing to take place. Below is an example of the change:
The entire script runs beautifully. Thankyou. I would like for 'first Val' to be published only when stable just as any change in 'finalLowIR' is tested. Can you make this change to the code for me? Thank you. Jack
Great - thanks for the clarification. Below is the updated JavaScript you can paste into an ARC Script robot skill. This version uses your original min-of-3 / 3-mini-set averaging and will NOT publish any $IRADC value until the computed finalLowIR has appeared requiredConsecutive times in a row (so the very first publish follows the same 3-equal-samples rule).
Notes:
Paste into Script JavaScript and Start.
Further suggestions / options
Would you like me to:
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.
Thankyou @Athena. All is working as I had hoped. Once again, you provided a wonderful service. Jack