Show Posts
Pages: [1]
1  Using Arduino / Programming Questions / Re: Trouble with micros() on: April 24, 2011, 07:59:52 am
Yep, detaching then reattaching INT0 LEVEL ISR works.

Here's the resolved code:

Code:
#include <avr/sleep.h>

#define IR_PIN 2

volatile int state = 0;
boolean reset = false;
boolean failed = false;

unsigned long logLastTime = 0;  // stores last output of micros()

// Onkyo RC-319S pulse-length coding signal spec (allowing ±10% timing error)
const unsigned long Tinit_min = 4050;
const unsigned long Tinit_max = 4950;

void setup()
{
  // start serial port at 9600 bps:
  Serial.begin(9600);

  // Set D2 to input to read GP1UM271:Vout
  pinMode(IR_PIN, INPUT); 

  // enable interrupt, which is triggered when D2 is low
  attachInterrupt(0, ir_level_isr, LOW);

  // to demonstrate waking up from power-down state
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);
  sleep_mode();
}

void loop()
{
  unsigned long time, T;

  // get current time & time elapsed since last log time
  time = micros();
  T = time - logLastTime;
 
  switch (state)
  {
  case 1:  // waiting for the start pulse

    if (digitalRead(IR_PIN))  // LO->HI transition occurred
    {
      logLastTime = time;  // log current time
      state = 2;  // start measuring the start bit length
    }
    break;

  case 2:  // waiting for the end of the start pulse

    if (digitalRead(IR_PIN))  // no change
    {
      if (T > Tinit_max) // waited longer than expected pulse duration
      {
        failed = true;
      }
    }
    else  // HI->LO transition occurred
    {
      if (T < Tinit_min)  // start pulse ended too early
      {
        failed = true;
      }
      else  // within the tolerable duration, move on to first bit
      {
        Serial.println("Start pulse detected");               
        reset = true;
      }
    }
    break;
  }

  // IR signal detection failed, reset loop
  if (failed)
  {
    Serial.print(state,DEC);
    Serial.println(" IR Command Reception Failed");               

    reset = true;
    failed = false;

    Serial.print("[logLastTime: ");
    Serial.print(logLastTime,DEC);
    Serial.print(" | time: ");
    Serial.print(time, DEC);
    Serial.print(" | T: ");
    Serial.print(T, DEC);
    Serial.println("]");
  }

  if (reset)
  {
   // reset the IR receiver state
    state = 0;

    // clear the reset flag
    reset = false;

    // re-enable the interrupt
    attachInterrupt(0, ir_level_isr, LOW);
  }
}

void ir_level_isr()
{
  // disable ISR
  detachInterrupt(0);
 
  // start IR decoding
  state = 1;
}

@Nick - I searched for "interrupts remembered in advance" but couldn't find anything on it. Would you post a link for the thread with this discussion?

Thanks
2  Using Arduino / Programming Questions / Re: Trouble with micros() on: April 23, 2011, 11:15:53 pm
Thanks guys for your responses!

@James - I tried that but serial port is too slow to keep up with IR data flow

@CR - oops. Fixed the original text. thx for point that out.

@Nick - You are absolutely right. Changed INT0 trigger to FALLING, and the problem went away. Yay!! Also, thanks for explaining the in-depth mechanism of micros().

Now, you also suggested
Quote
not even use interrupts

The reason for it being interrupt activated is that later I want to wake up the uC with the remote... Oh, that's why I decided to use the LOW trigger. The datasheet (p.39, Table 9-1, Note 3) only LEVEL INT0 can wake uC up.

Maybe I need to use one of PCINTs instead. Would that work?
3  Using Arduino / Programming Questions / Re: Trouble with micros() on: April 23, 2011, 08:58:06 pm
James,

Although I think you already know, the 70-min. roll-over is not the issue here (yet). It happens way too often for that.

That being said, I haven't run it long enough to know the effect of that. However, unsigned integer arithmetic should give me the correct difference (as long as the counter only rolls over once).

Kesh
4  Using Arduino / Programming Questions / Trouble with micros() [RESOLVED] on: April 23, 2011, 08:31:20 pm
Hi all,

I'm warming up to Arduino by trying to implement an IR remote receiver, but there is something funny going on in my code that I cannot get a grip of. Specifically, the value output by micros() is less than the previous micros() call.

The output of my IR detector outputs looks like this:

And the remote commands can be found here:
http://junknotjunks.blogspot.com/2011/04/remote-control-receiver.html

Here's my full Arduino code to detect the starting pulse (4.5 ms). Int0 (LEVEL) ISR is used to initiate the process.
Code:
#define IR_PIN 2

volatile int state = 0;
boolean failed = false;

unsigned long logLastTime = 0;  // stores last output of micros()

// Onkyo RC-319S pulse-length coding signal spec (allowing ±10% timing error)
const unsigned long Tinit_min = 4050;
const unsigned long Tinit_max = 4950;

void setup()
{
  // start serial port at 9600 bps:
  Serial.begin(9600);

  pinMode(IR_PIN, INPUT);  // Set D2 to input to read GP1UM271:Vout

  // enable interrupt, which is triggered when D2 is low
  attachInterrupt(0, ir_level_isr, LOW);
}

void loop()
{
  unsigned long time, T;

  // get current time & time elapsed since last log time
  time = micros();
  T = time - logLastTime;
 
  switch (state)
  {
  case 1:  // waiting for the start pulse

    if (digitalRead(IR_PIN))  // LO->HI transition occurred
    {
      logLastTime = time;  // log current time
      state = 2;  // start measuring the start bit length
    }
    break;

  case 2:  // waiting for the end of the start pulse

    if (digitalRead(IR_PIN))  // no change
    {
      if (T > Tinit_max) // waited longer than expected pulse duration
      {
        failed = true;
      }
    }
    else  // HI->LO transition occurred
    {
      if (T < Tinit_min)  // start pulse ended too early
      {
        failed = true;
      }
      else  // within the tolerable duration, move on to first bit
      {
        Serial.println("Start pulse detected");               
        state = 0;
      }
    }
    break;
  }

  // IR signal detection failed, reset loop
  if (failed)
  {
    Serial.print(state,DEC);
    Serial.println(" IR Command Reception Failed");               

    state = 0;
    failed = false;
    Serial.print("[logLastTime: ");
    Serial.print(logLastTime,DEC);
    Serial.print(" | time: ");
    Serial.print(time, DEC);
    Serial.print(" | T: ");
    Serial.print(T, DEC);
    Serial.println("]");
  }
}

void ir_level_isr()
{
  if (state==0) state = 1;
}

Most of the time, this code works. But every once in a while, it fails to detect the starting pulse. I'm monitoring the IR detector output with a scope to make sure that the incoming signal waveform is clean all the time. And when it fails, the elapsed time is all messed up. For example, here's one of the failed message that I got:

Code:
2 IR Command Reception Failed
[logLastTime: 370711192 | time: 370710632 | T: 4294966736]

logLastTime is the time when the start pulse began (i.e., LO-to-HI transition last occurred) and time is the time observed in the current loop iteration (when the start pulse ended). But we have logLastTime>time... which doesn't make any sense.

If anyone can explain this behavior or know how to fix the problem, I'd love to hear it. (I'm thinking it must be an interrupt related issue, but has not yet nailed down the cause.)

Thanks,
Kesh

edit: logLastTime<time changed to logLastTime>time
edit 2: Problem resolved! Please see my Reply #8 for the corrected code.
5  Using Arduino / General Electronics / Re: Series resistor for IC-to-IC interface on: March 31, 2011, 10:56:41 am
Thanks, Rug'd. That makes sense. - kesh
6  Using Arduino / General Electronics / Series resistor for IC-to-IC interface on: March 31, 2011, 10:08:05 am
Hi. First time poster, waiting for his Nano to arrive in a few days!

I need some help on basic understanding on IC-to-IC interface. I'm more of a software person and not much on (practical) circuit design. (My circuit design experience goes all the way back to the undergrad EE microprocessor class some umpteen years ago.)

I've been studying Arduino Nano schematic and see that there are 1k-Ohm resistors on the TX and RX lines between ATmega MCU and FT232RL. Are these resistors necessary? Or would it be possible to have these pins connected directly without resistors? And could someone enlighten me on the reason behind these series resistors?

I'm planning on connecting Noritake VFD module with CMOS async serial interface either to the Nano or to another FT232 chip, and figuring out whether I need to have the series resistors for it or not.

TIA,
Kesh
Pages: [1]