Teaching Arduino Uno How To Survive Space Radiation
Or at least trying.
TL;DR (the overview)
I adapted an FDIR Fault-Injection Evaluator to an Arduino UNO R3 equivalent board to learn how this software technique works in practice. Using a GPT-based tutorial inspired by the original Delfi-PQ FDIR Evaluator, I developed a Python-controlled, two-board experiment that completed two 100-trial campaigns with 100% fault detection and verified data restoration — according to the criteria used. The biggest learning was how to implement controlled software-based bit-flips to test data integrity and recovery, while establishing communication between 2 microcontrollers.
Bullet Speed Neutrons
Arduino Uno, like any microprocessor or computer chip, could realistically get hit by a bullet-speed neutron coming from the sky, as an effect of space radiation. Or, to better put it: cosmic rays.
Even though a malfunction on your robotic arm project wouldn’t affect humanity, an unresponsive satellite responsible for avionics and communications would.
This is why engineers started to develop radiation resistant computing: strategies to protect electronics from radiation.
And one of the main techniques is fault-injection, which deals with single-event upsets (SEUs) — soft software errors.
It relies on 2 main principles:
1°) Accept that failures will happen;
2°) “Teach” the software how to deal with them.
This article is about how I adapted a real FDIR fault-injection system, built to test the software of a mini satellite (Delfi-PQ) on Texas Instruments MSP432 boards, to an Arduino Uno, so I could learn how we “teach” processors to survive SEUs
The Gandalf of this Journey
Currently, I don’t have all the python abilities to execute this adaptation on my own.
Fortunately, this project was made in a time where AI had developed enough to help me with it.
I used a Chat GPT based tutorial to implement the code and guide me through this learning process, where a real FDIR Evaluator for a Delfi-PQ mini satellite was used as reference.
This original evaluator was designed to test the FDIR software of Delfi-PQ, a small satellite project. It used a Texas Instruments MSP432P401R LaunchPad development board as the primary test controller, a second MSP432 board to trigger resets, and Python software on a computer to coordinate the tests and monitor the results.
My goal was to reproduce the experimental methodology: inject a controlled fault, detect it, recover, and log the outcome automatically — all using Arduino Uno.
In other words, I tried to teach arduino how to survive space radiation.
disclaimers:
- I did not try to reproduce the original spacecraft hardware or its performance, but rather adapted an existing experiment to Arduino Uno-compatible boards. This is because both boards have distinct memory archtectures and computing capacities. [make it less redundant with previous information]
- I did NOT expose the Arduino Uno to radiation. The bit-flips are made by software, and ‘100%’ means it passed the test criteria. It doesn’t mean an Arduino Uno can survive space.
- The “imitation of bit-flips” is deterministic. Meaning X [a limitation if in comparison to the original one]
Toys Needed
- Primary Arduino Uno R3-compatible board (COM3): stores and checks the test data.
- Secondary Arduino Uno R3-compatible board (COM8): controls the primary board’s hardware reset.
- Python and PySerial: communicates with the boards, coordinates the experiment, and records results.
- CSV: stores the trial results.
The Main Characters
The image below is a diagram of the main architecture of this project:
It has 3 main characters:
- The Protagonist: the primary board is where the “magic happens”. Its firmware keeps a 32-byte test buffer in SRAM next to a trusted reference copy. It flips a chosen bit with an XOR operation when told to, reports what’s in memory, and writes the correct value back when asked to recover.
- The Watcher: the python host acts as the test controller. It runs the experiment and supervises everything. By sending commands over serial, it compares the primary’s data against the expected values to detect corruption, triggers the recovery, verifies the fix, and logs every trial to a CSV file.
- The Plan B: the secondary board is the redundacy in case the primary board stops responding. It’s wired to the primary’s RESET pin through a 1 kΩ resistor with a shared ground. On command, it pulls that pin low for about 250 ms, which forces a hardware restart that doesn’t depend on the primary’s own software.
Friendly Reminder: XOR
XOR stands for Exclusive Or. It can only be true (1) if it’s one value or the other, not both at the same time. A simplified way to see it:
When they are different values, the result is true (1)
When we have the same values, the result is false (0)
In code, it’s written with the ^ symbol.
For our case, this logical is extremely useful, as XOR can be used as a rule to mimic the flipping bits caused by SEUs.
A Single Event Upset flips one bit in memory, due to high energetic particle changing its state from true to false, and vice versa. To imitate that, the code picks one bit and XORs it with 1:
Before: 00101010 (42)
//Mask added by the code: 00000001 (the 1 represents the the bit-flip)
//XOR operation result after comparing the
//respective values of the orignal bite with bite of the mask/"bit-flip")
After: 00101011 (43)Only one bit changed, and the number went from 42 to 43, mimicking a stored value quietly changes by a single bit. In the code, it’s represented by:
Disclaimer: the code flips the bit on purpose, using an instruction. A real SEU is caused by a particle hitting the chip. So this imitates what an SEU does, not how it happens.
The Experiment Blueprint
Now we get to the fun part: connecting the main characters to the plot.
Think of this experiment as studying for a quiz, where we insert wrong answers (bit-flips) to see if the evaluator finds and corrects it (the python code)
- The primary board stores 32 numbers (42, 43, 44…) and keeps the same numbers as its answer key.
- Python chooses one byte and one bit, using a fixed formula so the experiment can be repeated.
- The primary flips that bit with XOR, our fake SEU.
- Python asks what’s in the byte and compares it with what it should be. Different means fault detected.
- Python sends the correct number back.
- Python asks again. If it matches, it’s recovered, then the trial goes into the CSV.
- If the primary ever stops answering, Python asks the secondary to restart it.
Repeat this process 100 times and you have the complete set up for this project.
Setting Up the Primary Board
First, you will need to upload the code “FaultInjection-ArduinoUno.ino” on the primary board, available on the repository of this project.
The first part of the code defines the memory area we are going to experiment with (BUFFER_SIZE), the actual test area in SRAM (experimentMemory), the “golden copy” (expectedData), the points where the bits we are manipulating actually are (flipPointer), and the track of which position in the buffer was selected (pointerIndex):
The process of the bit-flip happens here:
Remember the XOR explantion? Here is where we actually use it.
Troubleshooting the Primary Board ✨✨ =)
The original evaluator’s memory addresses don’t fit the Uno, so I used a small bounded buffer on the SRAM instead. This also solves the issue of overwriting the program’s own working memory by accident.
If you forget the ; at the end of a command, the board just waits.
Adding the Brain: Python
On the repository, the python code is named as “run_experiment.py”.
Using PySerial, Python communicates with both Arduino Uno boards through their USB ports. It sends commands, reads their responses, checks what happened, and keeps track of the results.
Get Sofia Berwanger’s stories in your inbox
Join Medium for free to get updates from this writer.
This is why at beggining we define the ports, communication speed, and number of trials:
This way, Python knows which board is responsible for the experiment, which one controls the reset, and how fast they should communicate.
One important detail: Python doesn’t just send commands and assume everything worked. It reads the Arduino’s responses and uses them to decide what happened. For example, after restoring a byte, it asks the board to report its current value and checks whether it matches the expected value.
Then, after completing the 100 trials, it stores the results on a .csv file (also available on the repository).
Troubleshooting the Python Code ✨✨ =)
Here goes some issues that I ran through while implementing it:
- COM port errors: If Python cannot access COM3 or COM8, check that the boards are connected and that the port numbers are correct. They can change when you reconnect a board.
- Serial Monitor is open: Close the Arduino IDE Serial Monitor before running Python. Two programs cannot normally use the same serial port at the same time.
- No response from the board: Check that the correct sketch is uploaded to each Arduino Uno and that both are using the same baud rate (9600)
Setting up Secondary Board + Breadboard
Almost done!
For this last step, upload reset-controller.ino to the secondary Arduino Uno. You can find it in the project repository.
The code is much smaller than the primary board’s. It basically does three things:
- Waits for a command from Python.
- Responds to a ping (
P) to confirm it is connected. - When it receives a reset command (
R), it pulls pin 7 LOW for 250 milliseconds, then sets it HIGH again (Arduino’s RESET pin is active-low: pulling it LOW triggers a restart)
setup() function, showing the serial initialization and RESET pin configuration.loop() function, especially the P and R command handling.Now the infamous question: how to wire both boards?
This was my first doing it, and I was REALLY scared to burn my boards somehow. I checked the wiring a few dozen times before testing their communication.
But, don’t worry fellow reader, it works :) (pls check a few times if you are doing it though)
You only need two connections between the boards:
- Connect pin 7 of the secondary Arduino to the RESET pin of the primary Arduino, using a 1 kΩ resistor in series.
- Connect the GND pins of both Arduinos together. This gives them a common ground reference.
Check if it is like in the image, then you are good to go!
Troubleshooting the Secondary Board ✨✨ =)
- Check the COM ports: Make sure the primary and secondary boards are connected to the expected ports. If you reconnect them, Windows may assign different COM numbers.
- Check the wiring: Make sure pin 7 is connected to the primary RESET pin through the 1 kΩ resistor, and that both boards share GND. A missing ground connection can prevent the reset signal from working correctly.
- Check the sketch: The secondary board must have
reset-controller.inouploaded, and its baud rate must match Python's 9600 baud setting.
Running our Baby
The lights blinking on the RX Led of the primary board (the left one on the video) means that information is being exchanged between the board and the computer. Even though it doesn’t mean that the commands were successfully processed, it does mean that communication was established between the board and the computer.
After everything is set up, the boards are connected, the codes are uploaded and communication is established, run this command on your terminal:
python run_experiment.pyThe screenshot below is what should appear on the terminal after doing this command:
What the terminal displays
- Input: selected byte index and bit position.
- Fault injection: controlled XOR-based bit toggling.
- Selection method: deterministic formulas, not random radiation events or random physical bit-flips.
- Measured outcomes: injected faults, detected faults, restored values, successful verification, and reset behavior.
Sparkling Results
This project was made in 2 steps: the first one testing only the primary board, and the second testing the experiment with both boards.
In both cases, 100% of the faults injected were detected and 100% of them were restored. And, as no lockup testing was realized, we had 0 reset required during trials. (.csv result of both steps available on the repository)
YAY! WE TAUGHT ARDUINO HOW TO SURVIVE SPACE RADIATION!
At least in our dreams.
What those results actually mean is that it had 100% success according with the deterministic extremely controlled experiment setup. They don’t prove that the Arduino Uno can withstand radiation, recover from a lockup, or operate reliably in space.
Additionally, it is important to highlight that the formulas used are deterministic. They choose byte and bit positions according to a predefined pattern; they do not simulate random radiation events.
Yet, this experiment did applied the methodology of a industry-level FDIR Fault Injection Evaluator on Arduino Uno Boards, by generating software-induced bit-flips in the test buffer, detecting them, restoring based on the original values, and verifying if the restoration was successful.
So we can call it a win. =)
Overcoming Limitations
Every experiment has its limitations, and this one is no exception. There are three main things to be improved for future versions:
- Increase the test area on the SRAM memory: gradually increase its size and test more memory locations beyond the 32-byte buffer.
- Heartbeats + Automatic Reset Recovery: primary board periodically sends a signal to the secondary board to confirm that it is still operating. If the heartbeat stops arriving within a predefined time, the secondary board triggers a hardware reset automatically (like the autonomous fault-recovery mechanism in the reference fdir)
- Add sensors: spacecraft store data from multiple sensors (temperature, velocity, etc.). And so should the Arduino Uno, within its capacity. This way would be possible to test fault-recovery with actual data.
Thank You from the Writer ❤
First of all: thank you for coming this far.
I hope you enjoyed reading this article as much as I enjoyed doing it, especially the experiment.
If you are also a teenager or an amateur interested in space sciences, leave this article sure of one thing: you don’t need a space lab or expensive equipment to start exploring space technology. Not even an Arduino.
There are plenty of simulators and tools out there to explore your passions. We just need to figure out how to use them.
If you are an engineer or expert in the field, I appreciate the time you invested in reading a project of someone that is aspiring to be one too.
If you have questions, suggestions, or ideas for what I should test next, I’d love to hear them in the comments!
See you on the next experiment =)
References
Arduino. “Arduino Uno Rev3.” Arduino, https://store.arduino.cc/products/arduino-uno-rev3. Accessed 2 Nov. 2026.
ANSTO Staff. “Predicting the Impact of Space Radiation on Satellite Electrical Systems.” ANSTO, 4 Nov. 2021, https://www.ansto.gov.au/news/predicting-impact-of-space-radiation-on-satellite-electrical-systems.
Gary Explains. “The Power of XOR.” YouTube, 27 Mar. 2018, https://www.youtube.com/watch?v=3Kvv7VEM3uc.
Kolasinski, W. A. “Effects of Space Radiation on Electronic Microcircuits.” NASA Technical Reports Server, 1 May 1989, https://ntrs.nasa.gov/archive/nasa/casi.ntrs.nasa.gov/19890014178.pdf.
maGriffioen. Delfi-PQ_FDIR_Evaluator. GitHub, https://github.com/maGriffioen/Delfi-PQ_FDIR_Evaluator. Accessed 2 Nov. 2026.
Microchip Technology. “ATmega328P.” Microchip Technology, https://www.microchip.com/en-us/product/ATMEGA328P. Accessed 2 Nov. 2026.
NASA Science Editorial Team. “How NASA Prepares Spacecraft for the Harsh Radiation of Space.” NASA Science, 10 June 2019, https://science.nasa.gov/science-research/heliophysics/how-nasa-prepares-spacecraft-for-the-harsh-radiation-of-space/.
NASA. “Single Event Effects Testing.” NASA Small Satellite Reliability Initiative Knowledge Base, 1 Nov. 2021, https://s3vi.ndc.nasa.gov/ssri-kb/topics/40/.
nchronas. FDIR_PQ9. GitHub, https://github.com/nchronas/FDIR_PQ9. Accessed 2 Nov. 2026.
Sberwan. Arduino FDIR Fault Injection. GitHub, https://github.com/Sberwan/arduino-fdir-fault-injection. Accessed 2 Nov. 2026.
“API Reference.” PySerial Documentation, https://www.pyserial.org/docs/api-reference. Accessed 2 Nov. 2026.








