Learned the hard way -- don't turn off TX & RX LEDs

I'm new, first time working with any microcontroller and no experience with C or C+ (but do know general programming principles from dabbling in other languages). I'm using an Arduino UNO R4 WiFi v. with 0.6.0 firmware.

I created a program to monitor a VL53L1X Laser Distance Sensor Module and turn on the entire LED 8x12 array when the measured distance fell below a threshold. Took me 3 days, one of which was spent finding out that a device connected to the Qwiic port of the Arduino had to use Wire1 as a referent rather than Wire (nearly all of the example sketches I found glossed over that point).

So with the board sitting on my desk next to me and the program working, I found the TX and RX LEDs to be annoying as I tweaked various aspects of my sketch. So I researched and found out that this code would work to turn those LEDs off:

  pinMode(21, OUTPUT);          //Set the TX LED pin as an output; want to turn it off
  pinMode(22, OUTPUT);          //Set the RX LED pin as an output; want to turn it off
  digitalWrite(21, HIGH);       //Now turn the annoying TX LED off
  digitalWrite(22, HIGH);       //Now turn the annoying RX LED off

Side effect: that code disconnects the Arduino board from the USB bus. Took me another couple of hours to figure out the cause of the disconnection (the loaded sketch continued to work, just no comm via USB, so it looked like a hardware problem outside the Arduino), and the solution (fast double-pressing the reset button and reloading a revised sketch without the offending code).

I hate being on the wrong slope of the learning curve.

Hi @john_f_land. Thanks for taking the time to share your findings!

The reason it did that is you used the wrong pin numbers. The TX LED is on pin 22 and the RX LED is on pin 23. So you were off by one.

Pin 21 has a very special function. The UNO R4 WiFi has a distinctive hardware design where the ESP32-S3 module on the board is normally connected to the USB socket, acting as a "bridge" between the computer and the primary Renesas RA4M1 microcontroller. However, the board has switches that can be used to change the electrical connection of the USB socket to instead be connected directly to the RA4M1. That capability is useful for certain use cases such as when you want to use the board to emulate a USB HID device such as a keyboard, mouse, game controller, or MIDI.

So when you set pin 21 HIGH, you changed the switches from their normal position and thus connected the RA4M1directly to the computer. Since the program running on the RA4M1 didn't generate a USB CDC serial port, this resulted in the board no longer producing a port. When you do a double reset, it puts the board into a "boot mode" where the sketch program no longer runs on the RA4M1, that allows the switches to go back into their default position, restoring the connection of the ESP32-S3 to the computer, and thus producing a serial port and allowing uploads.

You can control the LEDs via pins 22 and 23, and doing so won't cause the loss of the port.. However, this is still not a solution for disabling the normal functionality of the LEDs. Maybe it could be used in a case where the sketch program doesn't do any serial communication and more than one LED is needed as an indicator. However, in that case you would be much better off to use LED matrix on the board. So I don't think there is really a valid use case for controlling the RX and TX LEDs from the sketch code.

Thank you for that information! ChatGPT (which suggested that problematic code snippet I used) apparently doesn't know that subtle difference!

As to why I'd like to turn the RX/TX LEDs off, not only are they annoying while I play around with my sketch, but here's my ultimate technical goal: I'd like the board to be as dark as possible until a distance threshold event occurs, at which time a Zigbee light sensor juxtaposed to the LED array (within a black-box enclosure with a transparent window for the LIDAR device) will detect the entire array illuminating and send a signal to my Hubitat hub. This all works currently.

The end purpose is to detect the presence or absence of a car in my garage, with the enclosure installed on my garage ceiling.

I'm doing this kluge as a stop-gap solution while I figure out how to marry my Arduino to an Xbee Zigbee board and then interface that combination with Hubitat. If and when I get that accomplished, the Zigbee light sensor will be removed.

Again, I'm still on the wrong slope of the learning curve...

Using an Xbee with Arduino is relatively easy.
You configure the Xbee using Digi International XCTU configuration tool and the Arduino reads the packet transmitted by the Xbee.
You can build up a network of XBees consisting of routers and end devices.
One XBee acts as Coordinator and that connects to the Arduino.
I've been running a reasonably sized network of XBee devices on energy meters, leak detection, room temperatures and so on.
After well over 10-years running it, would I do it again?
Probably not.
Despite a lot of time spent on checking the network, routes, quality of the signal, optimising the locations, I've come to the conclusion it's just not reliable. Fickle is a good description.
The devices can work in several ways. You can set a time interval and the device will transmit that every few minutes with whatever sensor information is set up.
Sleeping end devices can sleep for very long times on battery power.
One of the useful features is to monitor digital change, say an LED on an electricity meter.
The XBee should transmit that straight away, together with the other sensor data.
Unfortunately, this is where it falls down.
Digital change transmissions are unreliable with a failure rate of 5 to 10 percent.
The timed transmissions are better.
The failures are quite random, but a 100% successful transmission is a rarity.
All this in a small detached house.
I don't know if it's the weather, the overcrowded 2.4-GHz frequency - I use a lot of WiFi stuff like Sonoff - it's a mystery.
Starting again I would be looking at something in the MHz range.
A possibility is to use the MicroPython XBee set up, store data at the device end and transmit that periodically rather than rely on digital change.
Another factor is the less than useful technical support from Digi.
On the whole, it works, but not well enough.

You aren't going to be using the serial output when the project is actually in use, then you can solve the problem by simply avoiding producing any serial output. It is useful to add serial output to your sketch code during development in order to get insight into the running program, but in many cases it is not needed in the finished project.

Here is a system you can use to quickly enable and disable the debug output:

Add this code near the top of your sketch:

#define DEBUG true  // Set to true for debug output, false for no debug output.
#define DEBUG_SERIAL \
  if (DEBUG) Serial

Then use code like this to initialize the serial communication:

DEBUG_SERIAL.begin(9600);

and code like this for debug output:

DEBUG_SERIAL.println("Some debug output");

When the DEBUG macro is set to false:

#define DEBUG false  // Set to true for debug output, false for no debug output.

the program will no longer produce any serial output, and thus the TX LED will not blink. The compiler will optimize the calls using DEBUG_SERIAL out of the code because it knows they will never run. This means the debug output code won't use up any memory and won't slow down the execution of the program.

The RX LED only lights when the board is receiving serial data, so that LED should not be a problem.

I would just put some black tape or sticker over the Led's.

Thank you for the info!

I have questions:

First, I've accessed the Xbee using XCTU and done initial configuration, but I'm still trying to figure out how to logically mate the Xbee with the Arduino (physically, I have a shield to mount the Xbee on the Arduino). Can you point me to any info on how to send Arduino output to the Xbee?

Second, I have a quite robust Zigbee network in place, using a Hubitat as my coordinator and with numerous routers (dedicated or as part of mains-powered switches/dimmers). I'd like to make the LIDAR/Arduino/Xbee device I've built be just an end-device. Do I need a 2nd Arduino/Xbee (or just an Xbee) as an interface between my LIDAR/Arduino/Xbee device and Hubitat?

Third, will I have to create a custom Groovy driver to grab data from the LIDAR/Arduino/Xbee device if I get that on my Zigbee network? (I've already written a couple very simple drivers but I'm still learning Groovy).

And fourth, can the Zigbee info flow be two-way? I'd like to set parameter values (e.g., debug mode, thresholds, time durations, etc.) for the LIDAR/Arduino/Xbee device using a Hubitat driver rather than have to dismount the device from my garage ceiling if I want to change such values.

Thank you!

I thought of that last night, except for the part about the compiler optimization -- that's new to me. I'll try that out today.

Thanks! That was my solution for the always-ON power LED.

Hi there
Just a quick reply.
A good reference is a book by Faludi called something like Wireless sensor networks using XBee.
All you do is connect the XBee Data out to the Arduino Data in, the serial RX and DX pins.
The XBee packet always starts with 7e (hex).
You need to know the length of the packet.
You read each separate part of the packet.
It might be 7e 13 20 0a..........
Each packet follows strict rules and contains the digital and analogue values.
It's going to take some work and I would strongly recommend getting some literature
Also look at Digi's hardware and user manuals.
I don't know anything about your application.
There might be other ways to read the XBee serial data.
As far as I can remember, if you have an XBee Explorer, you can use XCTU to look at eack packet as it comes in without the Arduino.
The useful packets are something like 92, Explicit sample...?
It does work quite well apart from configuration IC digital change.
I too have a robust network, but digital change isn't reliable for whatever reason.
Good luck