Problems with Serial.begin()

I’ve been developing an end product using the Artemis module and I’ve had LOTS of problems (I actually think I made a mistake by choosing Artemis). This one has to do with the Serial.begin() blocking the sketch execution when the USB is not plugged. My design is based on the RedBoard Nano but I used a different USB-Serial converter (an FTDI FT230 instead of the CH340) which is bus powered. Mi device, however, is ment to work on batteries and use de USB to download sketches (of course) but to configure my device and download some data captured. So I need the “Serial” object and its methods to interface with the PC. The thing is that, when the USB cable is not connected, the FT230 is not powered and RX/TX pins seem to change to tristate and that also seems to be detected by the Apollo3 so that when the “Serial.begin()” is executed, the sketch gets blocked. Sounds strange but I test it thoroughly. This is the simplest (and most convincing) test sketch I’ve used.

void setup() {
  pinMode(D41, OUTPUT);             // D41 is a pin I can measure on my custom board
}
void loop() {
  for(int i=0;i<10;i++) {
    digitalWrite(D41, HIGH); 
    delay(1000); 
    digitalWrite(D41, LOW);
    delay(1000);
  }
  Serial.begin(9600);
}

It’s just a slightly modified Blink example. When powered by a battery (FTDI chip unpowered) the pin D41 toggles 10 times and then it stops.

I haven’t been able to have a peek at the Serial.begin method (because I don’t really know where to find it) and the Apollo3 manual doesn’t say much about a related behavior for the UART module. I expect some may suggest a hardware design change but I think the Serial.begin() method shouldn’t block the code execution. It should, instead, return an error code and proceed. IMHO, anyway.

The problem is not reproducible on the Redboards most likely because the CH340 is always powered.

Any ideas will be highly appreciated.

Edit: I just realized I didn’t mentioned I’m using Arduino IDE 1.8.13 and Apollo3 boards definition version 2.0.2 (latest).

Hi, fellow Artemis developer here. Calling Serial.begin multiple times without a Serial.end in between is probably what’s tripping you up.

You might also try rolling back the Apollo3 core to the latest 1.x.x (although this doesn’t have bluetooth support for Arduino). The 2.x.x has been pretty undercooked and unstable, although I haven’t checked it in a while. I don’t use it yet.

Finally, see what happens when you remove your FTDI chip.

Hi @stephenf, thenks for your reply.

Your certanly right about a single Serial.begin at the middle of a loop() but as I stated this just a test code and by counting the blinks I can certainly know the execution is stopped as soon as it reaches that Serial.begin the first time. However, to leave out that bit of unorthodoxy I rewrote my blink code to this:

void setup() {
  pinMode(D41, OUTPUT);                               // Again, D41 is a pin I have access to in my board.
  for(int i=0;i<10;i++) {
    digitalWrite(D41, HIGH);
    delay(1000);
    digitalWrite(D41, LOW);
    delay(1000);
  }
  Serial.begin(9600);
}

void loop() {
  digitalWrite(D41, HIGH);
  delay(1000);
  digitalWrite(D41, LOW);
  delay(1000);
}

The behavior is exactly the same. It blinks 10 times and then it stops. It never reaches the main loop. I’ve seen this behavior with many versions of test codes I’ve came up with and the conclusion is always the same, the code hangs on the Serial.begin() and it’s not because I’m calling it more than once.

Moving back to 1.x.x is unfortunately not an option now because my device is using Bluetooth (that’s the reason I’ve chosen the Artemis in the first place) and when I have tried, then the bootloader doesn’t work any more. But apart from it everything seamed to work smoother on 1.2.1 (I’m also using multiple I2C ports, which worked well on 1.2.1 and 2.0.1 but not in 2.0.2, but that seems to be an mbed problem).

“Removing” the FTDI is also not an option either (that’s my bootloader!) but I managed to make a little “trick” on my board to keep the FTDI powered without the USB plugged in and then it works. That just confirms that it is not a bug in my code but the interaction between the Apollo3 and the FTDI through the Arduino core.

Again, for me it doesn’t make much sense to have a begin method that hangs the execution of the code when there is a problem with the hardware it is trying to interface with. I believe it’s not too absurd to think a begin method should return an error code instead of crashing!. That’s how many of the third party libraries work (BLE, LoRa…) but doesn’t seem to be the case with these standard libraries like Serial, Wire or SPI (although I haven’t had this kind of crash behavior on Wire or SPI).

By the way, Is there any alternative for the standard Serial library?

Thanks again.

I can confirm that with 1.2.1 Core version in Arduino IDE and nothing attached to the TX/RX pins (ie. my FTDI chip/s removed during board assembly troubleshooting/testing), my code still skips past a Serial.begin() and runs fine. Run your test code with Core 1.2.1 and if you are still gettings hangs, that indicates the problem is outside the core - ie. your hardware. If it runs (as mine does), that indicates a problem with v2.x.x Core.

I don’t really understand what you’re doing with an offboard bootloader, but it sounds like a source of complexity/customisation and thus a red flag for causing an error. The Artemis module will bootload and run itself in stock configuration so put a stock one on and remove all connections to the FTDI chip, or the chip itself. Or take the FTDI chip off a demo board.

I actually had a vague memory of trying to depower a USB-FTDI chip and having problems with it possibly similar to what you are experiencing. I ended up just leaving it powered, because the power draw was less than the leakage current of a MOSFET to turn it off! Partly why my instinct is still saying you have an “unknown unknown” hardware error. I could be wrong, but until you remove everything from the TX/RX/DTR lines and test, that can’t be written off.

Yeah obviously the onboard error handling should be better (make a fix in the core and a pull request?!). The joys of jumping on board a “new” development.

Hi stephenf. Once again thanks for taking the time to offer some possible solutions.

In the first post of this thread I already explained that I’m developing an end product with the Artemis module. As you may know, the Apollo3 doesn’t have a USB port so one has to add a USB-Serial converter to communicate with it through the UART and bootload the sketeches. That’s why I included an FTDI so, if I remove it as you suggest I won’t be able to bootload. The demo boards use a CH340 converter (I also explained that already), not FTDI chips, which are slightly more complex. The FTDI chips have an internal voltage regulator that can be powered through the USB bus or can be power with an external 3.3V source (self-powered device). Since my device is hybrid the Artemis can still operate even when not plugged to an USB hub or host but, in that case, the FTDI is not power. I really don’t need to test if that condition is causing the problem because I already know it and explained it like that on that first post.

We can argue about whether or not such configuration is correct, but my informed opinion is that a method that initiates a hardware module shouldn’t crash if it detects something “unusual” or “unexpected” on the module. An “unknown”. You have to keep in mind that I’m not trying to initiate the FTDI, the software is crashing when I try to initiate the internal UART of the Apollo3 which doesn’t have a problem AT ALL. Even so, if the method used to initiate it finds something wrong whith the module it should report it, not crash the whole sketch. There are certainly exceptions to this, like if you find an error in your program flash, but in this case I see no reason for a Serial.begin() to crash my program.

a method that initiates a hardware module shouldn’t crash if it detects something “unusual” or “unexpected” on the module. An “unknown”.

No arguments from me! There are a lot of things about the Artemis core and rollout that drive me up the wall. You might consider though whether you want the moral high ground or a working board. You could be waiting a long time for a fix to the core, especially if you haven't debugged your custom hardware.

We appear to be talking at cross-purposes and perhaps being a bit loose with terminology. Let’s just reiterate some basics, apologies if I’m tell you how to suck eggs.

A) In the context of the Artemis module, “bootloader” generally refers to some code which runs on the Apollo3 when it first powers up. There are actually 2 levels of bootloader code on the Artemis - search for “Ambiq Secure Bootloader” and “Sparkfun Variable Bootloader”.

B) In the vanilla configuration, FTDI/USB interface/CH340 chips allow PROGRAMMING of the Artemis module, and a serial monitor, they aren’t used for startup or bootloading. Ie. they aren’t used for normal operation, only for programming and testing.

To reiterate the debugging steps I recommend before going any further:

Try running your test code with Core 1.2.1, that’s a really easy one to tick off.

The simple hardware debugging I would do at this point:

  1. Program your board and watch it flash 10 times then freeze

  2. Unplug it and desolder your USB chip, and maybe anything else connected to the TX/RX/DTR signals

2a. If your USB chip is integral for power, temporily cut the TX/RX/DTR signals to the Artemis instead of removing the chip, or bodge in a different 3.3V supply

  1. Power up the board

  2. See if it flashes 10 times and stops, not at all, or keeps going forever

  3. Unplug, and revert the board to re-enable programming and serial monitoring

(I’ve already done this with Core 1.2.1 and it keeps going forever as it should.)

apologies if I’m tell you how to suck eggs

Funny expression. I’ve never heard it before. And yes, you are telling me how to suck eggs (we have another expression for it but I think is untranslatable).

You’re right about the loose use of terminology. I certainly misused the term “bootload” and “bootloader” when trying to refer to the act and function of programming the board. However, a very important part of the bootloader in the Apollo3, and in the Arduino boards in general, is a piece of code that allows the user to transfer a program to be written in flash through the serial port (the UART0 in this case) so, in fact, the bootloader has a programming function and serves as a programmer. That is actually the main reason why I use the Arduino ecosystem: I don’t need a separate port and device to program the chip. More over, since that goes through a standard serial port is not true that it can’t be used for “normal” operation. You’re probably confusing it with a dedicated programming and debugging port like the J-tag, which the Apollo3 also has.

The fact that I do not agree or do not will to debug the hardware the way you insist in proposing doesn’t mean my board hasn’t been debugged. In fact I have thoroughly debugged my hardware and stated twice here that my hardware configuration is having an issue with the way the Arduino core handles the UART of the Apollo3.

I’m definitely not looking for “moral high ground” but I think I know what you mean by that. However, there’s nothing wrong in aiming at both an ideal long-term solution to the issue, though out of our control, and the more practical one which one can implement now. So I won’t desolder anything on my board (I don’t have the tools to do that without damaging the board or the components) but I will try to test with core 1.x.x (if I somehow manage to get rid of the bootloader error that comes up when ever I try to roll back to 1.x.x).

I’m pretty sure I will end up changing my hardware design (and reorder manufacturing) so that it accommodates to the software and not the other way around, as I think it’s supposed to be.

In the meantime I came up with a work around that will blow your mind. If I don’t ever use the Serial.begin method my code never hangs but I still can use the port with Serial.read() or Serial.write() with the default 9600 speed (the Serial.read() doesn’t work though). How is it that if I use Serial.begin my sketch crashes but if I don’t it can still send data through the UART?

I’m sorry to insist but there’s something wrong with that.

Hi Rodri,

Have you tried the solution in this thread?

[viewtopic.php?f=169&t=54315

I had the same problem where the code could not get past Serial.begin() on the Artemis Nano and the above solution worked for me.](https://forum.sparkfun.com/viewtopic.php?f=169&t=54315)