I have a couple of nano 33 BLE sense boards...
After a couple of initial loads, the "No device found on ttyAMA0"
" An error occurred while uploading the sketch" errors started. Using a Pi4, I switched ports, switch cables, rebooted...nothing fixed that issue. So I got the other board and using the same port, same cable, etc, it worked. The only difference is that when I select the port, the one that works I see "/dev/ttyAMA0(Arduino Nano 33 BLE" and the one that has the error the port is just the "/dev/ttyAMA0"...So my question is...is the one that does not work somehow suddenly gone bad? No static, no power issues etc...is it fixable?
Hi @steinerrw. The tricky thing about the boards with native USB capability like your Nano 33 BLE Sense is the USB code that creates the CDC serial port is running on the same microcontroller as your sketch. This means your sketch code can change the behavior of the USB code in a way that causes problems with the identification of the port and interference with uploads.
This can be unexpected to those who previously mainly worked with the boards like Uno and Mega with a dedicated USB chip that can never be affected by the sketch code.
The situation is really not so bad because there is an independent program called the bootloader in a separate section of memory from your sketch, and that program has its own USB CDC code. So even if the sketch is completely broken, you only need to activate the bootloader to get a port back and be able to upload.
Fortunately, there is an easy way to manually activate the bootloader and recover from this situation:
- Press and release the reset button on your board quickly twice.
The double reset activates the bootloader. It will run until the board is reset normally, powered off, or an upload is done. You should see the LED on the board pulsing to indicate it is in this state. - Select the port of your board from the Tools > Port menu in Arduino IDE.
- Start an upload in Arduino IDE.
The upload should now finish successfully.
If you find that the port and uploading problems persist even after that first upload following the procedure above, the problem may be caused by your sketch code. You can verify this by uploading a simple sketch like the one from File > Examples > 01.Basics > BareMinimum in the Arduino IDE menus. If the uploads work normally after uploading that sketch, but not after uploading the previous sketch you were using, then you will know the issue is caused by that other sketch code.
ptillish;
Thank you for the response. It wasn't a code issue since I could switch one nano to the other and get results BUT the double press to reset worked.
| ptillisch Arduino Team
December 18 |
- | - |
Hi @steinerrw. The tricky thing about the boards with native USB capability like your Nano 33 BLE Sense is the USB code that creates the CDC serial port is running on the same microcontroller as your sketch. This means your sketch code can change the behavior of the USB code in a way that causes problems with the identification of the port and interference with uploads.
This can be unexpected to those who previously mainly worked with the boards like Uno and Mega with a dedicated USB chip that can never be affected by the sketch code.
The situation is really not so bad because there is an independent program called the bootloader in a separate section of memory from your sketch, and that program has its own USB CDC code. So even if the sketch is completely broken, you only need to activate the bootloader to get a port back and be able to upload.
Fortunately, there is an easy way to manually activate the bootloader and recover from this situation:
- Press and release the reset button on your board quickly twice.
The double reset activates the bootloader. It will run until the board is reset normally, powered off, or an upload is done. You should see the LED on the board pulsing to indicate it is in this state. - Select the port of your board from the Tools > Port menu in Arduino IDE.
- Start an upload in Arduino IDE.
The upload should now finish successfully.
If you find that the port and uploading problems persist even after that first upload following the procedure above, the problem may be caused by your sketch code. You can verify this by uploading a simple sketch like the one from File > Examples > 01.Basics > BareMinimum in the Arduino IDE menus. If the uploads work normally after uploading that sketch, but not after uploading the previous sketch you were using, then you will know the issue is caused by that other sketch code.
OK, I have my nano ble working somewhat again thanks to the info provided...
Now I have to double click the restart everytime cause without doing anything the port becomes blank...
When I try loading a small sketch like 'ReadSensors' as provided within examples it runs OK but if I try running this sketch I get the port errors when attempting to open the serial monitor...
I used a sketch that Klaus_K posted on the 'Time library with NANO 33 BLE'...
#include <ArduinoBLE.h>
#include <mbed.h>
#include <Arduino_HTS221.h>
#include <Arduino_LSM9DS1.h>
#include <Arduino_LPS22HB.h>
#include <Arduino_APDS9960.h>
#define BLE_UUID_CURRENT_TIME_SERVICE "1805"
#define BLE_UUID_DATE_TIME "2A08"
float temperature = HTS.readTemperature();
float humidity = HTS.readHumidity();
float x, y, z;
float xA, yA, zA;
float xB, yB, zB, ledvalue;
int plusThreshold = 30, minusThreshold = -30;
//----------------------------------------------------------------------------------------------------------------------
// BLE Date Time
//----------------------------------------------------------------------------------------------------------------------
typedef struct __attribute__( ( packed ) )
{
uint16_t year;
uint8_t month;
uint8_t day;
uint8_t hours;
uint8_t minutes;
uint8_t seconds;
} date_time_t;
union date_time_data
{
struct __attribute__( ( packed ) )
{
date_time_t dateTime;
};
uint8_t bytes[ sizeof( date_time_t ) ];
};
union date_time_data dateTimeData;
//----------------------------------------------------------------------------------------------------------------------
// BLE
//----------------------------------------------------------------------------------------------------------------------
#define BLE_DEVICE_NAME "Arduino Nano 33 BLE"
#define BLE_LOCAL_NAME "Arduino Nano 33 BLE"
BLEService currentTimeService( BLE_UUID_CURRENT_TIME_SERVICE );
BLECharacteristic dateTimeCharacteristic( "2A08", BLERead | BLEWrite | BLENotify, sizeof dateTimeData.bytes );
//----------------------------------------------------------------------------------------------------------------------
// I/O and App
//----------------------------------------------------------------------------------------------------------------------
#define BLE_LED_PIN LED_BUILTIN
bool timeUpdated = false;
void setup() {
Serial.begin(9600);
while (!Serial);
pinMode(BLE_LED_PIN, OUTPUT);
setupTime();
Serial.println("*****************START******************");
if (!HTS.begin()) {
Serial.println("Failed to initialize humidity/temperature/sensor!");
while (1);
}
if (!IMU.begin()) {
Serial.println("Failed to initialize IMU!");
while (1);
}
}
void loop() {
// read all the sensor values
if (IMU.accelerationAvailable()) {
accProc();
}
if (IMU.gyroscopeAvailable()) {
gyroProc();
}
magProc();
// print each of the sensor values
Serial.print("Temperature = "); Serial.print(temperature); Serial.println(" °C");
Serial.print("Humidity = "); Serial.print(humidity); Serial.println(" %");
// print an empty line
Serial.println();
timeTask();
bleTask();
// wait 1 second to print again
delay(1000);
}
void accProc()
{
IMU.readAcceleration(x, y, z);
Serial.print("Accelerometer sample rate = ");
Serial.print(IMU.accelerationSampleRate());
Serial.println(" Hz");
Serial.println();
Serial.println("Acceleration in g's");
Serial.println("X\tY\tZ");
Serial.print(x); Serial.print('\t'); Serial.print(y); Serial.print('\t'); Serial.println(z);
}
void gyroProc()
{
IMU.readGyroscope(xA, yA, zA);
Serial.print("Accelerometer sample rate = ");
Serial.print(IMU.accelerationSampleRate()); Serial.println(" Hz");
Serial.println();
Serial.println("Acceleration in g's");
Serial.println("xA\tyA\tzA");
Serial.print(xA); Serial.print('\t'); Serial.print(yA); Serial.print('\t'); Serial.println(zA);
}
void magProc()
{
IMU.readMagneticField(xB, yB, zB);
if (xB < 0)
{
ledvalue = -(xB);
} else {
ledvalue = xB;
}
Serial.println("Magnatromiter");
Serial.println("xB\tyB\tzB");
Serial.print(xB); Serial.print('\t'); Serial.print(yB); Serial.print('\t'); Serial.println(zB);
}
bool setupBleMode()
{
if ( !BLE.begin() )
{
return false;
}
// set advertised local name and service UUID
BLE.setDeviceName( BLE_DEVICE_NAME );
BLE.setLocalName( BLE_LOCAL_NAME );
BLE.setAdvertisedService( currentTimeService );
// add characteristics
currentTimeService.addCharacteristic( dateTimeCharacteristic );
// add service
BLE.addService( currentTimeService );
// set the initial value for the characeristics
dateTimeCharacteristic.writeValue( dateTimeData.bytes, sizeof dateTimeData.bytes );
// set BLE event handlers
BLE.setEventHandler( BLEConnected, blePeripheralConnectHandler );
BLE.setEventHandler( BLEDisconnected, blePeripheralDisconnectHandler );
// set service and characteristic specific event handlers
dateTimeCharacteristic.setEventHandler( BLEWritten, bleCharacteristicWrittenHandler );
// start advertising
BLE.advertise();
return true;
}
void bleTask()
{
#define BLE_UPDATE_INTERVAL 10
static uint32_t previousMillis = 0;
uint32_t currentMillis = millis();
if ( currentMillis - previousMillis >= BLE_UPDATE_INTERVAL )
{
previousMillis = currentMillis;
BLE.poll();
}
if ( timeUpdated )
{
timeUpdated = false;
dateTimeCharacteristic.writeValue( dateTimeData.bytes, sizeof dateTimeData.bytes );
}
}
void bleCharacteristicWrittenHandler( BLEDevice central, BLECharacteristic bleCharacteristic )
{
if ( bleCharacteristic.uuid() == ( const char* ) BLE_UUID_DATE_TIME )
{
dateTimeCharacteristic.readValue( dateTimeData.bytes, sizeof dateTimeData.bytes );
setTime( dateTimeData.dateTime );
}
}
void blePeripheralConnectHandler( BLEDevice central )
{
digitalWrite( BLE_LED_PIN, HIGH );
Serial.print( F( "Connected to central: " ) );
Serial.println( central.address() );
}
void blePeripheralDisconnectHandler( BLEDevice central )
{
digitalWrite( BLE_LED_PIN, LOW );
Serial.print( F( "Disconnected from central: " ) );
Serial.println( central.address() );
}
void timeTask()
{
#define TIME_UPDATE_INTERVAL 1000
static uint32_t previousMillis = 0;
unsigned long currentMillis = millis();
if ( currentMillis - previousMillis < TIME_UPDATE_INTERVAL )
{
return;
}
previousMillis = currentMillis;
time_t currentTime = time( NULL );
struct tm * now = localtime( ¤tTime );
dateTimeData.dateTime.year = now->tm_year + 1900;
dateTimeData.dateTime.month = now->tm_mon + 1;
dateTimeData.dateTime.day = now->tm_mday;
dateTimeData.dateTime.hours = now->tm_hour;
dateTimeData.dateTime.minutes = now->tm_min;
dateTimeData.dateTime.seconds = now->tm_sec;
timeUpdated = true;
}
void setupTime( void )
{
date_time_t dateTime = { 2023, 12, 18, 13, 15 , 0 };
setTime( dateTime );
}
void setTime( date_time_t time )
{
struct tm setTime;
setTime.tm_mon = time.month - 1; // month are from (0 - 11)
setTime.tm_year = time.year - 2000; // years since 1900
setTime.tm_mday = time.day; // day of month (0 - 31)
setTime.tm_hour = time.hours; // hour (0 - 23)
setTime.tm_min = time.minutes; // minutes (0 - 59)
setTime.tm_sec = time.seconds; // seconds (0 - 59)
Serial.print("Date: "); Serial.print(time.month); Serial.print("/");
Serial.print(time.year); Serial.print("/"); Serial.println(time.day);
Serial.print("Time: "); Serial.print(time.hours); Serial.print(":");
Serial.print(time.minutes); Serial.print(":"); Serial.println(time.seconds);
set_time( mktime( &setTime ) );
}
the code compiles, load OK. issues come when opening serial monitor.
As I said earlier, if I run a small sketch it works fine.
The problem is here:
You are calling HTS.readTemperature() and HTS.readHumidity() before the library has been initialized by the HTS.begin() call. So it is the code that is bad; not the boards.
Here is a minimal sketch that demonstrates the behavior of the USB code being broken by calling HTS.readTemperature() without first calling HTS.begin():
// This demonstration sketch will cause the Nano 33 BLE Sense board to no longer produce a port
#include <Arduino_HTS221.h>
void setup() {
HTS.readTemperature();
}
void loop() {}
You should change those lines to be simple declarations of the global variables:
float temperature;
float humidity;
Then call HTS.readTemperature() and HTS.readHumidity() somewhere in your sketch after HTS.begin() has been called:
temperature = HTS.readTemperature();
humidity = HTS.readHumidity();
Here is a minimal sketch demonstrating the correct usage of the library:
// This demonstration sketch will not affect the port of the Nano 33 BLE Sense board
#include <Arduino_HTS221.h>
void setup() {
if (!HTS.begin()) {
while (1);
}
HTS.readTemperature();
}
void loop() {}
This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.