Opening up the Arduino black box


As we worked with PFC V2 it came apparent to me that the Arduino is a black box that can only be seen through the PI. I wanted to look inside the Arduino box as it interfaced with its IO and did its job.

I opened up the Arduino black box by using serial port 1 and a UART to USB device to feed data back to my PC.

I added the following code:

void setup() {
Serial1.begin(115200); //DJL add second serial messagin port
Serial1.println(“SRC start testing”); //let me know program has started

Then I put messages in the arduino to give me the feedback I wanted from the arduino.

I used the following I got from Amazon
KEDSUM® CP2102 Module STC Download Cable USB 2.0 to TTL 6PIN Serial Converter For STC

It is only $7 and works great.

I hope this helps others.


Interesting. I too am interested in accessing and controlling the Arduino independently of the ROS node running on the PI. What is your strategy for the messaging that you are adding? Are you adding the ability to control things over this second serial line? Can the messaging be turned off once things are working and you are ready to let the PI ROS node take over control of the Arduino.


Sorry didn’t see this until now. Mostly this was for testing, allowing to see what the sensors were sending out. I did add the ability to turn off and on various IO like pumps etc. But if you stop the arduino for input and if the PI has not heard from from the Arduino it resets the communication port and that reboots the arduino. I got around this by faking out the PI and if I have halted the arduino I send something to the PI communication port to let it know the Arduino is still alive.


Interesting. I’m doing something similar using a fork of the OpenAg firmware that I modified. My strategy is to halt the ROS nodes on the PI while I’m debugging and then when debugging is done I run the ROS nodes on PI to “go live” as it were. I haven’t seen anything resetting the Arduino. I also added flags to the firmware to turn off the OpenAg functions in the setup() and loop() routines. Some of the modules are programmed to turn off if serial commands aren’t being received and I wanted to disable this behavior so that I can test things in people time (i.e minutes and sometimes hours :frowning: )without having to worry about actuators shutting down automatically.

Do you have code that I could look at?


Here is code I added to test arduino

void setup() {
Serial1.begin(115200); //M28 DJL add second serial messagin port
Serial1.println(“SRC start testing”);

I put this line at beggining of loop to tel what was being sent to PI

Serial1.print("FRM PI I2C: "); //M28
Serial1.println(message); //M28

I put code below in the checkSensorLoop

//m28 begin sensor report
Serial1.println(“Status, Sensor, reading”);
Serial1.print(checkModule(am2315_1, "AM2315 #1 “)); Serial1.print(” am2315 “);
Serial1.print(” "); Serial1.println(am2315_1.get_air_temperature());

Serial1.print(checkModule(mhz16_1, “MHZ16 #1”)); Serial1.print(" mhz16 ");
Serial1.println(mhz16_1.get_air_carbon_dioxide()); //m28

Serial1.print(" water_level_sensor_low “); Serial1.println(water_level_sensor_low_1.get_is_on());
Serial1.print(” water_level_sensor_high "); Serial1.println(water_level_sensor_high_1.get_is_on());

Serial1.print(checkModule(ds18b20_1, “DS18B20 #1”));Serial1.print(" DS18B20 ");

Serial1.print(checkModule(atlas_ph_1, “Atlas pH #1”)); Serial1.print(" Atlas pH ");

Serial1.print(checkModule(atlas_ec_1, “Atlas EC #1”)); Serial1.print(" Atlas EC ");

This section below tells status of output and allows changing output and freeze arduino in place, sends every 5 secnds a fake message to keep PI happy

//m28 begin output report

Serial1.println(“Status, port #, item name”);
Serial1.print(digitalRead(28));Serial1.println(" 28 DoserPump pump_1_nutrient_a_1");
Serial1.print(digitalRead(29));Serial1.println(" 29 DoserPump pump_2_nutrient_b_1");
Serial1.print(digitalRead(30));Serial1.println(" 30 PulseActuator pump_3_ph_up_1");
Serial1.print(digitalRead(31));Serial1.println(" 31 PulseActuator pump_4_ph_down_1");
Serial1.print(digitalRead(32));Serial1.println(" 32 BinaryActuator pump_5_water_1");
Serial1.print(digitalRead(33));Serial1.println(" 33 BinaryActuator chiller_fan_1");
Serial1.print(digitalRead(34));Serial1.println(" 34 BinaryActuator chiller_pump_1");
Serial1.print(digitalRead(35));Serial1.println(" 35 BinaryActuator heater_core_2_1");
Serial1.print(digitalRead(36));Serial1.println(" 36 BinaryActuator air_flush_1");
Serial1.print(digitalRead(37));Serial1.println(" 37 BinaryActuator water_aeration_pump_1");
Serial1.print(digitalRead(38));Serial1.println(" 38 BinaryActuator water_circulation_pump_1");
Serial1.print(digitalRead(39));Serial1.println(" 39 BinaryActuator chamber_fan_1");
Serial1.print(digitalRead(40));Serial1.println(" 40 PwmActuator led_blue_1");
Serial1.print(digitalRead(41));Serial1.println(" 41 wmActuator led_white_1");
Serial1.print(digitalRead(42));Serial1.println(" 42 PwmActuator led_red_1");
Serial1.print(digitalRead(43));Serial1.println(" 43 BinaryActuator heater_core_1_1");
Serial1.println(" ");
Serial1.println(“To set a port press #”);

if (Serial1.available() > 0)
incomingByte =;
while (incomingByte == 35)
Serial1.println(“enter 2 digit port number from above list”);
while (Serial1.available() == 0) {
// read the incoming byte:
incomingByte =;
portm28 = (incomingByte-48)*10; //m28 now have high port number
while (Serial1.available() == 0) {
incomingByte =;
portm28 = (incomingByte-48)+portm28; //m28 now have high port number
Serial1.println(" 1 to turn on port, 0 to turn off port");
while (Serial1.available() == 0) {
incomingByte =;
if (incomingByte == 49)
digitalWrite(portm28,HIGH); //turn on port
digitalWrite(portm28,LOW); //turn off port
Serial1.println("# to do another port or anykey to continue process");
unsigned long timeFake; //time check to knwo when to send fake message
timeFake = millis() -3000 ; //have it reboot within 2 seconds
while (Serial1.available() == 0) {
if (timeFake + 5000 < millis()) //time ot send fake message
Serial.print(‘OK’); //0,55.00,25.70,478,0.00,1,0,0.00,0.21 \n’); //fake line to keep PI happy and not reboot arduino
// Serial.flush(); 0,55.00,25.70,478,0.00,1,0,0.00,0.21
timeFake = millis();

  // read the incoming byte:
  incomingByte =;

Serial1.println(" ");
//m28 end