Volatile variables inside function

Hi I have the simple code that I am trying to make it work using ISR interrupts and a simple timer. Basically I use Interrupt to wait for Serial income of 1 Byte of data. The main loop uses a timer hat fires at every 1 second and increments volatile variable which then I would like to send via serial to the PC. I use RS485 so that is why I use the transmit/receive control on pin 2. The problem is that I always receive zeros instead of incremented value NBB. Whenever I write the constant values (commented) I received them on the other side correctly. Here is the code:

#include<avr/io.h>
#include <digitalWriteFast.h>
#include "avr/interrupt.h"


 
 #define SSerialTxControl 2   //RS485 Direction control
 #define RS485Transmit    HIGH
 #define RS485Receive     LOW 
 
#define USART_BAUDRATE 250000 //250000 e OK
#define BAUD_PRESCALE (((F_CPU/(USART_BAUDRATE*16UL)))-1)
char recieved_byte; 
uint16_t NBB = 25;
volatile byte HB,LB;
#include <SimpleTimer.h> 
SimpleTimer timer;


 void setup(){
 pinMode(SSerialTxControl, OUTPUT); 
 
 //transimit and recieve enable
 UCSR0B = (1 << TXEN0)| (1 << TXCIE0) | (1 << RXEN0) | (1 << RXCIE0); // Turn on the transmission and reception circuitry
 UCSR0C = (1 << UCSZ01) | (1 << UCSZ00);  //8 bit data format 
 UBRR0H  = (BAUD_PRESCALE >> 8);
 UBRR0L  = BAUD_PRESCALE;
  
 timer.setInterval(1000, timerCallback);
 
 sei();
 digitalWriteFast(SSerialTxControl, RS485Receive); 
 
}
void loop() {
  timer.run();

}
//void serialEvent()

ISR(USART_RX_vect)
{
  
     digitalWriteFast(SSerialTxControl, RS485Receive);
     //recieved_byte = Serial.read();
     while( ( UCSR0A & ( 1 << RXC0 ) ) == 0 ){} 
     //grab the byte from the serial port
     recieved_byte = UDR0;
      
      
       digitalWriteFast(SSerialTxControl, RS485Transmit);
       //byte * g = (byte *) &NBB;
       while (( UCSR0A & (1<<UDRE0))  == 0){};//prati broj na bytes da se citaat od kompresija
                    
                     
                      UDR0 = HB;
                      //UDR0 = 0x23;
                      while (( UCSR0A & (1<<UDRE0))  == 0){};
                      UDR0 = LB;
                      //UDR0 = 0x2A;
                      while (( UCSR0A & (1<<UDRE0))  == 0){};
                      
                      //dummy send 
                      UDR0 = 0x2A;
                      while (( UCSR0A & (1<<UDRE0))  == 0){};  
       
        digitalWriteFast(SSerialTxControl, RS485Receive);
}

void timerCallback()
{  
  noInterrupts ();
  NBB++;
  HB = highByte(NBB);
  LB = lowByte(NBB);
  interrupts ();
}

Basically I use Interrupt to wait for Serial income of 1 Byte of data.

WRONG! You NEVER use interrupts to wait.

void timerCallback()
{ 
  noInterrupts ();
  NBB++;
  HB = highByte(NBB);
  LB = lowByte(NBB);
  interrupts ();
}

Interrupts are already disabled in an ISR. Quit f**king with them.

Your loop() is accomplishing nothing. I can not imagine why you can't ditch all the timer and interrupt crap, and just read and write in loop().

Hi PaulS,

I need the timer so I can sample at some rate (200Hz) e.g timer fires at 5ms. I need the ISR in order to know when to send the sampled data.

Do you suggest any other approach?

Thanks,

I need the timer so I can sample at some rate (200Hz)

Why do you need to test for the arrival of serial data only 200 times per second? Why not test more often if you can?

Sorry maybe I was not clear. My main code is sampling at 200Hz data from sensor and putting the data into buffer. I need the interrupt so the PC can tell me when to send the buffered data. So inside the ISR routine I am sending the buffered data but noticed that some variables I use are zero even though they are declared as volatile.

Thanks,

I need the interrupt so the PC can tell me when to send the buffered data.

You need the Arduino to generate a timer interrupt so the PC can tell it something. I am seriously missing something.

The PC is sending 1 byte to the Arduino. Arduino uses the ISR(USART_RX_vect) to read that 1 byte, then sends the buffered data back.

The PC is sending 1 byte to the Arduino. Arduino uses the ISR(USART_RX_vect) to read that 1 byte, then sends the buffered data back.

So, what is the timer interrupt doing?

Have you changed your code to stop diddling with interrupts in the timer ISR?

The timer is firing every 5ms so I can read my sensor at 200Hz. The example above is with 1Hz for debugging

The example I posted is a simplified version of the problem I have with the variable I use in both the ISR routine and the main code. The main code is using timer that is firing every X ms and incrementing a volatile variable every X ms. The ISR routine is sending that variable to the PC after PC sends request.

In the example, I think you need for NBB to be volatile as well.

Thanks for the reply westfw but that didn't work...

Don't screw with the USART interrupts. The Arduino framework manages them for you.

Try this...

void loop() {
  timer.run();
  if(Serial.available()) {
    Serial.read(); //discard the character from the PC, it's just for timing purposes
    sendData();
  }
}

Then you would need to write the sendData() function to do the send action that you're talking about. I can't understand what you've written other than you seem to be hacking on the registers directly instead of using the simple functions that the Arduino framework provides.