Why reading 0 and 1 when using on FALLING edge interrupt?

Hello,

this is my code:

#ifndef rbi
#define rbi(sfr, bit) (((sfr) >> (bit)) & 0x01)
#endif
void gsm_rx_int1_falling () {

  cli();
  boolean rx_bit = rbi(PIND, 3);
  sei();
  Serial.println(rx_bit, DEC);

}

void setup () {
  Serial.begin(57600);
  attachInterrupt(1, gsm_rx_int1_falling, FALLING);
}

void loop () {
}

Im getting 0's, 1's and strange chars on serial console... why?

thanks,

cheers.

See trap #4

seems the pin state changes before I can get the proper value because baudrate is too high.

is there an easy way of starting to code some C/ASM for AVRs?

thanks,

cheers.

abeltomillo:
seems the pin state changes before I can get the proper value because baudrate is too high.

Don't do serial prints inside an ISR. It's nothing to do with using assembler.

If you want to, save some values in RAM, and then send them later.

abeltomillo:
seems the pin state changes before I can get the proper value because baudrate is too high.

is there an easy way of starting to code some C/ASM for AVRs?

thanks,

cheers.

You should read the answers you get. Larry told you exactly what's wrong.

You can't use Serial methods inside an interrupt routine. Save the value to a global variable, set a global BOOL data_available that tells your program something is available for printing, and then write code in your loop() function that checks data_available and does a Serial.println() if data IS available (and clears the flag after printing.)

Guys, we're connected. I did this before reading this, thanks a lot for support... really much appreciated.

void setup () {
  Serial.begin(19200);
  pinMode(3, INPUT);
  attachInterrupt(1, gsm_rx_int1_falling, FALLING);
}

#define rb(NBIT, SFR) ((SFR & ( 1 << NBIT )) >> NBIT)

boolean rx_bits[200];
int rx_bits_len = 0;

void gsm_rx_int1_falling() {
   rx_bits[rx_bits_len++] = rb(PIND, 3);
}

void loop () {
  delay(3000);
  for (int i = 0; i < rx_bits_len; i ++) {
    Serial.print(rx_bits[i], DEC);
  }
  Serial.println("");
}
   rx_bits[rx_bits_len++] = rb(PIND, 3);

rx_bits_len and rx_bits should be declared volatile.

Also I would be testing for going off the end of that array or things will crash pretty quickly.

really interesting that about "volatile" variables. what's about volatile asm inline code?

that array is going to crash, that's it :slight_smile: haha... just making a test :wink:

thanks,

cheers.

abeltomillo:
really interesting that about "volatile" variables. what's about volatile asm inline code?

that array is going to crash, that's it :slight_smile: haha... just making a test :wink:

thanks,

cheers.

Volatile has no meaning in ASM code. Volatile tells the C compiler that a variable's value can change in unexpected ways, so don't keep it in a register.

Imagine that the compiler decides to optimize by ignoring the value of a variable in memory and use a register instead. Then an interrupt routine comes along and changes the value in memory. When the interrupt returns, the program keeps reading and writing to the register, and the change made by the interrupt routine is completely missed.

With ASM, you explicitly control what's stored in fixed memory locations, what's saved on the stack, what's written to flash memory, and what's done in registers. The compiler doesn't make those decisions for you.

Rewriting in assembler is not going to help in any way. The C compiler is quite capable of generating efficient code.

just a question from long ago.

maybe not, at the moment arduino's lang is working fine ;).

thanks anyway.

cheers.