gillham / logic_analyzer

Implementation of a SUMP compatible logic analyzer for the Arduino
Other
463 stars 99 forks source link

Capturing Analog Data on Digital Pins? #21

Closed chino closed 9 years ago

chino commented 9 years ago

I have a setup where I'm listening to slight fluctuations on an analog pin.

How would I move such a test over to the digital pins so the logic-analyzer can read the values?

From my own testing the digital pin always seems to read 0 and then when trying with the logic-analyzer I also see no data coming through.

On the analog pin I will see fluctuations of +/-(4-20) from the IR detector.

Thanks for any help.

gillham commented 9 years ago

Sounds like you might be only seeing around 100mV on that pin. You need 2V+ to register as a logic high on a 5V device.
Try running the sketch on this page: http://arduino.cc/en/Tutorial/ReadAnalogVoltage And seeing what voltages it reports on your pin. You might need to boost the voltage off your IR detector such that it is 3.3V or higher at peak.

chino commented 9 years ago

Well what confuses me too is the logic-analyzer doesn't seem to use CHANPIN.

Does that treat the digital pin just like an analog pin would work or does it still need a digital signal?

If it needs a digital signal does that mean the logic-analyzer in current form isn't setup for rendering analog data?

gillham commented 9 years ago

Please test one of the ports on 'CHANPIN' with a 1k resistor to 5v on the Arduino and the other pins to ground. You can also enable the '#if 0' block in setup() to turn on the sample data via timer and validate you see it. I haven't used the AGLA in a few months, but the code hasn't changed so you should be able to capture on an Uno or 2009.

A logic analyzer is for digital logic only, you need an oscilloscope for analog. So if your source isn't either logic 0 (ground effectively) or logic 1 (2v+ in theory, 3.3V-5V commonly) then you won't benefit from a logic analyzer.

chino commented 9 years ago

oops sorry I meant to say that it doesn't use pluseIn but instead uses CHANPIN which I figure is probably a lower level AVR interface.

Ah I guess it's good to note that in the readme too since I discovered this project while reading around to see if I could just use my arduino to visualize analog data.

I followed this link and it seemed to imply that he was able to listen to listen to the raw ir data (pin 8 is raw and 9 is modulated)(http://letsmakerobots.com/node/31422) which would normally I think be read using an analog pin.

gillham commented 9 years ago

The 'CHANPIN' is just a define I do higher in the code. I read the register for the port directly, skipping the Arduino digitalRead() as it is slow.

The IR data that guy is looking at is digital. What it the part number of the IR receiver you're trying to read?

chino commented 9 years ago

I just have a straight IR detector plugged in not a modulator.

Ah I didn't check the other file to see: #define CHANPIN PIND.

But you just keep doing logicdata[i] = CHANPIN; ?

chino commented 9 years ago

Ah, ok, been doing some more reading and now I see how PIND and what not works. I wasn't aware of that before.

chino commented 9 years ago

I guess similarly the reason you didn't use digitalRead is fact that it does all of this other stuff inside of it:

https://github.com/arduino/Arduino/blob/master/hardware/arduino/cores/arduino/wiring_digital.c#L164

chino commented 9 years ago

Most of the stuff in that function just references is static data.

Would be cool if it was programmed in a way that it resolved most of those checks at compile time.

The only thing that would be left then is possibly turning off PWM (which I bet has confused someone at some point).

gillham commented 9 years ago

Exactly. The loop below reads PINB and stores to a 1KB array. The disassembly is below it.

void testloop() {
  int i;
  for (i = 0 ; i < 1024 ; i++)
    myglobal[i] = PINB;
}
00000000 <_Z8testloopv>:
   0:   e0 e0           ldi r30, 0x00   ; 0
   2:   f0 e0           ldi r31, 0x00   ; 0
   4:   83 b1           in  r24, 0x03   ; 3
   6:   81 93           st  Z+, r24
   8:   80 e0           ldi r24, 0x00   ; 0
   a:   e0 30           cpi r30, 0x00   ; 0
   c:   f8 07           cpc r31, r24
   e:   01 f4           brne    .+0         ; 0x10 <_Z8testloopv+0x10>
  10:   08 95           ret

Whereas the unrolled version just reads from PINB and stores to memory without the extra checks.

00000000 <_Z9testloop2v>:
   0:   83 b1           in  r24, 0x03   ; 3
   2:   80 93 00 00     sts 0x0000, r24
   6:   83 b1           in  r24, 0x03   ; 3
   8:   80 93 00 00     sts 0x0000, r24
   c:   83 b1           in  r24, 0x03   ; 3
   e:   80 93 00 00     sts 0x0000, r24
  12:   83 b1           in  r24, 0x03   ; 3
  14:   80 93 00 00     sts 0x0000, r24
  18:   83 b1           in  r24, 0x03   ; 3
  1a:   80 93 00 00     sts 0x0000, r24
  1e:   83 b1           in  r24, 0x03   ; 3
  20:   80 93 00 00     sts 0x0000, r24
  24:   83 b1           in  r24, 0x03   ; 3
  26:   80 93 00 00     sts 0x0000, r24
  2a:   83 b1           in  r24, 0x03   ; 3
  2c:   80 93 00 00     sts 0x0000, r24
  30:   08 95           ret

As you can see the unrolled takes up a lot more space, but only uses two instructions per sample.

chino commented 9 years ago

Yea, and concerns like cpu cache lines don't really make sense in this architecture either since the program memory is separate and directly accessed I think?

gillham commented 9 years ago

Yes, no cache issues to worry about on this chip. :) If you're interested in reducing overhead for built-in Arduino functions check out https://code.google.com/p/arduino-lite/ which uses preprocessor macros for a number of functions. The code hasn't been updated in a while, but it is still interesting. It works without the Arduino IDE, just avr-gcc etc, but it is interesting just to read the code.