I can't upload a specific ino file

Hello! I'm using an Arduino Nano ESP32. I had code flashed to it, I modified the code and tried to reupload, but I think I accidentally unplugged the USB before it was done and now I can't get the new code to flash. I try to flash the code, and it says "upload complete" with no errors, but the old code won't be overwritten. I was able to flash a blank file to the MCU, but when I try to flash my code, now it won't overwrite the blank file.

Any ideas?

Poweroff everything (yes, your laptop, too) try again.

Just tried it, including restarting the laptop. No change :frowning:

You most likely do not flash the device you think you are flashing.

I don't understand your reasoning. I have the computer connected to the MCU through serial, and the device shows up in the COM list on the computer. I am 100% certain that this is the right MCU. This is not the first time I've had this problem, so it's definitely not a fluke here.

You can't break the ESP32 boot process, even when you manage to write the wrong bootloader. What you describe can happen when you upload a binary for a wrong architecture or a corrupt binary over OTA. In that case you may or may not get an error message - depending on your OTA program - and the old binary would not be replaced. As you did not say you upload via OTA the only option is you have 2 units attached and flash the wrong one.

By your logic, since I have only one MCU connected, the only option is the OTA issue. Can you explain that a bit more and how to solve it? I'm uploading via COM using USB and the Arduino IDE.

Again, I am 100% certain that I am not flashing the "wrong device", as I can flash other sketches to the board, just not the one I was uploading when I prematurely disconnected the USB.

parent.ino (8.9 KB)

Here is the script I'm trying to upload. Credentials have been obscured.

I have narrowed the issue down to line 223 (Serial.println(dispenser_controls);). When I remove this line, the code flashes properly. If I replace the line with Serial.println("test");, the code also flashes properly.

After more testing, flashing appears to fail only if the contents of println are a variable. This didn't happen before the premature USB disconnect.

I must admit I can't see any reason for that behaviour, you're just printing a string variable. Try using a "C string" instead of a "String" and see if it works or not:

  // write dispenser motor controls to serial, to be sent to child MCU
  dispenser_controls = V5_value + V6_value + V7_value + V8_value + V9_value;
  //Serial.println(dispenser_controls); // send to serial buffer
  Serial.println(dispenser_controls.c_str()); // send to serial buffer

I think no USB disconnection could damage serial printing, anyway...

Sure, I'm just pointing out a correlation. I'm away from my lab right now but I'll test the cstring soon!

To sum up:

  • You do not use OTA
  • You flash over USB
  • There is only one device attached to the laptop

What output do you get on the serial console when you think the program is not running? IMO you get an exeption 'cause watchdog timer kicked in.

Correct.

I'm not sure what you're asking. If you're asking what I get when I upload the problematic script, the console output is as usual. Last four lines:

Download done.
DFU state(7) = dfuMANIFEST, status(0) = No error condition is present
DFU state(2) = dfuIDLE, status(0) = No error condition is present
Done!

If you're asking what is shown on the console afterward, the answer is: nothing.

No, open the serial console, upload the program, watch what you see on the console.

"nothing" --> make some Serial.println("xxx"); in your code so you see if it at least manages to execute setup()

I see what you mean. What you're referring to is called the "Serial Monitor" in the modern Arduino IDE. What is shown in the serial monitor is whatever is associated with the last correctly uploaded script. So, for any script that doesn't contain Serial.println(variable);, it will show the intended serial outputs. If a script with Serial.println(variable); is attempted to be uploaded, the serial monitor will show the serial output associated with the last successfully uploaded script. This is the indication I'm using to assume that the new script did not upload.

That method does allow for the code to be uploaded, and it functions as intended. Wow! I'll look into c_str more because I've never seem them before. Do you think it's safe to keep the code as-is now?

You need to add a Serial.println("something"); delay(1000); after each line in setup(), so that you know what line goes haywire. I suspect that binky has sideeffects you are unlucky to trigger.

If you want to be sure that your unit working at all you could just upload the blink example.

Your code is safe, but IMO you either have a stack problem due to extensive usage of String (that you do not know of) or Blinky has sideeffects you don't know of. The Serial.println() is just a way to yield to the core OS and reset the watchdog.