serialPrint() and ISR

Is it possible to make s print on serial monitor during an ISR (interrupt service routine)/timer interrupt, that is use serialPrint()?

Is it possible to make s print on serial monitor during an ISR

Yes you can just do it, but serial may block and thus hang your program permanently! So don't do it.

Mark

Can I do it without hanging the complete program and if yes, how?

logitech:
Is it possible to make s print on serial monitor during an ISR (interrupt service routine)/timer interrupt, that is use serialPrint()?

Serial.print() relies on interrupts to send data. There is a buffer. If you call Serial.print() to send data, it buffers the data, until the buffer gets full. When that happens, it has to wait until there is room in the buffer. Room becomes available in the buffer by interrupts firing, and moving data out.

Interrupts are blocked while your ISR is running, so, if the buffer becomes full, your progam will hand, with Serial.print() waiting for room in the buffer that will never be made.

Bottom line: It is possible to call Serial.print() in an ISR, if done with extreme care. Send very small amounts of data in an ISR that is not called often.

On the other hand, it really isn't a good idea. You have no way of knowing if any given call to Serial.print() will fill the buffer and cause blocking to happen.

NO not really.

Mark

Can I do it without hanging the complete program and if yes, how?

Maybe. Post your code, and we'll discuss your options. Enough of the theoretical.

#include <TimerOne.h>
#define MAX 50
int array [MAX];                     
int i = 0;
int temp;
volatile int old_error = 0;
volatile int pressed_error;
volatile int error;
volatile int z;
volatile int state = 1;
int L1;
int L2;
const int LED1 = 2;
const int LED2 = 3;
const int LED3 = 4;
const int LED4 = 5;
int old_b = 0;
int val;
int counter;


void setup () {                             
  pinMode (A5, INPUT_PULLUP);            
  Timer1.initialize(1000);                    
  Timer1.attachInterrupt(readERROR);       
  Serial.begin(9600);                       
}

void readERROR () {                                                                        
  z = analogRead(5);             
  if (z > 251 && z < 254) error = 5;      
  else error = 0;                                      
  if (error == old_error) {                    
    old_error = error;                            
    pressed_error = 0;                               
  } 
  else {                                                    
    old_error = error;                          
    pressed_error = error;                 
  }                                                             
  if ((state == 2) && (pressed_error == 5)) {   
    digitalWrite (LED1, LOW);
    digitalWrite (LED2, LOW);
    digitalWrite (LED3, LOW);
    digitalWrite (LED4, LOW);
  }
  state = 1;                                                               
}

int readButtons (int pin) {     
  int b, c;                                        
  c = analogRead(pin);             
  Serial.print("analogRead =  ");     
  Serial.println(c);                                              
  if (c > 1021) b = 0;                                           
  else if (c > 71 && c < 74) b = 1;                     
  else if (c > 125 && c < 128) b = 2;                
  else if (c > 171 && c < 174) b = 3;                
  else if (c > 213 && c < 216) b = 4;             
  else if (c > 251 && c < 254) b = 5;             
  else if (c > 286 && c < 289) b = 6;           
  else b = 0;                                                       
  if (b == stari_b) {                                          
    stari_b = b;                                                  
    return 0;                                                      
  } 
  else {                                                              
    stari_b = b;                                                    
    return b;                                                       
  }                                                                         
}                                                                

void loop () {
  if (state == 1) {                                                                                 
    while ((val = readButtons(5)) != 5) {                                                     
      if ((val == 1) || (val == 2) || (val == 3) || (val == 4)) {                        
        array[counter] = val;                                                                              
        counter++;                                                                                               
        if (counter == MAX) {                                                                            
          counter = 0;                                                                                          
        }                                                                                        
      }                                                            
    }                                                                                                                                                                                                                              
    temp = counter;                               
    counter = 0;                                       
    state = 2;                                              
  }                                                                


  for (i = 0; i < temp; i++) {                                        
    if (state == 2) {                                                              
      if (array[i] % 2 == 0) {                                                 
        L1 = 2;                                                                            
        L2 = array[i] / 3 + 3;                                                      
      } 
      else {                                                              
        L2 = 5;                                                            
        L1 = array[i] % 3 + 3;                                   
      }                                                                                                       
      digitalWrite (L1, HIGH);                                                                  
      digitalWrite (L2, HIGH);           
      delay(5000);                             
      digitalWrite (L1, LOW);           
      digitalWrite (L2, LOW);                 
    }                                                      
  }   
}

Everything works, except this interrupt, since when 5th button pressed during blinking, it doesn't exit state2, but just continues blinking like the 5th button wasn't pressed at all.
state = 1;

Serial.begin(9600);

That'll have to go higher if you want you to maximise your chances of Serial output in an ISR working.

AWOL:

Serial.begin(9600);

That'll have to go higher if you want you to maximise your chances of Serial output in an ISR working.

How higher should be enough?

As fast as you can handle - I generally use 115200

    pinMode (A5, INPUT_PULLUP);            
    Timer1.initialize(1000);                    
    Timer1.attachInterrupt(readERROR);       
    Serial.begin(9600);                       
}

void readERROR () {                                                                        
  z = analogRead(5);

Are you using the pin as an analog pin, using analogRead(), or as a digital pin, using pinMode with the internal pullup resistor turned on? Only one mode is appropriate.

You are calling the interrupt every millisecond. Is that really appropriate?

There are no useful comments in your code. The only comments you have state the obvious.

I have no idea what the stupid ASCII art in your code is about. Get rid of it. Add some comments that define WHY things are happening/being checked. Get rid of the obvious, insult our intelligence, comments.

PaulS:

    pinMode (A5, INPUT_PULLUP);            

Timer1.initialize(1000);                   
    Timer1.attachInterrupt(readERROR);       
    Serial.begin(9600);                       
}

void readERROR () {                                                                       
  z = analogRead(5);



Are you using the pin as an analog pin, using analogRead(), or as a digital pin, using pinMode with the internal pullup resistor turned on? Only one mode is appropriate.

You are calling the interrupt every millisecond. Is that really appropriate?

There are no useful comments in your code. The only comments you have state the obvious.

I have no idea what the stupid ASCII art in your code is about. Get rid of it. Add some comments that define WHY things are happening/being checked. Get rid of the obvious, insult our intelligence, comments.

ASCII looked good when I was editing the post. Don't now why was it displayed like a mess. Removed the comments. Never meant to insult anybody. If something isn't clear, say and I'll try to explain why I did what I did.

Calling the interrupt every millisecond so that it can be detected that state2 is currently going on and if the 5th button was pressed, blinking then should be stoped.

  if (error == old_error) {                    
    old_error = error;                            
    pressed_error = 0;                               
  } 
  else {                                                    
    old_error = error;                          
    pressed_error = error;                 
  }

If you are going to do something when the condition is true and the same thing when the condition is false, is there some reason that it's in the if/else statement at all?

Nice job removing the useless comments. Not so nice on putting in comments that explain what you are trying to do.

What is the significance of old_error, error, and pressed_error? None of them are intuitively obvious.

    while ((val = readButtons(5)) != 5) {                                                     
      if ((val == 1) || (val == 2) || (val == 3) || (val == 4)) {                        
        array[counter] = val;                                                                              
        counter++;                                                                                               
        if (counter == MAX) {                                                                            
          counter = 0;                                                                                          
        }                                                                                        
      }                                                            
    }

If val is not 5, is there some chance that it is not 1, 2, 3, or 4? Except for the 0 case? This code is ridiculously obtuse.

      digitalWrite (L1, HIGH);                                                                  
      digitalWrite (L2, HIGH);           
      delay(5000);                             
      digitalWrite (L1, LOW);           
      digitalWrite (L2, LOW);

The timer interrupt will not break out of the delay.

Personally, I think you should get rid of the timer interrupt and all its confusion, and read, understand, and embrace the blink without delay example.