Pages: [1]   Go Down
Author Topic: Digital Input Question  (Read 984 times)
0 Members and 1 Guest are viewing this topic.
0
Offline Offline
Newbie
*
Karma: 0
Posts: 6
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hey all. I've got a barcode reader that gives:

Quote
"A series of pulses with widths proportional to the widths of the bar code elements being scanned. A low output represents a bar, and a high output represents a space. The frequency of the pulses depends on the density of the symbol being scanned."
--LT 1800 Product Reference Guide

How would I read this? I've tried reading it as serial, but I don't think that's how it was meant to be done. Right now i'm toying with pulseIn HIGH and LOW, but I have a feeling that:
Code:
 duration1 = pulseIn(barCode, HIGH);
  duration2 = pulseIn(barCode, LOW);
misses a whole LOW, HIGH series in between, based on its description. If the first pulseIn waits for a HIGH, then counts until it hits a LOW, the next pulseIn wouldn't start on that LOW, it would start on the next LOW, right?

I mean, with that in my loop, I get about half the number of HIGH/LOW that I should for a barcode.

How *should* I do this? Is the PWM feature on the output only, or is there some kind of PWM input functionset?
« Last Edit: August 27, 2006, 11:23:11 pm by Shadyman » Logged

Forum Administrator
Cambridge, MA
Offline Offline
Faraday Member
*****
Karma: 12
Posts: 3538
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

If the input on a pin is already LOW when you call pulseIn(pin, LOW), it will start measuring that pulse (without waiting for the to go HIGH and return to LOW).  There is, however, some setup each time you call pulseIn(), which might mean you miss some pulses.  Do you have an idea of how long the pulses you do read are?

Since you're always reading on the same pin, you could try only doing the setup once.  This should make the pulse reading much faster, and hopefully mean you miss fewer pulses.  That is, you could put the first part of the pulseIn() code (modified slightly from what's in ARDUINO/lib/targets/arduino/wiring.c) in setup():

Code:
int pin = 10; // or whatever
int r;
int bit;
int mask;
int lowstate;
int hightstate;

extern "C" {
  int digitalPinToPort(int);
  int digitalPinToBit(int);
}

void setup()
{
  // cache the port and bit of the pin in order to speed up the
  // pulse width measuring loop and achieve finer resolution.  calling
  // digitalWrite() instead yields much coarser resolution.
  r = port_to_input[digitalPinToPort(pin)];
  bit = digitalPinToBit(pin);
  mask = 1 << bit;
  lowstate = LOW << bit;
  highstate = HIGH << bit;
}

And then, when you want to measure a pulse, use the rest of the pulseIn() code (again, modified slightly):

Code:
void loop()
{
  // ...

  int state;
  unsigned long width;
  unsigned long us;

  // ...

  /////////////////////////////// This code reads a single pulse: //

  width = 0;
  // compute the desired bit pattern for the port reading (e.g. set or
  // clear the bit corresponding to the pin being read).
  state = highstate; // or: state = lowstate;

  // wait for the pulse to start
  while ((_SFR_IO8(r) & mask) != state)
    ;

  // wait for the pulse to stop
  while ((_SFR_IO8(r) & mask) == state)
    width++;

  us = width * (16000000UL / F_CPU) * 20 / 23;
    
  // done reading a single pulse. //////////////////////////////////

  // ...      
}
Logged

Pages: [1]   Go Up
Jump to: