Serial monitor problem

Hi

Can anyone help with this problem?

I started out being sure that this sketch had a problem with the ISR, wire, or the ICM42688 HW/library, but now it seems that using the serial monitor and these commands below, is the problem

if (Serial.available() > 0) {

receivedDataMonitor = Serial.read();

I have shortened the original sketch to show only the important things. And in some of the test’s, things are commented out. The configuration of the IMU includes the setup of the interrupt signal on pin PIN1, which looks OK, see figure.

The only thing that happens in the ISR is setting the volatile var newICM42688Data true.

(A similar sketch, has been working OK on a nRF52840 board (seeed XIAO BLE nRF52840).

I’m using;

Windows 10

Arduino IDE 1.8.19.

Arduino nano ESP32 board, the “original” Arduino ESP32 Board Package

The IMU from invensense giving the data, and interrupt, is this ICM-42688-P | TDK InvenSense

Tests.

Test 1. ISR running, in loop only looking for input from serial monitor

Test 2. ISR running, in loop looking for input from serial monitor, and also calling the function gyroAngle(0) which is empty in this test

Test 3. ISR running, in loop looking for input from serial monitor, and also calling the function gyroAngle(0) which in this test contains one short line,

if (newICM42688Data== true) {

newICM42688Data= false;

Test 4. Not attaching the interrupt (attachInterrupt) so ISR not running, in loop only looking for input from serial monitor, same result as Test 1

Test 5. Not attaching the interrupt (attachInterrupt) so ISR not running, and also commented out ISR declarations. In loop only looking for input from serial monitor, same result as Test 1

Test 6. Commented out now also making of IMU object instance (and all relating to that), same result as Test 1 (except no IMU info)

Test 7. Commented out all IMU things, only thing left now is almost the use of serial monitor for writing data, and receiving data (characters) from user, same result as Test 1(except no IMU info)

Results.

Result Test 1. serial monitor reacting OK, when pressing ‘h’ printing one IMU reading OK. When pressing ‘a’ serial monitor writes “start vinkel” and then it (and sketch) stops working, inkl. the Arduino IDE sound (for reboot?)

Result Test 2. Serial monitor right from the beginning starts to print out data, which it shouldn’t until having pressed ‘h’, it looks like someone pressing ‘h’ fast - but that’s not the case
image

Result Test 3. Serial monitor is now “dead” from the beginning, not reacting to anything, not printing out anything

The ICM42688 interrupt signal INT1.

More info on the IDE settings

Another related question, I read that it is important to use the attribute IRAM_ATTR when using ISR with ESP32, which I did. But what is the difference to using ARDUINO_ISR_ATTR, which I have also seen used?

// TEST 1
//#include <ICM42688.h> // IMU from invensense


//void IRAM_ATTR myinthandler1(); // ISR for ICM42688
//void ARDUINO_ISR_ATTR myinthandler1(); // ISR for ICM42688
int gyroAngle(byte command); // function for measure angle


#define interruptPin1 20 // interrupt pin from ICM42688


// ICM42688
// an ICM42688 object with the ICM42688 sensor on I2C bus 0 with address 0x68
//ICM42688 IMU(Wire, 0x68);
//volatile bool newICM42688Data  = false;
float measuredAngle;


char receivedDataMonitor;
uint8_t reg;
int svarIMU;
int svarGyroAngle;


void setup() {
  // put your setup code here, to run once: -------------------------------------------------------------------------------------------
  Serial.begin(115200); 
  
  delay(5000); 
  
  for (int i= 0; i<= 5; i++) {
    delay(1000); 
    Serial.print("Serial init sec");
    Serial.println(i);
  }
  
  Serial.println("Debug");

/*
  // start communication with IMU
  int status = IMU.begin();
  if (status < 0) {
    Serial.println("IMU initialization unsuccessful");
    Serial.println("Check IMU wiring or try cycling power");
    Serial.print("Status: (stopper)");
    Serial.println(status);
    while(1) {}
  }
  Serial.println("ICM424688");
   
  
  // Turn Accel and Gyro Off
  //   reg PWR_MGMT0 = 0x00 = reset value = acc og gyro off temp on
  IMU.setBank(0);
  svarIMU= IMU.writeRegister(0x4E, 0x00); 
  Serial.print("svar "); Serial.println(svarIMU);
 
  // User bank 0, INTF_CONFIG1, 77 (4Dh)= 0x95 = RTC clock input is required, Select PLL when available, else select RC oscillator (default)
  // User bank 1, INTF_CONFIG5, 123 (7Bh)= 0x04 = pin 9 clock in
  IMU.setBank(0);
  IMU.writeRegister(0x4D, 0x95); 
  IMU.setBank(1);
  IMU.writeRegister(0x7B, 0x04); 
  IMU.setBank(0); 

  //   Interrupt functionality is configured via the Interrupt Configuration register, DS p.24 og p. 42
  //   - INT1 and INT2 can be push-pull or open drain
  //   - Level or pulse mode
  //   - Active high or active low
  //   
  // via reg kald:
  // User bank 0, INT_CONFIG, Address: 20 (14h), p. 66 INT1 del (bit 0, 1, 2) = 0x03 = push-pull, pulsed, active HIGH eller 0x07 = latched, pulsed, active HIGH
  // User bank 0, INT_STATUS, Address: 45 (2Dh), p. 70 bl.a bit 3 DATA_RDY_INT
  // User bank 0, INT_CONFIG0, Address: 99 (63h), only used when latched mode, Data Ready Interrupt Clear Option (latched mode) 0x00/ 0x20 
  // User bank 0, INT_CONFIG1, Address: 100 (64h), p. 86 bit 4 INT_ASYNC_RESET, User should change setting to 0 from default setting of 1, for proper INT1 
  //   and INT2 pin operation, ene library bruger resten af bits (beholde det) AND bit 4 = 0
  //   bit 6 INT_TPULSE_DURATION: 0= Interrupt pulse duration is 100µs. Use only if ODR < 4kHz. (Default)
  //   bit 5 INT_TDEASSERT_DISABLE: 0= The interrupt de-assertion duration () is set to a minimum of 100µs
  // User bank 0, INT_SOURCE0, Address: 101 (65h), = 0x08 = UI data ready interrupt routed to INT1 ( UI AGC ready er alternativ?)
  
  IMU.writeRegister(0x14, 0x03);
  IMU.writeRegister(0x64, 0x00);
  IMU.writeRegister(0x65, 0x08);
    
  // evt indstil interne filtre
  IMU.writeRegister(0x52, 0x77); // evt 1= OK, -1 = fejl
    
  // indstil ODR (sandsynlig bruge odr1k, odr500, odr200, odr100)
  IMU.setGyroODR(ICM42688::odr500);
 
  // indstil FSR (sandsynlig bruge dps125, dps62_5, dps31_25, dps15_625)
  IMU.setGyroFS(ICM42688::dps125);

  // Turn Gyro On
  //   reg PWR_MGMT0 = 0x2C gyro Low Noise (LN) Mode acc off, 0x0F eller 0x2F =  accel and gyro in Low Noise (LN) Mode, og enable 0x0F/disable 0x2F temperatur
  IMU.setBank(0);
  IMU.writeRegister(0x4E, 0x2C); // evt 1= OK, -1 = fejl


  // ISR set up INT1 fra ICM42688 (data ready)
  pinMode(interruptPin1, INPUT);
  //attachInterrupt(digitalPinToInterrupt(interruptPin1), myinthandler1, RISING);  // define interrupt for INT1 output of ICM42688
*/
 
  Serial.println("monitor kommandoer:");
  Serial.println("a= start vinkel, b= afslut vinkel, ... "); 
  

}

void loop() {
  // put your main code here, to run repeatedly: ------------------------------------------------------------------------------------

  // kommando på serial monitor ___________________________________________________________________________
  if (Serial.available() > 0) {
    receivedDataMonitor = Serial.read();
    switch (receivedDataMonitor) {
      case 'a':
        Serial.println("start vinkel");

        gyroAngle(1);
        
      break;
      case 'b':
        Serial.println("stop vinkel");

        Serial.print("vinkel: ");
        Serial.println(measuredAngle, 2);
  
      break;
      case 'c':
        //soundService(1, 0, 0); // play lyd 0
        
      break;
      case 'd':
        //soundService(2, 4, 6000); // play tid lyd 4 8000 ms
        
      break;
      case 'e':
        //soundService(3, 4, 0); // play loop lyd 4
        
      break;
      case 'f':
        //soundService(4, 0, 0); // play stop 
        
      break;
      case 'g':
        //soundService(3, 3, 0); // play loop lyd 3
        
      break;
      case 'h':

        //IMU.getAGT();
        //IMU.getGyroZ(); // egen funktion

        //Serial.print("z "); Serial.println(IMU.gyrZ(), 6);

        Serial.println("start h");
        
        //Serial.print("clk ");Serial.println(Wire.getClock()); 
        
      break;
      
      default:
        // intet
      break;
    }
  }  

   
  //svarGyroAngle= gyroAngle(0);


}


/*
void IRAM_ATTR myinthandler1() { // ISR for ICM42688
//void ARDUINO_ISR_ATTR myinthandler1();
  newICM42688Data= true;
  
}
*/

// services functions ____________________________________________________________________________________________________
int gyroAngle(byte command) {
  
  const float timePartODR200= 0.005;
  const float timePartODR500= 0.002;
  const float timePartODR1000= 0.001;
  
  switch(command) {
    case 0: // service
            
      /*
      if (newICM42688Data== true) {
        newICM42688Data= false;
  
        //Serial.print("g "); Serial.println(millis());
        
        //IMU.getAGT();
        //IMU.getGyroZ(); // egen 

        //Serial.print("z "); Serial.println(IMU.gyrZ(), 4);
        //measuredAngle= measuredAngle+ (IMU.gyrZ()* timePartODR500); // afhængig af valgte ODR
        
      }
      */
      
      
      
    break;
    case 1: // start
      measuredAngle= 0.0;
      
    break;
    case 2: // stop og udregn
          
    break;
    default:
  
    break;
  }

}

It turns out this was a a whole different problem, esp32 fails if no correct return in functions
https://github.com/espressif/arduino-esp32/issues/5867

1 Like